为你的网站切换 HTTPS 协议

网站配备 HTTPS 协议已经是潮流了,不论是出于防止运营商劫持的原因还是为了提高网站的安全性,各大网站都换上了 HTTPS 协议。作为个人开发者,要购买一个证书还是非常昂贵的。幸好 Let’s Encrypt 横空出世、救苦救难,不仅能够提供免费的证书,最近还支持了申请通配符域名证书。此文记录通配符域名证书申请的全过程。

申请证书

我选择使用acme.sh来申请证书。首先使用如下命令安装acme.sh

1
curl https://get.acme.sh | sh

acme.sh会默认安装到~/.acme.sh目录,当你看到屏幕输出Install success!时就表示安装成功了。由于安装过程中修改了~/.bashrc文件,所以最好手动source一次该文件。

acme.sh可以自动配置 DNS,不用我们手动去操作解析记录,所以申请证书之前我们需要申明两个环境变量以供其使用。如果你的域名在阿里云购买,请做如下环境变量声明:

1
2
export Ali_Key=YOUR_KEY
export Ali_Secret=YOUR_SECRET

这两个变量的值可以在阿里云控制台获取到;如果你的域名在 GoDaddy.com 购买,请前往GoDaddy 开发者中心获取。

配置完成后就可以开始申请我们自己的域名证书了。注意这里我申请的是一个通配符域名证书,也就是说申请到的证书可以用于我一级域名及其下的所有二级域名(如果需要对三级域名生效,需要单独为二级域名生成通配符证书)。执行如下命令:

1
acme.sh --issue --dns dns_ali -d your_domain.com -d *.your_domain.com

如果是在腾讯云购买的域名,可以在DNSPod 安全设置页面创建 API Token,然后进行如下配置:

1
2
export DP_Id="YOUR_ID"
export DP_Key="YOUR_KEY"

相应的证书申请命令为:

1
acme.sh --issue --dns dns_dp -d your_domain.com -d *.your_domain.com

其他域名服务商请参考acme.sh 项目说明。根据域名服务商的不同,你需要修改--dns参数后的值来确保acme.sh能够成功的操作你域名的解析。整个申请过程大概要 2 分钟,当看到Cert success.时就表示申请成功了。根据提示,域名证书会放置在~/acme.sh/your_domain.com目录下。

需要注意的是,acme.sh会自动生成一个定时任务,在每天凌晨 00:00 自动检测过期的域名证书并自动续期。如果你不需要此功能,可以手动删除定时任务和~/.acme.sh目录。

配置 Nginx

接下来我们将申请到的域名证书配置到 Nginx 服务器上。首先需要将用户发起的 HTTP 请求全部强制跳转到 HTTPS,然后配置我们的 HTTPS 服务器。以下是我个人的配置信息,仅供参考。

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
server {
listen 80;
server_name your_domain.com www.your_domain.com;
return 301 https://$server_name$request_uri;
}

server {
listen 443 ssl;
server_name your_domain.com www.your_domain.com;

ssl on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;

ssl_certificate YOUR_CERT_STORE_PATH/fullchain.cer;
ssl_certificate_key YOUR_CERT_STORE_PATH/your_domain.com.key;
ssl_trusted_certificate YOUR_CERT_STORE_PATH/ca.cer;

ssl_dhparam YOUR_CERT_STORE_PATH/dhparam.pem;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';

location / {
# YOUR_CONFIGURATION
}
}

配置中的fullchain.ceryour_domain.com.keyca.cer都是上一步我们申请域名证书时产生的。dhparam.pem是 DH-Key 交换秘钥,RSA 证书默认的交换秘钥只有 1024 位,所以特地生成这个 4096 位的秘钥来增强安全性。使用以下命令生成:

1
openssl dhparam -out dhparam.pem 4096

这时重新加载你的 Nginx 配置文件,看看是不是所有访问链接都变成了 HTTPS 呢?