0%

Nginx上安全协议配置

前面讲过SSL协议的细节,作为HTTPS的基础安全协议,SSL的重要性如何强调都不为过。近年来,网站流量劫持等安全问题屡有发生,为网站运营工作带来诸多困扰,另一方面,Google及苹果等巨头公司也陆续出具公告,全面支持HTTPS,HTTP网站下线开始进入倒计时。

拥抱互联网变革,促进信息技术发展传播,增强网站安全性壁垒,从一件简单的事情做起,这里介绍一下使用Nginx进行SSL证书挂载的过程,将网站HTTP服务升级为HTTPS。(文中涉及到的产品及公司描述并非广告。)

获取证书

证书的有效性由CA赋予,因此,网站所有者需要从一个具有证书颁发能力的机构获取证书,按照证书审核方式的不同,一般CA会提供三种类型的证书,分别是域名型SSL(DV SSL)、企业型SSL(OV SSL)以及增强型SSL(EV SSL)证书,而根据保护的域名数量的不同又分为单域名证书(保护单个域名及www子域名)、通配符型证书(保护域名及域名下多个子域名的安全,通常为*.domain.com通配)及多域名型证书。对于个人站点来说,单域名域名型证书比较合适,不少CA提供此种类型的免费证书申请,CA只需要验证网站的真实性就好了。

这里使用Let’s Encrypt证书为例进行说明,最终需要拿到证书文件、证书私钥文件(及中间证书文件,用于做双向SSL认证,这里就不做展开了)。

通过Let’s Encrypt申请证书的一个比较便利的地方在于,其制定的ACME在线证书续签协议已为大多数CA所接纳,协议2版本将在2018年成为IETF标准协议的一员,官方工具certbot也必将因开放,变得受众更广泛,我使用的操作系统CentOS7也已将certbot加入EPEL仓库,可直接使用yum安装,其他类型的操作系统,可根据官方文档指引,进行安装,过程比较简单。

安装certbot
1
$ yum install certbot

除了certbot,还可使用其它支持ACME的客户端,如acme.sh等,这里也只用certbot为例,获取证书文件。在ACME验证环节中,CA向目标验证服务器请求一个事先约定的文件,certbot提供几种方式对此请求进行响应:

  1. 最简单的一种是使用certbot提供的插件(certbot的nginx插件由于安全性问题,不推荐使用);
  2. 将certbot启动作为web服务器来响应CA请求,但是由于使用到默认端口,需要将web服务器挂起,对于可用率要求比较高的网站来说,也可能不太友好;
    安装certbot
    1
    $ certbot --authenticator standalone --installer nginx --pre-hook "nginx -s stop" --post-hook "nginx"
  3. certbot将验证文件保存在指定目录,配置nginx,将CA的请求分发到该目录下。
    nginx配置
    1
    2
    3
    4
    5
    6
    7
    8
    location ^~ /.well-known/acme-challenge/ {
    default_type "text/plain";
    root /usr/share/nginx/html; # 请根据需要修改
    }

    location = /.well-known/acme-challenge/ {
    return 404;
    }
    部署验证文件
    1
    $ nginx -s restart
    部署验证文件
    1
    2
    3
    $ certbot certonly --webroot -w /usr/share/nginx/html/ -d your.domain.com 
    # certbot可支持同时对多个域名进行签名,使用配置项-d增加域名,但是需要保证的是,在进行签名验证阶段,CA的所有域名验证的http请求能触及本机服务器(本人挂在腾讯云上的一个未备案域名被dnspod劫持,无法访问)
    # 当命令行出现Congratulations时,则申请证书成功,可以在'/etc/letsencrypt/live/your.domain.com/'目录下看到所有需要的证书素材,通过失效日期,可以知道证书的有效时长,目前为3个月,实际上有效期越短,越安全,这在之前的SSL的博客中有说明。

Nginx配置

接下来就是将证书文件配置到Nginx中,过程也比较简单,修改Nginx配置如下

nginx配置
1
2
3
4
5
6
7
8
9
10
server {
listen 443 ssl;
server_name your.domain.com;

ssl_certificate /etc/letsencrypt/live/your.domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your.domain.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/your.domain.com/chain.pem;

// ... other settings ...
}

如果需要将http协议自动跳转到https上,在同域名http server服务下增加

nginx配置
1
rewrite ^(.*) https://$host$1 permanent;

我们之前介绍SSL的时候,还提到过,记录协议传输过程中使用的加密算法可以在握手协议中协商确定,这里我们也可以配置HTTPS服务器支持的加密算法套件

nginx配置
1
2
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
ssl_prefer_server_ciphers on; # 优先使用服务端支持的加密算法

证书自动续签

当证书有效期过后,证书就会失效,访问网站时会被浏览器拦截,certbot也可以进行证书的续签,执行以下命令,可以测试续签过程

模拟更新
1
$ certbot renew --dry-run

如上congratulations,则表示续签正常,将此命令添加到crontab或其他定时任务管理器上,在证书有效期到来之前进行更新。

1
$ 30 2 * * 1 /usr/bin/certbot renew  >> /var/log/le-renew.log

通过指定的日志文件,可以查看续签的结果。

站点的安全检测,可以通过点我点我进行测试。

SSL协议介绍