IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    运维从零单排(二)—— 使用 Let\'s Encrypt 证书在 Nginx 中配置 HTTPS 和 HTTP2

    雨浣潇湘发表于 2018-11-01 13:56:03
    love 0

    写在最前

    本文是运维从零单排系列的第二篇,文中配置环境要求OpenSSL 1.0.2k及以上,Nginx 1.12.0及以上(由1.0.2k及以上版本的OpenSSL编译),Nginx和OpenSSL的安装可参考:
    运维从零单排(一)—— 服务器环境配置(安装Nginx、Node.js、OpenSSL)

    HTTPS已经几乎成为了现代网站的标配,开启HTTPS需要申请SSL证书。SSL证书主要有以下几种:

    SSL证书类型

    1. DV证书(Domain Validation Certificate)
      只提供对数据的加密,但是对提供证书的个人和机构的身份不做验证,申请证书时,CA只验证域名信息,10分钟内即可签发,适合一般个人网站/博客等。
    2. OV证书(Organization Validation Certificate)
      OV SSL 提供了对个人或者机构的审核,申请证书时需要公司信息,1-2天签发。
    3. EV证书(Extended Validation Certificate)
      EV SSL证书遵循全球统一的严格身份验证标准,是目前业界安全级别最高的顶级 (Class 4级)SSL证书。适合金融证券、银行、支付等重点强调网站安全、企业可信形象的网站。

    Let’s Encrypt 证书申请

    Let’s Encrypt是一个免费的,自动化的,开放的证书颁发机构(CA),它是互联网安全研究小组提供(ISRG)的一个服务,有关它的介绍可以看这里:https://letsencrypt.org/about/。

    下面我们以www.zhounan.win为例,来申请Let’s Encrypt的免费SSL证书。

    安装certbot

    certbot是Let’s Encrypt官方推荐的获取证书所需的客户端

    1
    2
    sudo yum install epel-release -y
    sudo yum install certbot -y

    申请证书

    申请过程中需要验证域名归属,验证方式有两种:

    1. Standalone:需要停止当前的Web Server,让出80端口,由客户端内置的Web Server与Let’s Encrypt通信。
    2. Webroot:需要在域名根目录下创建一个临时目录,并要保证外网通过域名可以访问这个目录。
      如果使用第一种方法,更新证书时需要重启 Web 服务器。
      如果已经有Web Server(如Nginx),建议使用第二种方式来进行。

    我们使用第二种方式来申请证书,修改Nginx的配置文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    server {
    listen 80;
    server_name www.example.com;
    root /var/www/html;
    # 如果没有该文件夹则新建一个
    # certbot 会自动在该文件夹下创建一个隐藏文件`.well-known/acme-challenge`
    # 并通过请求这个文件来验证域名归属。
    location ~ /.well-known/acme-challenge {
    allow all;
    }
    }
    # 重启Nginx
    systemctl restart nginx.service

    运行如下命令来申请证书

    1
    certbot certonly --webroot -w /var/www/html/ -d zhounan.win -d www.zhounan.win -d api.zhounan.win

    具体参数用法可以参考这里:https://certbot.eff.org/#centosrhel7-nginx
    注意Let’s Encrypt暂时不支持泛域名(*.zhounan.win)
    执行上述命令后会依次要求输入邮箱、同意协议、选择是否共享邮箱,注意邮箱需要输入真实邮箱以便能接收到Let’s Encrypt的邮件。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    Saving debug log to /var/log/letsencrypt/letsencrypt.log
    Enter email address (used for urgent renewal and security notices) (Enter 'c' to
    cancel): test@163.com

    Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org

    -------------------------------------------------------------------------------
    Please read the Terms of Service at
    https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf. You must agree
    in order to register with the ACME server at
    https://acme-v01.api.letsencrypt.org/directory
    -------------------------------------------------------------------------------
    (A)gree/(C)ancel: A

    -------------------------------------------------------------------------------
    Would you be willing to share your email address with the Electronic Frontier
    Foundation, a founding partner of the Let's Encrypt project and the non-profit
    organization that develops Certbot? We'd like to send you email about EFF and
    our work to encrypt the web, protect its users and defend digital rights.
    -------------------------------------------------------------------------------
    (Y)es/(N)o: N

    完成之后稍等片刻即可看到如下信息:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    IMPORTANT NOTES:
    - Congratulations! Your certificate and chain have been saved at
    /etc/letsencrypt/live/zhounan.win/fullchain.pem. Your cert will
    expire on 2017-07-25. To obtain a new or tweaked version of this
    certificate in the future, simply run certbot again. To
    non-interactively renew *all* of your certificates, run "certbot
    renew"
    - Your account credentials have been saved in your Certbot
    configuration directory at /etc/letsencrypt. You should make a
    secure backup of this folder now. This configuration directory will
    also contain certificates and private keys obtained by Certbot so
    making regular backups of this folder is ideal.
    - If you like Certbot, please consider supporting our work by:

    Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
    Donating to EFF: https://eff.org/donate-le

    证书已经生成完毕,保存在/etc/letsencrypt/live/zhounan.win/文件夹内。

    生成dhparam.pem

    为了更好的加密,我们进一步配置PFS(Perfect Forward Secrecy)。

    Forward Secrecy的概念很简单:客户端和服务器协商一个永不重用的密钥,并在会话结束时销毁它。服务器上的 RSA 私钥用于客户端和服务器之间的 Diffie-Hellman 密钥交换签名。从 Diffie-Hellman 握手中获取的预主密钥会用于之后的编码。因为预主密钥是特定于客户端和服务器之间建立的某个连接,并且只用在一个限定的时间内,所以称作短暂模式(Ephemeral)。如果使用Forward Secrecy,攻击者取得了一个服务器的私钥,他是不能解码之前的通讯信息的。这个私钥仅用于 Diffie Hellman 握手签名,并不会泄露预主密钥。Diffie Hellman 算法会确保预主密钥绝不会离开客户端和服务器,而且不能被中间人攻击所拦截。所有版本的 nginx 都依赖于 OpenSSL 给 Diffie-Hellman 的输入参数。如果不特别声明,将使用 OpenSSL 的默认设置,1024 位密钥,因为我们正在使用 2048 位证书,所以要有一个更强大的 DH。

    我们可以使用下面的命令来生成它:

    1
    sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

    Nginx配置

    Mozilla为我们提供了一个SSL配置生成器:https://mozilla.github.io/server-side-tls/ssl-config-generator/
    在这里选择了服务器和相应的版本之后,它会为我们提供一份安全的SSL配置,修改一下文件路径并加入到nginx的配置中即可。

    下面是一份较为完整的nginx.conf配置文件,供参考。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    #user  nobody;
    worker_processes 1;

    #error_log logs/error.log;
    #error_log logs/error.log notice;
    #error_log logs/error.log info;

    #pid logs/nginx.pid;

    events {
    worker_connections 1024;
    }

    http {
    include mime.types;
    default_type application/octet-stream;

    #access_log logs/access.log main;

    sendfile on;
    #tcp_nopush on;

    keepalive_timeout 65;

    gzip on;
    gzip_min_length 1k;
    gzip_buffers 4 16k;
    gzip_http_version 1.0;
    gzip_comp_level 6;
    gzip_types text/plain text/css text/javascript application/json application/javascript application/x-javascript application/xml;
    gzip_vary on;

    include /etc/nginx/conf.d/*.conf;

    server {
    listen 80 default_server;
    listen [::]:80 default_server;
    #永久重定向到https站点
    return 301 https://$host$request_uri;
    }

    server {
    # 开启HTTP2,需要OpenSSL版本大于1.0.2,Nginx版本大于1.9.12
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    # certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
    # fullchain.pem和privkey.pem文件路径
    ssl_certificate /etc/letsencrypt/live/zhounan.win/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/zhounan.win/privkey.pem;
    # dhparam.pem文件路径
    ssl_dhparam /etc/ssl/certs/dhparam.pem;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;

    # modern configuration. tweak to your needs.
    ssl_protocols TLSv1.2;
    #可选的加密算法,越靠前的优先级越高
    ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
    #在 SSLv3 或 TLSv1 握手过程一般使用客户端的首选算法,如果启用下面的配置,则会使用服务器端的首选算法.
    ssl_prefer_server_ciphers on;

    # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
    add_header Strict-Transport-Security max-age=15768000;

    # OCSP Stapling ---
    # fetch OCSP records from URL in ssl_certificate and cache them
    ssl_stapling on;
    ssl_stapling_verify on;

    ## verify chain of trust of OCSP response using Root CA and Intermediate certs
    ssl_trusted_certificate /etc/letsencrypt/live/zhounan.win/chain.pem;

    resolver <IP DNS resolver>;

    location / {
    # 你的项目路径
    root /home/cbg;
    index index.html index.htm;
    }

    #以下配置用于Let's Encrypt服务端和客户端校验目录配置
    location ^~ /.well-known/acme-challenge/ {
    default_type "text/plain";
    root /var/www/html;
    }

    # error_page 404 /404.html;

    # redirect server error pages to the static page /50x.html

    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
    root html;
    }
    }
    }

    配置完成后,重启nginx,访问你的域名,域名前方出现绿色的小锁图标,即说明配置成功。

    测试网站安全性

    Qualys SSL Labs 提供了全面的 SSL 安全性测试,在该链接中填入你的网站地址,即可测试安全性。如果不是A+,可以根据测试结果的提示对配置进行相应修改。

    证书自动续期

    Let’s Encrypt的证书默认有效期只有90天,我们需要配置自动续期。
    可以使用如下命令先模拟自动更新:

    1
    certbot renew --dry-run

    如果出现如下提示则说明配置成功:

    1
    2
    3
    4
    Congratulations, all renewals succeeded. The following certs have been renewed:
    /etc/letsencrypt/live/zhounan.win/fullchain.pem (success)
    ** DRY RUN: simulating 'certbot renew' close to cert expiry
    ** (The test certificates above have not been saved.)

    如果模拟更新正常,则可以使用crontab -e来启用自动任务:

    1
    crontab -e

    增加配置:

    1
    0 1 1 * * /mnt/apps/letsencrypt/certbot-auto renew -renew-hook "/etc/init.d/nginx reload"

    该配置含义为:每月1日凌晨1点执行任务

    参考链接

    http://www.restran.net/2017/01/24/nginx-letsencrypt-https/
    https://www.mzlion.com/CentOS7-Nginx-SSL-Install-Let's-Encrypt.html
    https://certbot.eff.org/#centosrhel7-nginx
    https://www.pupboss.com/nginx-add-ssl/
    http://blog.lzuer.net/2016/10/25/https/



沪ICP备19023445号-2号
友情链接