V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
sneezry
V2EX  ›  分享发现

80、443 端口无法使用时使用 Let’s Encrypt 签发证书

  •  
  •   sneezry · 2016-02-01 22:35:29 +08:00 · 5234 次点击
    这是一个创建于 3007 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Let ’ s Encrypt 自从公测以来,就唤起了各路开发者的兴趣,第三方自动化脚本也是雨后春笋般出现。但是 Let ’ s Encrypt 与其它 CA 签发证书时验证域名所有权不太相同,它使用 ACME-server 进行域名验证,原理就是验证服务器指定在客户端服务器的一个随机的目录下生成一个随机的文件,然后验证是否能下载到这个文件。

    本来这是个很方便的验证方法——更符合自动化的需求,但是,这也是 Let ’ s Encrypt 被抱怨的地方之一,很多情况下无法满足这个验证流程,比如我今天遇到的, 80 端口被完完全全 block 掉的情况。

    于是后来,更多的人开始呼吁支持 DNS 方式验证,最终 Let ’ s Encrypt 终于支持了 DNS 验证域名所有权。

    支持 DNS 验证的第三方自动化工具也不少,letsencrypt.sh就是其中之一,下面我来向大家分享一下我使用 letsencrypt.sh 并且结合 DNSpod 的 API 实现自动化签署 Let ’ s Encrypt 证书的过程,如果你使用其他的 DNS 服务,那么在后面调用 hook 的地方,改为你所使用的 API 即可。

    获取 letsencrypt.sh

    git clone https://github.com/lukas2511/letsencrypt.sh.git
    

    进入 letsencrypt.sh 目录

    cd letsencrypt.sh
    

    创建 domains.txt ,并把你要签发的域名写进去

    nano domains.txt
    

    下面是和 DNSpod 相关的,如果你使用的不是 DNSpod ,可以直接跳到编辑 hook.sh 。

    在 DNSpod 中添加一条 TXT 记录,主机名为_acme-challenge.<subname>。比如我要签发 wiki.lizhe.org 这个域名的证书,那么我就添加_acme-challenge.wiki 这个主机名。值随便写,后面签发时程序会自动改。

    获取你的 DNSpod 域名 id 和记录 id

    curl -k https://dnsapi.cn/Domain.List -d "login_email=xxx&login_password=xxx"
    curl -k https://dnsapi.cn/Record.List -d "login_email=xxx&login_password=xxx&domain_id=xxx"
    

    复制 hook.sh.example 到 hook.sh

    cp hook.sh.example hook.sh
    

    编辑 hook.sh

    nano hook.sh
    

    找到deploy_challenge这个函数,$TOKEN_VALUE就是我们需要更改的 TXT 记录值,对于 DNSpod ,通过我们前面找到的域名 id 和记录 id 进行更新。

    更新 DNS 记录,将下面的内容写在deploy_challenge函数中

    curl -k https://dnsapi.cn/Record.Modify -d "login_email=xxx&login_password=xxx&domain_id=xxx&record_id=xxx&sub_domain=_acme-challenge.xxx&record_type=TXT&record_line=默认&value=${TOKEN_VALUE}"
    

    记得把 xxx 都改成你自己的参数,注意sub_domain里还有个 xxx ,sub_domain的前缀我已经帮你加好了。

    最后运行 letsencrypt.sh 签发证书

    ./letsencrypt.sh -c -k ./hook.sh -t dns-01
    

    如果一切顺利,那么在 certs 下面在各个以域名命名的文件夹下就会有证书文件了,privkey.pem是私钥,fullchain.pem是拼好的完整证书链,其他的文件就不用管了。

    如果不想把证书文件放在当前路径,在 hook.sh 的deploy_cert函数中,将生成的相应证书移动到目标目录即可。

    7 条回复    2016-02-02 09:16:31 +08:00
    Tink
        1
    Tink  
       2016-02-01 22:44:35 +08:00
    我记得.le 那个项目好像也支持 dns 了
    DesignerSkyline
        2
    DesignerSkyline  
       2016-02-01 22:57:37 +08:00
    perfect !
    DesignerSkyline
        3
    DesignerSkyline  
       2016-02-01 22:58:02 +08:00
    @Tink 对的,现已支持 CF 的 DNS API
    neilp
        4
    neilp  
       2016-02-01 23:29:46 +08:00
    没错. 并且支持 CF 的 api

    https://github.com/Neilpang/le
    XiaoxiaoPu
        5
    XiaoxiaoPu  
       2016-02-02 01:17:19 +08:00
    写了个 Python3 脚本自动调用 DnsPod API
    https://gist.github.com/XiaoxiaoPu/d69f99fcebe49f3af843
    保存为 dnspod.py ,修改 111, 112 行的登录邮箱、密码、域名,在 hook.sh 的 deploy_challenge 函数中写上

    ./dnspod.py "${DOMAIN}" "${TOKEN_VALUE}"
    sleep 3

    欢迎使用&建议
    v1024
        6
    v1024  
       2016-02-02 08:13:56 +08:00 via iPhone
    一直有个问题,这个 acme-challenge ,是不是只有在签发、续期时候才用得到?
    hiroya
        7
    hiroya  
       2016-02-02 09:16:31 +08:00 via iPad
    感谢分享,现在貌似好多家 dns 都不支持 acme ,好像因为防护或是海外节点的问题。
    窝去研究一下 alidns 如何用这种方式验证

    昨天还有人说 : dns 能用来验证 ssl 是来秀下限的。我呵呵了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   976 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 22:26 · PVG 06:26 · LAX 15:26 · JFK 18:26
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.