自从今年的早先时候,阿里的免费ssl证书的有效期从12个月变成3个月,就总是收到ssl证书到期的提示。早就听说acme
可以申请免费的ssl证书,并且可以自动延长有效期,这次终于是被逼得没办法,只能试试了,因为一直用的是阿里的域名,看阿里ssl延期要收钱,以为这个acme
会比较困难,结果实际操作下来一点也不难,记录一下。
首先介绍一下我的需求,我的NAS在家里放着,上面部署了一些docker应用,使用frp对内网中的这些应用进行穿透,在一台远程服务器上部署frps
,在NAS上的frpc
上部署https2http
插件使用ssl证书,确保网页访问的时候不出现不安全的提示。
接下来是部署acme
的大体步骤如下:
部署acme.sh
应用,申请ssl证书,部署证书,检测是还过期,过期自动续期。
部署acme.sh
之所以在NAS上部署acme.sh
,我的想法是可以直接让fprc
访问申请下来的证书,这样就不用再折腾部署的那一部分,可以省点心。相应的docker-compose.yml
文件内容如下:
services:
acme-sh:
image: neilpang/acme.sh
container_name: acme
environment:
Ali_Key: "*****"
Ali_Secret: "*****"
volumes:
- /share/Container/frpc/acme:/acme.sh
network_mode: host
command: daemon
stdin_open: true
tty: true
restart: unless-stopped
其中需要注意的点是环境变量environment
中的两个变量,Ali_Key
和Ali_Secret
,要从阿里的控制台中申请。申请网址是:https://ram.console.aliyun.com/users
。
阿里云为了提高安全性不建议直接使用主账号创建AccessKey
(因为默认权限过大),建议使用RAM
用户(可以理解为子用户)的AccessKey
进行API
调用。新建的 RAM 用户 默认没有任何权限,需要手动添加 (这是一个坑点)。
登录阿里云工作台--->RAM访问控制--->身份管理--->用户--->找到对应RAM用户--->点击用户名--->点击“权限管理”tab页,可查看已授权的权限(直接点击用户列表操作栏的添加权限是看不到已有权限的)--->添加以下两个权限:AliyunDomainFullAccess - 管理域名服务的权限 AliyunDNSFullAccess - 管理云解析(DNS)的权限
否则会提示Error add txt for domain:_acme-challenge.yourdomain.com
错误。
以下代码中上面是使用docker
部署的执行命令,下方的代码是使用机器直接安装acme.sh
后的命令。
申请SSL证书
我使用的是dns
方法,不用暴露一些二级域名 (我才不会告诉你我使用http的方法申请失败了)。
设置用户邮箱,可以防止acme发证错误,可以接收一个邮件 (这个没试过,我只是使用默认的用户名申请失败了就换了自己的邮箱)
docker exec acme register -m your_email.com
//acme.sh register -m your_email.com
切换签证机构
//我用的是Let‘s encrypt
docker exec acme --set-default-ca --server letsencrypt
//acme.sh --set-default-ca --server letsencrypt
申请泛域名证书,之前在阿里控制台中使用的免费ssl证书都是一个子域名一个子域名申请,太费时了,这次索性试试
泛域名解析
,一个解析解决所有的子域名访问请求验证。
docker exec acme --issue --dns dns_ali -d *.example.com
//acme.sh --issue --dns dns_ali -d *.example.com
会在容器的/root/.acme.sh/yourdomain_ecc
文件夹下生成4个文件,而在我的docker-compose
文件中已经把这个文件夹持久化出来了,我们直接去我们持久化之后的文件夹中找,分别是cert
,cert key
,CA cert
和full chain certs
,而我们使用的是fullchain.cer
和*.example.com.key
这两个文件。
部署SSL证书
在frpc
的配置文件frpc.toml
中重新设置对应的服务:
[[proxies]]
name = "server name"
type = "https"
subdomain = "your-subdomain"
[proxies.plugin]
type = "https2http"
localAddr = "内网ip:内网port"
crtPath = "/etc/frp/acme/*.example.com_ecc/fullchain.cer"
keyPath = "/etc/frp/acme/*.example.com_ecc/*.example.com.key"
hostHeaderRewrite = "内网ip"
requestHeaders.set.x-from-where = "frp"
更新SSL证书
Let’s Encrypt 的证书有效期为3个月,每3个月得重新申请证书 (这个和阿里一样)。通过acme.sh
可以自动管理SSL证书的申请。通过上面步骤的安装后 acme.sh
会定期自动更新SSL证书 (这个还没验证,三个月后来删除这个TODO)。
手动更新方式记录如:。
docker exec acme --renew -d blog.exsvc.cn --ecc --force
//acme.sh --renew -d blog.exsvc.cn --ecc --force
取消更新SSL证书的自动续期
有时候我们可能需要移除特定域名的自动申请,这时候可以如下命令取消对特定域名的自动续期。
已申请的证书仍然有效,不会失效
docker exec acme --remove -d blog.exsvc.cn --ecc
//acme.sh --remove -d blog.exsvc.cn --ecc
评论区