全站启用https

把个人博客启用了https。

我们假设如下:

域名,也称为 Common Name,因为特殊的证书不一定是域名:example.com

组织或公司名字(Organization):Example, Inc.

部门(Department):可以不填写,这里我们写 Web Security

城市(City):Beijing

省份(State / Province):Beijing

国家(Country):CN

加密强度:2048 位,如果你的机器性能强劲,也可以选择 4096 位

按照以上信息,使用 OpenSSL 生成 key 和 csr 的命令如下

1
openssl req -new -newkey rsa:2048 -sha256 -nodes -out example_com.csr -keyout example_com.key -subj "/C=CN/ST=Beijing/L=Beijing/O=Example Inc./OU=Web Security/CN=example.com"

PS:如果是泛域名证书,则应该填写 *.example.com

在系统的任何地方运行这个命令,会自动在当前目录生成 example_com.csrexample_com.key 这两个文件

接下来你可以查看一下 example_com.csr,得到类似这么一长串的文字

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
-----BEGIN CERTIFICATE REQUEST-----
MIICujCCAaICAQAwdTELMAkGA1UEBhMCQ04xEDAOBgNVBAgTB0JlaWppbmcxEDAO
BgNVBAcTB0JlaWppbmcxFTATBgNVBAoTDEV4YW1wbGUgSW5jLjEVMBMGA1UECxMM
V2ViIFNlY3VyaXR5MRQwEgYDVQQDEwtleGFtcGxlLmNvbTCCASIwDQYJKoZIhvcN
AQEBBQADggEPADCCAQoCggEBAPME+nvVCdGN9VWn+vp7JkMoOdpOurYMPvclIbsI
iD7mGN982Ocl22O9wCV/4tL6DpTcXfNX+eWd7CNEKT4i+JYGqllqP3/CojhkemiY
SF3jwncvP6VoST/HsZeMyNB71XwYnxFCGqSyE3QjxmQ9ae38H2LIpCllfd1l7iVp
AX4i2+HvGTHFzb0XnmMLzq4HyVuEIMoYwiZX8hq+kwEAhKpBdfawkOcIRkbOlFew
SEjLyHY+nruXutmQx1d7lzZCxut5Sm5At9al0bf5FOaaJylTEwNEpFkP3L29GtoU
qg1t9Q8WufIfK9vXqQqwg8J1muK7kksnbYcoPnNgPx36kZsCAwEAAaAAMA0GCSqG
SIb3DQEBBQUAA4IBAQCHgIuhpcgrsNwDuW6731/DeVwq2x3ZRqRBuj9/M8oONQen
1QIacBifEMr+Ma+C+wIpt3bHvtXEF8cCAJAR9sQ4Svy7M0w25DwrwaWIjxcf/J8U
audL/029CkAuewFCdBILTRAAeDqxsAsUyiBIGTIT+uqi+EpGG4OlyKK/MF13FxDj
/oKyrSJDtp1Xr9R7iqGCs/Zl5qWmDaLN7/qxBK6vX2R/HLhOK0aKi1ZQ4cZeP7Mr
8EzjDIAko87Nb/aIsFyKrt6Ze3jOF0/vnnpw7pMvhq+folWdTVXddjd9Dpr2x1nc
y5hnop4k6kVRXDjQ4OTduQq4P+SzU4hb41GIQEz4
-----END CERTIFICATE REQUEST-----

这个 CSR 文件就是你需要提交给 SSL 认证机构的,当你的域名或组织通过验证后,认证机构就会颁发给你一个 example_com.crt

example_com.key 是需要用在 Nginx 配置里和 example_com.crt 配合使用的,需要好好保管,千万别泄露给任何第三方。

需要提交 CSR 文件给第三方 SSL 认证机构,通过认证后,他们会颁发给你一个 CRT 文件,我们命名为 example_com.crt

同时,为了统一,你可以把这三个文件都移动到 /etc/ssl/private/ 目录。

然后可以修改 Nginx 配置文件

1
2
3
4
5
6
7
8
9
server {
listen 80;
listen 443 ssl;
server_name lujq.me;
ssl on;
ssl_certificate /etc/ssl/private/lujq_me.crt;
ssl_certificate_key /etc/ssl/private/lujq_me.key;
}

但是这么做并不安全,默认是 SHA-1 形式,而现在主流的方案应该都避免 SHA-1,为了确保更强的安全性,我们可以采取迪菲-赫尔曼密钥交换

首先,进入 /etc/ssl/certs 目录并生成一个 dhparam.pem

1
cd /etc/ssl/certs
1
openssl dhparam -out dhparam.pem 2048 # 如果你的机器性能足够强大,可以用 4096 位加密

生成完毕后,在 Nginx 的 SSL 配置后面加入

1
2
3
4
5
6
7
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4";
keepalive_timeout 70;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;

同时,如果是全站 HTTPS 并且不考虑 HTTP 的话,可以加入 HSTS 告诉你的浏览器本网站全站加密,并且强制用 HTTPS 访问

1
2
3
add_header Strict-Transport-Security max-age=63072000;
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;

同时也可以单独开一个 Nginx 配置,把 HTTP 的访问请求都用 301 跳转到 HTTPS

1
2
3
4
5
6
server {
listen 80;
listen [::]:80 ipv6only=on;
server_name example.com;
return 301 https://example.com$request_uri;
}

我的做法是采用了第一种。

这样就完成了,最终的配置文件如下:

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
server {
listen 80;
listen 443 ssl;
server_name lujq.me;
ssl on;
ssl_certificate /etc/ssl/private/lujq_me.crt;
ssl_certificate_key /etc/ssl/private/lujq_me.key;
root /home/wwwroot/lujq.me/;
access_log off;
index index.html index.htm index.php;
include wordpress.conf;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4";
keepalive_timeout 70;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
add_header Strict-Transport-Security max-age=63072000;
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
location ~ .*\.(php|php5)?$ {
#fastcgi_pass remote_php_ip:9000;
fastcgi_pass unix:/dev/shm/php-cgi.sock;
fastcgi_index index.php;
include fastcgi.conf;
}
location ~ .*\.(gif|jpg|jpeg|png|pdf|bmp|swf|flv|ico)$ {
expires 30d;
access_log off;
}
location ~ .*\.(js|css)?$ {
expires 7d;
access_log off;
}
}