使用https

之前一直没有给站点添加https,考虑到我的服务器在国外,速度不快,加了https连接更加费时,但这两天发现几个问题,手机上查看站点时,会被植入广告,这个实在不能忍,于是决定为nginx配置https支持。

证书选择

OpenSSL生成

一开始,我直接使用了openssl生成了一套证书,两三下配好之后,发现在浏览器中打开时,会有安全提醒,说证书未认证云云,更要命的是,在微信自带的浏览器中,直接就无法打开了,应该是微信考虑到安全问题,把未经CA验证证书的站点全部不显示了。呃,没办法,只能找一家CA签发的证书了。

购买DV证书

证书分成3类,我这里的需求只要一个域名验证(Domain Verification)证书即可,倒不是很贵,一两百一年,一些云计算平台也支持申请免费的证书,但要求域名有备案什么的,看起来都好复杂。

Let's encrypt

搜索的过程中,发现let's encrypt提供证书服务,虽然证书每3个月需要续签一次,但是有相关的工具可以自动操作,而且是免费的。

使用Let's encrypt

证书的生成非常方便,几个命令就搞定。

安装certbot

Debian安装的话,直接apt-get install就好了。


$ sudo apt-get install certbot -t jessie-backports

更多平台可以在https://certbot.eff.org/选择。

生成证书

安装完毕后,就可以使用certbot生成安全证书了。如果nignx服务器已经开启了443端口,需要暂时先把nginx停掉。输入命令


$ sudo certbot certonly --standalone -d hoyt-tian.com -d www.hoyt-tian.com

==Let's encrypt暂时还不支持wildcard domain,不能写成-d *.hoyt-tian.com,因此需要逐一添加所有的二级域名。==好在二级域名不算多,而且2018年以后Let's encrypt会正式支持wildcard domain。

命令行会对每一个-d给定的域名进行dns解析测试,都没有问题的话,证书就自动生成好了,在/etc/letsencrypt/live/your.domain目录下就能看到全部的安全文件。最好把letsencrypt的根证书也一并下载下来,和生成的chain.pem合并成root_ca_cert_plus_intermediates。


$sudo wget https://letsencrypt.org/certs/isrgrootx1.pem
cat isrgrootx1.pem chain.pem > root_ca_cert_plus_intermediates

到这里,证书的生成工作就全部完成了。

Nginx配置

生成dhparam文件

首先为nginx生成dhparam文件,这是迪菲-赫尔曼加密法需要用到的。输入命令


sudo openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048

2048应该够了,数值越大越安全,等的也越久。

配置ssl证书

为了让所有的server共享证书配置信息,可以把配置项直接添加到$nginx_home/nginx.conf文件中,而不是一个server一个server的独立配置。在其中的http设置中,可以找到SSL Setting,默认情况下都是注释,开始手动添加吧。(记得打开文件时要有写入权限,最好sudo vi)。

ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_certificate $letsencrypt_home/live/hoyt-tian.com/fullchain.pem;
ssl_certificate_key $letsencrypt_home/live/hoyt-tian.com/privkey.pem;
ssl_dhparam $nginx_home/ssl/dhparam.pem;
ssl_trusted_certificate $letsencrypt_home/live/hoyt-tian.com/root_ca_cert_plus_intermediates;

nginx设置好ssl功能之后,接下来还要做的工作,就是让server同时监听80端口和443端口,并且自动将80端口的请求转发到443端口。

https重定向

为了实现https重定向功能,为每个独立的server进行配置更新。将原来的listen 80改为listen 443,并添加ssl on;然后在原来的server后面新建一个server,只需要3项配置,listen、server_name和return,如下:

server{
listen 80;
server_name www.hoyt-tian.com;
return 301 https://www.hoyt-tian.com$request_uri;
}

如果还有其他server需要开启ssl,同样配置即可。这样当有http请求时,就会被自动重定向为https请求。

到这里nginx的配置就完成了,使用sudo nginx -t可以测试配置文件是否有误,全部通过后,就可以打开nginx服务器了。

定时更新

Let's encrypt的证书有效期只有3个月,因此需要设置一个定时更新任务。直接使用Debian的systemctl就可以添加定时任务。

在/etc/systemd/system目录下创建letsencrypt.service和letsencrypt.timer两个文件。其中.service文件中包含具体的更新命令,而.timer文件中则定义了定时启动规则。差不多每个月执行一次更新命令即可。

[Unit]
Description=Monthly renewal of certificates

[Timer]
OnCalendar= *-*-11 03:00:00
Persistent=true

[Install]
WantedBy=timers.target

这样每个月的11号凌晨3点就会触发更新脚本。
.service文件内容如下:

[Unit]
Description=Let's Encrypt update

[Service]
Type=oneshot
ExecStart=/usr/bin/certbot renew --quiet --agree-tos
ExecStartPost=/usr/sbin/nginx -s reload

吐槽

国内抄袭disque的那个谁啊,好歹支持一下https啊!知不知道什么叫一颗老鼠屎坏了一锅汤啊!!

Show Comments

Get the latest posts delivered right to your inbox.