教程 · 建站与 Web
用 Nginx 托管静态网站并签发 Let's Encrypt 证书
难度
入门
预计时长
25 分钟
步骤
8 步
最近修订
基准系统
Debian 12
要点
用 Nginx 托管静态网站并签发 Let's Encrypt 证书
在 Debian 上安装 Nginx,把站点文件放进 /var/www/example.com,写一段 server 块并用 nginx -t 校验后重载,再用 certbot --nginx 申请 Let's Encrypt 证书,续期由 systemd timer 自动完成。前提是域名 A 记录已经指向服务器且 80 端口对外可达 —— HTTP-01 验证走的就是这个端口。
前置条件
开始之前,先确认这些都具备
- 一台已加固的服务器与 sudo 权限
- 一个自己控制 DNS 的域名
- 防火墙已放行 80 与 443
操作步骤
共 8 步
步骤 01 / 08
安装 Nginx 并确认它在跑 #
Debian 与 Ubuntu 官方仓库里的 Nginx 版本足够稳定,除非要用特定的新模块,否则不必折腾第三方源。安装后先用本机 curl 确认默认页能出来,把「服务问题」和「网络问题」分开。
Shell sudo apt update && sudo apt install -y nginx systemctl status nginx --no-pager curl -I http://127.0.0.1 sudo ufw allow 80,443/tcp comment 'web'步骤 02 / 08
建立站点目录并放上首页 #
一个域名一个目录,命名就用域名本身,机器上有十几个站点时你会感谢现在的自己。属主给 www-data,权限用符号写法一次搞定:目录 755、文件 644。
Shell sudo mkdir -p /var/www/example.com/html echo '<h1>example.com</h1>' | sudo tee /var/www/example.com/html/index.html sudo chown -R www-data:www-data /var/www/example.com sudo chmod -R u=rwX,go=rX /var/www/example.com步骤 03 / 08
写 server 块 #
try_files 的作用是:先找同名文件,再找同名目录,都没有就返回 404 —— 静态站点这样写足够了。每个站点单独一份访问日志,排查问题时不用在几十万行里翻。
Nginx 配置 # /etc/nginx/sites-available/example.com server { listen 80; listen [::]:80; server_name example.com www.example.com; root /var/www/example.com/html; index index.html; access_log /var/log/nginx/example.com.access.log; error_log /var/log/nginx/example.com.error.log; location / { try_files $uri $uri/ =404; } location ~ /\. { deny all; } }步骤 04 / 08
启用站点、校验、重载 #
nginx -t 是这一步的安全带:配置有错时它会指出文件与行号,而重载一个有错的配置会让整台机器上的所有站点一起下线。顺手删掉默认站点,避免未匹配的域名落到 Nginx 的欢迎页。
Shell sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/ sudo rm -f /etc/nginx/sites-enabled/default sudo nginx -t sudo systemctl reload nginx curl -I -H "Host: example.com" http://127.0.0.1步骤 05 / 08
确认 DNS 已经生效,再去签证书 #
证书签发失败最常见的原因就是 DNS 还没生效。先 dig 确认解析确实指向这台机器的 IP。如果域名挂在 CDN 后面,建议先切成仅解析(DNS only)完成签发,再打开代理。
Shell # Debian 最小安装可能没有 dig sudo apt install -y bind9-dnsutils dig +short example.com @1.1.1.1 dig +short www.example.com @1.1.1.1 # 应当返回这台服务器的公网 IP curl -4 -s ifconfig.me; echo步骤 06 / 08
签发证书并开启自动跳转 #
certbot 的 nginx 插件会自动改写 server 块、加上 443 监听与证书路径。--redirect 让 HTTP 自动跳转到 HTTPS。调试阶段先加 --dry-run 试跑,避免反复失败触发签发频率限制。
Shell sudo apt install -y certbot python3-certbot-nginx sudo certbot --nginx \ -d example.com -d www.example.com \ --agree-tos -m [email protected] --no-eff-email \ --redirect curl -I https://example.com步骤 07 / 08
确认自动续期真的会跑 #
证书有效期不长,续期必须是自动的。certbot 的软件包会装好一个 systemd timer;用 --dry-run 完整模拟一次续期流程,比等到过期前收到告警要从容得多。
Shell systemctl list-timers | grep -i certbot sudo certbot renew --dry-run sudo certbot certificates步骤 08 / 08
(可选)加上压缩与缓存头 #
静态资源加长缓存、开压缩,对跨境访问的体感提升明显 —— 少一次往返在 200 ms 以上的链路上就是实打实的时间。注意 HTML 本身不要设长缓存,否则改了内容访客看不到。
Nginx 配置 # 放进 server 块内部 gzip on; gzip_types text/css application/javascript application/json image/svg+xml; gzip_min_length 1024; location ~* \.(?:css|js|jpg|jpeg|png|gif|webp|woff2)$ { expires 30d; add_header Cache-Control "public, immutable"; access_log off; }
常见错误
这一步最容易踩的坑
下面每一条都对应一个真实会发生的故障。先读完再动手,比出问题之后再回来查要省时间。
- DNS 还没生效就急着签发。certbot 会失败,而失败次数是计入签发频率限制的,反复重试只会让自己被临时锁住。先 dig,再 certbot。
- 域名在 CDN 后面且开着代理时签发失败。签发阶段先切成仅解析,或者改用 DNS-01 验证方式。
- 只签了主域名没签 www。访客输入 www 就会看到证书错误页,这比 404 更劝退。
- 权限给成 777 或者属主是 root。前者不安全,后者常常表现为莫名其妙的 403。
- 忘了删 sites-enabled/default。未匹配的域名会落到默认站点,别人把域名解析到你的 IP 就能蹭你的服务器。
- 续期失败往往是因为 80 端口后来被防火墙关了 —— 续期同样要走 HTTP-01 验证。
- 手工大改 certbot 生成的 443 server 块,改乱之后 renew 会报错。要改就改自己新增的部分,别动它管理的证书行。
这篇教程的边界
- 命令以 Debian 12 为准。Ubuntu 与 Rocky Linux 的差异只在正文明确标注之处,未标注的部分请以你所用发行版的官方文档为准。
- 示例中的 IP 来自文档保留段 203.0.113.0/24,域名为 example.com,端口为示意值。复制后必须替换成自己的值, 原样执行不会有任何效果。
- 教程不能替代备份。任何会改动数据或线上流量的步骤,执行前先确认有一份验证过能恢复的备份。
- 本站不提供任何用于绕过网络审查的配置或说明,这篇也不例外。
发现命令过时或有误,请发邮件到 [email protected]。 指出错误的邮件比沉默的旧文档有价值得多。