用 frp 做内网穿透时的几个配置要点

2026-10-05 约 1400 字 内网穿透

frp 的结构很简单:一台有公网 IP 的服务器跑 frps, 内网机器跑 frpc 主动连上去,由服务端把公网端口上的连接转发到内网。 配置本身不复杂,但有几个点不注意会带来安全或运维上的麻烦。

最小可用配置

服务端 frps.toml:

bindAddr = "0.0.0.0"
bindPort = 7000

auth.method = "token"
auth.token = "换成一串足够长的随机值"

webServer.addr = "127.0.0.1"
webServer.port = 7501
webServer.user = "admin"
webServer.password = "另一串随机值"

log.to = "/var/log/frps.log"
log.level = "info"
log.maxDays = 7

客户端 frpc.toml:

serverAddr = "公网服务器地址"
serverPort = 7000

auth.method = "token"
auth.token = "与服务端一致"

[[proxies]]
name = "home-ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 13322
第一点 服务端的 Dashboard 一定要绑 127.0.0.1,不要跟 frps 一起暴露到公网。 需要看面板时用 SSH 隧道:ssh -L 7501:127.0.0.1:7501 服务器。

allowPorts:限制能被占用哪些公网端口

默认情况下 frpc 想占哪个 remotePort 都行。这意味着一旦 token 泄漏, 对方可以把服务端上任意空闲端口占走,包括你留给别的用途的口。

用 allowPorts 把它收窄:

allowPorts = [
  { start = 22,   end = 22 },
  { start = 80,   end = 80 },
  { start = 443,  end = 443 },
  { start = 10000, end = 20000 },
]

改了之后记得 systemctl restart frps,并且同步确认云厂商的安全组也放行了对应端口—— 安全组没开的时候,frpc 能连上、映射也显示成功,但外网访问不到,很容易误判成 frp 的问题。

remotePort 冲突

同一个 remotePort 在同一时刻只能被一个 proxy 占用。 如果改了配置重启后映射没生效,先看 frps 日志:

grep -i "port already used\|proxy \[.*\] already exists" /var/log/frps.log

另外要注意别和服务端本机已在监听的口撞车。比如服务端跑了 nginx(80)和 sshd(22), 这时再让 frpc 去占 22 就会失败。

容易被忽略的一点:来源 IP 全变成 127.0.0.1

frpc 是从内网机器本地发起连接的,所以被映射的服务(SSH、Web、远程桌面)看到的 所有请求来源都是 127.0.0.1。这会带来两个实际后果:

  • 基于 IP 的封禁失效。fail2ban、RDPGuard 这类按来源 IP 封的工具 在这里完全没用,因为所有攻击看起来都是本机在连自己。
  • 日志失去溯源能力。安全日志里只有本机地址,无法区分正常访问和外部扫描。

实际经历是:把远程桌面通过 frp 暴露到公网后,一周内本机安全日志记录了 两万多次登录失败,来源全部是 127.0.0.1,尝试的账号是 admin、administrator、root 这类字典词。攻击没成功(只开了密钥认证), 但日志被彻底刷满,排查自己的问题时反而找不到记录。

建议 不要把 RDP、数据库这类高风险端口直接映射出去。真的需要图形界面,走 SSH 隧道: ssh -p 13322 -L 3390:127.0.0.1:3389 服务器, 然后本地连 127.0.0.1:3390。SSH 只开密钥认证,攻击面小得多,还能审计。

把 frpc 做成开机自启

Linux 上直接用 systemd(写法见本系列的另一篇)。Windows 上用计划任务, 触发器选「计算机启动时」,账户选 SYSTEM,这样不用等用户登录就能连上。

排查顺序

  1. frpc 进程在不在:ps aux | grep frpc
  2. 客户端日志有没有连上:tail -50 frpc.log,看 login to server success
  3. 服务端有没有注册成功:grep "\[home-" /var/log/frps.log | tail
  4. 服务端端口在不在监听:ss -ltn | grep 13322
  5. 本机服务本身通不通:curl 127.0.0.1:端口
  6. 安全组放行了没有

按这个顺序走,基本能定位到是哪一层的问题,不用靠猜。

← 返回笔记列表 下一篇:SSH 密钥登录排错 →