把SSL和二级域名们架上吧
域名准备
想要架上二级域名,首先,我们需要一个一级域名……自行在心仪的厂家选购。我比较常用的(价格比较实惠的)是国内的是万网,特价的时候一百多人民币买过十年的。国外的是NameSilo,首年特价很多,.com,.xyz比较实惠,但像.top之类的还是当年万网买得更便宜。(不过拿.top,.cyou之类的便宜域名发邮件比较容易被当成垃圾邮件屏蔽……)
提醒一下,Freenom的虽然免费,但在那个bug多端的网站申请其实还挺麻烦的,而且实测无法使用LetsEncrypt获取证书(不支持那几个顶级域名)。
DNS准备
获得域名后,如果那家的DNS不尽如人意,可以转接其他服务商的DNS,比如Cloudflare。NameSilo接Cloudflare走这里
在Cloudflare的话,可以这样配置域名:
Type | Name | Content |
---|---|---|
A | 你弄到的那个域名,比如mydomain.com | 你的IP(IPv4) |
CNAME | 二级域名,比如blog | 你的主域名,如上面的mydomain.com |
CNAME | 另一个二级域名,如repo | 你的主域名 |
CNAME | 其他想要配置的二级域名,如www | 你的主域名 |
后面的proxy status显示橙色的云表示已经应用了Cloudflare的CDN,很好,不用管,除非设置的某个子域名是用来直接SSH、FTP服务器的。
然后,记得在SSL/TLS里切换模式到Full(不然在下面的配置中,会让访问在http和https间反复横跳,too many redirections)。
SSL准备
在有了一个域名的基础上,可以申请LetsEncrypt的域名证书。
可以使用acme.sh
安装:curl https://get.acme.sh | sh -s [email protected]
其中后面那个email不要用[email protected],会出错的。
其他就跟着GitHub的教程来吧,有中文的:
https://github.com/acmesh-official/acme.sh/wiki/说明
厂家DNS不给力的记得先换了其他厂家的DNS,不然可以这一步申请证书会超时。
Nginx
基础的配置
/etc/nginx/nginx.conf里,http花括号里确保有
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*.conf;
这样conf.d和sites-enabled目录下.conf后缀名的文件都会被包含进设置。
sites-enabled目录下,可以每个站点单写一个.conf文件,方便管理。需要关闭某个站点的时候,直接mv the_site_name.conf ../sites-available
把文件移走,然后service nginx restart
。要开启某个站点就从sites-available移回来,再重启nginx。
ssl snippets
如果站点很多的话,给ssl配置部分写一个snippet会方便很多。这样,在每个站点的文件中就可以直接引用snippet,不用一遍一遍的重复证书路径、加密等等的设置了。
每份域名证书都需要一个对应的snippet,泛域名证书的话,可以多个子域名站点共用同一个snippet。
例,申请了
*.mysite.com
的证书,并为它写了ssl snippet
a.mysite.com
b.mysite.com
c.mysite.com
都可以共用这个snippet
存放一份据说是安全的设置的模板:
# /etc/nginx/snippets/ssl.conf
# 就是个提醒自己的路径啦
server_tokens off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 60m;
ssl_session_tickets on;
# OCSP stapling
# 证书状态缓存
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.4.4 8.8.8.8 valid=300s;
resolver_timeout 10s;
ssl_prefer_server_ciphers on;
# Ephemeral Diffie-Hellman key exchange
ssl_dhparam /your_path_to_cert/dhparam.pem;
ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0
# path to ssl certificates
ssl_certificate /your_path_to_cert/fullchain.cer;
ssl_certificate_key /you_path_to_cert/<domain>.key;
# disable TLSv1.0 & TLSv1.1
# 禁用安全性不好的 TLS1.0和1.1
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;";
# headers
add_header Strict-Transport-Security "max-age=31536000;includeSubDomains;preload";
add_header X-Frame-Options sameorigin;
add_header Referrer-Policy strict-origin-when-cross-origin;
add_header X-Content-Type-Options nosniff;
add_header x-xss-protection "1; mode=block";
add_header Content-Security-Policy "default-src 'self' *.your_domain.com other_sites.com; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: https:; connect-src 'self' https:; img-src 'self' data: https: blob:; style-src 'unsafe-inline' https:; font-src 'self' https: data:";
其中,your_path_to_cert(放证书、秘钥等的路径)和CSP请自行调整。
DF参数提高到至少2048位(乐意的话4096位也可以哦):
openssl dhparam -out /your_path_to_cert/dhparam.pem 2048
openssl如果没有就apt-get安装
CSP(Content-Security-Policy)里加入你信任的、需要用到的网站和加载方式,浏览器会把没包含在内的加载内容全都截下来的(F12看network或者console里面)。如果配置完,从HTTPS访问时网站有部分内容不显示或表现不正常,优先查看是否因为CSP被浏览器拦截。
站点设置
站点的模板,每个站点要使用含有对应证书的ssl snippet哦:
server {
listen 80;
listen [::]:80;
server_name <your_secondary_domain>.<your_domain>.com; # 不是.com的自己改啦
return 301 https://$server_name$request_uri; # 如果被以http访问了,转https
}
server {
listen 443 ssl; # 这个ssl很重要,不写的话可能会有奇奇怪怪的悲剧发生。另外这行是ipv4
listen [::]:443 ssl; # 这行是ipv6
server_name <your_secondary_domain>.<your_domain>.com; # 同上
include snippets/ssl.conf; # 上文中写好的对应snippet,或者自己的ssl设置
client_max_body_size 20m;
location / {
proxy_pass http://127.0.0.1:<port_number>/<app_name>; #你要转到哪里
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
proxy_set_header Origin http://$host;
}
}
后续步骤
配置好之后,nginx -t
测试配置。测试通过的话sudo service nginx restart
重启就可以看到效果了。不过要刷新ssl证书(比如更新过、或者吊销又重新申请了证书等情况)的话需要sudo service nginx force-reload
哟。