配置SSL证书

HTTPS协议依赖证书实现密钥交换和身份认证。这篇笔记记录如何用openssl生成一个自签名证书,以及如何在Nginx中配置SSL证书。

生成自签名证书

这里我们使用Linux下的openssl命令生成一个自签名证书。生成证书的步骤其实很好理解,我们先生成一个私钥,然后根据私钥生成一个包含公钥的证书,发布到网络上即可。

步骤1:首先生成一个RSA私钥,秘钥我们使用RSA 2048,对称加密算法使用3DES,生成文件名为server.key,生成时,会要求我们输入密码。

openssl genrsa -des3 -out server.key 2048

步骤2:这里还需要生成一个CSR文件(Certificate Signing request,证书请求文件),这一步会要求输入一些内容,按要求输入即可。

openssl req -new -key server.key -sha256  -out server.csr

步骤3:生成自签名证书

openssl x509 -req -days 365 -in server.csr -signkey server.key -sha256 -out server.crt

这里生成的.crt文件就是证书了。

注:许多政府机关、国企的HTTPS网站都是使用的自签名证书,用户必须手动下载安装证书,其实不是买不起,而是由于国内互联网起步晚,证书颁发这个操作被欧美垄断了,但我们又不能让证书的「合法性」掌握在美国人手中。而个人网站为了避免让用户安装证书的麻烦,通常使用Let's encrypt等提供的免费证书。

配置Nginx

配置Nginx时,还需要指定额外的一个文件,作为ssl_password_file的配置项,里面的内容是生成证书时输入的密码。

实际上,如果配置了SSL证书,Nginx启动时会要求输入密码。但是,Linux下我们的Nginx是通过systemd来管理启动的,因此没有手动输入密码的步骤就会报错,所以这里必须加上密码配置。

server {
        listen 443 ssl;
        listen [::]:443 ssl;

        ssl_certificate /home/ubuntu/workspace/server.crt;
        ssl_certificate_key /home/ubuntu/workspace/server.key;
        ssl_password_file /home/ubuntu/workspace/passphrase;

        root /var/www/html;
        index index.html index.htm index.nginx-debian.html;

        location / {
                try_files $uri $uri/ =404;
        }
}

由于SSL证书是我们自签名的,所以访问时浏览器会给我们一个大大的警告,我们不用理它。

针对80端口的兼容配置

假如我们的网站之前使用的是HTTP,位于80端口,很多用户喜欢我们的网站,加入了收藏夹,加为了友情链接,或者把链接收藏在笔记本中。如果我们突然把80端口关闭改为443,这部分用户就会无法访问我们的网站。较好的解决方案是针对80端口的请求,直接301重定向到443端口,这可以用重写URL实现。

server {
        listen 80;
        server_name www.aaa.com;
        rewrite ^(.*)$ https://$host$1 permanent;
}

个人网站证书获取

我们自己的小网站如果使用自签名证书肯定是不符合实际的。个人网站一般使用Let's Encrypt颁发免费证书,这样既可以使用HTTPS,用户访问时也不会有证书风险的提示了。而Let's Encrypt免费证书可以通过certbot程序自动申请,该工具同时还支持自动修改Nginx配置文件等功能。

注意:出于各种复杂原因,Let's Encrypt的免费证书有效期正变得越来越短,未来可能缩短至45天,因此手动配置是不现实的,一般都需要采用certbot程序来自动维护。

certbot使用简介

我们可以在官网获取CertBot的安装方式,CertBot官方网站:https://certbot.eff.org/。对于Ubuntu操作系统,我们可以直接从APT源安装certbot程序。

apt install certbot

Nginx配置中,我们只配置80端口和HTTP服务即可,其余的HTTPS、证书申请、证书设置都可以交给certbot程序,我们直接在命令行中运行certbot命令,根据提示操作即可自动配置。

certbot

下面命令可以检查当前certbot程序在维护哪些证书。

certbot certificates

下面命令可以删除证书,注意certbot delete只会将证书删除但不会更新Nginx配置,Nginx配置我们需要自己手动删除。

certbot delete --cert-name <你的域名>

当证书需要续签时,我们可以运行以下命令重新自动申请证书并更新Nginx配置,该命令会自动检查即将过期(默认是30天内)的HTTPS证书更新。

certbot renew

--dry-run:如果你只是想检查一下certbot renew是否能正常工作,可以使用certbot renew --dry-run命令,这条命令会请求Let's Encrypt的测试服务器并模拟证书更新检查主机是否有潜在配置问题,但不会真的更新证书,也不会消耗每个域名每周5次的限额。

--force-renewal:使用certbot renew --force-renewal命令可以忽略证书的过期时间检查,强制更新一次证书。

最后,我们需要将证书更新命令配置到Crontab中,以实现自动更新。下面Crontab配置在每天3点执行certbot renew命令,它会在证书有效期不足30天时自动续签。

0 3 * * * certbot renew --quiet --deploy-hook "systemctl reload nginx"
作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。