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 信息

posted @ 2023-07-26 13:34  ejiyuan  阅读(245)  评论(0编辑  收藏  举报