模式三:frp vhost 模式 + 无 PROXY 协议(推荐用于多站共享 80/443)

社区话题 Linux/macOS 与自动化运维 frps使用tcp协议通信到frpc + Nginx真实IP获取三种部署模式指南 模式三:frp vhost 模式 + 无 PROXY 协议(推荐用于多站共享 80/443)

#1384

追光
管理员

模式三:frp vhost 模式 + 无 PROXY 协议(推荐用于多站共享 80/443)

适用于:
• 公网服务器无 80/443 端口权限(如 NAT VPS、家用宽带)
• 需要穿透多个域名到不同本地服务
• 不要求本地 Nginx 的 remote_addr 为真实客户端 IP(可通过 Header 获取)
• 完全关闭 PROXY 协议,配置更简单、更安全

架构拓扑说明

客户端
↓ (HTTP/HTTPS 请求,带 Host: your.domain.com)
frps(监听 vhost_http_port / vhost_https_port,如 8080/8443)
↓ (基于 Host 头路由,TCP 转发,无 PROXY 协议)
frpc(匹配 proxy name)
↓ (转发到 127.0.0.1:本地端口)
本地 Nginx(标准监听 80/443)

说明:
• frps 替代 Nginx 作为反代,可以直接解析 Host 并路由到后端多台服务器
• 全程不使用 PROXY 协议,transport.proxyProtocolVersion 必须关闭
• 客户端真实 IP 通过 X-Real-IP 或 X-Forwarded-For Header 传递(由 frps 自动添加)

一、frps 配置(公网服务器)

启用 vhost HTTP / HTTPS 支持


# HTTP/HTTPS 虚拟主机端口
vhostHTTPPort =  80
vhostHTTPSPort = 443
custom404Page = "/home/usrdata/NetworkServer/frps/404.html"

可选:绑定自定义域名(用于 HTTPS SNI)

subdomain_host = yourdomain.com

启动后,frps 会监听:

• 0.0.0.0:8080 用于 HTTP
• 0.0.0.0:8443 用于 HTTPS

将域名 DNS 指向公网服务器 IP,然后通过
http://your.domain.com

如果vhost使用的是非 80 443端口,则可以额外使用 Nginx反向代理将域名转发到自定义的 vhost端口,那只是优化手段,不属于本模式的核心部分。

二、frpc 配置(本地)


#################http配置####################
[[proxies]]
name = "AMH-lnmp"
#type = "http"
type = "tcp"
localIP = "127.0.0.1"
localPort = 80
remotePort = 8080
#customDomains = ["*.x.newvfx.com", "x.newvfx.com"]

#transport.useEncryption = true
#transport.useCompression = true

#################https配置####################
[[proxies]]
name = "AMH-lnmp-https"
#type = "https"
type = "tcp"
localIP = "127.0.0.1"
localPort = 443
remotePort = 4443
#customDomains = ["*.x.newvfx.com", "x.newvfx.com"]

关键点:
不启用 proxyProtocolVersion
以下配置必须删除或注释:
transport.proxyProtocolVersion = “v2”

可选项(不影响本模式):
transport.useEncryption = true
transport.useCompression = true

说明:
• type 必须是 http 或 https,这是 vhost 模式的标志
• customDomains 必须与客户端请求的 Host 头完全一致

三、本地 Nginx 配置(标准配置,无需任何特殊修改)


server {
listen 80;
server_name site1.example.com;

location / {
root /var/www/site1;
index index.html;
}

}

server {
listen 443 ssl;
server_name site2.example.com;

ssl_certificate /path/to/site2.pem;
ssl_certificate_key /path/to/site2.key;

其余网站正常配置

}

说明:
• 不需要 proxy_protocol
• 不需要修改 remote_addr 的获取方式

四、真实客户端 IP 的获取方式

在 vhost 模式下,frps 会自动添加标准 Header:
• X-Real-IP: 客户端真实 IP
• X-Forwarded-For: 客户端真实 IP

在nginx全局设置的http模块加入以下设置即可获取真实ip


# ✅ 反代的真实客户端 IP
    set_real_ip_from 0.0.0.0/0;
    real_ip_header X-Forwarded-For;
    real_ip_recursive on;

Nginx 日志示例:

log_format main ‘$http_x_real_ip - $remote_addr - $request’;

PHP 示例:

$real_ip = $_SERVER[‘HTTP_X_REAL_IP’] ?? $_SERVER[‘REMOTE_ADDR’];

安全说明:
frps 是从 TCP 连接中获取客户端 IP 后写入 Header,客户端无法自行伪造,因为连接只来自 frps 公网服务器。

五、如何让用户访问标准 80 / 443 端口

由于 frps 实际监听的是 8080 / 8443,可以使用以下方式之一:

方案 A:DNS + 显式端口访问
• 用户访问 http://site1.example.com:8080
• 适合测试环境或可接受非标准端口的场景

方案 B:公网 Nginx 做端口转发(推荐)

server {
listen 80;
server_name site1.example.com;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
}
}

说明:
• frps 仍然工作在 vhost 模式
• Nginx 仅做端口映射,不改变本模式本质

方案 C:使用 CDN(例如 Cloudflare)
• CDN 回源到 your.ip:8080
• 用户访问标准 80 / 443
• CDN 会通过 CF-Connecting-IP 等 Header 传递真实 IP
• frps 注入的 X-Real-IP 会变为 CDN 节点 IP

六、优点总结
• 不占用公网 80 / 443 端口,适合端口受限环境
• 支持多域名路由,一个 frpc 可穿透多个网站
• 配置简单,不依赖 PROXY 协议
• frps 自动注入真实 IP Header,安全可靠
• 兼容 Let’s Encrypt,本地直接申请证书

七、注意事项
1. 不要混用 type = tcp 与 type = http / https,vhost 模式必须使用 http / https。
2. customDomains 必须能够解析到 frps 的公网 IP(或通过 hosts 文件测试)。
3. HTTPS 穿透时,证书必须部署在本地 Nginx,frps 不负责 SSL。
4. 不要启用 proxyProtocolVersion,否则连接会失败,vhost 模式不支持 PROXY 协议。

模式三是 Web 穿透场景中最推荐的 frp 部署方式,在功能、安全性和易用性之间取得了良好平衡。