[GH-ISSUE #3970] 求助几个关于安全性和真实IP的问题 #3150

Closed
opened 2026-05-05 14:02:20 -06:00 by gitea-mirror · 4 comments
Owner

Originally created by @chrisuhg on GitHub (Feb 1, 2024).
Original GitHub issue: https://github.com/fatedier/frp/issues/3970

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 = "user@qq.com"
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
  • Security
  • User Experience
  • Test and Release
  • Developer Infrastructure
  • Client Plugin
  • Server Plugin
  • Extensions
  • Others
Originally created by @chrisuhg on GitHub (Feb 1, 2024). Original GitHub issue: https://github.com/fatedier/frp/issues/3970 ### 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 = "user@qq.com" 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 1. 2. 3. ... ### Affected area - [ ] Docs - [ ] Installation - [ ] Performance and Scalability - [X] Security - [ ] User Experience - [ ] Test and Release - [ ] Developer Infrastructure - [ ] Client Plugin - [ ] Server Plugin - [ ] Extensions - [ ] Others
gitea-mirror 2026-05-05 14:02:20 -06:00
Author
Owner

@xqzr commented on GitHub (Feb 8, 2024):

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

<!-- gh-comment-id:1934579546 --> @xqzr commented on GitHub (Feb 8, 2024): 1、不需要 2、frp 可能对 X-Forwarded-For 进行了 覆写、追加 看起来,需要修改 群晖 的 Nginx 参考:https://www.alainlam.cn/?p=403
Author
Owner

@chrisuhg commented on GitHub (Feb 18, 2024):

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

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

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

<!-- gh-comment-id:1951114458 --> @chrisuhg commented on GitHub (Feb 18, 2024): > 1、不需要 2、frp 可能对 X-Forwarded-For 进行了 覆写、追加 看起来,需要修改 群晖 的 Nginx 参考:https://www.alainlam.cn/?p=403 感谢回答! 我尝试根据参考链接在NAS上配置Nginx转发,但是不管是用https还是http的frpc配置都无法通过subdomain访问(403)。然后我又尝试直接指定域名(customDomain),网页返回的结果为`未发送任何数据。ERR_EMPTY_RESPONSE` 也许是我的访问路径比较复杂,配置没有成功,不管怎么样,感谢你提出的建议!
Author
Owner

@AlainLam commented on GitHub (Feb 24, 2024):

虽然...但是...

看起来你似乎是在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来进行反代,原理是一样的。

<!-- gh-comment-id:1962354630 --> @AlainLam commented on GitHub (Feb 24, 2024): 虽然...但是... 看起来你似乎是在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; } } ``` 3. 或者直接点,frps接管80/443,全部走tcp,VPS专门当转发 至于群晖的反向代理,如果你不想修改群晖的系统文件,你也可以选择启用一个docker,或者局域网中的任意nginx来进行反代,原理是一样的。
Author
Owner

@github-actions[bot] commented on GitHub (Mar 20, 2024):

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

<!-- gh-comment-id:2008403533 --> @github-actions[bot] commented on GitHub (Mar 20, 2024): Issues go stale after 21d of inactivity. Stale issues rot after an additional 7d of inactivity and eventually close.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: github-starred/frp#3150
No description provided.