采用 Ubuntu 20.04 LTS服务器作为实例。
家里搭建了一个TureNas用于存储服务,另外在 Ubuntu 服务器上搭建了Jellyfin,用于媒体服务,但如果想要通过外部访问,默认的http的明文传输是非常不安全的,因此需要采取https的方法进行安全传输。而运营商网络一般无法开启80与443端口(部分地区),而80端口是let’s encrypt申请证书需要用到的端口,443是SSL端口,好像…陷入了死局。
但其实 Certbot
还提供了另外一种 dns-01
的发放证书的方法,采用更新DNS解析的方式来验证域名所有者。
另外,因为我这边目前 IPv6 访问环境良好,就没有申请 IPv4 公网,采用的是 IPv6 的环境,但理论上 IPv6 和 IPv4 应该是一样的。
STEP1 – 安装certbot
Ubuntu / CentOS / Debian :
确保 snapd
已经安装,如果没有安装:
sudo snap install core; sudo snap refresh core
安装certbot
sudo snap install --classic certbot
其他操作系统
参见 certbot 官网
STEP2 – DNS 认证
certbot certonly --manual --pref erred-challenge dns -d <your.domain.com>
输入完后会提示一串字符串,选中即可复制,之后按照说明到你的DNS服务商处增加一个 TXT 的 DNS 记录。
_acme-challenge.<你的域名> | TXT记录 | <终端提示的字符串>
成功后就会自动发放证书到你的 /etc/letsencrypt/live/<域名>/
目录下。
STEP3 – 转换证书格式并导入Jellyfin
Jellyfin 控制台中的证书配置只支持 PKCS #12 的正式格式,因此,需要对正式格式进行转换。
输入一下指令即可转换到指定目录下:
openssl pkcs12 -password pass:<证书密码> -export -out <指定目录>/certificate.p12 -inkey /etc/letsencrypt/live/<你的域名>/privkey.pem -in /etc/letsencrypt/live/<你的域名>/cert.pem -certfile /etc/letsencrypt/live/<你的域名>/chain.pem
转换证书的指定目录建议选择 Jellyfin 可以访问到的目录,如果采用的是 Docker 运行,可以存放在 Jellfin 配置的 /config 目录下
转换后在Jellyfin控制台的 联网-> HTTPS 设置 -> 服务器地址设置
中选择 启用 HTTPS
。
在联网-> HTTPS 设置 -> HTTPS 设置
中选择 自定义 SSL 证书路径
。
就可以使用 https://<你的域名>:8920 进行访问啦。
注:在确认HTTPS可以访问正常前,不要勾选强制 HTTPS
STEP4 – 自动定期更新
Let’s encrypt 证书有效期为 90 天,如果你不想每次在证书即将到期时手动输入上面的指令更新的话,就需要利用cerbot提供的manual-auth-hook 写一个更新的脚本。
Hostker DNS
以下是我为 Hostker 写的一个脚本,可供参考:
renew.sh
echo "recode:"$CERTBOT_VALIDATION
# 向解析提供服务商更新解析记录
curl --location --request POST 'https://i.hostker.com/api/dnsEditRecord' \
--form 'email="<邮箱>"' \
--form 'token="<token>"' \
--form 'id="<解析id>"' \
--form 'data='$CERTBOT_VALIDATION \
--form 'ttl="300"'
# 等待 一会儿 让解析生效一下
sleep 20
# 转换证书格式到指定目录下
openssl pkcs12 -password pass:<证书密码> -export -out /<指定目录>/certificate.p12 -inkey /etc/letsencrypt/live/<你的域名>/privkey.pem -in /etc/letsencrypt/live/<你的域名>/cert.pem -certfile /etc/letsencrypt/live/<你的域名>/chain.pem
# 重启 Jellyfin 服务 | 因人而定,我这里采用的是docker-compose
cd /home/<用户名>/config/jellyfin
docker-compose restart
关于如何查询Hostker的解析id:
curl --location --request POST 'https://i.hostker.com/api/dnsGetRecords' \
--form 'email="<你的邮箱>"' \
--form 'token="<你的token>"' \
--form 'domain="<你的域名>"'
改指令可以打印出你所有域名解析记录的信息,查找到我们之前添加的那个TXT解析的id号即可。
DNSPod
以下是 EllisonZhang 为DNSPod写的一个脚本,稍加补充,可供参考:
echo "recode:"$CERTBOT_VALIDATION
curl -k https://dnsapi.cn/Record.Modify -d "login_email=${ACCOUNT}&login_password=${PASSWORD}&domain_id=${DOMAIN_ID}&record_id=${REC_BBS}&sub_domain=_acme-challenge.${RECORD}&record_line=默认&record_type=TXT&value=$CERTBOT_VALIDATION"
sleep 20
# 转换证书格式到指定目录下
openssl pkcs12 -password pass:<证书密码> -export -out /<指定目录>/certificate.p12 -inkey /etc/letsencrypt/live/<你的域名>/privkey.pem -in /etc/letsencrypt/live/<你的域名>/cert.pem -certfile /etc/letsencrypt/live/<你的域名>/chain.pem
# 重启 Jellyfin 服务 | 因人而定,我这里采用的是docker-compose
cd /home/<用户名>/config/jellyfin
docker-compose restart
关于如何查询 domain_id 和 record_id ,详见 原文 。
Cloudflare
echo "recode:"$CERTBOT_VALIDATION
curl --location --request PUT 'https://api.cloudflare.com/client/v4/zones/<你的zone_id>/dns_records/<你的域名_id>/?identifier=<你的域名_id>&zone_identifier=<你的zone_id>' \
--header 'Authorization: Bearer <你的token>' \
--header 'Content-Type: application/json' \
--data-raw '{
"comment":"RENEW",
"type":"TXT",
"name": "_acme-challenge.<你的域名>",
"proxied":false,
"content": "'$CERTBOT_VALIDATION'"
}'
sleep 20
# 转换证书格式到指定目录下
openssl pkcs12 -password pass:<证书密码> -export -out /<指定目录>/certificate.p12 -inkey /etc/letsencrypt/live/<你的域名>/privkey.pem -in /etc/letsencrypt/live/<你的域名>/cert.pem -certfile /etc/letsencrypt/live/<你的域名>/chain.pem
sleep 20
# 重启 Jellyfin 服务 | 因人而定,我这里采用的是docker-compose
cd /home/<用户名>/config/jellyfin
sleep 20
docker-compose restart
其它的 DNS 服务商
可以参照 DNS 服务器提供的 API 接口来编写,阿里云DNS可以采用 阿里云CLI
。
STEP1 – 测试
certbot renew --manual-auth-hook /root/au.sh --dry-run
如遇文件无法执行,更改下权限:
sudo chmod +x renew.sh
测试通过后就可以加入到定时任务中了:
sudo crontab -e
# 选择一个你喜欢的编辑器
在文件中加入:
30 0 * * 1 certbot renew --manual-auth-hook /root/au.sh
每周一凌晨0点30分会尝试更新证书.
参考资料
本文内容参考了以下资料:
https://certbot.eff.org/instructions
https://gist.github.com/janikvonrotz/9413205
https://www.cnblogs.com/ellisonzhang/p/14298492.html
https://askubuntu.com/questions/419548/how-to-set-up-a-root-cron-job-properly
https://webnetforce.net/lets-encrypt-p12-pkcs12/
问题反馈: