Nginx 全系列
无论是为了安全还是为了B格(地址栏的小锁),我们都很有必要给自己的网站加 SSL,并使用 HTTPS 访问。
前提:拥有域名#
没有的话一切就无从谈起了。
使用 acme.sh 获取证书#
以下主要参考官方说明。
下载安装#
1
| curl https://get.acme.sh | sh
|
申请证书#
1
| acme.sh --issue -d mydomain.com --nginx --ocsp
|
- 上述命令包含了 OCSP 协议的支持。
- 若同时申请多个域名,可以写多个
-d <domain>
。 - 申请通配符证书需要使用 DNS API,以后再补。
安装证书#
1
2
3
4
| acme.sh --installcert -d <domain>.com \
--key-file /path/to/cert/<domain>.key \
--fullchain-file /path/to/cert/<domain>.crt \
--ca-file /path/to/cert/ca.crt
|
在 Nginx 中配置证书#
以下为推荐配置,参考了 gavinhungry/nginx-tls.conf。大部分内容照抄即可,只需要设置第 6 行的主机名和第 13-15 行的证书,并下载推荐使用的 DH 密钥。
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
| server {
# 监听
listen 443 ssl http2 spdy;
# 主机名
server_name example.com www.example.com;
############
## SSL 设置
############
# 设置证书
ssl_certificate /path/to/cert/<domain>.crt;
ssl_certificate_key /path/to/cert/<domain>.key;
ssl_trusted_certificate /path/to/cert/ca.crt;
# D-H 交换密钥
## 推荐使用 https://wiki.mozilla.org/Security/Server_Side_TLS#ffdhe4096
ssl_dhparam /path/to/cert/ffdhe4096.pem;
# 设置连接协议、加密方式
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA512:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:ECDH+AESGCM:ECDH+AES256:DH+AESGCM:DH+AES256:RSA+AESGCM:!aNULL:!eNULL:!LOW:!RC4:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS;
ssl_ecdh_curve X25519:P-256:P-384;
# 缓存和会话设置
ssl_buffer_size 4k;
ssl_session_cache shared:TLS:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 114.114.114.114 223.5.5.5 valid=300s;
resolver_timeout 10s;
# TLS 1.3 0-RTT
ssl_early_data on;
proxy_set_header Early-Data $ssl_early_data;
# 关闭 Nginx 版本显示
server_tokens off;
# HSTS
add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains; preload' always;
############
## 其他设置
############
location ...
}
|
自动跳转#
通过 HTTP 访问时,返回 301 跳转到 HTTPS
1
2
3
4
5
6
| server {
listen 80;
server_name example.com www.example.com;
rewrite ^(.*)$ https://$host$1 permanent;
}
|
关于 strict-SNI#
此功能需要至少两个开启 HTTPS 的 server,所以对于只托管了一个网站的情况需要再添加一个启用 SSL 的虚拟主机作为 fake server。幸运的是它对证书等具体配置没有要求,证书随便生成一个或者直接用真实主机的也可以:
1
2
3
4
5
6
7
8
9
10
| server {
listen 443 ssl;
server_name localhost;
ssl_certificate /path/to/cert/<domain>.crt;
ssl_certificate_key /path/to/cert/<domain>.key;
return 444;
}
|
测试配置:#
本地检验#
https://ssllabs.com