12 KiB
nginx 真实 IP 还原 — 生产部署(小白友好版)
术语速查:nginx = 你这台服务器的"门卫",负责把用户请求分发给后端 / 把静态文件返回给浏览器 配置 = nginx 的工作规则,改配置 = 改门卫的工作方式
我们要做啥(整体目标)
一句话目标:https://itsupport.servyou.com.cn/itadmin/ 之前返回 403(被门卫拦了),原因是门卫把"代理服务器 IP"当成了"用户 IP",而代理 IP 不在白名单里。这次我们改门卫的规则,让它从请求头里读"真实用户 IP"。
一共 7 个动作:
| # | 动作 | 大概多久 | 风险 |
|---|---|---|---|
| 1 | PuTTY 连上服务器 | 1 分钟 | ⚪ 无风险 |
| 2 | 备份当前配置 | 几秒 | 🟢 备份原文件,可还原 |
| 3 | 写入 13 行新规则 | 几秒 | 🟡 改配置,但有备份 |
| 4 | 确认写入正确 | 几秒 | ⚪ 只读不写 |
| 5 | 检查配置语法 | 几秒 | ⚪ 只读不写 |
| 6 | 让 nginx 重新读规则 | 1 秒 | 🟡 短暂重载,服务不中断 |
| 7 | 浏览器看效果 | 几秒 | ⚪ 只读 |
总耗时:第一次大概 5-10 分钟;熟练了 2 分钟
整体风险:🟢 低 — 每一步都给了"回滚"按钮,改坏了随时能恢复
PuTTY 是啥?在哪儿打开?
PuTTY = 一个 SSH 客户端软件,作用是让你从你的 Windows 电脑远程连到公司的 Linux 服务器
打开方式:
- 按
Win 键→ 输入putty→ 回车 - 或者开始菜单 → 找到 PuTTY 图标
打开后会看到一个灰底配置界面,我们要填 4 项:
┌──────────────────────────────────────┐
│ Host Name (or IP address) │ ← 填: 10.212.189.210
│ Port │ ← 填: 2222
│ Connection type │ ← 选: SSH(默认就是)
│ Saved Sessions │ ← 填: wecom-bastion(起个名)
└──────────────────────────────────────┘
点 Save 保存 → 点 Open 开始连接
连接后会黑底白字,提示 login as: → 输入 sxn 回车 → 提示 password: → 输入你的堡垒机密码(输入时屏幕不显示,正常,输完回车就行)
注意:输错密码不会锁账号,直接重新输
动作 1:PuTTY 连服务器(⚪ 无风险)
为啥要连服务器?:改配置必须在服务器上操作,你 Windows 这边只是"遥控器"
连上堡垒机后,黑底白字会显示一个类似 sxn@jump-host:~$ 的提示符,说明你已经到堡垒机了。
决策树:
你现在看到了堡垒机提示符(类似 sxn@jump-host:~$)
├─ 是 → 在 PuTTY 里继续输入下面命令
└─ 否 → 截图发给我,卡哪儿了
贴下面的命令(右键 = 粘贴,Enter = 执行):
# 从堡垒机跳到真正的生产服务器
ssh sxn@10.90.5.110
回车后可能要输密码(堡垒机和目标机密码可能不同,试一下你之前用过的那个)
✅ 成功长这样:
sxn@prod-server:~$
❌ 失败常见:
Permission denied→ 密码错了,重输Connection timed out→ 网络问题,可能 VPN 没连- 卡住不动 → 可能需要输
yes确认服务器指纹,看到(yes/no/[fingerprint])?就输yes回车
动作 2:备份当前配置(🟢 低风险,改坏了能还原)
为啥要备份?:运维铁律 — 改任何东西之前先备份,这样改坏了能用备份还原,不会把生产搞挂
# 进入 nginx 配置所在目录
cd /opt/wecom-it-desk/nginx
# 复制一份当前配置,文件名带当前时间(分),方便区分
sudo cp nginx.conf nginx.conf.bak-$(date +%H%M)
# 列出所有备份文件,确认刚才那行成功
ls -la nginx.conf.bak-*
为啥用 $(date +%H%M)?:这个写法会自动拼上当前时间(比如 1430 表示 14:30),每次备份文件名都不一样,不会覆盖之前的备份
✅ 成功长这样:
-rw-r--r-- 1 root root 4821 Jun 15 14:30 nginx.conf.bak-1430
❌ 失败常见:
cp: cannot stat 'nginx.conf'→ 当前不在 nginx 目录,先cd /opt/wecom-it-desk/nginx进去Permission denied→ 缺sudo,命令前面加sudo重试
动作 3:写入 13 行新规则(🟡 中风险,但有备份兜底)
写入啥?:13 行 nginx 配置,告诉 nginx"从请求头 X-Forwarded-For 里读真实用户 IP"
为啥要这样做?:用户通过公司 WAF/堡垒机访问,WAF 会把真实 IP 放在
X-Forwarded-For请求头里,但 nginx 默认只看直连 IP,所以才误判 403
重要:把下面从 cat > /tmp/patch.py 到 PYEOF 的整段一次性粘贴进 PuTTY(右键 = 粘贴)。整段会作为一条命令执行。
# 创建一个 python 脚本到 /tmp/patch.py
cat > /tmp/patch.py << 'PYEOF'
fp = '/opt/wecom-it-desk/nginx/nginx.conf'
with open(fp) as f:
c = f.read()
patch = '''
# ------------------------------------------------------------------
# 真实 IP 还原(2026-06-15 v0.5.1 修复)
# ------------------------------------------------------------------
set_real_ip_from 10.0.0.0/8;
set_real_ip_from 172.16.0.0/12;
set_real_ip_from 192.168.0.0/16;
set_real_ip_from 10.212.0.0/16;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
'''
old = 'error_log /var/log/nginx/error.log warn;'
new = old + patch
new_c = c.replace(old, new, 1)
with open(fp, 'w') as f:
f.write(new_c)
print('patched, +{} bytes'.format(len(new_c) - len(c)))
PYEOF
# 运行这个 python 脚本,它会自动把上面那 13 行插入到 nginx.conf
sudo python3 /tmp/patch.py
术语解释:
cat > /tmp/patch.py→ 创建一个文件,内容是后面所有内容<< 'PYEOF' ... PYEOF→ 这种写法叫 heredoc(直译"这里是文档"),作用是把多行文字原样写入文件sudo→ 以管理员身份运行(改系统文件需要权限)
✅ 成功长这样:
patched, +492 bytes
❌ 失败常见:
Permission denied→ 缺sudo,或者 nginx.conf 不存在NameError: name 'fp' is not defined→ heredoc 没贴完整,最末尾的PYEOF没贴上- 没任何输出 → python 没运行,看光标有没有新行,可能没回车
动作 4:确认写入正确(⚪ 无风险,只读)
为啥要确认?:虽然脚本说写入了,但人眼看到才真的算。这步只读不写,放心跑
# 在 nginx.conf 里搜索"真实 IP 还原"关键字,并显示后面 13 行
sudo grep -A 13 "真实 IP 还原" /opt/wecom-it-desk/nginx/nginx.conf
✅ 成功长这样(应该看到完整 13 行):
# 真实 IP 还原(2026-06-15 v0.5.1 修复)
# ------------------------------------------------------------------
set_real_ip_from 10.0.0.0/8;
set_real_ip_from 172.16.0.0/12;
set_real_ip_from 192.168.0.0/16;
set_real_ip_from 10.212.0.0/16;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
❌ 失败:
- 啥也没输出 → 写入失败,回到动作 3 重做
- 只输出一两行 → heredoc 没贴全,需要回滚后重来
动作 5:检查配置语法(⚪ 无风险,只读不执行)
为啥要检查?:这个命令 nginx 会"假装"按新配置启动,只检查语法,不会真的重启。通过 = 配置写得对,放心用;不通过 = 写得有问题,继续走会出问题
# 在 nginx 容器(就是跑 nginx 服务的那个小 Linux)内,做配置语法检查
docker compose exec nginx nginx -t
术语解释:
docker compose→ 管理这台服务器上所有"容器"的命令exec→ "钻进"某个容器里执行命令nginx -t→ nginx 自带的"语法检查"工具(全称--test)
✅ 成功长这样:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
❌ 失败(test is successful 没出现):
unexpected "}"/unknown directive→ 写错字了,回去动作 4 看看哪里对不上- 直接停下,不要继续 → 复制错误信息贴回给我
动作 6:让 nginx 重新读规则(🟡 中风险,但服务不中断)
"重新读"是啥意思?:nginx 现在用的还是旧配置,我们让 nginx 不用重启(不会断服务)就把新配置加载进来。这个动作叫"热加载"或 "reload"
会断网吗?:不会,reload 是无缝的,用户那边无感知
# 通知 nginx 容器内的 master 进程重新读配置
docker compose exec nginx nginx -s reload
术语解释:-s reload = 发信号(英文 signal)给 nginx,告诉它"重读配置"
✅ 成功长这样(没报错即成功):
2026/06/15 14:35:12 [notice] 1#1: signal process started
❌ 失败:
nginx: [error]开头 → 配置没通过,回去动作 5 看哪里没对- 啥也没输出 → 命令没执行,看光标位置
动作 7:浏览器看效果(⚪ 无风险)
为啥这步是浏览器而不是 curl?:curl 看响应头,浏览器看真实页面。人眼看到才作数
操作步骤:
- 打开浏览器
- 开隐身模式(
Ctrl + Shift + N,Chrome / Edge 都是这个快捷键)- 为啥要隐身?:隐身模式不读本地缓存,看到的就是 nginx 当下返回的
- 地址栏输入
https://itsupport.servyou.com.cn/itadmin/ - 按回车
✅ 成功长这样:
- 页面正常显示
- 按
F12打开开发者工具 →Network选项卡 → 顶部那一行状态码是 200(不是 403)
❌ 失败:
- 仍然是 403 → 见下面"如果还是 403"段
- 502 / 504 → nginx 后面那个服务挂了,贴错误给我
- 页面打不开(连接被拒) → DNS 没配,联系 IT 运维
如果还是 403 — 看 WAF 出口 IP(诊断)
啥是 WAF?:公司部署在 nginx 前面的"统一入口",所有用户请求先经过 WAF 再到 nginx。WAF 自己的 IP 不一定在你写的 4 段内网里,所以还得加
# 看 nginx 最后 20 条访问日志,找 $remote_addr 是不是 WAF 的 IP
docker compose exec nginx tail -20 /var/log/nginx/access.log
日志长这样:
10.80.5.123 - - [15/Jun/2026:14:35:45 +0800] "GET /itadmin/ HTTP/1.1" 403 ...
^^^^^^^
这就是 $remote_addr
把那个 IP 数字(比如 10.80.5.123)贴回给我,我会:
- 给你追加一行
set_real_ip_from 10.80.5.123; - 让你重跑动作 5 + 动作 6
如果改坏了 — 回滚(啥时候都能用)
啥时候用?:任何一个动作出问题,你都可以直接回滚到动作 2 备份的版本
# 列出所有备份,挑最近的一个
ls -la /opt/wecom-it-desk/nginx/nginx.conf.bak-*
# 用最近那个备份覆盖当前配置(把 1430 换成上面列出的真实时间)
sudo cp /opt/wecom-it-desk/nginx/nginx.conf.bak-1430 /opt/wecom-it-desk/nginx/nginx.conf
# 重新加载回滚后的配置
docker compose exec nginx nginx -s reload
回滚后页面应该回到改之前的状态(403 回来),说明回滚成功
一张图看懂流程
PuTTY 连服务器
│
▼
备份原配置
│
▼
写入 13 行新规则
│
▼
确认写入正确 ──→ ❌ 不对 ──→ 重做写入 / 回滚
│ ✅
▼
检查配置语法 ──→ ❌ 语法错 ──→ 复制错误贴回给我,不要继续
│ ✅
▼
重载 nginx ─────→ ❌ 报错 ──→ 检查容器状态 / 找 Claude
│ ✅
▼
浏览器看效果 ──→ ❌ 还是 403 ──→ 看 WAF 出口 IP,贴给 Claude
│ ✅
▼
🎉 完成
我建议你第一次做
第一次建议:动作 1 → 动作 2 → 停一下,截图发给我 → 我确认备份成功 → 你再继续动作 3 之后
熟练了以后:一口气跑完动作 1-7,中间不打断
关联
- 评审报告:
review-p0-security-2026-06-14.mdP0-3 - 待办:
ip-whitelist-trust-proxies-todo.md— v1.0 前必须收窄 4 段 → 4 个 IP - 本地配置:
deploy-server/nginx/nginx.conf(已包含 patch,下次重打包自动带) - 服务器 IP 变更:
project-production-server-ip-2026-06-15.md— 10.80.0.136 已下线,用 10.90.5.110 - 客户端约束:
feedback-putty-not-openssh.md— 用 PuTTY,不用ssh -J - 命令行规范:
feedback-cmd-step-by-step.md— 每行一条 + 中文注释 - 小白引导规范:
feedback-beginner-friendly-guide.md— 讲清目标+风险、术语解释、出错兜底