frp内网穿透
1,服务端配置
服务端新建配置文件 :“/data/frp/frps.ini”
# https://gofrp.org/docs/reference/
[common]
bind_port=7100
# 启用面板
dashboard_port=7101
# 面板登录名和密码
dashboard_user=admin
dashboard_pwd=admin123
# 使用http代理并使用80端口进行穿透(这个是对外暴露端口)
# 多web只需要在客户端绑定多个http配置不同域名,服务端无需nginx
vhost_http_port=80
# 服务token(根据实际情况修改),相当于连接密码,建议设置
token=Token123
2,启动服务
docker run -p 7100:7100 -p 7101:7101 -p 80:80 -d -v /data/frp:/etc/frp --name frps snowdreamtech/frps
服务端 放行 7100、7102端口
# 放行端口
firewall-cmd --zone=public --add-port=7100/tcp --permanent
firewall-cmd --zone=public --add-port=7101/tcp --permanent
# 重新加载防火墙
firewall-cmd --reload
浏览器访问服务端ip:7101
3,客户端配置
客户端新建配置文件 :“/data/frp/frpc.ini”
# https://gofrp.org/docs/reference/
[common]
#远程服务器地址
server_addr=121.00.00.00
# 远程服务器地址端口号
server_port=7100
#远程服务器设置的密码
token=Token123
# 客户端监控
admin_addr=127.0.0.1
admin_port=7200
admin_user=admin
admin_pwd=admin123
# 绑定第一个web 命名为 "web_track"
[web_track]
type=http
# web服务绑定本地网卡 0.0.0.0为全部
local_ip=127.0.0.1
# 监听本地端口
local_port=8080
# 远程端口,即 frps端口
remote_port=80
# web服务必须包含一个域名
custom_domains=track.xxx.com
[web_test]
type=http
local_ip=127.0.0.1
# 监听本地端口
local_port=8180
# 远程端口,即 frps端口
remote_port=80
# web服务必须包含一个域名
custom_domains=test.xxx.com
[ssh]
type = tcp
#ssh执行本机,也可以是局域网的另一台机器
local_ip=127.0.0.1
local_port=22
#ssh远程服务器端口号
remote_port=2022
4,启动客户端
docker run -p 7200:7200 --network host -d -v /data/frp:/etc/frp --name frpc snowdreamtech/frpc
客户端防火墙放行7200端口
# 放行端口
firewall-cmd --zone=public --add-port=7200/tcp --permanent
# 重新加载防火墙
firewall-cmd --reload
浏览器输入http://192.168.0.32:7200,进入客户端管理
5,结合Nginx
若你的服务器上部署了nginx,占用了80,433端口,可以结合结合nginx 反向代理到内网。
1)服务端frps配置
服务端新建配置文件 :“/data/frp/frps.ini”
# https://gofrp.org/docs/reference/
[common]
bind_port=7100
# 启用面板
dashboard_port=7101
# 面板登录名和密码
dashboard_user=admin
dashboard_pwd=admin123
# 使用http代理并使用8080端口进行穿透(这个是对外暴露端口)
vhost_http_port=8080
# 使用https代理并使用4433端口进行穿透(这个是对外暴露端口)
vhost_https_port=4433
# 服务token(根据实际情况修改),相当于连接密码,建议设置
token=Token123
客户端无需修改
2)nginx穿透设置
server {
listen 80;
server_name www.tangthink.com tangthink.com cbb.store www.cbb.store;
client_max_body_size 10M;
location / {
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Scheme http;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme; # request.getSchema()可以返回正确的当前页面使用的协议,http 或是 https;
proxy_pass http://127.0.0.1:9880; #指向本机docker 容器端口
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
server {
server_name esxi.meylink.cn; #项目域名
ssl_certificate /data/cert/esxi.meylink.cn.pem;
ssl_certificate_key /data/cert/esxi.meylink.cn.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
client_max_body_size 10M;
# proxy_buffer缓冲 设置
proxy_buffer_size 1024k;
proxy_buffers 8 1024k;
proxy_busy_buffers_size 1024k;
proxy_temp_file_write_size 1024k;
# zip
gzip on;
gzip_http_version 1.1;
gzip_vary on;
gzip_comp_level 7;
gzip_proxied any;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; #SSL算法加密选项
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
listen 443 ssl http2;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
location / {
# 需要配置dns地址用来解析upstream中的域名(用域名替代ip地址,后来经过测试upstream中配置域名只会在nginx启动时解析一次,然后就一直用这个ip,无法使用resolver实现每次解析)
resolver 223.5.5.5; # 阿里公共DNS
proxy_pass https://$host:4433;
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 Host $host;
proxy_ssl_server_name on;
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
这里要使用 “resolver 223.5.5.5; # 阿里公共DNS”否者无法穿透到frp的https,会报:
[error] 16513#16513: *133785 peer closed connection in SSL handshake while SSL handshaking to upstream, client: xxx.xxx.xxx.xxx, server: *.xxx.xxx.xxx, request: "GET / HTTP/2.0", upstream: "https://127.0.0.1:7443/", host: "xxx.xxx.xxx"
,推测是 frp 在反向代理https的时候,因为 Nginx 已经处理过了 https 的握手信息,所以, Frp 无法获取到 SNI 信息,导致发送请求的时候就是不完整的https请求。因为如果改成http或者tcp反向代理都可以成功,顾认为是 Frp 机制的问题,他访问的域名变成127.0.0.1,没有 SNI 信息