两步搞定 TLS1.2 + HSTS + HTTP/2 配置

作者: 左蓝 | 来源:发表于2017-01-09 22:48 被阅读822次

    之前看到一个安全测评网站:SSL 服务器测试,就测了一下,然后发现才 A 级,“强迫症”病发的我想提升到最高级 A+ ,经过一番折腾最后评级如下:

    网站评级

    今天晚上闲来无事把资料整理一下,发出来,如果你有兴趣就折腾一下吧~

    这是一篇把普通网站升级到 TLS1.2 + HSTS + HTTP/2 的文章,至于什么是 HSTS 之类的自己百度。

    什么是 HSTS

    TLS1.2 和 HTTP/2 相信大家都熟悉,但是 HSTS 相对来说比较少听到。

    HSTS 是 “HTTP Strict Transport Security”(HTTP 严格安全传输)的缩写,开启了这项设置以后,主流浏览器会强制性地使用 HTTPS 来请求资源,能够更加有效地保护你网站和用户的数据安全。

    一般情况(未启用 HSTS),浏览器会允许用户在了解了安全风险之后继续使用不安全的连接来访问,但如果启用了 HSTS,则不允许这样做,所以你得有一定要长期使用 HTTPS 的打算,才能启动 HSTS。

    第一步、获取 SSL 证书

    首先我的站点负载工具是 Nginx,SSL 证书从 Certbot 申请,先克隆仓库,然后生成证书:

    $ sudo git clone https://github.com/certbot/certbot /opt/certbot
    $ cd /opt/certbot
    $ ./letsencrypt-auto certonly -d example.com -d www.example.com
    

    域名改你自己的,然后选择第二个模式,安装一些东西,等一会就好了(先关掉占用80端口和443端口的程序,避免冲突,申请结束后再恢复即可):


    选择第二个模式

    生成下面文字即为成功:

    IMPORTANT NOTES:
     - Congratulations! Your certificate and chain have been saved at
    .........
    .........
     - If you like Let's Encrypt, please consider supporting our work by:
       Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
       Donating to EFF:                    https://eff.org/donate-le
    

    为了确保证书更新正常,执行下面这句验证一下:

    /opt/certbot/letsencrypt-auto renew 
    

    然后用 openssl 生成一个中间证书,后面的 2048 你可以自己根据服务器性能修改,比如改成 4096 之类的,数值越大加密程度越高:

    sudo openssl dhparam -out ~/nginx/certs/dhparam.pem 2048
    

    第二步、配置 Nginx

    前面生成的文件不用移动,后面会一步搞定处理这些,那么接下来就好办了,首先新建一个 Nginx 配置文件:

    sudo vim ~/nginx/nginx.conf

    server {
        listen 80 default_server;
        listen [::]:80 default_server;
        # 这里改成你的域名
        server_name example.com www.example.com;
        server_tokens off;
        location /generate_204 { return 204; }
        # Discourage deep links by using a permanent redirect to home page of HTTPS site
        return 301 https://$host;
        # Alternatively, redirect all HTTP links to the matching HTTPS page
        return 301 https://$host$request_uri;
    }
    
    server {
        listen 443 ssl http2 default_server;
        listen [::]:443 ssl http2 default_server;
        # 这里改成你的域名
        server_name example.com www.example.com;
        server_tokens off;
        location /generate_204 { return 204; }
    
        # ssl on;
        ################
        # SSL 配置,如果你是完全按照上面命令行操作,分毫不改下面内容即可
        ################
        ssl_certificate /etc/nginx/certs/fullchain.pem;
        ssl_certificate_key /etc/nginx/certs/privkey.pem;
        ################
        # from https://cipherli.st/
        # and https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
        ################
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;
        # ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
        ssl_ciphers "EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5:!MEDIUM:!LOW";
        ssl_ecdh_curve secp384r1;
        ssl_session_cache shared:SSL:10m;
        ssl_session_tickets off;
        ssl_stapling on;
        ssl_stapling_verify on;
        resolver 8.8.8.8 8.8.4.4 valid=300s;
        resolver_timeout 5s;
        ####################################
        # 警告:如果你不能保证全部子域开启 HTTPS,请不要开启 HSTS,不然浏览器将拒绝打开你的网站。
        add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
        # add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";
        ####################################
        add_header X-Frame-Options DENY;
        add_header X-Content-Type-Options nosniff;
    
        ssl_dhparam /etc/nginx/certs/dhparam.pem;
        ################
        # SSL END
        ################
        add_header 'Access-Control-Allow-Origin' *;
        add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS';
        location / {
            # 这里的 IP:Port 改成你服务器的信息,比如我的博客端口就是 9090
            proxy_pass http://12.34.56.78:9090;
            proxy_redirect off;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }
    

    保存退出,你已经完成了全部准备工作,剩下只需要启动即可。


    好了,到这里就结束了教程,如果你的 Nginx 足够新,支持 HTTP/2,那么后面就不用看了,直接启动你的 Nginx 即可。
    如果不支持 HTTP/2,你将无法启动 Nginx,会有模块报错。你需要重新编译最新版的 OpenSSL。


    第三步、使用 Docker 启动 Nginx 服务

    为什么使用 Docker 来启动 Nginx?因为我懒得重新编译 Nginx 更新 OpenSSL,使用官方的 nginx:alpine 可以马上拥有最新版本的 Nginx 和最新版的 OpenSSL 啊。

    如果没有安装 Docker,就先安装吧:

    sudo curl -sSL https://get.docker.com/ | sh

    然后再安装 Docker-Compose:

    $ curl -L https://github.com/docker/compose/releases/download/1.9.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
    $ chmod +x /usr/local/bin/docker-compose
    

    新建一个文件叫做 docker-compose.yml:
    sudo vim ~/nginx/docker-compose.yml
    然后复制粘贴下面内容,修改域名即可。

    version: '2'
    services:
      nginx:
        container_name: nginx
        image: nginx
        privileged: true
        volumes:
          - "~/nginx/:/etc/nginx/conf.d/"
          - "~/nginx/certs/dhparam.pem:/etc/nginx/certs/dhparam.pem:ro"
          # 域名改成你的(这一句注释不要复制进去)
          - "/etc/letsencrypt/live/example.com/cert.pem:/etc/nginx/certs/cert.pem:ro"
          - "/etc/letsencrypt/live/example.com/chain.pem:/etc/nginx/certs/chain.pem:ro"
          - "/etc/letsencrypt/live/example.com/fullchain.pem:/etc/nginx/certs/fullchain.pem:ro"
          - "/etc/letsencrypt/live/example.com/privkey.pem:/etc/nginx/certs/privkey.pem:ro"
        ports:
          - "80:80"
          - "443:443"
        restart: always
    

    搞定之后执行 dokcer-compose up -d 就可以跑起来了,现在打开你网站,已经同时启用 TLS1.2 + HSTS + HTTP/2 了!

    设置自动更新证书:

    $ crontab -e
    30 2 * * 1 /opt/certbot/letsencrypt-auto renew >> /var/log/le-renew.log
    35 2 * * 1 docker restart nginx
    

    申请加入 HSTS Preload List

    HSTS 必须要在浏览器访问过你的网站一次以后才会生效,如果希望提前生效,需要申请 HSTS Preloading List。

    目前这个 Preload List 由 Google Chrome 维护,Chrome、Firefox、Safari、IE 11 和 Microsoft Edge 都在使用。如果要想把自己的域名加进这个列表,首先需要满足以下条件:

    • 拥有合法的证书(如果使用 SHA-1 证书,过期时间必须早于 2016 年);
    • 将所有 HTTP 流量重定向到 HTTPS;
    • 确保所有子域名都启用了 HTTPS;
    • 输出 HSTS 响应头:max-age 不能低于 18 周(10886400 秒);
    • 必须指定 includeSubdomains 参数;
    • 必须指定 preload 参数;

    觉得妥了就去 HSTS Preload List (hstspreload.appspot.com) 这个页面申请。

    HSTS 申请页面

    在唯一一个文本框输入你的网站即可,这个列表是人工审核,因此可能需要一段时间。申请成功之后查询会显示:“Status: example.com is currently preloaded.”

    结果:成功加入 HSTS 列表

    经过将近两个月的时间,域名已经进入正式版 HSTS 列表。

    申请成功

    最后提醒一句,如果不能保证你所有域名都使用HTTPS的话请不要使用HSTS,不然浏览器会拒绝打开你的网站。

    相关文章

      网友评论

        本文标题:两步搞定 TLS1.2 + HSTS + HTTP/2 配置

        本文链接:https://www.haomeiwen.com/subject/vwnhbttx.html