[GH-ISSUE #1035] 和#520一样的https的转发访问问题 #820

Closed
opened 2026-05-05 12:31:24 -06:00 by gitea-mirror · 3 comments
Owner

Originally created by @nickfan on GitHub (Jan 7, 2019).
Original GitHub issue: https://github.com/fatedier/frp/issues/1035

Issue is only used for submiting bug report and documents typo. If there are same issues or answers can be found in documents, we will close it directly.
(为了节约时间,提高处理问题的效率,不按照格式填写的 issue 将会直接关闭。)

Use the commands below to provide key information from your environment:
You do NOT have to include this information if this is a FEATURE REQUEST

What version of frp are you using (./frpc -v or ./frps -v)?

frps: 0.22.0
frpc: 0.21.0

What operating system and processor architecture are you using (go env)?

frps:

GOARCH="amd64"
GOHOSTARCH="amd64"
GOHOSTOS="linux"

frpc:

GOARCH="arm64"
GOHOSTARCH="arm64"
GOHOSTOS="linux"

Configures you used:

frps.ini

common]
# A literal address or host name for IPv6 must be enclosed
# in square brackets, as in "[::1]:80", "[ipv6-host]:http" or "[ipv6-host%zone]:80"
bind_addr = 0.0.0.0
bind_port = 7443
bind_udp_port = 7444
# udp port used for kcp protocol, it can be same with 'bind_port'
# if not set, kcp is disabled in frps
kcp_bind_port = 7443
# if you want to configure or reload frps by dashboard, dashboard_port must be set
dashboard_port = 6443
# dashboard assets directory(only for debug mode)
dashboard_user = admin
dashboard_pwd = xxx
# assets_dir = ./static

vhost_http_port = 5880
vhost_https_port = 5843
# console or real logFile path like ./frps.log
log_file = ./frps.log
# debug, info, warn, error
log_level = info
log_max_days = 3
# privilege mode is the only supported mode since v0.10.0
token = xxx
# only allow frpc to bind ports you list, if you set nothing, there won't be any limit
#allow_ports = 1-65535
# pool_count in each proxy will change to max_pool_count if they exceed the maximum value
max_pool_count = 50
# if tcp stream multiplexing is used, default is true
tcp_mux = true

frpc.ini

# [common] is integral section
[common]
# A literal address or host name for IPv6 must be enclosed
# in square brackets, as in "[::1]:80", "[ipv6-host]:http" or "[ipv6-host%zone]:80"
server_addr = xxx-frp.mydev.com
server_port = 7443

# if you want to connect frps by http proxy, you can set http_proxy here or in global environment variables
# it only works when protocol is tcp
# http_proxy = http://user:pwd@192.168.1.128:8080

# console or real logFile path like ./frpc.log
log_file = /var/log/frp/frpc.log

# trace, debug, info, warn, error
log_level = info
#log_level = trace

log_max_days = 3

# for authentication
token = xxx
privilege_token = xxx

# set admin address for control frpc's action by http api such as reload
admin_addr = 127.0.0.1
admin_port = 7400
admin_user = admin
admin_pwd = xxx

# connections will be established in advance, default value is zero
pool_count = 5

# if tcp stream multiplexing is used, default is true, it must be same with frps
tcp_mux = true

# your proxy name will be changed to {user}.{proxy}
#user = your_name

# decide if exit program when first login failed, otherwise continuous relogin to frps
# default is true
login_fail_exit = true

# communication protocol used to connect to server
# now it supports tcp and kcp, default is tcp
protocol = tcp
#protocol = kcp

