# 向 TCP 后端传递访问者真实 IP

> 使用 PROXY v1/v2 向兼容的 TCP 后端传递公网访问者地址

---

LLMS 索引： [llms.txt](/llms.txt)

---

普通 TCP 转发会由 NPC 连接目标服务，因此后端默认只能看到 NPC 的地址。需要保留公网访问者地址时，应根据业务协议选择 PROXY 协议或 HTTP 请求头。

## 方案选择

| 场景                                         | 推荐方式                                                                             |
| -------------------------------------------- | ------------------------------------------------------------------------------------ |
| 数据库、自定义 TCP 协议、TCP 模式承载的 HTTP | PROXY v1 或 v2                                                                       |
| NPS 的 HTTP(S) 域名隧道                      | `X-Forwarded-For` / `X-Real-IP`，参见[获取用户真实 IP](/extend/feature/real-ip.html) |
| SSH、RDP 等后端不支持 PROXY 协议             | 不要开启；改由应用审计、VPN 或支持该协议的前置代理处理                               |

## 在 NPS 中启用

新增或编辑 TCP 隧道，在“PROXY 协议版本”中选择：

- `V1`：可读文本头，便于抓包排障。
- `V2`：紧凑二进制头，适合支持 v2 的后端。
- 留空：不发送 PROXY 头，保持普通 TCP 字节流。

NPS 会让 NPC 在连接目标成功后、业务数据之前写入 PROXY 头。目标服务必须从连接的第一个字节开始解析所选版本；不支持时通常会把它当作错误业务数据并断开。启用“由 NPS 服务端连接目标”时不要依赖此功能，应由 NPC 连接后端。

## 常见后端配置

Nginx HTTP 后端：

```nginx
server {
    listen 8080 proxy_protocol;
    set_real_ip_from 127.0.0.1; # 后端实际看到的 NPC 地址
    real_ip_header proxy_protocol;

    location / {
        proxy_pass http://127.0.0.1:8081;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
```

HAProxy TCP 后端：

```haproxy
frontend from_nps
    bind :9000 accept-proxy
    mode tcp
    default_backend app_nodes

backend app_nodes
    mode tcp
    server app1 127.0.0.1:9001
```

若 HAProxy 还要把来源继续传给支持 PROXY 的下游，在 `server` 行增加 `send-proxy` 或 `send-proxy-v2`。

## 验证

先在非生产端口验证。Nginx 可记录 `$proxy_protocol_addr`，HAProxy 日志可查看客户端地址；也可用 `tcpdump` 抓取连接开头确认 v1 文本 `PROXY ...` 或 v2 签名。出现“开启后服务立即断开”时，优先检查后端监听端口是否真的启用了相同版本，而不是修改 NPS 网络参数。

---

反链：

- [HTTP 后端获取真实 IP](/extend/feature/real-ip.html)
