给自己的网站搞上免费HTTPS

  • A+
所属分类:linux技术
摘要

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


背景

租了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 */12 * * * certbot renew --quiet --renew-hook "/etc/init.d/nginx reload"