作为一个常年跟Linux服务器打交道的运维,我经常遇到这样的场景:实验室的Ubuntu工作站跑着重要任务,但人不在办公室时想查看进度;家里的NAS存了大量资料,出差时急需某个文件却无法访问。这时候就需要内网穿透技术了。
内网穿透的本质是打通内外网之间的通信壁垒。举个例子,就像你家的内线电话(内网设备)无法直接拨打外网手机,需要在总机(公网服务器)上开通转接服务。frp就是这样一个"智能总机",它通过建立稳定的转发通道,让外部请求能够抵达内网中的设备。
相比传统的端口映射或DDNS方案,frp有三大优势:一是配置简单,10分钟就能跑通基础功能;二是性能稳定,实测在5M带宽的VPS上能保持SSH流畅操作;三是安全性好,支持TLS加密传输。最重要的是,它完美解决了没有公网IP这个痛点。
我的实验环境采用腾讯云轻量应用服务器(1核2G,Ubuntu 20.04)作为服务端,本地用树莓派4B模拟内网设备。这里有个省钱小技巧:如果只是用于SSH管理,选择最便宜的按量计费云服务器即可,实测1核1G配置完全够用。
VPS需要满足两个硬性条件:一是必须有公网IP(推荐选择BGP多线机房),二是防火墙要开放相应端口。以腾讯云为例,需要在控制台的安全组里放行7000(服务端口)和6000(转发端口)的TCP入站规则。
首先在两台机器上同步安装frp。截至2023年7月,稳定版是v0.51.3。这里有个避坑提示:务必保持服务端和客户端版本一致!我曾在升级时混用版本导致连接异常。
bash复制# 下载解压(服务端和客户端同样操作)
wget https://github.com/fatedier/frp/releases/download/v0.51.3/frp_0.51.3_linux_amd64.tar.gz
tar -zxvf frp_0.51.3_linux_amd64.tar.gz
mv frp_0.51.3_linux_amd64 frp
cd frp
解压后的目录结构需要注意这几个关键文件:
先给服务端做个"瘦身",删除客户端相关文件后编辑配置:
bash复制rm frpc frpc.ini
vim frps.ini
基础配置建议采用以下增强版模板,比默认配置多了身份验证和日志记录:
ini复制[common]
bind_port = 7000
authentication_method = token
token = your_secure_password_here
log_file = ./frps.log
log_level = info
log_max_days = 3
这里重点说下token的安全设置:千万不要用简单密码!建议使用openssl rand -base64 16生成随机字符串。我曾有个客户使用123456作为token,结果服务器成了矿机...
测试运行时直接./frps -c frps.ini,但生产环境推荐用systemd托管:
bash复制sudo cp systemd/frps.service /etc/systemd/system/
sudo vim /etc/systemd/system/frps.service
修改ExecStart路径为你的实际路径,例如:
ExecStart=/home/ubuntu/frp/frps -c /home/ubuntu/frp/frps.ini
然后启动服务:
bash复制sudo systemctl enable frps
sudo systemctl start frps
journalctl -u frps -f # 查看实时日志
这种管理方式比nohup更可靠,服务器重启后会自动恢复服务。曾经有次机房断电,所有nohup启动的服务都挂了,唯独systemd托管的frps完好无损。
客户端配置才是真正的重头戏。先看基础SSH转发配置:
ini复制[common]
server_addr = your_server_ip
server_port = 7000
token = your_secure_password_here
[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000
use_encryption = true
use_compression = true
这里启用了加密和压缩,实测在跨国连接时能降低30%的延迟。如果管理多台设备,可以这样配置:
ini复制[lab_pc_ssh]
type = tcp
local_ip = 192.168.1.100
local_port = 22
remote_port = 6001
[home_nas_ssh]
type = tcp
local_ip = 192.168.50.10
local_port = 22
remote_port = 6002
客户端同样建议用systemd管理,这里分享几个实战经验:
ini复制[common]
...
heartbeat_interval = 30
heartbeat_timeout = 90
ini复制[common]
...
login_fail_exit = false
ini复制[ssh]
...
bandwidth_limit = 1MB
有次我忘记设带宽限制,内网设备同步大文件时直接把VPS带宽跑满,导致所有连接卡死。现在都会给每个服务加上合理的带宽限制。
看到太多人配置完frp就被入侵,必须强调安全防护:
ini复制[common]
...
tls_only = true
对于企业级应用,建议:
ini复制[ssh]
...
allow_ports = 6000-6005
ini复制[ssh]
...
proxy_protocol_version = v2
有次安全审计发现,黑客通过暴力破解尝试了上万次token。后来我们改用动态token+失败锁定机制,再没出现过未授权访问。
连接不上时,按这个顺序排查:
bash复制telnet your_server_ip 7000
bash复制journalctl -u frps --since "1 hour ago"
bash复制./frpc -c frpc.ini --log-level=debug
当连接延迟高时:
ini复制use_compression = true
ini复制use_encryption = false
ini复制protocol = kcp
记得有次跨国SSH卡顿,启用KCP协议后,延迟从800ms降到了300ms左右,效果立竿见影。
除了SSH,还可以转发其他服务:
ini复制[vnc]
type = tcp
local_ip = 192.168.1.100
local_port = 5900
remote_port = 5900
内网Web服务也能对外暴露:
ini复制[web]
type = http
local_port = 8080
custom_domains = your.domain.com
需要先在服务端配置HTTP端口:
ini复制[common]
...
vhost_http_port = 8080
frp还支持UDP、STCP等协议。比如转发DNS查询:
ini复制[dns]
type = udp
local_ip = 192.168.1.53
local_port = 53
remote_port = 6003
配置过程中发现个有趣现象:UDP转发在4G网络下比TCP更稳定,适合移动设备连接。