跳到主要内容
注册无需实名认证
安云主机 AnYun VPS

教程 · 建站与 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

  1. 步骤 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'
  2. 步骤 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
  3. 步骤 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;
        }
    }
  4. 步骤 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
  5. 步骤 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
  6. 步骤 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
  7. 步骤 07 / 08

    确认自动续期真的会跑 #

    证书有效期不长,续期必须是自动的。certbot 的软件包会装好一个 systemd timer;用 --dry-run 完整模拟一次续期流程,比等到过期前收到告警要从容得多。

    Shell
    systemctl list-timers | grep -i certbot
    sudo certbot renew --dry-run
    sudo certbot certificates
  8. 步骤 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]。 指出错误的邮件比沉默的旧文档有价值得多。

联系 工单
扫码
手机访问

扫码在手机上打开