校园网内网穿透与ssh自动判断

校园网内网穿透与ssh自动判断

SingleDog Other Waste

请不要在涉密场景使用该服务。 本文提供的方案仅供自行学习参考,实际运用中产生的风险请自行承担。

众所周知,很多场景下我们的服务器只能在内网联通,外网无法访问。为了解决这一问题,fatedier/frp 应运而生。

Quick Review: 什么是 FRP?
FRP 是一个内网穿透的高性能的反向代理应用。通俗地说,就是在内网上 “ 打洞 “,让我们能在外网也能访问内网的服务。

Prerequisites:

  • 拥有公网 ip 的服务器 A
  • 内网服务器 B

FRP

参照 文档 | frp,安装和配置还是很简单的。

前往 release 下载最新的发布,tar -xzvf 解压后可以得到一个同时包含 frps, frpc 和对应配置文件的文件夹。

参照文档中的写法,在 Server A 上编辑 frps.toml

1
2
bindPort = 7000 
auth.token= "your_password_here" # Optinal, Recommended

在内网机器上编辑 frpc.toml

1
2
3
4
5
6
7
8
9
10
serverAddr = "x.x.x.x" # Server A的IP
serverPort = 7000
auth.token= "your_password_here" # Optinal, Recommended
[[proxies]]
name = "ssh" #change to your favor
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 6000 #记得在Server A上也打开这个端口的防火墙

Tips:
内网多个服务或者服务器(多个 frpc)需要转发时,name 必须不同。

然后在 Server A 上 ./frps -c frps.toml,在 Server B 上 ./frpc -c frpc.toml,两边的 frp 服务就建立起来了。大概的拓扑如下:

这时候我们通过在自己的机器上 ssh -p 6000 user@x.x.x.x,就可以直接连接到内网的 server B 了。

当然,frp 除了 tcp,还支持 udp 等协议,几乎所有服务都可以通过 frp 转发出来。

最后用 systemd 守护起来就行。

SSH

现在我们能访问内网服务器了,但为了更好的开发体验,只有 Terminal 肯定是不够的。

VS Code Remote 虽然也能通过 frp 直接转发,但是 Remote 会认为通过 FRP 连接的 Server A 和内网直连的 Server A 不是同一个。

为了解决这个问题,最简单的方式就是在 ssh 的 config 中使用相同的 Host,但是一套 Host 只有一个固定 IP,怎么让这个 Host 后面对应不同的连接方式 (内网直连/frp 转发) 呢?

下面就要说到 ssh 的 Match 功能了:Match 是 config 中的条件块,只有满足条件时才会应用对应的配置。

有了 Match,我们就可以:

  1. 判断当前连接的是内网还是外网
  2. 内网:直连
  3. 外网:FRP 转发

基于这个简单的架构,给出下面的 config:

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
# ==================================================================
# 逻辑:检查本机 WiFi 是否连接了 特定SSID(在内网)
# 解释:
# 1. netsh wlan show interfaces -> 获取 WiFi 状态
# 2. findstr "..." -> 类似于 grep OR,只要出现其中任意一个字符串,就返回真(0)
# ==================================================================

Match Host <ServerB> exec "netsh wlan show interfaces | findstr /i /C:<SSID1> /C:<SSID2> /C:<SSID3>"
Hostname <ip> # Server B内网IP
Port 22 # ssh port

# ==================================================================
# 下面是原来的默认配置(兜底走外网 FRP)
# ==================================================================
Host <ServerB>
# 默认走公网 FRP
Hostname <ip> # Server A
Port 6000 # frp转发的port

# 通用参数
User <xx>
IdentityFile <xx>
# 强制统一指纹,防止 VS Code 报错
HostKeyAlias <ip> # Server B内网IP
#Keep vsc remote alive
ServerAliveInterval 60
ServerAliveCountMax 3

其中的 Match Host <ServerB> exec "netsh wlan show interfaces | findstr /i /C:<SSID1> /C:<SSID2> /C:<SSID3>" 就是关键的判断当前连接的是内网还是外网的条件了。SSID 就是当前连接的 WIFI 名称。

由于我本机的代理会响应内网的 ping 请求,这里使用了 SSID 来判断,实际可以通过 ping 内网,mac 地址等多种方式。

这时候就可以通过 ssh Server B 来直接连接内网服务器了,无需区分当前是在内网还是外网。同样地,在 vsc remote 的选择界面中直接选择对应的服务器即可。

无论内网外网,为什么不都直接用 FRP 来访问,还要做区分?
因为我的 Server A 流量有限,直接转发使用比较贵。

到这里,就可以继续愉快的开发了!在家也能当牛马了

duaa 并没有使用 frp,而是使用了稍复杂的 redis 方案。现在看来完全可以写好前后端直接 frp,虽然截止到 26.1.5 已经停运了

  • Title: 校园网内网穿透与ssh自动判断
  • Author: SingleDog
  • Created at : 2026-01-05 16:03:00
  • Updated at : 2026-01-05 17:02:26
  • Link: https://www.singledog233.top/Innet_FRP/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments
On this page
校园网内网穿透与ssh自动判断