从裸奔到上锁
三讲服务器运维笔记
按「每章做了什么 → 用了什么命令 → 遇到的问题和解决办法」重新整理三讲教材,配套验证清单与命令速查,可搜索、可折叠、可一键复制,全部离线可用。
学习路线 · 三讲全景
从「守住门」到「开出门」再到「上安全锁」,一步依赖一步
服务器安全加固
让你的第一台服务器学会自我防护
把一台「裸奔」的服务器,加固成只认密钥、守得住、还会自动反击的机器。本章不改 SSH 端口。
学完本章,你将能够 点击展开
- 说清 SSH 密钥认证原理,配置密钥登录并安全禁用密码登录
- 理解并配置「安全组 + 主机防火墙」两层防护,读懂 ICMP 与端口的关系
- 用 fail2ban 让服务器自动封禁暴力破解者
- 把自己锁在门外时,用 VNC 完成自救
本章做了什么
12 个关键步骤- 01
看见威胁
用 journalctl 调出 sshd 日志,看到大量陌生 IP 对 root 的失败登录,确认暴力破解真实存在,确定「攻击者会从哪里进来」这条主线。
- 02
分清两条登录通道
SSH / Workbench 走公网 22 端口、受 sshd 管辖;VNC 走阿里云带外管理通道,不经过安全组与 sshd —— 真正能救命的后路是 VNC。
- 03
准备普通用户
新建 study、设置密码、加入 wheel 组,为稍后禁止 root 远程登录做准备。
- 04
亲自走通 VNC
控制台 VNC 登录 study,用 whoami 与 tty 确认是 /dev/tty1 本地终端,再 exit 退出;后路只有走通过一次才靠得住。
- 05
本机生成密钥对
ssh-keygen -t ed25519 生成密钥对,私钥从诞生起只留在自己电脑,复制公钥准备安装。
- 06
安装公钥并卡死权限
写入 ~/.ssh/authorized_keys,目录 700、文件 600、属主本人,避开「SSH 静默拒绝、不给报错」这个最难排查的坑。
- 07
铁律:先验证再收口
回自己电脑 ssh study@公网IP 免密登录成功,才允许去禁用密码 —— 顺序反了就会把自己关在门外。
- 08
配置 teacher 巡检账号
只装老师的公钥,绝不交出自己的私钥;因 teacher 无密码,单独写免密 sudo 规则并用 visudo -c 校验语法。
- 09
加固 sshd_config
开密钥、禁密码、禁 root、限尝试次数、清空闲会话、设 AllowUsers 白名单;sshd -t 通过后 reload 生效。
- 10
两层门最小化放行
firewalld 加 --permanent 再 --reload 只放行 ssh;安全组保留 22 与 ICMP,读懂「ICMP 端口=任何」不是漏洞;ss -tlnp 对照实际监听。
- 11
部署 fail2ban 自动反击
装 EPEL 源,在 jail.d/sshd.local 写规则(Rocky 9 必须 backend = systemd),10 分钟失败 3 次封禁 1 小时,启动后查看 Banned IP list。
- 12
验证与提交
逐项核对 9 条清单;只向老师提交公网 IP,老师用自己的私钥登录检查。
用了什么命令
52 条 · 8 组命令均以等宽字体代码块呈现,灰色 ↳ 行是作用说明(不会被复制);点击代码块右上角「复制全部」或组标题右侧「复制本组」即可带走该组命令。
威胁排查 · 看见正在发生的暴力破解
sudo journalctl -u sshd | grep -i "failed" | tail -30↳ 查 sshd 系统日志 → 只筛含 failed 的行(-i 忽略大小写) → 只显示最后 30 条whoami↳ 显示当前登录用户名,VNC 下应为 studytty↳ 显示终端设备:VNC 为 /dev/tty1,SSH 为 /dev/pts/0 —— 从系统内部印证两条独立通道exit↳ 退出 VNC 登录准备普通用户 study
sudo adduser study↳ 新建普通用户;把 study 换成自己的用户名sudo passwd study↳ 设置登录密码(按提示输入两次)sudo usermod -aG wheel study↳ 加入 wheel 组,只有 wheel 成员才能用 sudo 执行管理员命令生成密钥对(在自己的电脑上执行)
ssh-keygen -t ed25519 -C "你的名字-服务器加固"↳ 生成 ed25519 密钥对(现代、短小、安全),一路回车即可;私钥绝不外传type $env:USERPROFILE\.ssh\id_ed25519.pub↳ Windows PowerShell 查看公钥(.pub 结尾)cat ~/.ssh/id_ed25519.pub↳ macOS / Linux 查看公钥;不带 .pub 的那个是私钥安装公钥到服务器 · 权限一步都不能省
sudo su - study↳ 切换到 study 并加载其环境,此后 ~ 代表 /home/studymkdir -p ~/.ssh↳ 创建 .ssh 目录;-p 表示已存在也不报错chmod 700 ~/.ssh↳ 目录 700:仅本人可进入读写,权限过松 SSH 会直接拒绝使用且不报错vi ~/.ssh/authorized_keys↳ 按 i 进入编辑 → 粘贴公钥(一整行,中间不能换行)→ Esc → :wq 保存chmod 600 ~/.ssh/authorized_keys↳ 文件 600:SSH 强制要求,权限过松会拒绝用它登录ls -l ~/.ssh↳ 核对:authorized_keys 应为 -rw-------,且属主是本人而不是 rootssh study@服务器公网IP↳ 回到自己电脑验证:能直接登入且不要求输密码,才算密钥配置成功为老师配置巡检账号 teacher
sudo adduser teacher↳ 新建专供老师巡检的账号sudo mkdir -p /home/teacher/.ssh↳ 为 teacher 创建 .ssh 目录sudo vi /home/teacher/.ssh/authorized_keys↳ 贴入【老师发给你的公钥】一整行 —— 注意不是你自己的公钥sudo chmod 700 /home/teacher/.ssh↳ 目录权限 700sudo chmod 600 /home/teacher/.ssh/authorized_keys↳ 文件权限 600sudo chown -R teacher:teacher /home/teacher/.ssh↳ 用 sudo 建的目录属主是 root,必须改回 teacherecho "teacher ALL=(ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/teacher↳ teacher 无密码,wheel 组 sudo 需本人密码,故单独写免密规则sudo chmod 440 /etc/sudoers.d/teacher↳ sudoers 规则文件要求权限 440(只读)sudo visudo -c↳ 检查所有 sudo 配置语法,全部 parsed OK 才算过;写错会让所有账号 sudo 失效sudo -u teacher sudo -n true && echo "teacher 免密 sudo 可用"↳ 以 teacher 身份测试,-n 表示不询问密码收口:加固 /etc/ssh/sshd_config
sudo vi /etc/ssh/sshd_config↳ 打开 SSH 服务端主配置文件PubkeyAuthentication yes↳ 允许密钥登录(本章加固的基础,保持开启)PasswordAuthentication no↳ 禁止密码登录,杜绝被猜密码 —— 务必确认密钥能登录后再改这一项PermitRootLogin no↳ 禁止 root 直接远程登录,缩小攻击面MaxAuthTries 3↳ 单次连接最多 3 次认证尝试,超过即断开,拖慢暴力破解ClientAliveInterval 300↳ 每 300 秒探测一次客户端是否还在ClientAliveCountMax 2↳ 连续 2 次无响应就断开,自动清理空闲会话AllowUsers study teacher↳ 登录白名单:写错用户名或漏掉 teacher,对应的人就会被挡在门外sudo sshd -t↳ 测试配置语法:没有任何输出即正确,有错会指出具体行号sudo systemctl reload sshd↳ 重新加载生效;reload 不会断开当前连接,比 restart 安全两道门 · firewalld 与端口核对
sudo firewall-cmd --permanent --add-service=ssh↳ 永久放行 SSH;Rocky 上必须加 --permanent,否则重启后规则失效sudo firewall-cmd --reload↳ 重新加载防火墙,让永久规则真正生效sudo firewall-cmd --list-all↳ 列出当前区域放行的服务/端口,核对结果sudo ss -tlnp↳ -t 只看 TCP / -l 只看监听 / -n 数字显示不解析 / -p 显示占用进程;与安全组规则对照让服务器自动反击 · fail2ban
sudo dnf install -y epel-release↳ 先装 EPEL 扩展源(Rocky 默认源里没有 fail2ban)sudo dnf install -y fail2ban↳ 安装 fail2ban 本体sudo vi /etc/fail2ban/jail.d/sshd.local↳ 在 jail.d/ 写 .local 规则,不直接改 jail.conf —— 软件升级时配置不会被覆盖[sshd]↳ 针对 sshd 服务的防护规则enabled = true↳ 启用本规则backend = systemd↳ Rocky 9 关键:日志由 systemd 统一管理;旧教程读 /var/log/secure 在这里不生效maxretry = 3↳ 允许的最大失败次数findtime = 600↳ 统计窗口:600 秒(10 分钟)内累计失败bantime = 3600↳ 触发后的封禁时长:3600 秒(1 小时)sudo systemctl enable --now fail2ban↳ 启动并设为开机自启(--now 立即启动,enable 开机自启)sudo fail2ban-client status sshd↳ 查看运行状态,重点看 Banned IP list(已被自动封禁的攻击者 IP)遇到的问题和解决办法
9 个sudo sshd -tsudo systemctl reload sshdls -l ~/.sshchmod 700 ~/.sshchmod 600 ~/.ssh/authorized_keyssudo chown -R teacher:teacher /home/teacher/.sshsudo systemctl reload sshdsudo visudo -csudo firewall-cmd --permanent --add-service=sshsudo firewall-cmd --reloadsudo fail2ban-client status sshd验证清单
勾选状态自动保存本章小结
| 攻击者想做的事 | 你部署的加固 |
|---|---|
| 猜密码登进来 | SSH 密钥登录 + 禁用密码 + 禁止 root |
| 从别的端口钻进来 | firewalld + 安全组,两层最小化放行 |
| 反复爆破 SSH | fail2ban 自动封禁 |
| 进来了不被发现 | journal 日志审计 |
网站上线
域名解析与 Nginx 个人主页
为已备案域名配置解析,安装 Nginx,发布带备案号的个人主页,让任何人输入域名都能访问。
学完本章,你将能够 点击展开
- 说清 DNS 的作用,为域名添加解析记录并验证生效
- 按需在安全组和防火墙中开放网页访问端口
- 安装 Nginx、编写站点配置,并安全地让配置生效
- 发布个人主页,排查 403、404、连接超时等常见故障
本章做了什么
13 个关键步骤- 01
补做 teacher 免密 sudo
上一章 teacher 没设密码,而 wheel 组成员用 sudo 必须输本人密码,实际用不了 sudo;先补 NOPASSWD 规则并 visudo -c 校验。
- 02
理清上线的三个环节
DNS 让域名指向 IP → 开门放行 80 → Nginx 接收请求并发出主页,三者缺一不可,排查也按这个顺序。
- 03
先做解析,让等待在后台发生
添加 A 记录:@ 与 www 都指向公网 IP,TTL 默认 10 分钟;把需要等待的事提前做,是运维常用思路。
- 04
验证解析
本机 nslookup 查两个域名;暂时查不到或 IP 不对先继续做后面步骤,几分钟后再查。
- 05
最小化开门
安全组 + firewalld 只放行 80;443 留到下一章配证书时再开 —— 最小化不是什么都不开,而是服务真正上线才开对应的门。
- 06
安装并启动 Nginx
dnf 安装、enable --now 开机自启、看状态与版本;浏览器访问公网 IP 看到默认测试页,说明 80 已打通。
- 07
准备网站目录
/var/www/mysite 交给 study、权限 755,之后上传改网页不必 sudo;getenforce 确认阿里云 Rocky 镜像 SELinux 默认 Disabled。
- 08
编写站点配置
conf.d/mysite.conf 写 server_name / root / index / 双日志 / try_files;server_name 最关键,Nginx 靠 Host 请求头区分站点;nginx -t 通过后 reload。
- 09
发布个人主页
硬性要求:首页底部必须显示 ICP 备案号并链接工信部备案查询网站;AI 生成或模板修改后必须自己核对;scp 上传或 vi 直接编辑。
- 10
理解 server_name 与 Host
用 curl -H 手动指定 Host 亲眼验证;用 IP 访问因 Host 不匹配,请求被交给默认站点,所以看到的仍是 Nginx 默认页。
- 11
亲手制造并修复一次 403
chmod 600 → curl -I 得 403 → 错误日志出现 Permission denied → ps 查到 nginx 工作进程身份 → chmod 644 恢复 200 → 删除测试文件。
- 12
看见第一位访客
tail -f 访问日志,同学每刷新一次就多一行:来访 IP、时间、页面、状态码、浏览器。
- 13
验证与提交
逐项核对 7 条清单,向老师提交域名;合规提醒:开通后 30 日内还需办理公安联网备案。
用了什么命令
48 条 · 10 组命令均以等宽字体代码块呈现,灰色 ↳ 行是作用说明(不会被复制);点击代码块右上角「复制全部」或组标题右侧「复制本组」即可带走该组命令。
补做:为 teacher 配置免密 sudo
echo "teacher ALL=(ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/teacher↳ teacher 无密码,wheel 组 sudo 需本人密码,所以用不了,单独写免密规则sudo chmod 440 /etc/sudoers.d/teacher↳ sudoers 规则文件要求权限 440sudo visudo -c↳ 必须全部 parsed OK;写错会让所有账号 sudo 失效,用 VNC 以 root 修复sudo -u teacher sudo -n true && echo "teacher 免密 sudo 可用"↳ 以 teacher 身份验证免密 sudo 是否可用DNS 解析验证(在自己电脑上执行)
nslookup 你的域名↳ 查询解析结果,看 Address 一栏是不是服务器公网 IPnslookup www.你的域名↳ 带 www 的记录同样要能查到为网站开门 · 只放行 80
控制台:安全组入方向添加 TCP 80 / 0.0.0.0/0↳ 允许任何来源访问网页;控制台通常也有 HTTP(80) 快速添加选项sudo firewall-cmd --permanent --add-service=http↳ 永久放行 HTTP 服务(即 TCP 80)sudo firewall-cmd --reload↳ 重新加载防火墙,使永久规则生效sudo firewall-cmd --list-services↳ 查看已放行服务,应包含 ssh 和 http安装与启动 Nginx
sudo dnf install -y nginx↳ 从系统软件源安装,-y 自动确认sudo systemctl enable --now nginx↳ 立即启动并设为开机自启systemctl status nginx↳ 查看运行状态,应显示 active (running),按 q 退出nginx -v↳ 查看 Nginx 版本号准备网站目录
sudo mkdir -p /var/www/mysite↳ 单独建自己的站点目录,结构清晰,以后加第二个站点不互相干扰sudo chown -R study:study /var/www/mysite↳ 把目录交给 study,之后上传和修改网页不必用 sudosudo chmod 755 /var/www/mysite↳ 目录 755:属主可读写,其他人(包括 Nginx)可进入ls -ld /var/www/mysite↳ 核对:应显示 drwxr-xr-x,属主为 studygetenforce↳ 查看 SELinux 状态:阿里云 Rocky 公共镜像默认显示 Disabled编写站点配置 /etc/nginx/conf.d/mysite.conf
sudo vi /etc/nginx/conf.d/mysite.conf↳ Nginx 自动加载 conf.d/ 下所有 .conf 文件;把 example.com 换成自己的域名server {↳ 站点配置块开始 listen 80;↳ 监听 80 端口,接收 HTTP 请求 server_name example.com www.example.com;↳ 本站响应哪些域名:带 www 和不带 www 都要写;Nginx 靠 Host 请求头匹配它 root /var/www/mysite;↳ 网站文件所在目录 index index.html;↳ 访问目录时默认返回的首页文件 access_log /var/log/nginx/mysite_access.log;↳ 本站访问日志:记录每一次访问 error_log /var/log/nginx/mysite_error.log;↳ 本站错误日志:出问题时先看这里 location / {↳ 路径匹配规则 try_files $uri $uri/ =404;↳ 按请求路径查找文件或目录,找不到就返回 404 }↳ 结束 location}↳ 结束 serversudo nginx -t↳ 检查所有配置语法,显示 syntax is ok 和 test is successful 才算通过sudo systemctl reload nginx↳ 重新加载生效;reload 不中断正在进行的访问发布个人主页 · 两种方式任选其一
scp index.html study@你的服务器公网IP:/var/www/mysite/↳ 方式一:本地写好再上传,用的是和 ssh 同一把密钥,不需要密码(推荐)vi /var/www/mysite/index.html↳ 方式二:直接在服务器上编辑;目录已交给 study,所以不需要 sudo页面底部:<a href="https://beian.miit.gov.cn/" target="_blank">浙ICP备XXXXXXXX号-1</a>↳ 硬性合规要求:备案号换成自己的,链接指向工信部,新窗口打开验证 server_name 与 Host 请求头机制
curl -H "Host: 你的域名" http://127.0.0.1↳ 手动指定 Host 为你的域名 → 返回你的主页内容curl http://127.0.0.1 | head -5↳ 不带你的域名 → 返回默认测试页;head -5 只看前 5 行排障实验 · 亲手制造并修复 403
echo "<h1>test</h1>" > /var/www/mysite/test.html↳ 在网站目录新建一个测试页面chmod 600 /var/www/mysite/test.html↳ 权限改为 600:只有属主 study 能读写curl -I -H "Host: 你的域名" http://127.0.0.1/test.html↳ -I 只看响应头:结果是 403 Forbiddenps -o user= -C nginx | sort -u↳ 查 nginx 进程身份:主进程 root,工作进程 nginx —— 真正读文件的是 nginx 用户ls -l /var/www/mysite/↳ test.html 显示 -rw-------,对 nginx 用户属于「其他人」,600 不允许读sudo tail -3 /var/log/nginx/mysite_error.log↳ 错误日志里有 (13: Permission denied),直接说明原因chmod 644 /var/www/mysite/test.html↳ 改为 644:属主可读写,其他人可读 —— 网页文件至少需要 644curl -I -H "Host: 你的域名" http://127.0.0.1/test.html↳ 再次访问:返回 200 OKrm /var/www/mysite/test.html↳ 实验结束,删除测试文件看见你的第一位访客
sudo tail -f /var/log/nginx/mysite_access.log↳ 持续显示文件末尾新增内容,按 Ctrl+C 退出;每刷新一次多一行访问记录遇到的问题和解决办法
9 个nslookup 你的域名nslookup www.你的域名sudo firewall-cmd --list-servicessudo tail -3 /var/log/nginx/mysite_error.logls -l /var/www/mysite/chmod 644 /var/www/mysite/文件名ls -l /var/www/mysite/sudo nginx -tsudo systemctl reload nginxsudo nginx -tjournalctl -u nginxsudo visudo -csudo nginx -tgetenforce验证清单
勾选状态自动保存本章小结
| 环节 | 本章做了什么 | 出问题时的表现 |
|---|---|---|
| DNS | 添加 A 记录,域名指向服务器 IP | 域名打不开,IP 能打开 |
| 开门 | 安全组 + firewalld 放行 80 端口 | 连接超时 |
| Nginx | 安装、配置站点、发布主页 | 403、404 或看到默认页 |
HTTPS 与证书自动续期
给网站加上安全锁
为上一章的个人主页申请免费 HTTPS 证书,让网站从「不安全」变为带安全锁的加密站点,并配置到期自动续期。
学完本章,你将能够 点击展开
- 说清 HTTP 明文传输的风险,以及 HTTPS 加密了什么、没有加密什么
- 理解数字证书作用,以及 CA 如何确认域名属于你
- 用 certbot 申请证书,并编写 Nginx 的 HTTPS 配置
- 配置证书自动续期,并验证它确实可用
本章做了什么
12 个关键步骤- 01
亲眼看见 HTTP 在「裸奔」
装 tcpdump 抓 80 端口,屏幕上出现 GET /、Host、User-Agent、甚至 <title> —— 若有登录表单,账号密码也会被看得一清二楚。
- 02
理解 HTTPS 解决什么
HTTPS = HTTP + TLS:一是加密(内容变只有浏览器和服务器能解开的密文),二是身份认证(证书=网站身份证,由浏览器信任的 CA 签发)。
- 03
理解 HTTP-01 验证与三个前提
CA 给 certbot 一串随机内容 → 放进 /.well-known/acme-challenge/ → Let's Encrypt 从公网访问验证 → 推出三个前提:域名正确解析、80 对外开放、Nginx 能发出验证文件(server_name 与 root 都要对)。
- 04
认识到自动续期是必须项
证书有效期 90 天,并宣布 2028 年 2 月前逐步缩短到 45 天;Let's Encrypt 已于 2025 年停发到期提醒邮件 —— 靠人记着续期迟早会忘。
- 05
开放 443,并牢牢保留 80
安全组 + firewalld 放行 https;80 不能关:一是 http 访问要跳转,二是每次续期 Let's Encrypt 仍通过 80 做 HTTP-01 验证。
- 06
安装 certbot,先演练再正式
--dry-run 走 Let's Encrypt 测试环境,不真签证书、不占正式环境失败次数;看到 The dry run was successful. 再去掉参数正式申请。
- 07
查看并认识证书
certbot certificates 看域名 / 到期时间 / 路径;openssl x509 看颁发者、有效期、SAN 域名列表;认识 fullchain.pem 与 privkey.pem —— 证书私钥绝不外泄,目录仅 root 可访问。
- 08
备份并改写 Nginx 配置
备份名必须以 .bak 结尾(写成 .conf 会被一并加载造成重复配置);80 只做 ACME 验证 + 301 跳转,443 才提供内容(只允许 TLSv1.2 / TLSv1.3);nginx -t 通过后 reload。
- 09
验证跳转与安全锁
浏览器访问 http 自动变 https 并出现锁;Windows PowerShell 里 curl 是别名,必须写 curl.exe -I 才能拿到 301 / 200 响应头。
- 10
配置自动续期
启用 certbot-renew.timer;写 deploy 钩子 reload-nginx.sh 并 chmod +x、手动跑一次确认;最后 certbot renew --dry-run 演练整个续期流程。
- 11
再抓一次 443 包做对比
内容全是无法阅读的乱码,但仍能在其中找到自己的域名(SNI 明文)—— HTTPS 隐藏的是「你看了什么内容」,不是「你访问了哪个网站」。
- 12
验证与交付
逐项核对 8 条清单。★ 作品一完成:带域名、备案号与 HTTPS 安全锁的完整规范网站;本章无需提交新材料。
用了什么命令
62 条 · 11 组命令均以等宽字体代码块呈现,灰色 ↳ 行是作用说明(不会被复制);点击代码块右上角「复制全部」或组标题右侧「复制本组」即可带走该组命令。
第 1 节 · 亲手「偷看」HTTP 明文流量
sudo dnf install -y tcpdump↳ 安装抓包工具 tcpdumpsudo tcpdump -i any -A -nn 'tcp port 80' | grep -a -E "GET |Host:|User-Agent|<title>"↳ -i any 所有网卡 / -A 文本显示 / -nn 数字不解析 / -a 二进制当文本;请同学用手机访问 http://你的域名 观察开放 443 端口 · 80 保留不关
控制台:安全组入方向添加 TCP 443 / 0.0.0.0/0↳ 控制台通常也提供 HTTPS(443) 快速添加选项sudo firewall-cmd --permanent --add-service=https↳ 永久放行 HTTPS 服务(即 TCP 443)sudo firewall-cmd --reload↳ 重新加载防火墙使永久规则生效sudo firewall-cmd --list-services↳ 核对:应包含 ssh、http、https安装 certbot
sudo dnf install -y certbot↳ 从 EPEL 源安装(第 1 章装 fail2ban 时已装过 EPEL)certbot --version↳ 查看版本号,确认安装成功先演练 --dry-run(申请失败有次数限制)
sudo certbot certonly --webroot -w /var/www/mysite \↳ certonly 只申请证书不自动改 Nginx;--webroot 把验证文件放进网站目录由 Nginx 发出;行尾 \ 表示命令未完 -d example.com -d www.example.com \↳ -d 证书要包含的域名,带 www 和不带 www 各写一个 -m 你的邮箱 --agree-tos --no-eff-email --dry-run↳ -m 联系邮箱 / --agree-tos 同意条款 / --no-eff-email 不订阅新闻 / --dry-run 演练模式正式申请(去掉 --dry-run)
sudo certbot certonly --webroot -w /var/www/mysite \↳ 看到 Successfully received certificate. 说明证书已签发 -d example.com -d www.example.com \↳ 两个域名缺一不可 -m 你的邮箱 --agree-tos --no-eff-email↳ 演练成功后才执行这一步查看证书与四个 pem 文件
sudo certbot certificates↳ 列出本机所有证书:包含哪些域名、到期时间、剩余天数、文件位置sudo ls -l /etc/letsencrypt/live/example.com/↳ 目录名取自第一个 -d 域名;fullchain.pem 证书链发访问者 / privkey.pem 私钥留服务器绝不泄露sudo openssl x509 -in /etc/letsencrypt/live/example.com/cert.pem -noout -issuer -dates -ext subjectAltName↳ -issuer 颁发者应含 Let's Encrypt / -dates 生效与到期时间 / -ext subjectAltName 域名列表备份并改写站点配置(共 6 处 example.com 要替换)
sudo cp /etc/nginx/conf.d/mysite.conf /etc/nginx/conf.d/mysite.conf.bak↳ 备份名不能以 .conf 结尾,否则会被 Nginx 一并加载造成重复配置sudo vi /etc/nginx/conf.d/mysite.conf↳ 把文件全部内容替换为下面的双 server 块# ① 80 端口:只做 ACME 验证 + 跳转到 HTTPS↳ 80 不再直接提供网页server {↳ 80 server 块 listen 80;↳ 监听 80 server_name example.com www.example.com;↳ 两个域名都要写 location /.well-known/acme-challenge/ {↳ 证书续期验证专用路径 root /var/www/mysite;↳ Let's Encrypt 仍通过 HTTP 读取这里的验证文件 }↳ 结束 location location / {↳ 其余请求 return 301 https://$host$request_uri;↳ $host 请求域名 / $request_uri 请求路径,保证 /about.html 准确跳转而不是一律回首页 }↳ 结束 location}↳ 结束 80 server# ② 443 端口:真正提供网站内容↳ HTTPS 站点server {↳ 443 server 块 listen 443 ssl;↳ 监听 443 并启用 SSL/TLS 加密 server_name example.com www.example.com;↳ 两个域名都要写 ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;↳ 证书(含中间证书),发给访问者证明身份 ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;↳ 证书私钥,留在服务器用于解密,绝不能泄露 ssl_protocols TLSv1.2 TLSv1.3;↳ 只允许较新的安全协议版本,淘汰有漏洞的旧版本 root /var/www/mysite;↳ 网站目录 index index.html;↳ 首页文件 access_log /var/log/nginx/mysite_access.log;↳ 访问日志 error_log /var/log/nginx/mysite_error.log;↳ 错误日志 location / {↳ 路径匹配 try_files $uri $uri/ =404;↳ 找不到就返回 404 }↳ 结束 location}↳ 结束 443 serversudo nginx -t↳ 显示 syntax is ok 和 test is successful 才算通过;报 cannot load certificate 多半是路径域名写错sudo systemctl reload nginx↳ 重新加载配置使其生效验证跳转(Windows PowerShell 必须写 curl.exe)
curl.exe -I http://example.com↳ 应返回 301 Moved Permanently,Location 指向 https://example.com/curl.exe -I https://example.com↳ 应返回 200 OKcurl.exe -I https://www.example.com↳ 带 www 的同样应返回 200 OK配置自动续期 · 定时器 + deploy 钩子
sudo systemctl enable --now certbot-renew.timer↳ 启用续期定时器并立即计时;每天检查,到期前约 30 天自动续期systemctl list-timers 'certbot*'↳ 查看定时器:NEXT 一列是下次检查时间sudo vi /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh↳ 续期成功后自动执行的钩子脚本#!/bin/bash↳ 脚本内容第 1 行systemctl reload nginx↳ 脚本内容第 2 行:Nginx 不会自动读新证书,必须重载一次才生效sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh↳ 钩子脚本必须有执行权限才会被调用sudo /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh↳ 手动运行一次,没有报错即可systemctl is-active nginx↳ 确认 Nginx 仍在正常运行,应显示 activesudo certbot renew --dry-run↳ 演练一次续期全过程;成功显示 Congratulations, all simulated renewals succeeded第 7 节 · 再抓一次包看 HTTPS
sudo tcpdump -i any -A -nn -c 40 'tcp port 443'↳ -c 40 抓够 40 个包自动停止;看不到 GET / User-Agent / 标题,全是乱码,但域名(SNI)仍明文改坏了配置想恢复
sudo cp /etc/nginx/conf.d/mysite.conf.bak /etc/nginx/conf.d/mysite.conf↳ 用备份还原sudo nginx -t && sudo systemctl reload nginx↳ 还原后照例先测语法再生效遇到的问题和解决办法
12 个nslookup 你的域名nslookup www.你的域名sudo firewall-cmd --list-servicessudo nginx -tsudo certbot certonly --webroot -w /var/www/mysite -d example.com -d www.example.com --dry-runsudo certbot certificatessudo firewall-cmd --list-servicescurl.exe -I http://example.comsudo systemctl reload nginxsudo cp /etc/nginx/conf.d/mysite.conf.bak /etc/nginx/conf.d/mysite.confsudo nginx -t && sudo systemctl reload nginx验证清单
勾选状态自动保存本章小结
| 步骤 | 做了什么 | 关键点 |
|---|---|---|
| 开门 | 放行 443 端口 | 80 端口不能关:跳转和续期都要用到 |
| 申请证书 | certbot 以 webroot 方式申请 | 先 --dry-run 演练,再正式申请 |
| 配置 HTTPS | 80 负责跳转,443 提供内容 | 证书私钥 privkey.pem 绝不外泄 |
| 自动续期 | 定时器 + deploy 钩子 | 90 天有效期,靠自动化而不是靠人记 |