fatedier / frp

A fast reverse proxy to help you expose a local server behind a NAT or firewall to the internet.
Apache License 2.0
85.34k stars 13.24k forks source link

[Feature Request] 希望TCP可以支持hostHeaderRewrite(类似于tcp2https)IP+自签证书情况 #4433

Closed Jenking-Zhang closed 2 days ago

Jenking-Zhang commented 1 month ago

Describe the feature request

【为什么没有域名,又为什么还要用https】 阿里云 没有“北岸”域名,未本案域名访问会被sni阻断,只能用IP访问,有些服务又只允许使用https链接(比如bitwarden),也不想完全用http裸奔,决定自签IP证书并添加信任来进行自我安慰。

【没有域名只能配tcp代理】 因为没有域名,也就没有子域名(二级域名)用来配https代理的分流,只能配置为tcp代理,frpc的后端是nginx,配置了匹配规则做了限制:不匹配server_name无法访问,只能允许server_name是我配置域名和IP访问。然后发现IP访问会无法,经过半天的测试,发现nginx收到的$host变成了server:0.0.0.0:port了,tcp是点对点的穿透,自然没有$host可以传递。所以希望可以有插件,可以把服务器ip重写为$host。或者https代理能不能增加路径区分的方式来分流。

【其他】 另外用不用备案的机器配置https代理发现了一个问题:一个frpc配置的多个https代理(对应本地多个端口),如:

[[proxies]]
name = "Bitwarden-https"
type = "https"
localIP = "127.0.0.1"
localPort = 3000
customDomains = ["a.yourdomain.com"]
transport.useEncryption = true
transport.useCompression = true
transport.proxyProtocolVersion = "v2"

[[proxies]]
name = "NAS1-https"
type = "https"
localIP = "127.0.0.1"
localPort = 3001
customDomains = ["b.yourdomain.com"]
transport.useEncryption = true
transport.useCompression = true
transport.proxyProtocolVersion = "v2"

[[proxies]]
name = "NAS2-https"
type = "https"
localIP = "127.0.0.1"
localPort = 3002
customDomains = ["c.yourdomain.com"]
transport.useEncryption = true
transport.useCompression = true
transport.proxyProtocolVersion = "v2"

nginx本地监听了 3000-3002都配置了服务和server_name匹配规则(禁止未匹配的域名访问),也开启了proxy_protocol;。

    server {
        listen 3000 ssl proxy_protocol;
        server_name a.yourdomain.com;
        http2 on;
        ssl_certificate     $ssl_cert;
        ssl_certificate_key $ssl_key;
...
}
    server {
        listen 3000 proxy_protocol default_server;
        server_name  _;
        http2 on;
        ssl_certificate     $ssl_cert;
        ssl_certificate_key $ssl_key;
        set_real_ip_from  127.0.0.1;
        real_ip_header    proxy_protocol; 
        real_ip_recursive on; 
        return 444;
    }
..3001...3002....

只能同时访问1个服务,有时候是2个。检查了nginx日志,流量是转发到每个对应nginx监听端口,但是server_name不匹配了,被444拒绝了。断开全部连接之后,就可以访问任意一个,同样的,其他的就又被444了。“也就是三个都能访问,但不能同时访问” 用tcp代理的配置方式: [[proxies]] name = "Bitwarden-tcp" type = "tcp" localIP = "127.0.0.1" localPort = 3000 remotePort = 3000 transport.useEncryption = true transport.useCompression = true transport.proxyProtocolVersion = "v2" ...3001、3002同,略...

所有服务可以同时全部正常访问,真实IP也可以完美传递。问题就是一个服务要对应一个端口。没办法复用443了。所以怀疑https有条多配置的时候,server_name或者host参数传递可能存在问题。但是影响不大,因为配置为https代理的时候,nginx的通配的检测限制可以不要,因为frps的https代理,本身就限制了非指定域名的访问情况

其实写到这儿,自己的思路好像又明白了一点点:用IP访问的情况下,也不需要去匹配是否是IP访问的规则,单开的端口,没有其他方式暴露公网的情况下,因为必然是从服务器传递过去的数据,也不需要去校验,去做限制。一切都交给了frps把关了。

但问题也客观存在,ipv4+ipv6双栈同时开放的情况下,同时需要几种暴露服务的情况方案时(甚至frpc一个服务配多个代理的情况下),很多时候没办法共用一个server块,就要去写不同的服务。

Describe alternatives you've considered

**

  1. 希望tcp重写host的功能,以增强tcp2https、https的访问数据兼容性;
  2. 希望增加多个server(frps)的支持,不同的服务通过不同的服务器穿透。 3.希望修正一下多个https代理时的包头问题 **

Affected area

xqzr commented 1 month ago

1、需要终结 TLS,使用 https2https 插件 https://gofrp.org/zh-cn/docs/reference/client-plugin/#https2httpspluginoptions 2、启动多个 frpc

./frpc -c 1.toml
./frpc -c 2.toml
./frpc -c 3.toml
...

3、使用 v0.59.0 及以上版本。

github-actions[bot] commented 1 week ago

Issues go stale after 21d of inactivity. Stale issues rot after an additional 7d of inactivity and eventually close.