把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/TLS模式设置

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哟。