frp + Nginx 子路径代理部署笔记
本文档旨在总结通过 Nginx 反向代理 frp 内网穿透服务的最终成功方案,实现将特定域名路径 http://mcpstore.wiki/mcp
指向内网服务的目标。
一、 环境与文件路径
公网服务器 (Ubuntu):
- IP 地址:
59.110.160.18
- frp 服务端配置文件:
~/frp/frps.toml
(此为示例路径,请根据您的实际情况调整) - Nginx 配置文件:
/etc/nginx/conf.d/mcpstore.wiki.conf
- IP 地址:
内网本地服务器:
- frp 客户端配置文件:
frpc.toml
(位于您本地的 frp 目录中) - 本地服务监听地址:
127.0.0.1:21923
- frp 客户端配置文件:
二、 Nginx 安装 (公网服务器)
在公网服务器上安装 Nginx 并设置为开机自启。
- 更新软件包列表:
sudo apt update
- 安装 Nginx:
sudo apt install nginx
- 设置开机自启:
sudo systemctl enable nginx
- 启动 Nginx (在 frp 配置修改后执行):
sudo systemctl start nginx
三、 frp 配置 (最终版)
1. frps (服务端 - 公网服务器)
核心是修改 vhostHTTPPort
和 vhostHTTPSPort
,为 Nginx 让出 80
和 443
端口。
- 文件路径:
~/frp/frps.toml
- 最终配置:
# FRP 服务器端(frps.toml)配置 bindAddr = "0.0.0.0" bindPort = 7000 # 将默认的 80/443 端口修改为其他端口,以避免与 Nginx 冲突 vhostHTTPPort = 801 vhostHTTPSPort = 4431 # Web 控制台(Dashboard)配置 webServer.addr = "0.0.0.0" webServer.port = 7500 webServer.user = "admin" webServer.password = "" # 身份验证配置 auth.method = "token" auth.token = ""
- 生效方式: 修改并保存后,必须重启
frps
服务。sudo systemctl restart frps
2. frpc (客户端 - 内网本地服务器)
Nginx 负责处理所有复杂的 HTTP 逻辑,frp 只需做一个纯粹的 TCP 端口转发。
- 文件路径:
frpc.toml
- 最终配置:
serverAddr = "59.110.160.18" serverPort = 7000 auth.method = "token" auth.token = "" transport.protocol = "tcp" # 目标服务代理,使用最简单的 tcp 类型 [[proxies]] name = "21923mcp" type = "tcp" localIP = "127.0.0.1" localPort = 21923 remotePort = 21923
- 生效方式: 修改并保存后,重启您本地的
frpc
客户端。
四、 Nginx 配置 (最终版)
这是整个方案的核心,包含了对流式协议的完整支持,并且正确处理了代理路径。
- 文件路径:
/etc/nginx/conf.d/mcpstore.wiki.conf
- 最终配置:
server { listen 80; server_name mcpstore.wiki; # 根路径的默认行为,防止直接访问 location / { return 404; } # 核心:处理 /mcp 端点 # 注意:这里的 location /mcp 没有末尾的斜杠,这对于精确匹配很重要 location /mcp { # --- 协议与流式传输控制 --- proxy_http_version 1.1; chunked_transfer_encoding on; proxy_buffering off; proxy_request_buffering off; proxy_cache off; # --- 请求头设置 --- proxy_set_header Host $host; proxy_set_header Connection ''; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Upgrade $http_upgrade; proxy_set_header Accept 'application/json, text/event-stream, */*'; # --- 代理目标 --- # 关键:proxy_pass 的路径包含了 /mcp # 这意味着 Nginx 不会重写路径,而是将 /mcp 的请求完整地转发给后端的 /mcp proxy_pass [http://127.0.0.1:21923/mcp](http://127.0.0.1:21923/mcp); } # 可选:添加健康检查端点,这是一个很好的实践 location /health { proxy_pass [http://127.0.0.1:21923/health](http://127.0.0.1:21923/health); proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }
- 生效方式: 修改并保存后,执行以下命令测试并重载 Nginx。
sudo nginx -t && sudo systemctl reload nginx
五、 成功原因总结
- 无需路径重写: 最终成功的关键在于 Nginx 配置中的
location /mcp
和proxy_pass http://.../mcp
,它保证了后端FastMCP
服务能收到它所期望的、未经修改的完整路径。 - 完整的流式协议支持: 配置中
proxy_http_version 1.1;
,chunked_transfer_encoding on;
,proxy_buffering off;
等一系列指令,为后端服务的streamable-http
协议提供了必要的环境。 - 正确的请求头:
proxy_set_header
相关指令确保了后端服务能收到正确的Host
、Accept
等关键信息,避免了400
或406
错误。