没讲到的内容参考项目地址。
在当前互联网环境中,网站安全是用户体验的重要决定因素。拥有正式签发的 SSL 证书可以加密网站数据传输,同时用图标和文字明确告知用户这是个安全域名。了解如何获取和设置证书是每个网站运营者必不可少的技能。
1、安装 acme.sh
curl https://get.acme.sh | sh -s email=你的邮箱.com
安装的过程中,做了 3 件事:
- 复制
acme.sh
到主目录($HOME),一般是/root/.acme.sh/
,生成的证书也会放在这个目录。 - 创建 一个 bash:
acme.sh=~/.acme.sh/acme.sh
。有时候需要重启 bash,用以下命令重启:source ~/.bashrc
- 创建 crontab 任务检查是否需要更新证书:
0 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null
安装过程不会破坏已有的系统任何功能和文件, 所有的修改都限制在安装目录中。
查看帮助信息:acme.sh -h
查看 crontab 任务:crontab -l
2、选择默认 CA
目前 acme.sh 支持六个 CA:
- ZeroSSL.com CA(default)
- Letsencrypt.org CA
- BuyPass.com CA
- SSL.com CA
- Google.com Public CA
- Pebble strict Mode
其他符合 RFC8555 的 CA 也支持。
默认使用 ZeroSSL,如果需要更换可以使用以下命令:
通过使用 ZeroSSL 的 ACME 功能,能够免费生成无限数量的 90 天 SSL 证书,还支持多域证书和通配符。创建的每个证书都将存储在 ZeroSSL 帐户中。所以别看到 ZeroSSL 的免费套餐的 3 个单域名证书就放弃,能加入开源项目中的,一般不会太坑。
# xxx 是 server 名。
# server 列表:https://github.com/acmesh-official/acme.sh/wiki/Server
acme.sh --set-default-ca --server xxx
因为默认使用 ZeroSSL,所以需要一个 ZeroSSL 帐号。注册 ZeroSSL 帐号之后,在后台控制面板拿到 API Key,然后执行以下命令:
curl -s -X POST "https://api.zerossl.com/acme/eab-credentials?access_key=API_Key" | jq
如果设备上没有安装 jq,则需要手动安装,Ubuntu 安装命令示例如下:
apt install jq
终端输出以下内容:
{
"success": true,
"eab_kid": "kid",
"eab_hmac_key": "hmac_key",
}
通过终端输出内容使用下面的命令添加 ZeroSSL 账号。
acme.sh --register-account --server zerossl \
--eab-kid kid \
--eab-hmac-key hmac_key
3、申请域名SSL证书
申请证书有两种方式,一种是 http,一种是 dns。SSL 证书有两种,分别是 rsa 证书和 ecc 证书,两者功能上无区别。ecc 证书比 rsa 证书性能更好,推荐使用 ecc 证书。但是太老的系统或者软件是不支持 ecc 证书的,所以最好配置双证书。如果 nginx 的版本大于 1.11,并且配置文件里,指明了 ecc 和 rsa 证书的路径,那么 nginx 会优先使用 ecc 证书,不支持则使用 rsa 证书。
如果你使用的 CA 是 ZeroSSL,同一个域名申请 rsa 证书之后想再申请 ecc 证书(反之亦然),则需要在申请第二份证书的命令中加上 --force 参数。
3.1、通过 http 方式申请证书
使用这种方式申请证书有个前提,必须有一个网站,acme.sh 会全自动的生成验证文件, 并放到网站的根目录, 然后自动完成验证, 最后会删除验证文件。
# /var/www/letsencrypt 是网站的根目录。
acme.sh --issue -d 你的域名.com -w /var/www/letsencrypt
# 在后边加上--keylength ec-256 就可以生成 ecc 证书,不加则默认生成 rsa 证书。
# ecc-256 中的 256 是公钥长度,越长越安全,但解密时间也越长。
# 可选长度有 256、384、521。
acme.sh --issue -d 你的域名.com -w /var/www/_letsencrypt/ --keylength ec-256
如果你用的 web 服务器是 apache 或者 nginx,有更方便的方法。
# 如果你用 apache 服务器, acme.sh 可以根据 apache 的配置完成验证, 不需要指定网站根目录。
acme.sh --issue -d 你的域名.com --standalone
# nginx 服务器也同理。
acme.sh --issue -d 你的域名.com --nginx
需要对多个域名申请证书,可以添加新的 -d 你的域名.com
。
例如:acme.sh --issue -d 你的域名.com -d 他的域名.com -d 我的域名.com --nginx
等到出现 Cert success
就代表证书申请完成。证书的位置,可以随意,不推荐放在 acme.sh 的目录里,万一那天删除了,就寄了。在网站的配置文件中指明证书的路径(具体操作自行搜索),就可以启用证书,宝塔面板的网站设置菜单有 SSL 的选项,设置证书方便。
3.2、通过 dns 方式申请证书
dns 申请证书分为手动和自动两种。通配符证书只能通过 dns 方式申请,什么是通配符证书呢?一个域名可以有很多个子域名。
例如:a.你的域名.com
、b.你的域名.com
、c.你的域名.com
如果要用很多的子域名,一个一个给子域名申请证书,这也太麻烦了。子域名和主域名不同的地方,就只有三级域名(例子上的a、b、c),所以使用通配符代替掉三级域名申请证书,这样,所有的子域名使用一个证书就好。通配符证书和单域名命令相同,域名要用 ' ' 引起来。
3.2.1、手动 dns 申请证书
# 申请 rsa 证书。
# 会有提示出现,安装提示添加 DNS 解析,解析到你的 vps,证书申请完了,这个解析可以删除。
acme.sh --issue --dns -d 你的域名.com --yes-I-know-dns-manual-mode-enough-go-ahead-please
# 添加完 DNS 解析,接着执行下面的命令。
acme.sh --renew -d 你的域名.com --yes-I-know-dns-manual-mode-enough-go-ahead-please
# 申请 ecc 证书。
# 会有提示出现,安装提示添加 DNS 解析,解析到你的 vps,证书申请完了,这个解析可以删除。
# 在后边加上 --keylength ec-256 就可以生成 ecc 证书,不加则默认生成 rsa 证书。
acme.sh --issue --keylength ec-256 --dns -d 你的域名.com --yes-I-know-dns-manual-mode-enough-go-ahead-please
# 添加完 DNS 解析,接着执行下面的命令。
acme.sh --renew --ecc -d 你的域名.com --yes-I-know-dns-manual-mode-enough-go-ahead-please
# 申请通配符证书例子。
acme.sh --issue --dns -d '*.你的域名.com' --yes-I-know-dns-manual-mode-enough-go-ahead-please
acme.sh --renew '*.你的域名.com' --yes-I-know-dns-manual-mode-enough-go-ahead-please
3.2.2、自动 dns 申请证书
DNS API 支持很多厂商,请查找自己的厂商的使用命令。API链接
# key 和 secret 到官网自行申请。这里用阿里云举例。
export Ali_Key="xxxxxx"
export Ali_Secret="yyyyyyy"
# 申请 rsa 证书。
acme.sh --issue --dns dns_ali -d 你的域名.com
# 申请 ecc 证书。
acme.sh --issue --dns dns_ali -d 你的域名.com --keylength ec-256
# 申请通配符证书例子。
acme.sh --issue --dns dns_ali -d '*.你的域名.com'
acme.sh --issue --dns dns_ali -d '*.你的域名.com' --keylength ec-256
4、安装域名 SSL 证书
4.1、移动证书
# rsa 证书。
# 放在那,随意,目录要提前创建好。
acme.sh --install-cert -d 你的域名.com \
--key-file /www/server/panel/vhost/cert/rsa/key.pem \
--fullchain-file /www/server/panel/vhost/cert/rsa/cert.pem \
# service nginx force-reload 可以使证书进行自动续期后及时更新 Nginx 读取的配置。
--reloadcmd "service nginx force-reload"
# ecc 证书。
# 放在那,随意,目录要提前创建好。
acme.sh --install-cert --ecc -d 你的域名.com \
--key-file /www/server/panel/vhost/cert/ecc/key.pem \
--fullchain-file /www/server/panel/vhost/cert/ecc/cert.pem \
# service nginx force-reload 可以使证书进行自动续期后及时更新 Nginx 读取的配置。
--reloadcmd "service nginx force-reload"
4.2、修改 nginx 配置
listen 80;
listen 443 ssl http2;
# 网站配置里指明证书的路径,修改完就重启 nginx。
# ecc 证书路径。
ssl_certificate /www/server/panel/vhost/cert/ecc/cert.pem;
ssl_certificate_key /www/server/panel/vhost/cert/ecc/key.pem;
# rsa 证书路径。
ssl_certificate /www/server/panel/vhost/cert/rsa/cert.pem;
ssl_certificate_key /www/server/panel/vhost/cert/rsa/key.pem;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
add_header Strict-Transport-Security "max-age=63072000" always;
ssl_stapling on;
ssl_stapling_verify on;
resolver 127.0.0.1;
error_page 497 https://$host$request_uri;