使用背景
在没有公网IP的情况下需要将运营商内网的服务暴露到外网访问就需要使用到反向代理。需要有一台能够被公网访问的机器,局域网内的机器主动与公网机器建立tcp连接。公网机器处理用户的请求,并把流量转发给局域网机器。这种原理与服务发现类似,而 FRP
就优雅地实现了该功能。
frp 使用go语言编写,只有一个服务端文件和一个客户端文件加上配置文件就能快速部署,非常优雅。frp使用go语言编写,内嵌了一个 vue 的页面,方便在网页看到对应的流量转发和服务注册情况。
FRP 服务端配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| bindPort = 7100
vhostHTTPPort = 8888
auth.token = "xxxxx"
sshTunnelGateway.bindPort = 2222 sshTunnelGateway.privateKeyFile = "./ssh/id_rsa" sshTunnelGateway.autoGenPrivateKeyPath = "./ssh/frp_autogen_ssh_key" sshTunnelGateway.authorizedKeysFile = "./ssh/authorized_keys"
webServer.port = 8880 webServer.user = "xxx" webServer.password = "xxx"
|
所有的配置项可以参考: https://github.com/fatedier/frp/blob/dev/conf/frps_full_example.toml
./frps -c frps.toml
来启动服务端。
NGINX 配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| # mobile sub domain upstream frps_dashboard { server localhost:8880 weight=5; } server { listen 443 ssl; listen [::]:443 ssl;
ssl_certificate /xxx/kangqingfei.cn.pem; ssl_certificate_key /xxx/kangqingfei.cn.key; ssl_session_timeout 1d; ssl_session_cache shared:MozSSL:10m; ssl_session_tickets off;
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; ssl_prefer_server_ciphers off; #listen 80; server_name mobile.kangqingfei.cn; root /usr/share/nginx/;
location = /admin/ { 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 X-NginX-Proxy true;
rewrite ^/admin/(.*)$ /$1 break; proxy_pass http: #proxy_pass http: } location ^~ /static/ { proxy_pass http: } location ^~ /api/ { proxy_pass http: }
location / { proxy_pass http: } } server { listen 80; server_name mobile.kangqingfei.cn; rewrite ^(.*)$ https: }
|
防火墙配置
CentOS 8 SELinux 需要配置防火墙才能访问对应的端口:
1 2 3 4 5 6 7 8 9 10 11 12 13
| firewall-cmd --permanent --list-all
firewall-cmd --permanent --add-port=7100/tcp systemctl restart firewalld.service
2201: mbp16 2202: desktop macos catalina 2203: oppo findx5 termux 2204: desktop linux 2205: xps13 macos catalina 2206: rk3399_device1 ubuntu
|
FRP 客户端配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| user = "rk3399"
serverAddr = "127.0.0.1" serverPort = 7100 auth.token = "xxxx"
webServer.addr = "192.168.2.102" webServer.port = 7400 webServer.user = "admin" webServer.password = "admin"
[[proxies]] name = "python web" type = "tcp" localIP = "127.0.0.1" localPort = 8000 remotePort = 7200 customDomains = ["mobile.kangqingfei.cn"]
|
还有一些带宽等相关配置可以参考:https://github.com/fatedier/frp/blob/dev/conf/frpc_full_example.toml
./frpc -c frpc.toml
来启动客户端。
然后访问 mobile.kangqingfei.cn:7200 就能访问到局域网内的 8000 端口的python服务了
同样可以用来代理ssh服务
另外还支持反代 dns,udp, http,socket 等协议。
FRP 管理后台
客户端,主要进行配置的热更新
服务端,主要查看当前注册的连接
FRP 实现 SSH 跳板
SSH Tunnel Gateway,通常用来作为外网到内容ssh的跳板机,对连接进行审计和鉴权(例如两步验证)。这就需要客户端A拥有 到跳板机B的连接权限,再检查客户端到目标机器C的连接权限。
ssh 跳板机逻辑
1 2 3 4 5
| sshTunnelGateway.bindPort = 2222 sshTunnelGateway.privateKeyFile = "~/.ssh/id_rsa" sshTunnelGateway.autoGenPrivateKeyPath = "~/.ssh/frp_autogen_ssh_key" sshTunnelGateway.authorizedKeysFile = "~/.ssh/authorized_keys"
|
被代理机器(任意小鸡)C 发起代理(开启后门)
1 2 3 4 5 6 7 8 9 10 11
|
ssh -R :80:{local_ip:port} v0@{frps_address} -p {frps_ssh_listen_port} {tcp|http|https|stcp|tcpmux} --remote_port {real_remote_port} --proxy_name {proxy_name} --token {frp_token}
ssh -R :80:localhost:22 [email protected] -p 2222 tcp --token xxxx --remote_port 2206 --proxy_name rk3399
User: qingfei.kang@xxx ProxyName: [email protected] Type: tcp RemoteAddress: :2201
|
网关B登录
ssh -p 2201 [email protected]
验证ok
客户端 A 登录
ssh -t [email protected] ssh -p 2201 [email protected]
验证ok
ssh [email protected] -p 2201
直接连接,验证ok
反代 http
1 2 3 4 5
| ssh -R :80:127.0.0.1:8080 v0@{frp address} -p 2200 http --proxy_name "test-http" --custom_domain test-http.frps.com
ssh -R :80:localhost:8000 [email protected] -p 2222 http --token xxx --custom_domain cd.kangqingfei.cn
ssh -R :80:localhost:8000 [email protected] -p 2222 http --token xxx --custom_domain 127.0.0.1
|