frp icon indicating copy to clipboard operation
frp copied to clipboard

求助几个关于安全性和真实IP的问题

Open chrisuhg opened this issue 1 year ago • 3 comments

Bug Description

对于网络知识没有很过关,问GPT也没问出个结果来,希望有大佬可以帮忙解答一下子~

我部署的环境是搬瓦工的VPS,穿透的应用是黑群晖,通过VPS上的面板使用nginx反向代理开启强制https访问frp的二级域名

🙋提问:

  1. 在开启双向认证的情况下,群晖-> Frps之间的通讯是否还有必要启用https?

  2. 如何在VPS中使用nginx反代配置真实IP? (我在网上寻求答案看到的都是直接在群晖中配置Nginx反代,有尝试将其应用到VPS的Nginx中,结果无法访问)

  3. 在穿透后的域名中,外网可以直接访问,回到内网的情况下我在尝试在路由中配置了DNS劫持为内网IP地址提高响应速度,网页可以直接访问,但是群晖App在内外网切换后必须要重新登录才可以连接,我猜想是证书不一致导致的,这个问题有没有大佬研究过的,求个思路或者研究方向!

以下是配置文件:

frpc Version

0.52

frps Version

0.52

System Architecture

linux/amd64

Configurations

# /home/cch/frps/frps.toml
# OpenPort: 11133-11144, 11080, 11443

bindPort = 11133
log.to = "console" 
subdomainHost = "frp.mydomain.com"
vhostHTTPPort = 11080
vhostHTTPSPort = 11443

# openssl双向验证
transport.tls.certFile = "/etc/frp/server.crt"
transport.tls.keyFile = "/etc/frp/server.key"
transport.tls.trustedCaFile = "/etc/frp/ca.crt"

# 身份验证
auth.method = "token"
auth.token = "token"

# 下面是服务端仪表板配置
webServer.port = 11144
webServer.addr = "0.0.0.0"
webServer.user = "[email protected]"
webServer.password = "password"
# frpc.toml
serverAddr = "66.666.666.66"
serverPort = 11133
vhostHTTPPort = 11080
vhostHTTPSPort = 11443
auth.token = "password"

# frpc双向认证
transport.tls.certFile = "/etc/frp/client.crt"
transport.tls.keyFile = "/etc/frp/client.key"
transport.tls.trustedCaFile = "/etc/frp/ca.crt"

# NAS HTTP
[[proxies]]
name = "Syno-Nas"
type = "http"
localIP = "10.11.1.10"
localPort = 5000
subdomain = "nas"
transport.useCompression = true
transport.proxyProtocolVersion = "v2"
# 反向代理配置
server {
    listen 80 ; 
    listen 443 ssl http2 ; 
    server_name *.frp.mydomain.com; 
    index index.php index.html index.htm default.php default.htm default.html; 
    proxy_set_header Host $host; 
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
    proxy_set_header X-Forwarded-Host $server_name; 
    proxy_set_header X-Real-IP $remote_addr; 
    proxy_http_version 1.1; 
    proxy_set_header Upgrade $http_upgrade; 
    proxy_set_header Connection "upgrade"; 
    access_log /www/sites/AllHttpForFrps/log/access.log; 
    error_log /www/sites/AllHttpForFrps/log/error.log; 
    access_by_lua_file /www/common/waf/access.lua; 
    set $RulePath /www/sites/AllHttpForFrps/waf/rules; 
    set $logdir /www/sites/AllHttpForFrps/log; 
    set $redirect on; 
    set $attackLog on; 
    set $CCDeny off; 
    set $urlWhiteAllow off; 
    set $urlBlockDeny off; 
    set $argsDeny off; 
    set $postDeny off; 
    set $cookieDeny off; 
    set $fileExtDeny off; 
    set $ipBlockDeny off; 
    set $ipWhiteAllow off; 
    location ~ /.well-known/acme-challenge {
        allow all; 
        root /usr/share/nginx/html; 
    }
    if ($scheme = http) {
        return 301 https://$host$request_uri; 
    }
    ssl_certificate /www/sites/AllHttpForFrps/ssl/fullchain.pem; 
    ssl_certificate_key /www/sites/AllHttpForFrps/ssl/privkey.pem; 
    ssl_protocols TLSv1.3 TLSv1.2 TLSv1.1 TLSv1; 
    ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5; 
    ssl_prefer_server_ciphers on; 
    ssl_session_cache shared:SSL:10m; 
    ssl_session_timeout 10m; 
    add_header Strict-Transport-Security "max-age=31536000"; 
    error_page 497 https://$host$request_uri; 
    proxy_set_header X-Forwarded-Proto https; 
    root /usr/share/nginx/html/stop; 
}
# 反向代理配置
location ^~ / {
    proxy_pass http://127.0.0.1:11080; 
    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 REMOTE-HOST $remote_addr; 
    proxy_set_header Upgrade $http_upgrade; 
    proxy_set_header Connection "upgrade"; 
    proxy_http_version 1.1; 
    add_header X-Cache $upstream_cache_status; 
}

Logs

No response

Steps to reproduce

...

Affected area

  • [ ] Docs
  • [ ] Installation
  • [ ] Performance and Scalability
  • [X] Security
  • [ ] User Experience
  • [ ] Test and Release
  • [ ] Developer Infrastructure
  • [ ] Client Plugin
  • [ ] Server Plugin
  • [ ] Extensions
  • [ ] Others

