simplessl
使用 Let's Encrypt 自动颁发和更新 SSL 证书
$ opm get jxskiss/simplessl
simplessl
在 OpenResty/nginx、Envoy 和任何 Golang TLS 程序中,使用 Let's Encrypt 实时免费注册和更新 SSL 证书。
simplessl 会在收到请求时自动透明地从 Let's Encrypt 颁发 SSL 证书,当证书需要续期时,它会自动在后台异步续期证书。
OpenResty 插件使用 OpenResty 1.9.7.2+ 中的 ssl_certificate_by_lua
功能。
对于 Envoy,simplessl 实现 SDS 服务器以向数据平面提供 SSL 证书。
通过使用 simplessl 向 Let's Encrypt 注册 SSL 证书,您即表示同意 Let's Encrypt 订阅者协议。
免责声明:我最初从很棒的项目 lua-resty-auto-ssl 和 Go 的 autocert 包中获得了灵感并借鉴了一些代码。此外,此程序使用 Lego 来解决 dns-01 挑战。非常感谢 😀
特性
依赖最小,部署简单,对分布式环境友好。
高性能,对用户请求增加的延迟非常低。
使用 http-01 挑战为每个域名颁发和更新证书,支持 OpenResty 和 Golang。
使用 tls-alpn-01 挑战为每个域名颁发和更新证书,支持 Golang。
使用 tls-alpn-01 挑战颁发和更新SAN 证书,支持 Golang。
使用 dns-01 挑战颁发和更新通配符证书,支持 OpenResty 和 Golang。
服务手动管理的证书。
服务 OCSP 装订,带缓存和异步更新,延迟可以忽略不计。
生成和服务自签名证书。
像 Nginx 一样优雅重启,不会丢失任何请求。
支持目录和 Redis 作为缓存存储,添加新的存储支持很容易。
注意:当前此程序设计用于内部网络,未认真考虑安全功能,请务必妥善保护您的证书服务器并关注安全问题。
集中式证书服务器
与其他类似项目相比,此项目提供了一个集中式证书服务器,用于在一个地方管理所有证书(自动颁发或手动管理,以及自签名)。OpenResty 插件和 Golang TLS 配置库充当服务器的客户端。
通过这种设计,有几个优点
将与 ACME 相关的工作和与存储的通信卸载到后端 Golang 服务器,让 Nginx/OpenResty 做它设计和擅长的事情;
它对分布式部署更加友好,可以在一个地方管理所有证书,OpenResty 插件和 Golang 库的部署简单直接;您可以为一个域名获取单个证书,而不是像您的 Web 服务器实例那样多(像某些其他类似项目那样);
与使用 Lua 进行 ACME 工作和存储相比,Golang 程序被认为更容易维护和进行故障排除;
此外,Golang 程序被认为更容易扩展以支持新型存储或新功能(例如通配符证书、安全性等);
使用多层缓存机制来帮助前端 Nginx 和 Golang Web 服务器自动更新到续期的证书,性能损失可以忽略不计,并且无需任何重新加载
OpenResty 每个工作进程的 LRU 缓存,使用 cdata 指针(Golang 客户端使用内存中的写时复制缓存),回退到
OpenResty 共享内存缓存(Golang 客户端不需要),回退到
后端 simplessl 服务器中的内存缓存,最后转到
存储或 ACME 服务器。
缓存的证书和 OCSP 装订会在后端 simplessl 服务器中自动续期和刷新。
状态
视为 Beta 版本。
虽然此程序已经运行了近 5 年,支持我的个人网站,但这是一个业余项目,并且没有已知的用于大型生产系统的部署。
强烈建议任何对此感兴趣的人在您的环境中进行测试。
安装
对于 OpenResty
lua 库使用 OPM 发布,以下命令将安装 simplessl 库及其依赖项“lua-resty-http”。
opm get jxskiss/simplessl
如果您没有 opm,您可以手动安装 lua 库,以 OpenResty 安装在“/usr/local/openresty”下为例(您可能需要使用 sudo 来授予适当的权限)
mkdir -p /usr/local/openresty/site/lualib/resty
cd /usr/local/openresty/site/lualib/resty
wget https://raw.githubusercontent.com/ledgetech/lua-resty-http/v0.16.1/lib/resty/http.lua
wget https://raw.githubusercontent.com/ledgetech/lua-resty-http/v0.16.1/lib/resty/http_connect.lua
wget https://raw.githubusercontent.com/ledgetech/lua-resty-http/v0.16.1/lib/resty/http_headers.lua
wget https://raw.githubusercontent.com/jxskiss/simplessl/master/lib/resty/simplessl.lua
对于 Golang TLS 程序
go get github.com/jxskiss/simplessl/lib/tlsconfig@latest
有关使用 lib/tlsconfig
的示例,请参阅以下文档。
运行 simplessl
下载证书服务器服务二进制文件,您可以自己构建
go install github.com/jxskiss/simplessl@latest
或从 发布页面 下载预构建的二进制文件。
将 example.conf.yaml
复制到您喜欢的地址并编辑它以满足您的需求。配置文件中解释了配置选项。
运行您的证书服务器
/path/to/simplessl run -c /path/to/your/conf.yaml
或者要生成自签名证书,请参阅 simplessl generate-self-signed -h
。
现在您可以配置您的 OpenResty 或 Golang 程序以使用证书服务器获取 SSL 证书,请参阅以下示例。
Nginx 配置示例
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
lua_shared_dict ssl_certs_cache 1m;
init_by_lua_block {
-- Define a function to determine which SNI domains to automatically
-- handle and register new certificates for. Defaults to not allowing
-- any domain, so this must be configured.
function allow_domain(domain)
if domain:find("example.com$") then
return true
end
return false
end
-- Initialize backend certificate server instance.
-- Change lru_maxitems according to your deployment, default 100.
simplessl = (require "resty.simplessl").new({
backend = '127.0.0.1:8999',
allow_domain = allow_domain,
lru_maxitems = 100,
})
}
# HTTPS Server
server {
listen 443 ssl;
# Works also with non-default HTTPS port.
listen 8443 ssl;
server_name hello.example.com;
# Dynamic handler for issuing or returning certs for SNI domains.
ssl_certificate_by_lua_block {
simplessl:ssl_certificate()
}
# Fallback certificate required by nginx, self-signed is ok.
# simplessl generate-self-signed \
# -days 3650 \
# -cert-out /etc/nginx/certs/fallback-self-signed.crt \
# -key-out /etc/nginx/certs/fallback-self-signed.key
ssl_certificate /etc/nginx/certs/fallback-self-signed.crt;
ssl_certificate_key /etc/nginx/certs/fallback-self-signed.key;
location / {
content_by_lua_block {
ngx.say("It works!")
}
}
}
# HTTP Server
server {
listen 80;
server_name hello.example.com;
# Endpoint used for performing domain verification with Let's Encrypt.
location /.well-known/acme-challenge/ {
content_by_lua_block {
simplessl:challenge_server()
}
}
}
}
Golang lib/tlsconfig
您可以使用包 lib/tlsconfig
来运行带有 TLS 的 Golang 程序。例如
func main() {
handler := func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("It works!"))
}
// See doc of tlsconfig.Options for available options.
tlsConfig := tlsconfig.NewConfig("127.0.0.1:8999", tlsconfig.Options{})
listener, err := tls.Listen("tcp", ":8443", tlsConfig)
if err != nil {
log.Fatal(err)
}
http.Serve(listener, http.HandlerFunc(handler))
}
依赖
OpenResty >= 1.9.7.2
lua-resty-http >= 0.16.1
更改历史
v0.6.2 @ 2022-11-02
更改:整理日志消息
更改:更新依赖项
修复:无效的内存地址或空指针取消引用 (#10)
修复:添加使用选项配置 redis 存储的示例 (#11)
v0.6.0 @ 2022-09-03
从头开始进行主要重构。
新增:支持除 Let's Encrypt 之外的 ACME 服务器
新增:支持颁发和更新 SAN 证书
新增:使用新的配置格式 (v2)
新增:支持按配置的名称查询证书
更改:重构 HTTP API 以使用 [drpc][drpc] 以提高可维护性和一致性
更改:更改为使用 [acmez][acmez](而不是
acme/autocert
和lego
)与 ACME 服务器通信
[drpc]: https://github.com/storj/drpc [acmez]: https://github.com/mholt/acmez
v0.5.0 @ 2022-06-12
修复:在查询证书之前查询 OCSP 装订时的错误行为
新增:支持通配符证书,使用 Lego 解决 dns-01 挑战
更改:使
lib/tlsconfig
成为独立模块更改:将依赖项升级到最新版本
更改:重构代码以使用更复杂的 cli 和日志库
更改:重构代码以提高可维护性
v0.4.3 @ 2022-05-17
修复:OCSP 装订失败,因为选择了错误的证书作为颁发者证书,感谢 @cedricdubois (#6)
新增:Redis 存储的可选“前缀”选项
v0.4.2 @ 2021-06-02
修复:仅配置默认证书可用时请求失败,#2
修复:当 OCSP 服务器返回错误时抑制日志消息,#3
更改:将依赖项升级到最新版本
v0.4.1 @ 2020-08-23
新增:支持 Golang 库的 tls-alpn-01 挑战
新增:使用 cdata 指针代替 der 用于 LRU 缓存
更改:从 LRU 缓存中删除 OCSP 装订,这是不必要的并且没有正确刷新
v0.4.0 @ 2020-08-16
更新:此版本存在已知错误,请升级到较新版本。
新增:支持管理证书
新增:支持自签名证书
新增:Golang 库,用于需要 TLS 支持的任意 Golang 程序
新增:用于生成自签名证书的子命令
新增:(lua)分层缓存,以实现最佳性能(每个工作进程的 LRU 缓存 + 共享内存缓存)
新增:像 Nginx 一样优雅重启,不会丢失任何请求
更改:使用 YAML 配置文件替换命令行标志,因为我们支持更多功能,命令行标志不足以进行配置
更改:(内部)将代码重组为更小的文件,以提高可维护性
更改:(内部)优化 lua 共享内存缓存,以提高性能
修复:向证书和 OCSP 装订缓存添加指纹,以确保我们为相应的证书获取正确的 OCSP 装订,没有它,在证书更新后短时间内可能会使用错误的 OCSP 装订缓存
此版本是一个重大更改,包含大量新功能和改进。
v0.3.0 @ 2020-03-13
新增:可选的 redis 作为缓存存储
更改:更新 autocert 以支持 ACMEv2
更改:使用 go module 管理 golang 依赖项
v0.2.1 @ 2018-10-10
更改:整理日志消息
更改:小幅改进
v0.2.0 @ 2018-08-11
修复:OCSP 装订更新程序在运行数月后出现死循环
更改:删除不必要的 golang 依赖项(
gocraft/web
、jxskiss/glog
),从而减少二进制文件大小并简化安装更改:由于已删除 glog 依赖项,因此 glog 提供的标志不再可用
更改:使用官方的
acme/autocert
包而不是分叉,使代码更清晰并允许更容易地跟踪上游更改新增:使用 glide 管理 golang 依赖项
v0.1.2 @ 2018-06-20
修复:来自 OCSP 装订服务器的 408 请求超时
v0.1.1 @ 2018-01-06
初始公开发布。
作者
Shawn Wang (jxskiss)
许可证
mit
依赖项
ledgetech/lua-resty-http >= 0.16.1,openresty >= 1.9.7.2
版本
-
jxskiss/simplessl 0.6.0使用 Let's Encrypt 自动颁发和更新 SSL 证书 2023-05-20 12:44:19