目录
- 引入
- 背景
- 失败的尝试
- 新的方案
- 步骤
- VPS端
- 内网server端
- 测试连通性
- 尾言
引入 背景 两台 server 没有公网 ip ( server 连接的路由器倒是有教育网的 ip ),boss 想在公网访问,想利用手上一台 vps 做内网穿透,比如把 server 的 1:10000 端口映射到 vps 的 10001:20000 上。vps和server的系统均为ubuntu。
失败的尝试 尝试的做法是 vps 上搭个 o server,两台 server 连接之后用
iptables
的 DNAT 映射把 vps 指定端口转发给 10.8.0.x,但是遇到了两个问题:-
iptables
没法非对称映射端口段
(要么 8000→20000 单个端口映射
要么 1000:2000→1000:2000 对称映射
没法 1:10000→10001:20000 非对称的端口段映射)
- server 连接 o 之后,server 的全部流量都走那个 o 的虚拟网卡了…
又因为从 vps 传到 server 的请求是从公网来的,源 ip 都是公网 ip,没法单独区分返回的数据包只让它走虚拟网卡…
如果o配置上no-route
,那么除了来自虚拟子网、源 ip 是 10.8.0.x 的请求能通过虚拟网卡回去,
一般来自公网的请求都会尝试走物理网卡回去,也就是实际上收不到返回值…
- vps使用
frps
,使用systemd实现自启动; - 使用某一台server运行
frpc
,将vps的10001:20000转发到server1的1:10000端口,将vps的20001:30000转发到server2的1:10000端口。
步骤 VPS端 下载FRP0.29.0 Release 并解压
wget https://github.com/fatedier/frp/releases/download/v0.29.0/frp_0.29.0_linux_amd64.tar.gz
tar -zxf frp_0.29.0_linux_amd64.tar.gz
mv frp_0.29.0_linux_amd64 frp
进入frp文件夹,编辑
frps.ini
cd frp
vim frps.ini
配置文件为:
[common]
bind_port = 2221
max_pool_count = 5
log_level = error
绑定的端口2221需要在vps防火墙设置中放行UDP和TCP流量。
然后运行frps,进行测试:
./frps -c frps.ini
【Linux|【经验】使用FRP搭建内网穿透服务】和frpc测试连通(见下文)后,可以设置为service,实现自启动:
先修改service文件:
vim frp/systemd/frps.service
修改
ExecStart
的路径为实际frp解压路径,并且注意如果是以root用户执行,默认的User=nobody
会出现错误,需要改为User=root
。并注意以service执行的程序受到IO限制,无法打开太多端口,添加LimitNOFILE=65535
以放宽限制。[Unit]
Description=Frp Server Service
After=network.target[Service]
Type=simple
User=root
Restart=on-failure
RestartSec=5s
ExecStart=/root/frp/frps -c /root/frp/frps.ini
LimitNOFILE=65535[Install]
WantedBy=multi-user.target
之后添加服务并设置为自启动
cp systemd/frps.service /lib/systemd/system/
systemctl daemon-reload
systemctl enable frps
systemctl start frps
这时可以使用
systemctl status frps
查看进程的PID,之后使用cat /proc/1238/limits
确认Max open files
项是否放宽为65535。内网server端 下载FRP0.29.0 Release 并解压
wget https://github.com/fatedier/frp/releases/download/v0.29.0/frp_0.29.0_linux_amd64.tar.gz
tar -zxf frp_0.29.0_linux_amd64.tar.gz
mv frp_0.29.0_linux_amd64 frp
进入frp文件夹,编辑
frpc.ini
cd frp
vim frpc.ini
配置文件为:
[common]
server_addr = vps的ip
server_port = 2221
pool_count=2[range:server1_tcp]
type = tcp
local_ip = 内网server1的ip,可以是本机127.0.0.1,也可以是内网里其他server的ip如192.168.1.101
local_port = 1-10000
remote_port = 10001-20000[range:server1_udp]
type = udp
local_ip = 内网server1的ip,可以是本机127.0.0.1,也可以是内网里其他server的ip如192.168.1.101
local_port = 1-10000
remote_port = 10001-20000[range:server2_tcp]
type = tcp
local_ip = 内网server2的ip,可以是本机127.0.0.1,也可以是内网里其他server的ip如192.168.1.101
local_port = 1-10000
remote_port = 20001-30000[range:server2_udp]
type = udp
local_ip = 内网server2的ip,可以是本机127.0.0.1,也可以是内网里其他server的ip如192.168.1.101
local_port = 1-10000
remote_port = 20001-30000
先启动vps上的
frps
,再启动server上的frpc
:./frpc -c frpc.ini
这时就可以通过vps ip:port+10000访问server1的ip:port,vps ip:port+20000访问server2的ip:port了。
因为实际使用
frpc
是在server的docker容器内,systemd自启动有些问题,所以目前frpc
使用screen
工具来后台运行:screen -S frpcScreen
./frpc -c frpc.ini
然后按Ctrl+A Ctrl+D退出当前screen。
终止正在前台运行的
frpc
以及frps
需要使用Ctrl+C组合键关闭,如果使用Ctrl+Z或者Break或者关闭ssh客户端的方式终止,则已经打开的端口无法解除占用,只能重启系统。测试连通性 测试tcp连通性可以在内网server上运行
python3 -m http.server 8888
来启动一个http服务,然后访问http://vps ip:18888/测试是否能够打开网页。测试udp连通性可以使用
netcat
这个工具包。安装
netcat
:apt install netcat-openbsd
内网server运行udp监听:
nc -ul 8883
vps上连接netcat,注意这里是连接vps本机的18883端口,frp给转发到内网server的8883端口上:
nc -u 127.0.0.1 18883
之后类似于聊天工具,在任意一方输入字符并回车,另一方可以看到对方的输入,证明udp连接成功。
尾言 作者声称没有对于大范围的ip段映射进行优化,但实际测试映射20000个端口是可实现的。目前还需要继续观察是否存在性能和稳定性问题。
推荐阅读
- Linux|109 个实用 shell 脚本
- linux笔记|linux 常用命令汇总(面向面试)
- 计算机网络|计算机网络——DHCP协议详解
- Linux|Linux--网络基础
- 网络|一文彻底搞懂前端监控
- linux|apt update和apt upgrade命令 - 有什么区别()
- 网络夺命连环问系列|网络夺命连环问5--HTTP怎么传输大文件()
- 网络|网络编程释疑(TCP连接拔掉网线后会发生什么)
- android-面试|我经历的IT公司面试及离职感受
- linux|2022年云原生趋势