chrisuhg avatar Feb 01 '24 19:02 chrisuhg

1、不需要 2、frp 可能对 X-Forwarded-For 进行了 覆写、追加 看起来,需要修改 群晖 的 Nginx 参考:https://www.alainlam.cn/?p=403

xqzr avatar Feb 08 '24 17:02 xqzr

1、不需要 2、frp 可能对 X-Forwarded-For 进行了 覆写、追加 看起来,需要修改 群晖 的 Nginx 参考:https://www.alainlam.cn/?p=403

感谢回答! 我尝试根据参考链接在NAS上配置Nginx转发,但是不管是用https还是http的frpc配置都无法通过subdomain访问(403)。然后我又尝试直接指定域名(customDomain),网页返回的结果为未发送任何数据。ERR_EMPTY_RESPONSE

也许是我的访问路径比较复杂,配置没有成功,不管怎么样,感谢你提出的建议!

chrisuhg avatar Feb 18 '24 10:02 chrisuhg

虽然...但是...

看起来你似乎是在VPS中仍然有其他服务或者网站,而期望所有网站都使用的都是443/80端口。

我的建议是

  1. 实际上我们NAS并不会使用443端口进行通讯,而是使用高位端口来减少扫描,如果你乐意使用高位端口,我们直接使用TCP+proxy_protocol后根据文章中的内容配置即可(当然还是得修改群晖的nginx,同时还解决你密码的问题)

  2. 如果你一定要使用443端口的话,且如果FRP会修改X-Forwarded-For(我没验证),那么就有点复杂了。可以像下面一样将443/80都启用proxy_protocol,(当然还是的修改群晖的nginx)。以下配置如果不存在于你VPS中的网站都会往frp走。

http {
    # 其他配置省略

    ######### 加入以下内容 #########
    # 注意,这个配置需要将全部VPS中的网站的默认端口都修改为8080,8443。
    # 因为这两个端口将被nginx的Stream模块接管,而不是http模块
    # 我没有做很多的测试,仅供参考

    set_real_ip_from xxx.xxx.xxx.xxx/24;
    real_ip_header proxy_protocol;
    real_ip_recursive on;

    # 默认反向代理到frp的http服务
    server {
        listen 80 default_server;
        listen [::]:80 default_server;
        server_name _;

        location / {
                # 修改12345为你frp的http服务端口
                proxy_pass http://127.0.0.1:12345;

                # 设置请求头,以便被代理的服务器能获取原始请求信息
                proxy_set_header Host $host;
                proxy_set_header REMOTE-HOST $remote_addr;

                # 设置X-Forwarded-*系列头部,用于维护原始请求的协议和主机信息
                proxy_set_header X-Forwarded-Host $host;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header X-Forwarded-For $remote_addr;
                proxy_set_header X-Forwarded-Port $server_port;

                # 提供Forwarded头部,遵循标准格式
                proxy_set_header Forwarded "for=$remote_addr;host=$host;proto=$scheme";

                # 提供原始请求URI和IP信息
                proxy_set_header X-Original-URI $request_uri;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Real-Port $remote_port;

                # 支持Websocket
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";

                # 设置超时时间
                proxy_connect_timeout 60s;
                proxy_read_timeout 60s;
                proxy_send_timeout 60s;

                # 禁用缓存
                proxy_cache off;
            }
        }
    }

    # 只是为了让其他域名请求不需要添加proxy_protocol
    server {
        # 默认启用proxy_protocol,将影响全部https请求
        listen 8443 ssl proxy_protocol;
        server_name _;
        index index.html;
        # 修改为你的网站根目录
        root /var/www/html;
        # 修改为你的证书路径
        ssl_certificate /path/to/your/cert.pem;
        ssl_certificate_key /path/to/your/key.pem;
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256';
        # ssl_prefer_server_ciphers on;
        ssl_prefer_server_ciphers off;
        ssl_session_cache shared:SSL:10m;
        ssl_session_timeout 10m;
    }
}

stream {
    # 其他配置省略

    # 这意味着需要将服务端运行的网站都放这里
    map $ssl_preread_server_name $https_backend {
        sg1.alainlam.cn https_default_backend;
        default https_frp_backend;
    }

    # 服务端的http,这意味着每一个网站都需要修改端口为8443
    upstream https_default_backend {
        server 127.0.0.1:8443;
    }

    # frp的https监听的端口,但是类型是tcp
    upstream https_frp_backend {
        server 127.0.0.1:12346;
    }

    # 代替http模块监听443端口,注意看map部分
    server {
        listen 443 reuseport;
        listen [::]:443 reuseport;
        proxy_pass $https_backend;
        ssl_preread on;
        proxy_protocol on;
    }
}
  1. 或者直接点,frps接管80/443,全部走tcp,VPS专门当转发

至于群晖的反向代理,如果你不想修改群晖的系统文件,你也可以选择启用一个docker,或者局域网中的任意nginx来进行反代,原理是一样的。

AlainLam avatar Feb 24 '24 12:02 AlainLam

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

github-actions[bot] avatar Mar 20 '24 00:03 github-actions[bot]