基于OpenResty自动签发Let's Encrypt证书

安装OpenResty

yum-config-manager --add-repo https://openresty.org/yum/centos/OpenResty.repo
yum install -y openresty

OpenResty所有的文件以及依赖包都安装在 /usr/local/openresty 目录下

安装配置lua-resty-auto-ssl

安装Luarocks

Luarocks是Lua的包管理工具,很多OpenResty的包都可以通过luarocks来安装。

yum install -y unzip openssl gcc make
wget http://luarocks.github.io/luarocks/releases/luarocks-2.4.2.tar.gz
tar xzf luarocks-2.4.2.tar.gz
cd luarocks-2.4.2
./configure --prefix=/usr/local/openresty/luajit/ --with-lua-include=/usr/local/openresty/luajit/include/luajit-2.1
make build && make install
rm -rf luarocks-2.4.2*
ln -s /usr/local/openresty/luajit/bin/luarocks /usr/local/bin/

安装lua-resty-auto-ssl

luarocks install lua-resty-ssl

配置lua-resty-auto-ssl

编辑配置文件 vim conf/nginx.conf ,内容如下:

env DOMAINS; events { worker_connections 1024; } http { # The "auto_ssl" shared dict should be defined with enough storage space to # hold your certificate data. 1MB of storage holds certificates for # approximately 100 separate domains. lua_shared_dict auto_ssl 1m; # A DNS resolver must be defined for OCSP stapling to function. # # This example uses Google's DNS server. You may want to use your system's # default DNS servers, which can be found in /etc/resolv.conf. If your network # is not IPv6 compatible, you may wish to disable IPv6 results by using the # "ipv6=off" flag (like "resolver 8.8.8.8 ipv6=off"). resolver 8.8.8.8; # Initial setup tasks. init_by_lua_block { auto_ssl = (require "resty.auto-ssl").new() -- Define a function to determine which SNI domains to automatically handle -- and register new certificates for. Defaults to not allowing any domains, -- so this must be configured. auto_ssl:set("allow_domain", function(domain) domains = os.getenv("DOMAINS") return ngx.re.match(domain, domains, "ijo") end) auto_ssl:set("dir", "/tmp/") auto_ssl:init() } init_worker_by_lua_block { auto_ssl:init_worker() } # HTTPS server server { listen 443 ssl; # Dynamic handler for issuing or returning certs for SNI domains. ssl_certificate_by_lua_block { auto_ssl:ssl_certificate() } # You must still define a static ssl_certificate file for nginx to start. # # You may generate a self-signed fallback with: # # openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 \ # -subj '/CN=sni-support-required-for-valid-ssl' \ # -keyout /etc/ssl/resty-auto-ssl-fallback.key \ # -out /etc/ssl/resty-auto-ssl-fallback.crt ssl_certificate /etc/ssl/resty-auto-ssl-fallback.crt; ssl_certificate_key /etc/ssl/resty-auto-ssl-fallback.key; } # HTTP server server { listen 80; # Endpoint used for performing domain verification with Let's Encrypt. location /.well-known/acme-challenge/ { content_by_lua_block { auto_ssl:challenge_server() } } } # Internal server running on port 8999 for handling certificate tasks. server { listen 127.0.0.1:8999; location / { content_by_lua_block { auto_ssl:hook_server() } } } } 

注意!以上配置文件来自项目的README的示例配置,我修改了两个地方:

  1. 证书的输出路径,为了避免权限问题我将证书写到了/tmp/目录下,但是 非常不建议 在生产环境下降证书写到这里。
  2. 默认配置允许给所有的域名签发证书,这样显然可能会被滥用,所以我对 allow_domain 这个配置项加了一些限制,只允许我自己的域名进来。

修改脚本权限

Luarocks安装的lua-resty-ssl里有些脚本的权限不对,导致证书签发失败,这里赋予可执行权限:

chmod 755 /usr/local/openresty/luajit/share/lua/5.1/resty/auto-ssl/shell/start_sockproc
chmod 755 /usr/local/openresty/luajit/share/lua/5.1/resty/auto-ssl/vendor/sockproc
chmod 755 /usr/local/openresty/luajit/share/lua/5.1/resty/auto-ssl/vendor/dehydrated
chmod 755 /usr/local/openresty/luajit/share/lua/5.1/resty/auto-ssl/shell/letsencrypt_hooks

启动OpenResty

openresty -t
openresty

容器化lua-resty-auto-ssl

如果你觉得上边这个过程太复杂了,那么你也可以使用我自己build的Let's encrypt image来运行

docker run -d --name letsencrypt --net host -e DOMAINS=example.com -v $PWD:/tmp xdays/letsencrypt

使用

首先将你要签发证书的域名解析到运行openresty的机器上,然后直接向域名发送https请求即可拿到对应的证书:

curl https://ttt.xdays.me/
Show Comments