Debian / Ubuntu nginx-acme SSL 证书配置
本文根据 Showfom 的文章 Debian / Ubuntu 下使用 nginx-acme 自动签发并配置 SSL 证书 整理。原文发布于 2026-01-16,最后编辑于 2026-05-20,页面标注协议为 WTFPL。
nginx-acme 是 Nginx 官方维护的 ACME 模块,可以让 Nginx 直接通过 ACME 协议申请和续签证书。对于 Debian Stable 和 Ubuntu LTS,使用已经打包好 nginx-acme 的 N.WTF 源,可以省掉自己编译模块的步骤。
开始前先确认三件事:
- 域名已经解析到当前服务器。
- 服务器 80 和 443 端口对公网开放。
- 使用
root或具备sudo权限的用户操作。
安装 N.WTF 源
先更新系统并安装基础工具:
sudo apt update
sudo apt upgrade -y
sudo apt install curl vim wget gnupg dpkg apt-transport-https lsb-release ca-certificates
添加 N.WTF 的 GPG 公钥和 apt 源:
curl -sSL https://n.wtf/public.key | sudo gpg --dearmor -o /usr/share/keyrings/n.wtf.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/n.wtf.gpg] https://mirror-cdn.xtom.com/sb/nginx/ $(lsb_release -sc) main" \
| sudo tee /etc/apt/sources.list.d/n.wtf.list
国内服务器可以改用清华 TUNA 镜像:
curl -sSL https://mirrors.tuna.tsinghua.edu.cn/n.wtf/public.key \
| sudo gpg --dearmor -o /usr/share/keyrings/n.wtf.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/n.wtf.gpg] https://mirrors.tuna.tsinghua.edu.cn/n.wtf/ $(lsb_release -sc) main" \
| sudo tee /etc/apt/sources.list.d/n.wtf.list
Debian 也可以通过 extrepo 启用源:
sudo apt update
sudo apt install extrepo -y
sudo extrepo enable n.wtf
然后安装带扩展模块的 Nginx:
sudo apt update
sudo apt install nginx-extras -y
准备证书状态目录
nginx-acme 需要一个可写目录保存 ACME 状态和证书文件。这里沿用 /var/cache/nginx/letsencrypt:
sudo mkdir -p /var/cache/nginx/letsencrypt
sudo chown -R www-data:www-data /var/cache/nginx
在 Debian / Ubuntu 上,www-data 通常对应 UID/GID 33:33。使用用户名写法更直观,也避免不同系统上 UID 不一致。
配置 ACME issuer
下面以 example.com 和 www.example.com 为例,邮箱为 user@example.com。先在站点配置文件开头加入 ACME issuer:
resolver 8.8.8.8:53 ipv6=off valid=5s;
acme_issuer letsencrypt {
uri https://acme-v02.api.letsencrypt.org/directory;
contact user@example.com;
state_path /var/cache/nginx/letsencrypt;
accept_terms_of_service;
ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
ssl_verify off;
}
acme_shared_zone zone=ngx_acme_shared:1M;
如果只是测试配置,建议先把 uri 改成 Let's Encrypt staging endpoint,避免频繁失败触发正式环境的速率限制:
uri https://acme-staging-v02.api.letsencrypt.org/directory;
HTTP 跳转 HTTPS
80 端口保留给 HTTP 请求和 ACME HTTP-01 验证。未命中验证路径的请求统一跳转到 HTTPS:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
location /.well-known/ {
return 404;
}
location / {
return 301 https://$host$request_uri;
}
}
这里不需要手动写 /.well-known/acme-challenge/ 的文件逻辑,nginx-acme 会接管证书验证需要的 challenge 响应。
主域名 HTTPS 站点
给主域名配置 TLS、HTTP/2、HTTP/3,以及自动证书变量:
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
http2 on;
listen 443 quic reuseport;
listen [::]:443 quic reuseport;
add_header Alt-Svc 'h3=":443"; ma=86400' always;
add_header X-Protocol $server_protocol always;
server_name example.com;
root /var/www/html;
index index.html;
ssl_protocols TLSv1.3;
ssl_ecdh_curve X25519:prime256v1:secp384r1;
ssl_prefer_server_ciphers off;
acme_certificate letsencrypt;
ssl_certificate $acme_certificate;
ssl_certificate_key $acme_certificate_key;
ssl_certificate_cache max=2;
}
acme_certificate letsencrypt; 会关联前面定义的 acme_issuer letsencrypt。证书和私钥通过 $acme_certificate、$acme_certificate_key 变量交给 Nginx。
www 跳转到主域名
如果希望 www.example.com 跳转到 example.com,再加一个 server:
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
listen 443 quic;
listen [::]:443 quic;
add_header Alt-Svc 'h3=":443"; ma=86400' always;
add_header X-Protocol $server_protocol always;
server_name www.example.com;
return 301 https://example.com$request_uri;
ssl_protocols TLSv1.3;
ssl_ecdh_curve X25519:prime256v1:secp384r1;
ssl_prefer_server_ciphers off;
acme_certificate letsencrypt;
ssl_certificate $acme_certificate;
ssl_certificate_key $acme_certificate_key;
ssl_certificate_cache max=2;
}
如果不需要 www 跳转,可以删除这个 server,或者改成你自己的业务站点。
检查并重新加载
写完配置后先检查语法:
sudo nginx -t
确认无误后重新加载:
sudo nginx -s reload
申请证书时,可以在访问日志中看到 Let's Encrypt 验证服务器请求 challenge:
23.178.112.210 - - [15/Jan/2026:16:08:18 +0000] "GET /.well-known/acme-challenge/... HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)"
等待数秒后访问:
https://example.com/
如果证书未成功签发,优先检查 DNS、80 端口入站、防火墙、安全组、Nginx access/error log,以及 ACME issuer 的 state_path 权限。
IP 地址证书
如果要给 IP 地址签发证书,需要使用 ACME short-lived profile。在 accept_terms_of_service; 下方加入:
profile shortlived;
同时 server_name 必须写完整 IP,不能使用 _:
server_name 192.0.2.2 2001:db8::2;
这一能力依赖当前 nginx-acme 和 ACME CA 支持。生产环境使用前建议先用 staging endpoint 测试。