背景
由于 HTTP 是明文传输,在使用 NextCloud 等服务时不够安全,需要配置 SSL 证书。不想让在被别人浏览的时候,出现莫名的广告[运营商劫持]。
签发 SSL 证书需证明这个域名的所有权,一般有两种方式验证: http 和 dns 验证。使用 acme.sh
能够定时自动续签,非常方便。泛域名证书貌似只能使用 DNS 验证的方式,这种方式要获取 DNS 验证 api,不同服务器商家各有不同,腾讯云的在 API 密钥 - DNSPod。在该页面的 DNSPod Token 中创建密钥。
安装acme.sh
代码语言:javascript复制# curl https://get.acme.sh | sh -s email=jxiao@visionmedicals.com
# 如果是国内的机器,可以使用拖回源码直接安装
git clone https://gitee.com/neilpang/acme.sh.git
cd acme.sh
./acme.sh --install -m jxiao@visionmedicals.com
普通用户和 root 用户都可以安装使用. 安装过程进行了以下几步:
- 1. 并创建 一个 shell 的 alias, 例如 .bashrc,方便你的使用:
alias acme.sh=~/.acme.sh/acme.sh
vim ~/.bashrc
# 在合适的位置写入:
alias acme.sh=~/.acme.sh/acme.sh
source ~/.bashrc
新版acme.sh使用ZeroSSL作为CA,建议切换到Let’s Encrypt的CA:
代码语言:javascript复制acme.sh --set-default-ca --server letsencrypt
acme.sh
依赖于cron
执行定时任务,安装完成后,输入 crontab -l
命令,能看到如下输出:
13 0 * * * "/home/ubuntu/.acme.sh"/acme.sh --cron --home "/home/ubuntu/.acme.sh" > /dev/null
定时任务保证了证书在到期前能自动续期。由于ACME协议和Let’s Encrypt CA都在频繁的更新,因此建议开启acme.sh的自动升级
代码语言:javascript复制acme.sh --upgrade --auto-upgrade
使用acme.sh签发证书
有4种方式可以选择
方式一:如果网站已经运行Nginx/Apache,指定对应插件就可以了
代码语言:javascript复制acme.sh --issue -d tmp1210.visionmedicals.cn --nginx # 如果是apache,换成 --apache
方式二:如果你的服务器上已经运行了web软件,指定webroot即可签发证书:
代码语言:javascript复制acme.sh --issue -d 域名 --webroot web目录
方式三:如果没有运行web软件并且80端口空闲,可以使用acme.sh自己监听80端口进行验证:
代码语言:javascript复制~/.acme.sh/acme.sh --issue -d 域名 --standalone
方式四:可以使用DNS方式,手动添加DNS记录进行验证:
代码语言:javascript复制~/.acme.sh/acme.sh --issue --dns -d 域名
# 命令结束后,acme.sh会显示解析记录,需要到DNS后台设置解析
# 设置好解析后,生成证书
~/.acme.sh/acme.sh --renew -d 域名
对于DNS方式,acme.sh内置了许多DNS服务商的插件,使用方法参考:https://github.com/Neilpang/acme.sh/blob/master/dnsapi/README.md
如果有通配符证书要求,需要使用DNS验证方式,其他方式一个证书的域名数不能超过20
申请好证书的证书位于~/.acme.sh
目录内,不建议直接使用,而是将其安装到指定目录:
~/.acme.sh/acme.sh --install-cert -d 域名
--key-file 密钥存放路径(例如/etc/nginx/ssl/域名.key)
--fullchain-file 证书存放路径(例如/etc/nginx/ssl/域名.pem)
--reloadcmd "service nginx force-reload"
实践demo
step1.先配置好域名解释
step2.配置一个新的站点
使能够正常http访问
代码语言:javascript复制server {
listen 80;
listen [::]:80;
server_name tmp1210.visionmedicals.cn;
#access_log /var/log/nginx/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
step3.生成证书到指定目录
代码语言:javascript复制root@iZ7xva33l57s9vs0useftcZ:~/software/docker/nginx/config/conf.d/cert# acme.sh --issue -d tmp1210.visionmedicals.cn --webroot /root/www/html
--key-file /root/software/docker/nginx/config/conf.d/cert/tmp1210.visionmedicals.cn.key
--fullchain-file /root/software/docker/nginx/config/conf.d/cert/tmp1210.visionmedicals.cn.cer
[Sun Dec 10 10:22:57 PM CST 2023] Using CA: https://acme-v02.api.letsencrypt.org/directory
[Sun Dec 10 10:22:57 PM CST 2023] Creating domain key
[Sun Dec 10 10:22:57 PM CST 2023] The domain key is here: /root/.acme.sh/tmp1210.visionmedicals.cn_ecc/tmp1210.visionmedicals.cn.key
[Sun Dec 10 10:22:57 PM CST 2023] Single domain='tmp1210.visionmedicals.cn'
[Sun Dec 10 10:22:57 PM CST 2023] Getting domain auth token for each domain
[Sun Dec 10 10:23:02 PM CST 2023] Getting webroot for domain='tmp1210.visionmedicals.cn'
[Sun Dec 10 10:23:02 PM CST 2023] tmp1210.visionmedicals.cn is already verified, skip http-01.
[Sun Dec 10 10:23:02 PM CST 2023] Verify finished, start to sign.
[Sun Dec 10 10:23:02 PM CST 2023] Lets finalize the order.
[Sun Dec 10 10:23:02 PM CST 2023] Le_OrderFinalize='https://acme-v02.api.letsencrypt.org/acme/finalize/1457692006/228224606046'
[Sun Dec 10 10:23:04 PM CST 2023] Downloading cert.
[Sun Dec 10 10:23:04 PM CST 2023] Le_LinkCert='https://acme-v02.api.letsencrypt.org/acme/cert/0491a19b4d10bf136b5df595eba6f4d4d2c0'
[Sun Dec 10 10:23:05 PM CST 2023] Cert success.
-----BEGIN CERTIFICATE-----
MIIENDCCAxygAwIBAgISBJGhm00QvxNrXfWV66b01NLAMA0GCSqGSIb3DQEBCwUA
MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD
EwJSMzAeFw0yMzEyMTAxMzIzMDNaFw0yNDAzMDkxMzIzMDJaMCQxIjAgBgNVBAMT
GXRtcDEyMTAudmlzaW9ubWVkaWNhbHMuY24wWTATBgcqhkjOPQIBBggqhkjOPQMB
BwNCAASoISM1YfxvlDvTe/iHwgydXhAGRzTp2eLK iUkmgOUOJhmk3CE6HMohVaY
0g44DXwE6HgEUAIRQ0PlDSbuZwy5o4ICGzCCAhcwDgYDVR0PAQH/BAQDAgeAMB0G
A1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB0GA1Ud
DgQWBBQNEDw2Iuan7ZpzBIe7dYoqgAOrLTAfBgNVHSMEGDAWgBQULrMXt1hWy65Q
CUDmH6 dixTCxjBVBggrBgEFBQcBAQRJMEcwIQYIKwYBBQUHMAGGFWh0dHA6Ly9y
My5vLmxlbmNyLm9yZzAiBggrBgEFBQcwAoYWaHR0cDovL3IzLmkubGVuY3Iub3Jn
LzAkBgNVHREEHTAbghl0bXAxMjEwLnZpc2lvbm1lZGljYWxzLmNuMBMGA1UdIAQM
MAowCAYGZ4EMAQIBMIIBBAYKKwYBBAHWeQIEAgSB9QSB8gDwAHYASLDja9qmRzQP
5WoC p0w6xxSActW3SyB2bu/qznYhHMAAAGMVBw0hAAABAMARzBFAiEA7yG807CL
tKPMk/fs4vVfcV8h3HXzwTY2HTBuVYgahxkCICq/5IyoGPzwy 9pQZaRA5kUMcvP
KfsusGVXNtbCL/XTAHYAouK/1h7eLy8HoNZObTen3GVDsMa1LqLat4r4mm31F9gA
AAGMVBw0kQAABAMARzBFAiEA53/yYbPIwlRGvOXu9eihUAp2khzsGgAAuQ1XFcxy
CvICIEB p2bUXl yKnxpHqBLO95YbTh6cBjuP/xzueESUkLhMA0GCSqGSIb3DQEB
CwUAA4IBAQCFRZ5AucidEQD08yrtR6TwAzWYWnfEE7m5ItY2r8VQnIsEXKr/O5 x
rfOEu6d0WO3ZvnjZT5RQzaF6e2517Vu7nZvu5vSAelYe b/ygmFI7OJOTk4Hpf5N
tdQ8Pd4WAz6WLKA0hfgydRS90tLjfsRUmgR3IdlZveM/dVmvzJAA1If/ZoWsFIpo
2AEPeN3Q8a5eLOyouc5seuBxj3AzNSyBqBJZETIuPVpM6jNFCWAHTrIJJkCsmYJ2
feWnTGIx1hpAAq4dXBb5AEZ1YuWsiGN2ufQfDYOIRo2M2zObNOuKL Dggnw75T30
9cKxoNPVjTa1lfWfQAKJWOXt8aiQI pY
-----END CERTIFICATE-----
[Sun Dec 10 10:23:05 PM CST 2023] Your cert is in: /root/.acme.sh/tmp1210.visionmedicals.cn_ecc/tmp1210.visionmedicals.cn.cer
[Sun Dec 10 10:23:05 PM CST 2023] Your cert key is in: /root/.acme.sh/tmp1210.visionmedicals.cn_ecc/tmp1210.visionmedicals.cn.key
[Sun Dec 10 10:23:05 PM CST 2023] The intermediate CA cert is in: /root/.acme.sh/tmp1210.visionmedicals.cn_ecc/ca.cer
[Sun Dec 10 10:23:05 PM CST 2023] And the full chain certs is there: /root/.acme.sh/tmp1210.visionmedicals.cn_ecc/fullchain.cer
[Sun Dec 10 10:23:05 PM CST 2023] Installing key to: /root/software/docker/nginx/config/conf.d/cert/tmp1210.visionmedicals.cn.key
[Sun Dec 10 10:23:05 PM CST 2023] Installing full chain to: /root/software/docker/nginx/config/conf.d/cert/tmp1210.visionmedicals.cn.cer
step4.更新配置
代码语言:javascript复制server {
listen 443 ssl;
server_name tmp1210.visionmedicals.cn;
#access_log /var/log/nginx/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
ssl_certificate conf.d/cert/tmp1210.visionmedicals.cn.cer;
ssl_certificate_key conf.d/cert/tmp1210.visionmedicals.cn.key;
ssl_session_timeout 5m;
ssl_session_cache shared:SSL:1m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
}
server {
listen 80;
server_name tmp1210.visionmedicals.cn;
rewrite ^ https://$host$1 permanent;
}
我有个大胆的想法
小伙伴在平常有没有遇到以下这种情况:遇到技术难题时,网上教程一堆堆,优秀的很多,但也有很多是过时的,或者是copy来copy去,甚至错别字都没改。
我公众号的技术文章,都是亲自校验过的。至少可以保证在发文的一段时间,不会过时。如果你在实操过程中,有遇到问题,可以在同名公众号留言,免费解答,相互学习,相互成长^v^