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

lua-resty-acme: ACMEv2 客户端和 Let's Encrypt 证书的自动化管理

  •  
  •   fffonion ·
    fffonion · 2019-09-21 07:06:12 +08:00 · 4024 次点击
    这是一个创建于 1894 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我又来骗星了 https://github.com/fffonion/lua-resty-acme

    相比于现有实现,不需要安装任何第三方程序或者 C 扩展,所有依赖均为 Lua 和 FFI 实现。

    安装

    使用 opm:

    opm install fffonion/lua-resty-acme
    

    opm 中没有 luaossl 库,所以这种安装使用的是基于 FFI 的 Openssl 后端;需要 OpenResty 链接了大于等于 1.1 版本的 OpenSSL。

    如果有完整的编译工具链,可以使用 luarocks 安装,需要安装 OpenSSL 的头文件:

    luarocks install lua-resty-acme
    
    

    使用

    以 /etc/openresty 目录为例,如果目录不存在,请自行修改。

    生成一个账户密钥

    openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -out /etc/openresty/account.key
    

    生成一个默认证书

    openssl req -newkey rsa:2048 -nodes -keyout /etc/openresty/default.pem -x509 -days 365 -out /etc/openresty/default.key
    

    在 Nginx 配置的 http 节插入以下内容

    resolver 8.8.8.8;
    
    lua_shared_dict acme 16m;
    lua_shared_dict autossl_events 128k;
    
    init_by_lua_block {
        require("resty.acme.autossl").init({
            -- setting the following to true
            -- implies that you read and accepted https://letsencrypt.org/repository/
            tos_accepted = true,
            -- uncomment following for first time setup
            -- staging = true,
            -- uncomment folloing to enable RSA + ECC double cert
            -- domain_key_types = { 'rsa', 'ecc' },
            account_key_path = "/etc/openresty/account.key",
            account_email = "此处填写邮箱",
        })
    }
    init_worker_by_lua_block {
        require("resty.acme.autossl").init_worker()
    }
    
    # required to verify Let's Encrypt API
    lua_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
    lua_ssl_verify_depth 2;
    

    CentOS/Fedora 等系统的根证书在 /etc/ssl/certs/ca-bundle.crt ,请根据实际情况修改 lua_ssl_trusted_certificate。

    首次配置时,建议将 init_by_lua_block 中的 staing = true 取消注释,以防错误过多触发限流;测试通过后再加回注释使用生产 API。

    在需要使用证书的 server 节插入

    server {
        server_name example.com;
    
        # fallback certs, make sure to create them before hand
        ssl_certificate /etc/openresty/default.pem;
        ssl_certificate_key /etc/openresty/default.key;
    
        ssl_certificate_by_lua_block {
            require("resty.acme.autossl").ssl_certificate()
        }
    
        location /.well-known {
            content_by_lua_block {
                require("resty.acme.autossl").serve_http_challenge()
            }
        }
    }
    

    配置完成后,reload nginx。

    双证书配置见 https://yooooo.us/2019/lua-resty-acme

    福利:

    # RSA
    echo q |openssl s_client -connect 随机子域名.acme.yooooo.us -port 8443 -cipher ECDHE-RSA-AES128-GCM-SHA256|openssl x509 -noout -text|grep -P "Public Key Algorithm|After"
    # ECC
    echo q |openssl s_client -connect 随机子域名.acme.yooooo.us -port 8443 -cipher ECDHE-ECDSA-AES128-GCM-SHA256|openssl x509 -noout -text|grep -P "Public Key Algorithm|After"
    

    首次请求后等 10 秒钟,即可收到新证书加密的链接

    欢迎讨论和提供建议!

    9 条回复    2022-09-19 21:44:46 +08:00
    hanxiV2EX
        1
    hanxiV2EX  
       2019-09-21 09:07:32 +08:00
    不错的样子,star 了。
    Remember
        2
    Remember  
       2019-09-21 09:08:42 +08:00 via iPhone
    acme 了解一下,shell 的,搞了好几年了
    noqwerty
        3
    noqwerty  
       2019-09-21 10:55:38 +08:00 via Android
    一直在用 certbot,懒得手动弄这些了
    fffonion
        4
    fffonion  
    OP
       2019-09-21 11:49:46 +08:00 via iPhone
    @noqwerty 这个比 certbot 更自动化,可以尝试一下 = )
    Cbdy
        5
    Cbdy  
       2019-09-21 11:52:59 +08:00 via Android
    目前用 acme.sh
    littlespider89
        6
    littlespider89  
       2019-09-21 14:35:42 +08:00
    k8s ingress + cert-manager, 真的香
    justing
        7
    justing  
       2019-09-23 08:06:33 +08:00
    我也用的是 acme.sh ,配合 https://www.cloudflare.com 的 dns api,完全不用任何配置,无脑操作。
    tufu9441
        8
    tufu9441  
       2019-09-24 08:52:28 +08:00 via iPhone
    @justing 这个姿势真是非常舒适
    tinypig
        9
    tinypig  
       2022-09-19 21:44:46 +08:00
    @fffonion 仓库文档里的 example config 似乎有点错误?

    location = /.well-known { }
    是不是应该修改为:
    location ^~ /.well-known { }

    如果用文档里的写法,Let's encrypt 会在校验域名请求时出现 404 错误。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3525 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 00:07 · PVG 08:07 · LAX 16:07 · JFK 19:07
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.