简介
Let's Encrypt提供了免费的SSL/TLS证书,之前都是单个子域名申请一个证书,现在它提供了泛域名(通配符域名*.example.com)的申请,这样就更加简单了。
官方普通地申请方法,可以参考它的网站https://certbot.eff.org/ 按照步骤一步步操作就很容易申请好了,不过可能有个问题,需要安装它地客户端certbot,还会遇到依赖问题。我使用了 https://github.com/acmesh-official/acme.sh这个的好处是它实纯Shell脚本写的,很少有依赖问题。
certbot结合cloudflare获取通配符证书的,请看:https://blog.terrynow.com/2021/10/04/centos7-or-8-certbot-cloudflare-letsencrypt-wildcard-ssl-cert-and-auto-renew/
我们下面将讨论如何安装acme,生成证书,以及如何在web服务器部署SSL服务
安装 acme.sh
curl https://get.acme.sh | sh # 所有的安装都在~/.acme.sh/下,新建一个快捷方式,后续直接运行acme.sh即可 alias acme.sh=~/.acme.sh/acme.sh # 安装好了以后,还会自动创建排程, 每天凌晨0点自动检测所有的证书, 如果快要过期,则自动续期 # 如果要修改排程的时间,如下命令 crontab -e
获取证书
获取证书,需要验证域名所有权(证明域名是你的),一般有两种方式http和dns
- http方式,就是在你的网站下(80端口)请求一个特殊的路径,返回正确的结果,来验证域名
# -d 后面加子域名可以-d多个,或者加 -d *.terrynow.com 这样的通配符域名 acme.sh --issue -d blog.terrynow.com -d www.terrynow.com --webroot /var/www/terrynow.com/ # 如果服务器没有任何web服务, 80端口可以对外服务,且是空闲的, 那么acme.sh还能自己生成一个webserver, 临时听在80端口, 完成验证: acme.sh --issue -d *.terrynow.com --standalone
- dns方式,就是在你的域名解析那边,添加一条txt记录,来验证域名所有权,添加txt记录,可以是手工填写,或者通过域名服务商提供的API的方式来自动填写,好处是这样在续期的时候,可以做到自动续期(Let's Encrypt申请的域名有效期都是3个月,所以续期还是比较频繁的,推荐使用自动续期)
# 手动DNS验证 acme.sh --issue --dns -d *.terrynow.com #acme.sh 会生成相应的TXT记录显示出来, 你只需要在你的域名服务商的管理面板中添加这条txt记录即可 #等一段时间后,就可以运行下面的renew了 acme.sh --renew -d *.terrynow.com
自动DNS验证,如果你的域名服务商是阿里云、腾讯云的DNSPod、Cloudflare等,可以通过创建类似APIkey的方式来自动验证
例如阿里云,在https://ak-console.aliyun.com/#/accesskey(可以根据提示,启动子帐号来生成accessKey,创建编程访问方式的帐号,权限是AliyunDNSFullAccess)
#Aliyun export Ali_Key="XXX" export Ali_Secret="YYY" acme.sh --issue --dns dns_ali -d *.terrynow.com
例如DNSPod,在腾讯云https://www.dnspod.cn/console/user/security获得ID和Token
#DNSPod export DPI_Id="1234" export DPI_Key="5678" acme.sh --issue --dns dns_dp -d *.terrynow.com
例如Cloudflare, 在https://dash.cloudflare.com/profile/api-tokens生成Token
export CF_Token="123" #AccountID可以在域名的Overview页面往下拉,在API->Account ID下面看到 export CF_Account_ID="000011111" acme.sh --issue --dns dns_cf -d *.terrynow.com
其他支持的域名服务商,请参考这里:https://github.com/acmesh-official/acme.sh/wiki/dnsapi
安装证书
acme.sh生成的证书,都会到~/.acme.sh/下,推荐的做法是不要直接让nginx或者apache直接配置到这个目录下读取证书,因为这些是acme内部使用,且结构目录会发生变化,导致web服务器读取错误
推荐的做法是使用acme --install-cert
来安装
# Apache作为web服务器 acme.sh --install-cert -d example.com \ --cert-file /path/to/certfile/in/apache/cert.pem \ --key-file /path/to/keyfile/in/apache/key.pem \ --fullchain-file /path/to/fullchain/certfile/apache/fullchain.pem \ --reloadcmd "service apache2 force-reload" # Nginx作为web服务器的写法 acme.sh --install-cert -d *.terrynow.com \ --key-file /etc/nginx/cert/key.pem \ --fullchain-file /etc/nginx/cert/cert.pem \ --reloadcmd "service nginx force-reload" #这里指定的所有参数都会被自动记录下来, 并在将来证书自动更新以后, 被再次自动调用,??一个
配置web服务器,如nginx
Nginx配置如下,更详细的nginx ssl配置,详见:https://blog.terrynow.com/2021/02/15/nginx-https-ssl-config/
# HTTPS server 设置 server { listen 443 ssl; ssl_certificate /etc/nginx/cert/cert.pem; ssl_certificate_key /etc/nginx/cert/key.pem; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA; ssl_session_cache shared:SSL:50m; #openssl dhparam -rand /dev/urandom 4096 -out /dhparam.pem #or openssl dhparam -out dhparam.pem 4096 #ssl_dhparam 可选,如果需要使用上面的命令生成dhparam.pem ssl_dhparam /etc/nginx/cert/dhparam.pem; ssl_prefer_server_ciphers on; server_name blog.terrynow.com; #server_name _; root /var/www/wordpress; index index.php index.html index.htm; client_max_body_size 100M; charset utf-8; access_log logs/wordpress.access.log mains; #强制跳转 if ($host !~ ^blog.terrynow.com$){ rewrite ^(.*) https://blog.terrynow.com$1 permanent; } #其他设置省略 }
Apache下配置SSL,新建或者编辑ssl.conf
LoadModule ssl_module modules/mod_ssl.so Listen 443 SSLPassPhraseDialog builtin SSLSessionCache shmcb:/var/cache/mod_ssl/scache(512000) SSLSessionCacheTimeout 300 SSLMutex default SSLRandomSeed startup file:/dev/urandom 256 SSLRandomSeed connect builtin SSLCryptoDevice builtin <VirtualHost _default_:443> ErrorLog logs/ssl_error_log TransferLog logs/ssl_access_log LogLevel warn SSLEngine on SSLProtocol all -SSLv2 -SSLv3 SSLCipherSuite !RC4:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA SSLHonorCipherOrder on #SSLOpenSSLConfCmd DHParameters "/opt/server.dhparam" SSLCertificateFile /etc/nginx/cert/cert.pem SSLCertificateKeyFile /etc/nginx/cert/key.pem #SSLCertificateChainFile /etc/letsencrypt/live/104china.com/chain.pem <Files ~ "\.(cgi|shtml|phtml|php3?)$"> SSLOptions +StdEnvVars </Files> <Directory "/var/www/cgi-bin"> SSLOptions +StdEnvVars </Directory> SetEnvIf User-Agent ".*MSIE.*" \ nokeepalive ssl-unclean-shutdown \ downgrade-1.0 force-response-1.0 CustomLog logs/ssl_request_log \ "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b" </VirtualHost>
其他详情请参考 https://cloud.tencent.com/document/product/400/35243
文章评论