给自己的网站搞上免费HTTPS

背景

租了ESC和域名, 跑了3个小网站和2个服务, 但打开网站时总提示不安全(即http)
用Nginx做的代理, 跑在Debian 9上
搜罗了下https证书供应商, 大都收费或有免费试用期, 个人小网站不值得用他们
最终选了certbot来获取Let’s Encrypt证书

Certbot 介绍

  • Certbot是Electronic Frontier Foundation(EFF)旗下的一个项目。EFF是一家501(c)3非营利组织,总部设在加州旧金山,致力于保护数字隐私、言论自由和创新。

  • Certbot是一个免费的开源软件工具,可以在网站上自动使用Let’s Encrypt(提供TLS证书的非盈利性证书颁发机构)证书来启用HTTPS

安装方法(debian/ubuntu)为例

  • 借助snap(一款类似apt-get的工具)

    $ sudo apt update
    $ sudo apt install snapd
    $ sudo snap install core; sudo snap refresh core   # 更新至最新
    
  • 安装certbot

    $ sudo snap install --classic certbot
    $ sudo ln -s /snap/bin/certbot /usr/bin/certbot    # 加入到命令行
    $ sudo snap set certbot trust-plugin-with-root=ok  # 确认插件包含级别,可以略过
    

生成证书

我的情况是Nginx做代理, 多个二级域名分开配置, 即在 /etc/nginx/nginx.conf中只配置公共选项, 非公共的在/etc/nginx/sites-available/目录下面
  1. 注释掉nginx.conf 关于 ssl_certificate 和 ssl_certificate_key ---- 没有就略过

  2. sites-available下配置好server并设置软连接到sites-enabled ---- 非常重要, certbot会获取里面的配置

    # 如 mock.z417.com 的配置
    $ sudo ln -s /etc/nginx/sites-available/mock /etc/nginx/sites-enabled/
    
    • 我的mock是这么配置的, 请结合实际修改
    server {
         listen 80;
         server_name mock.z417.com;
         return 301 https://$server_name:443$request_uri;
    }
    
    server {
         charset utf-8;
         server_name mock.z417.com;
         access_log /var/log/nginx/mock_access.log main;
    
         listen 443 ssl http2;
    
         location ~*^.+$ {
               proxy_pass http://127.0.0.1:5000;
               proxy_set_header Host $host;
               proxy_set_header Upgrade $http_upgrade;
               proxy_set_header Connection upgrade;
               proxy_set_header Accept-Encoding gzip;
               proxy_set_header X-Real-IP $remote_addr;
               proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         }
    }
    
  3. 重启nginx且确认未报错

    $ sudo systemctl restart nginx
    
  4. 删除certbot原来的证书数据 --- 没有就略过

    $ sudo rm -rf /etc/letsencrypt
    
  5. 开始制作证书

    $ sudo certbot certonly --nginx
    
    • 会依次提示输入"邮箱"; "A": 同意协议; "N": 是否接收邮件通知; "回车": 给所有域名配置证书

    • 执行完会提示你证书有效期只有90天, 没关系, 后面我们设置定时任务, 帮我们自动更新

  6. 检查是否成功生成

    $ sudo ls /etc/letsencrypt/live/z417.com    # z417.com 改成你自己的域名
    cert.pem  chain.pem  fullchain.pem  privkey.pem  README
    

使用证书

  1. 配置/etc/nginx/nign.conf, 如我的就配置成了下面这样t

    • 注意ssl_certificatessl_certificate_key配置成自己的路径,其他可以复制
    user www-data;
    worker_processes auto;
    worker_rlimit_nofile 51200;
    
    error_log  /var/log/nginx/error.log warn;
    pid /run/nginx.pid;
    include /etc/nginx/modules-enabled/*.conf;
    
    events {
         worker_connections 768;
         use epoll;
         multi_accept on;
    }
    
    http {
    
         ##
         # Basic Settings
         ##
         client_body_buffer_size 32k;
         client_header_buffer_size 2k;
         client_max_body_size 2m;
    
         sendfile on;
         tcp_nopush on;
         tcp_nodelay on;
         keepalive_timeout 65;
         types_hash_max_size 2048;
         server_tokens off;
    
         # server_names_hash_bucket_size 64;
         # server_name_in_redirect off;
    
         limit_req_zone $binary_remote_addr zone=one:10m rate=30r/s;
         include /etc/nginx/mime.types;
         default_type application/octet-stream;
    
         ##
         # SSL Settings
         ##
    
         ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
         ssl_prefer_server_ciphers on;
    
         ssl_certificate /etc/letsencrypt/live/z417.com/fullchain.pem;
         ssl_certificate_key /etc/letsencrypt/live/z417.com/privkey.pem;
         ssl_session_cache shared:SSL:10m;
         ssl_session_timeout 5m;
         ssl_session_tickets off;
         ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    
         ##
         # header Settings
         ##
    
         add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
         add_header X-Xss-Protection 1;
         add_header X-Content-Type-Options nosniff;
         # add_header X-Frame-Options DENY;
    
         add_header Access-Control-Allow-Origin *;
         add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
         add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
         add_header Access-Control-Allow-Credentials true;
         add_header Access-Control-Max-Age 86400;
    
         ##
         # Logging Settings
         ##
         log_not_found off;
         log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                       '$status $body_bytes_sent "$http_referer" '
                       '"$http_user_agent" "$http_x_forwarded_for"';
         access_log /var/log/nginx/access.log;
         error_log /var/log/nginx/error.log;
    
         ##
         # Gzip Settings
         ##
    
         gzip on;
         gzip_disable "msie6";
    
         gzip_vary on;
         gzip_min_length  1k;
         # gzip_proxied any;
         gzip_comp_level 2;
         gzip_buffers 16 8k;
         gzip_http_version 1.0;
         gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
    
         ##
         # Virtual Host Configs
         ##
    
         include /etc/nginx/conf.d/*.conf;
         include /etc/nginx/sites-enabled/*;
    }
    
  2. 测试nginx配置是否有错并加载配置

    $ sudo nginx -t                    # 检查配置是否有效
    $ sudo systemctl reload nginx      # 重新加载nginx配置, 或用restart也行
    

定时任务更新证书

$ sudo crontab -e
0 0 1 */3 * certbot renew --quiet --renew-hook "/etc/init.d/nginx reload"
posted @ 2020-11-19 11:49  z417  阅读(689)  评论(0编辑  收藏  举报