--- title: "Debian / Ubuntu 下使用 nginx-acme 自动签发并配置 SSL 证书" tags: ['Nginx', 'SSL', 'nginx-acme', 'Debian', 'Ubuntu'] published: 2026-01-16 03:05:21 updated: 2026-07-07 01:00:00 excerpt: "本文将介绍在 Debian 或 Ubuntu 下使用 nginx-acme 自动签发并配置 SSL 证书的方法。" --- > 本文件是烧饼博客文章的 Markdown 原文,正式版本见 https://u.sb/debian-nginx-acme/ > 全站文章与页面索引见 https://u.sb/llms.txt,建议先读索引再继续抓取。 本文将介绍在 Debian 或 Ubuntu 下使用 nginx-acme 自动签发并配置 SSL 证书的方法。 以下操作需要 root 权限,本文命令均已带上 `sudo` 前缀,请确保当前用户拥有 `sudo` 权限;或者直接使用 root 用户操作并省略命令中的 `sudo`。 ## 1、什么是 nginx-acme [nginx-acme](https://github.com/nginx/nginx-acme) 是 Nginx 官方开发的基于 ACME 协议自动签发 SSL 证书的模块,隔壁 Caddy 都出了几百年的功能, Nginx 也终于赶上了。 和 Nginx 使用 C 语言开发不同,这个模块是用 Rust 语言开发的,这里就不做评价。 这个模块支持 [RFC8555](https://datatracker.ietf.org/doc/html/rfc8555)、[RFC8737](https://datatracker.ietf.org/doc/html/rfc8737)、[RFC8738](https://datatracker.ietf.org/doc/html/rfc8738) 和 [draft-ietf-acme-profiles](https://datatracker.ietf.org/doc/draft-ietf-acme-profiles/) 等规范,目前我实际测试下来已经基本可以用于生产环境。 ## 2、安装 N.WTF 这里我们使用[烧饼博客](https://u.sb/)打包的 [N.WTF](https://n.wtf/),这个项目已经集成了 `nginx-acme` 模块,可以做到开箱即用。 首先,安装一些必要的软件包: ```bash 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 源: ```bash curl -sSL https://n.wtf/public.key | sudo bash -c 'gpg --dearmor > /usr/share/keyrings/n.wtf.gpg' sudo bash -c '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" > /etc/apt/sources.list.d/n.wtf.list' ``` 国内机器可以用[清华 TUNA](https://mirrors.tuna.tsinghua.edu.cn/) 的国内源: ```bash curl -sSL https://mirrors.tuna.tsinghua.edu.cn/n.wtf/public.key | sudo bash -c 'gpg --dearmor > /usr/share/keyrings/n.wtf.gpg' sudo bash -c '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" > /etc/apt/sources.list.d/n.wtf.list' ``` Debian 下也可以直接使用 [extrepo](/debian-extrepo/): ```bash sudo apt update sudo apt install extrepo -y sudo extrepo enable n.wtf ``` 接着更新系统并安装 Nginx: ```bash sudo apt update sudo apt install nginx-extras -y ``` ## 3、nginx-acme 准备工作 准备工作很简单,我们需要建立一个目录来存放 SSL 证书并给予正确的权限,这里我们以 `/var/cache/nginx/letsencrypt` 为演示: ```bash sudo mkdir -p /var/cache/nginx sudo mkdir -p /var/cache/nginx/letsencrypt sudo chown 33:33 /var/cache/nginx -R ``` 然后别忘了把域名解析到你的服务器哦! ## 4、配置 Nginx 站点 我们以 `example.com` 为例,假设你的邮箱是 `user@example.com`,需要配置的域名是 `example.com` 和 `www.example.com`,并且希望访问 `www.example.com` 跳转到 `example.com`: 直接修改 `/etc/nginx/sites-enabled/default` 文件: ```nginx 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 on; } acme_shared_zone zone=ngx_acme_shared:1M; server { # Listen on port 80 for all IPv4 and IPv6 addresses listen 80 default_server; listen [::]:80 default_server; # Match all domain names server_name _; location /.well-known/ { return 404; } location / { # Redirect all other HTTP requests to HTTPS using 301 permanent redirect return 301 https://$host$request_uri; } } server { # Standard TLS listening listen 443 ssl default_server; listen [::]:443 ssl default_server; # HTTP/2 protocol support http2 on; # HTTP/3 QUIC protocol support 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; # modern configuration 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; # do not parse the certificate on each request ssl_certificate_cache max=2; } 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; # do not parse the certificate on each request ssl_certificate_cache max=2; } ``` 然后验证 Nginx 配置并重新加载: ```bash sudo nginx -t sudo nginx -s reload ``` 此时,在默认的 Nginx 日志文件 `/var/log/nginx/access.log` 中可以看到 Let's Encrypt 验证服务器的请求记录: ```ini 23.178.112.210 - - [15/Jan/2026:16:08:18 +0000] "GET /.well-known/acme-challenge/blablablablablablablablablablablablablablab HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)" 34.212.137.78 - - [15/Jan/2026:16:08:18 +0000] "GET /.well-known/acme-challenge/blablablablablablablablablablablablablablab HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)" 18.222.179.58 - - [15/Jan/2026:16:08:18 +0000] "GET /.well-known/acme-challenge/blablablablablablablablablablablablablablab HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)" 16.171.19.61 - - [15/Jan/2026:16:08:18 +0000] "GET /.well-known/acme-challenge/blablablablablablablablablablablablablablab HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)" 13.228.72.222 - - [15/Jan/2026:16:08:18 +0000] "GET /.well-known/acme-challenge/blablablablablablablablablablablablablablab HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)" 2600:3000:2710:200::81 - - [15/Jan/2026:16:08:20 +0000] "GET /.well-known/acme-challenge/blablablablablablablablablablablablablablab HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)" 2600:1f14:804:fd02:f7fd:3c68:dec7:a062 - - [15/Jan/2026:16:08:20 +0000] "GET /.well-known/acme-challenge/blablablablablablablablablablablablablablab HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)" 2600:1f16:269:da00:c9ce:508c:ea69:9c2 - - [15/Jan/2026:16:08:20 +0000] "GET /.well-known/acme-challenge/blablablablablablablablablablablablablablab HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)" 2a05:d016:39f:3101:8b83:62b8:2603:d15d - - [15/Jan/2026:16:08:20 +0000] "GET /.well-known/acme-challenge/blablablablablablablablablablablablablablab HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)" 2406:da18:85:1401:1f69:967a:a988:cdc8 - - [15/Jan/2026:16:08:20 +0000] "GET /.well-known/acme-challenge/blablablablablablablablablablablablablablab HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)" ``` 等待数秒后即可访问 `https://example.com/` 了。 如果要给 IP 地址签发证书,则需要在 `acme_issuer letsencrypt {}` 段里添加一行 `profile shortlived;`,并且 `server_name` 必须写入完整的 IP 地址,不能直接用 `server_name _` 哦。 ~~不过目前 nginx-acme 最新版本 0.3.1 签发 IP 证书还是会失败,开发版已经修复,应该需要等下一个版本才能使用。~~ 目前最新版本已经支持 IP 地址证书的签发,可以在 `accept_terms_of_service;` 下方加入一条 `profile shortlived;` 并且自行修改 `server_name example.com;` 为你的 IP 地址,比如 `server_name 192.0.2.2 2001:db8::2;` 即可。 读者们在使用过程中如果遇到问题,可以在 V2EX 交流讨论: https://be.st/Mv7j