一、起因
想把PVE后臺(tái)頁面通過frp代理到外網(wǎng)上去,因?yàn)閜ve后臺(tái)默認(rèn)就是https協(xié)議端口為8006。
二、架構(gòu)流程
外網(wǎng) HTTPS 請(qǐng)求 → Nginx(HTTPS) → FRP 服務(wù)端(HTTPS) → FRP 客戶端 → 內(nèi)網(wǎng) HTTPS 服務(wù)
三、配置
1. Nginx配置
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name 域名;
ssl_certificate /etc/nginx/conf.d/key/域名.pem;
ssl_certificate_key /etc/nginx/conf.d/key/域名.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #指定SSL服務(wù)器端支持的協(xié)議版本
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on; #在使用SSLv3和TLS協(xié)議時(shí)指定服務(wù)器的加密算法要優(yōu)先于客戶端的加密算法
error_page 497 301 =307 https://$host:$server_port$request_uri;
location / {
proxy_pass https://127.0.0.1:8081; # 這里是frps的https端口
proxy_set_header Host $host;
proxy_ssl_server_name on; # 關(guān)鍵:啟用 SNI 傳遞
proxy_ssl_name $host; # 指定 SNI 字段為請(qǐng)求的域名
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Cookie $http_cookie;
#下面這一項(xiàng)設(shè)置上傳大小。默認(rèn)設(shè)置是5G,有需要自己改。
client_max_body_size 5g;
proxy_connect_timeout 300s;
proxy_read_timeout 300s;
proxy_send_timeout 300s;
send_timeout 300s;
#開啟websocket
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Ssl on;
}
}
2. frps 配置
# 服務(wù)器端口
bindPort = 5000
kcpBindPort = 5000
# http/https端口
vhostHTTPPort = 8080
vhostHTTPSPort = 8081
# 其他配置
3. frpc 配置
# 服務(wù)器域名端口
serverAddr = "frps服務(wù)器地址"
serverPort = 5000
# PVE后臺(tái)
[[proxies]]
name = "PVE"
type = "https"
localIP = "127.0.0.1"
localPort = 8006
customDomains = ["域名"]
# 外網(wǎng) HTTPS 證書配置,和外網(wǎng)Nginx配置的證書一樣
ssl_cert = "/home/frp/域名.pem"
ssl_key = "/home/frp/域名.key"
四、遇到的問題
剛開始配置的時(shí)候,直接訪問frp服務(wù)器https端口可以訪問,但訪問Nginx是無法轉(zhuǎn)發(fā)到frps。查看Nginx日志發(fā)現(xiàn)
2025/02/27 22:31:39 [crit] 25066#25066: *691882 SSL_do_handshake() failed (SSL: error:14094458:SSL routines:ssl3_read_bytes:tlsv1 unrecognized name:SSL alert number 112) while SSL handshaking to upstream, client: xx.xx.xx.xx., server: 域名, request: "GET / HTTP/1.1", upstream: "https://127.0.0.1:8081/", host: "域名"
這是SSL/TLS 握手過程中 SNI錯(cuò)誤,原因可能是以下幾種:
- SNI 未正確傳遞:Nginx 作為反向代理與上游服務(wù)(如 FRP 或內(nèi)網(wǎng) HTTPS 服務(wù))建立 TLS 連接時(shí),未攜帶 Host 頭或 SNI 信息,導(dǎo)致上游服務(wù)無法識(shí)別請(qǐng)求的域名。這個(gè)可以強(qiáng)制 Nginx 傳遞 SNI 信息,在Nginx的server 中l(wèi)ocation 內(nèi)添加
proxy_ssl_server_name on; # 關(guān)鍵:啟用 SNI 傳遞
proxy_ssl_name $host; # 指定 SNI 字段為請(qǐng)求的域名
- 2.協(xié)議不匹配:上游服務(wù)僅支持較新的 TLS 版本(如 TLS 1.2/1.3),而 Nginx 嘗試使用舊版本(如 TLS 1.0)握手。
- 證書域名不匹配:上游服務(wù)的 SSL 證書未覆蓋請(qǐng)求的域名。