V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
danbao
V2EX  ›  分享创造

通过 GitHub Actions + acme.sh 免费全自动申请/续签泛域名 SSL 证书

  •  
  •   danbao · 58 天前 · 3337 次点击
    这是一个创建于 58 天前的主题,其中的信息可能已经有所发展或是发生改变。

    repo 在此

    https://github.com/danbao/auto-ssl

    记得不要直接 fork 这个 repo , 用 clone 然后 push 到你自己的 private github repo

    Features

    • 自动申请 SSL 证书,并通过 git commit 的方式保存证书到 SSL
    • 每天检查 SSL 证书是否快过期,如果小于 30 天,自动续期
    • 每天的检查报告会同步到 CHECK_LIST.md 文件中
    • 证书是泛域名证书
    • 同时申请 ECDSA 和 RSA 证书
    34 条回复    2024-07-18 15:46:37 +08:00
    totoro625
        1
    totoro625  
       58 天前
    大概好几年前有类似的项目,配置好后正常跑了一两年,然后 actions 就会 Skipped
    网友告诉我是我这个项目太久没有修改过代码,导致 actions Skipped
    totoro625
        2
    totoro625  
       58 天前
    目前用的方案是 GCP 免费服务器,每月 200G 流量足够拉取证书等需要可靠运行的服务了
    w292614191
        3
    w292614191  
       58 天前
    感谢分享。

    现在阿里云只有 90 天免费了,大家都怎么解决的。
    linyongxin
        4
    linyongxin  
       58 天前
    宝塔自带的经常出错,后来就直接全部接入 CloudFlare ,一劳永逸
    bilulanlv
        5
    bilulanlv  
       58 天前
    @linyongxin
    我看介绍,他似乎只是源服务器和 Cloudflare 的认证,其他厂家认这种证书吗?

    源证书生成由 Cloudflare 签名的免费 TLS 证书,以安装在源服务器上。

    源证书仅对 Cloudflare 与源服务器之间的加密有效。
    danbao
        6
    danbao  
    OP
       58 天前
    @totoro625
    我这个 repo 应该会避免这个问题,因为每天都会检查 SSL,检查完后会更新时间戳并提交 commit
    danbao
        7
    danbao  
    OP
       58 天前
    @w292614191 这个 repo 就是用来解决这个问题的
    keyfunc
        8
    keyfunc  
       58 天前
    不是,私钥就这么公开了?
    knva
        9
    knva  
       58 天前
    私钥已撸
    danbao
        10
    danbao  
    OP
       58 天前
    @keyfunc @knva 哈哈,私钥在提交的时候已打码了~不过这个域名本来就是学费米,无所谓
    logictan89
        11
    logictan89  
       58 天前
    @linyongxin 宝塔垃圾,试试 1panel 。我就是因为宝塔经常续签 ssl 证书出错才换的。
    highFreqSurfer
        12
    highFreqSurfer  
       58 天前
    @w292614191 用 certbot, 定时任务跑
    stormwindcity
        13
    stormwindcity  
       58 天前
    感谢分享
    Jinnrry
        14
    Jinnrry  
       57 天前 via Android
    道理我都懂,可是 commit 以后私钥不就泄漏了?要是把私钥打码了,那你自己怎么用啊?

    要么别用 commit ,提交到自己网盘,要么你 aes 加密一下再 commit 呀
    danbao
        15
    danbao  
    OP
       57 天前
    @Jinnrry 注意看这句话
    记得不要直接 fork 这个 repo , 用 clone 然后 push 到你自己的 private github repo
    br_wang
        16
    br_wang  
       57 天前
    @Jinnrry 也可以放到项目的 Actions secrets 里,就是泄露给 github 了。
    acme.sh 不是有自动更新的 cronjob 么?
    wdssmq
        17
    wdssmq  
       57 天前
    wdssmq/php-nginx-dc: 用于部署多站点 PHP + Nginx 环境的 Docker Compose 配置,使用 webdevops/php-nginx ;
    https://github.com/wdssmq/php-nginx-dc

    我现在换了 All In Docker 。。acme 也跑在容器里。。/doge
    danbao
        18
    danbao  
    OP
       57 天前
    @br_wang 我的使用场景是内网有 ssl 的需求,比如 esxi ,adguard 的 DoH,但又不想专门搞个 vps 跑 cronjob
    lblblong
        19
    lblblong  
       57 天前
    有没有腾讯云版的
    Donaldo
        20
    Donaldo  
       57 天前
    @totoro625 #1 隔一段时间 commit 一次就行,可以设置个机器人干这个?
    molezznet
        21
    molezznet  
       57 天前 via Android
    看起来方便的。暂时在用免费的微林
    lblblong
        22
    lblblong  
       57 天前
    @lblblong 改了下代码已经可以了
    lxqxqxq
        23
    lxqxqxq  
       57 天前
    @w292614191 #3 哈哈哈 定时任务 /85 天执行一次
    danbao
        24
    danbao  
    OP
       57 天前
    @lblblong 参考 acme.sh 的文档改一下密钥就行了

    ```yaml
    name: DnsPod SSL Certificates

    on:
    schedule: # execute every 24 hours
    - cron: "35 7 * * *"
    workflow_dispatch:

    env:
    ACME: /home/runner/.acme.sh/acme.sh
    DP_ID: ${{ secrets.DP_ID }}
    DP_KEY: ${{ secrets.DP_KEY }}
    EMAIL: ${{ secrets.EMAIL }}

    jobs:
    build:
    runs-on: ubuntu-latest
    if: github.event_name == 'schedule' || github.event.repository.owner.id == github.event.sender.id
    steps:
    - name: Checkout
    uses: actions/checkout@v4
    - name: Install & Configure acme.sh
    run: |
    curl https://get.acme.sh | sh -s email=$EMAIL
    - name: Issue & Deploy Certificates
    run: |
    export DP_Id=$DP_ID
    export DP_Key=$DP_KEY

    git config --global user.email $EMAIL
    git config --global user.name acme

    # 如果想要其他证书发行机构,可以把 acme.sh 的 ca 目录拷贝到 repo 的 ca 目录
    # mkdir -p /home/runner/.acme.sh/ca/
    # cp -r ca/* /home/runner/.acme.sh/ca/

    check_certificate_validity() {
    cert_path=$1
    if [ -f "$cert_path" ]; then
    if openssl x509 -checkend $(( 30 * 86400 )) -noout -in "$cert_path"; then
    echo "Certificate at $cert_path is valid for more than 30 days, skipping..."
    return 0
    else
    return 1
    fi
    else
    return 1
    fi
    }

    issue_and_install_certificate() {
    domain=$1
    cert_type=$2 # "EC" or "RSA"
    acme_server=$3 # default choose "letsencrypt" 其他 CA 请参考 https://github.com/acmesh-official/acme.sh/wiki/CA
    keylength=$4 # empty for EC, "3072" for RSA

    cert_path="./ssl/$domain"
    [ "$cert_type" = "RSA" ] && cert_path="$cert_path/rsa"
    cert_file="$cert_path/$domain.cer"
    key_file="$cert_path/$domain.key"

    # Issue certificate
    issue_status=0
    $ACME --issue --server $acme_server --debug --dns dns_dp -d "$domain" -d "*.$domain" ${keylength:+--keylength $keylength} || issue_status=$?
    if [ $issue_status -ne 0 ]; then
    echo "Failed to issue $cert_type certificate for $domain, skipping..."
    return
    fi

    # Install certificate
    install_status=0
    $ACME --installcert -d "$domain" --key-file "$key_file" --fullchain-file "$cert_file" || install_status=$?
    if [ $install_status -ne 0 ]; then
    echo "Failed to install $cert_type certificate for $domain, skipping..."
    return
    fi

    TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
    git add $cert_path/
    git commit -m "Update $cert_type certificate files for $domain at $TIMESTAMP"
    }

    while IFS= read -r domain || [ -n "$domain" ]; do
    mkdir -p "./ssl/$domain/rsa"

    # Check and issue/install EC certificate
    if ! check_certificate_validity "./ssl/$domain/$domain.cer"; then
    issue_and_install_certificate "$domain" "EC" "letsencrypt" ""
    fi

    # Check and issue/install RSA certificate
    if ! check_certificate_validity "./ssl/$domain/rsa/$domain.cer"; then
    issue_and_install_certificate "$domain" "RSA" "letsencrypt" "3072"
    fi

    done < dnspod_domains_list.txt
    - name: Push changes
    uses: ad-m/github-push-action@master
    with:
    github_token: ${{ secrets.GITHUB_TOKEN }}
    ```
    gaojiren
        25
    gaojiren  
       57 天前
    我用 AlphaSSL ,泛域名 1 年 30 块钱,花小钱办大事
    Actrace
        26
    Actrace  
       56 天前
    vx 有免费的自动续签的 SSL 服务,只需要配置 DNS 就完成配置下证书。
    应该是目前最简单的。
    wushenlun
        27
    wushenlun  
       56 天前
    @totoro625 GCP 有免费服务器吗,细说以下?
    blankmiss
        28
    blankmiss  
       56 天前
    @gaojiren AlphaSSL 的 30 块钱证书 不已经被回收了? 萌咖那种 ?
    jeffma
        29
    jeffma  
       56 天前   ❤️ 1
    自荐下自己的方案,已经稳定运行两年多了——

    借助腾讯云·云函数实现的 ACME Let’s Encrypt SSL 证书自动更新

    https://github.com/Jeff2Ma/acme-qcloud-scf
    jeffma
        30
    jeffma  
       56 天前
    @lblblong 自荐下自己的方案,已经稳定运行两年多了——

    借助腾讯云·云函数实现的 ACME Let’s Encrypt SSL 证书自动更新

    https://github.com/Jeff2Ma/acme-qcloud-scf
    ilylx2008
        31
    ilylx2008  
       56 天前
    有自动更新阿里云腾讯云 cdn 的证书么
    GoRoad
        32
    GoRoad  
       55 天前
    @danbao #18 那老哥是给内网地址解析的域名吗,我现在也是这个问题,直接把域名解析到内网的私有网段了,证书就很苦恼
    danbao
        33
    danbao  
    OP
       55 天前
    @GoRoad 按 github action 的方式获取证书还苦恼啥
    lblblong
        34
    lblblong  
       51 天前
    @jeffma 🐂🍺老哥
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2418 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 02:37 · PVG 10:37 · LAX 19:37 · JFK 22:37
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.