[myrp_ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 7722

[myrp_webhttp]
type = http
local_port = 80
use_encryption = false
use_compression = true
custom_domains = *.myrp.mydev.com

[myrp_webhttps]
type = https
local_port = 443
use_encryption = false
use_compression = false
custom_domains = *.myrp.mydev.com

公网机器nginx配置:


server {
       listen 443 ssl;
       include snippets/ssl_mydev_com.conf;
       server_name *.mydev.com;
       location / {
            proxy_pass https://127.0.0.1:5843; # 本地服务器地址
            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 X-Url-Scheme $scheme;
            proxy_set_header Host $http_host;
            proxy_set_header X-NginX-Proxy true;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_max_temp_file_size 0;
            proxy_redirect off;
            proxy_read_timeout 240s;
       }
}

server {
       listen 80;
       server_name *.mydev.com;
       location / {
            proxy_pass http://127.0.0.1:5880; # 本地服务器地址
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
            proxy_set_header X-NginX-Proxy true;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_max_temp_file_size 0;
            proxy_redirect off;
            proxy_read_timeout 240s;
       }
}

内网nginx配置:

server {
	listen 80;
	listen [::]:80;

	# SSL configuration
	#
	listen 443 ssl;
	listen [::]:443 ssl;
	#
	# Note: You should disable gzip for SSL traffic.
	# See: https://bugs.debian.org/773332
	#
	# Read up on ssl_ciphers to ensure a secure configuration.
	# See: https://bugs.debian.org/765782
	#
	# Self signed certs generated by the ssl-cert package
	# Don't use them in a production server!
	#
	# include snippets/snakeoil.conf;
	include snippets/ssl_mydev_com.conf;

	root /home/www/mydev/www;

	# Add index.php to the list if you are using PHP
	index index.html index.htm index.php index.nginx-debian.html;

	server_name www.myrp.mydev.com;

	location / {
		# First attempt to serve request as file, then
		# as directory, then fall back to displaying a 404.
		try_files $uri $uri/ =404;
	}

	# pass PHP scripts to FastCGI server
	#
	location ~ \.php$ {
		include snippets/fastcgi-php.conf;

	#	# With php-fpm (or other unix sockets):
		fastcgi_pass unix:/var/run/php/php7.1-fpm.sock;
	#	# With php-cgi (or other tcp sockets):
	#	fastcgi_pass 127.0.0.1:9000;
	}

	# deny access to .htaccess files, if Apache's document root
	# concurs with nginx's one
	#
	location ~ /\.ht {
		deny all;
	}
}

Steps to reproduce the issue:

我和 #520 遇到的问题比较像:

请求的预期流程是

client.browser->公网固定ip的nginx:https-443(指定/泛域名+有效ssl证书)->
proxy_pass到本地的127.0.0.1:5843(frps服务端监听的vhost_https端口)
<- frpc内网客户端机器和frps服务端互联
-> frpc指定的type:https服务local_port = 443
-> 内网机器的nginx的https-443(指定/泛域名+有效ssl证书)提供https的web服务

实际使用过程中如果跳过第一段nginx的proxy_pass本地5843的流程

client.browser->直接公网ip的frps的5843服务

也就是访问https://www.myrp.mydev.com:5843/的时候的确是没有问题的
但是走nginx转发一道直接访问https://www.myrp.mydev.com/就出问题了

2019/01/07 11:57:53 [error] 30819#30819: *17863 peer closed connection in SSL handshake while SSL handshaking to upstream, client: xxx.xxx.xxx, server: *.mydev.com, request: "GET / HTTP/1.1", upstream: "https://127.0.0.1:5843/", host: "www.myrp.mydev.com

我在frps和nginx上没有找到什么好的解决办法,不过我通过ssh做端口转发却不会出现同样的问题:
比如我用ssh在内网机器上做转发穿透:

/usr/bin/ssh -gNR 5743:127.0.0.1:443 user@公网机器ip -p22

然后把公网机器的nginx的转发配置端口从frps的vhost_https的5843调整为ssh的5743:

proxy_pass https://127.0.0.1:5743; # 本地服务器地址

则client.browser对公网nginx的https:443的 https://www.myrp.mydev.com的访问正常
换回5843也就是frps的端口则出现问题。

我不太清楚是否nginx的配置的问题,在公网服务器和内网服务器的证书都是一致的情况下,
frps的端口直连5843可以访问,但是走了nginx的proxy_pass的情况下就无法访问,然而走ssh的穿透又可以通过nginx的proxy_pass

所以到底是ssh的转发不严格?还是frps的vhost_https的转发机制有问题?

@sxul @fatedier 不知道各位有什么见解?

Describe the results you received:

Describe the results you expected:

Additional information you deem important (e.g. issue happens only occasionally):

Can you point out what caused this issue (optional)

Originally created by @nickfan on GitHub (Jan 7, 2019). Original GitHub issue: https://github.com/fatedier/frp/issues/1035 Issue is only used for submiting bug report and documents typo. If there are same issues or answers can be found in documents, we will close it directly. (为了节约时间,提高处理问题的效率,不按照格式填写的 issue 将会直接关闭。) Use the commands below to provide key information from your environment: You do NOT have to include this information if this is a FEATURE REQUEST **What version of frp are you using (./frpc -v or ./frps -v)?** frps: 0.22.0 frpc: 0.21.0 **What operating system and processor architecture are you using (`go env`)?** frps: ``` GOARCH="amd64" GOHOSTARCH="amd64" GOHOSTOS="linux" ``` frpc: ``` GOARCH="arm64" GOHOSTARCH="arm64" GOHOSTOS="linux" ``` **Configures you used:** frps.ini ``` common] # A literal address or host name for IPv6 must be enclosed # in square brackets, as in "[::1]:80", "[ipv6-host]:http" or "[ipv6-host%zone]:80" bind_addr = 0.0.0.0 bind_port = 7443 bind_udp_port = 7444 # udp port used for kcp protocol, it can be same with 'bind_port' # if not set, kcp is disabled in frps kcp_bind_port = 7443 # if you want to configure or reload frps by dashboard, dashboard_port must be set dashboard_port = 6443 # dashboard assets directory(only for debug mode) dashboard_user = admin dashboard_pwd = xxx # assets_dir = ./static vhost_http_port = 5880 vhost_https_port = 5843 # console or real logFile path like ./frps.log log_file = ./frps.log # debug, info, warn, error log_level = info log_max_days = 3 # privilege mode is the only supported mode since v0.10.0 token = xxx # only allow frpc to bind ports you list, if you set nothing, there won't be any limit #allow_ports = 1-65535 # pool_count in each proxy will change to max_pool_count if they exceed the maximum value max_pool_count = 50 # if tcp stream multiplexing is used, default is true tcp_mux = true ``` frpc.ini ``` # [common] is integral section [common] # A literal address or host name for IPv6 must be enclosed # in square brackets, as in "[::1]:80", "[ipv6-host]:http" or "[ipv6-host%zone]:80" server_addr = xxx-frp.mydev.com server_port = 7443 # if you want to connect frps by http proxy, you can set http_proxy here or in global environment variables # it only works when protocol is tcp # http_proxy = http://user:pwd@192.168.1.128:8080 # console or real logFile path like ./frpc.log log_file = /var/log/frp/frpc.log # trace, debug, info, warn, error log_level = info #log_level = trace log_max_days = 3 # for authentication token = xxx privilege_token = xxx # set admin address for control frpc's action by http api such as reload admin_addr = 127.0.0.1 admin_port = 7400 admin_user = admin admin_pwd = xxx # connections will be established in advance, default value is zero pool_count = 5 # if tcp stream multiplexing is used, default is true, it must be same with frps tcp_mux = true # your proxy name will be changed to {user}.{proxy} #user = your_name # decide if exit program when first login failed, otherwise continuous relogin to frps # default is true login_fail_exit = true # communication protocol used to connect to server # now it supports tcp and kcp, default is tcp protocol = tcp #protocol = kcp [myrp_ssh] type = tcp local_ip = 127.0.0.1 local_port = 22 remote_port = 7722 [myrp_webhttp] type = http local_port = 80 use_encryption = false use_compression = true custom_domains = *.myrp.mydev.com [myrp_webhttps] type = https local_port = 443 use_encryption = false use_compression = false custom_domains = *.myrp.mydev.com ``` 公网机器nginx配置: ``` server { listen 443 ssl; include snippets/ssl_mydev_com.conf; server_name *.mydev.com; location / { proxy_pass https://127.0.0.1:5843; # 本地服务器地址 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 X-Url-Scheme $scheme; proxy_set_header Host $http_host; proxy_set_header X-NginX-Proxy true; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_max_temp_file_size 0; proxy_redirect off; proxy_read_timeout 240s; } } server { listen 80; server_name *.mydev.com; location / { proxy_pass http://127.0.0.1:5880; # 本地服务器地址 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header X-NginX-Proxy true; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_max_temp_file_size 0; proxy_redirect off; proxy_read_timeout 240s; } } ``` 内网nginx配置: ``` server { listen 80; listen [::]:80; # SSL configuration # listen 443 ssl; listen [::]:443 ssl; # # Note: You should disable gzip for SSL traffic. # See: https://bugs.debian.org/773332 # # Read up on ssl_ciphers to ensure a secure configuration. # See: https://bugs.debian.org/765782 # # Self signed certs generated by the ssl-cert package # Don't use them in a production server! # # include snippets/snakeoil.conf; include snippets/ssl_mydev_com.conf; root /home/www/mydev/www; # Add index.php to the list if you are using PHP index index.html index.htm index.php index.nginx-debian.html; server_name www.myrp.mydev.com; location / { # First attempt to serve request as file, then # as directory, then fall back to displaying a 404. try_files $uri $uri/ =404; } # pass PHP scripts to FastCGI server # location ~ \.php$ { include snippets/fastcgi-php.conf; # # With php-fpm (or other unix sockets): fastcgi_pass unix:/var/run/php/php7.1-fpm.sock; # # With php-cgi (or other tcp sockets): # fastcgi_pass 127.0.0.1:9000; } # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # location ~ /\.ht { deny all; } } ``` **Steps to reproduce the issue:** 我和 #520 遇到的问题比较像: 请求的预期流程是 ``` client.browser->公网固定ip的nginx:https-443(指定/泛域名+有效ssl证书)-> proxy_pass到本地的127.0.0.1:5843(frps服务端监听的vhost_https端口) <- frpc内网客户端机器和frps服务端互联 -> frpc指定的type:https服务local_port = 443 -> 内网机器的nginx的https-443(指定/泛域名+有效ssl证书)提供https的web服务 ``` 实际使用过程中如果跳过第一段nginx的proxy_pass本地5843的流程 ``` client.browser->直接公网ip的frps的5843服务 ``` 也就是访问https://www.myrp.mydev.com:5843/的时候的确是没有问题的, 但是走nginx转发一道直接访问https://www.myrp.mydev.com/就出问题了。 ``` 2019/01/07 11:57:53 [error] 30819#30819: *17863 peer closed connection in SSL handshake while SSL handshaking to upstream, client: xxx.xxx.xxx, server: *.mydev.com, request: "GET / HTTP/1.1", upstream: "https://127.0.0.1:5843/", host: "www.myrp.mydev.com ``` 我在frps和nginx上没有找到什么好的解决办法,不过我通过ssh做端口转发却不会出现同样的问题: 比如我用ssh在内网机器上做转发穿透: ``` /usr/bin/ssh -gNR 5743:127.0.0.1:443 user@公网机器ip -p22 ``` 然后把公网机器的nginx的转发配置端口从frps的vhost_https的5843调整为ssh的5743: ``` proxy_pass https://127.0.0.1:5743; # 本地服务器地址 ``` 则client.browser对公网nginx的https:443的 https://www.myrp.mydev.com的访问正常 换回5843也就是frps的端口则出现问题。 我不太清楚是否nginx的配置的问题,在公网服务器和内网服务器的证书都是一致的情况下, frps的端口直连5843可以访问,但是走了nginx的proxy_pass的情况下就无法访问,然而走ssh的穿透又可以通过nginx的proxy_pass 所以到底是ssh的转发不严格?还是frps的vhost_https的转发机制有问题? @sxul @fatedier 不知道各位有什么见解? **Describe the results you received:** **Describe the results you expected:** **Additional information you deem important (e.g. issue happens only occasionally):** **Can you point out what caused this issue (optional)**
Author
Owner

@nickfan commented on GitHub (Jan 8, 2019):

另外用frpc的tcp的配置模式可以正常使用但是用https的模式不行:

[myrp_tcphttps]
type = tcp
local_ip = 127.0.0.1
local_port = 443
use_encryption = false
use_compression = false
remote_port = 5743

<!-- gh-comment-id:452141121 --> @nickfan commented on GitHub (Jan 8, 2019): 另外用frpc的tcp的配置模式可以正常使用但是用https的模式不行: ``` [myrp_tcphttps] type = tcp local_ip = 127.0.0.1 local_port = 443 use_encryption = false use_compression = false remote_port = 5743 ```
Author
Owner

@fatedier commented on GitHub (Jan 8, 2019):

不要重复提交问题,可以从已有 issue 中找到答案,或者通过 google 搜索相关解决方案。

<!-- gh-comment-id:452146677 --> @fatedier commented on GitHub (Jan 8, 2019): 不要重复提交问题,可以从已有 issue 中找到答案,或者通过 google 搜索相关解决方案。
Author
Owner

@nickfan commented on GitHub (Jan 8, 2019):

@fatedier 好吧找到了,#671 不过为了这个vhost_https端口复用还得开dnsmasq,走tcp/ssh的话,一个客户端要占一个公网机器端口,也是需要取舍。。。

<!-- gh-comment-id:452163744 --> @nickfan commented on GitHub (Jan 8, 2019): @fatedier 好吧找到了,#671 不过为了这个vhost_https端口复用还得开dnsmasq,走tcp/ssh的话,一个客户端要占一个公网机器端口,也是需要取舍。。。
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#820
No description provided.