frp + Nginx

发布于:2025-07-14 ⋅ 阅读:(18) ⋅ 点赞:(0)

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
  • 内网本地服务器:

    • frp 客户端配置文件: frpc.toml (位于您本地的 frp 目录中)
    • 本地服务监听地址: 127.0.0.1:21923

二、 Nginx 安装 (公网服务器)

在公网服务器上安装 Nginx 并设置为开机自启。

  1. 更新软件包列表:
    sudo apt update
    
  2. 安装 Nginx:
    sudo apt install nginx
    
  3. 设置开机自启:
    sudo systemctl enable nginx
    
  4. 启动 Nginx (在 frp 配置修改后执行):
    sudo systemctl start nginx
    

三、 frp 配置 (最终版)

1. frps (服务端 - 公网服务器)

核心是修改 vhostHTTPPortvhostHTTPSPort,为 Nginx 让出 80443 端口。

  • 文件路径: ~/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
    

五、 成功原因总结

  1. 无需路径重写: 最终成功的关键在于 Nginx 配置中的 location /mcpproxy_pass http://.../mcp,它保证了后端 FastMCP 服务能收到它所期望的、未经修改的完整路径。
  2. 完整的流式协议支持: 配置中 proxy_http_version 1.1;, chunked_transfer_encoding on;, proxy_buffering off; 等一系列指令,为后端服务的 streamable-http 协议提供了必要的环境。
  3. 正确的请求头: proxy_set_header 相关指令确保了后端服务能收到正确的 HostAccept 等关键信息,避免了 400406 错误。