大神的frp工具可以高效简便的进行内网穿透,我实践了一下用家里的斐讯K2P路由器作为服务器进行内网穿透,把遇到的坑写出来。

解释一下,之所以用家里的路由器作为服务器是因为家里是拨号,有公网IP,不用就浪费了。

路由器默认不接受传入数据

我遇到最大的坑是,路由器开了端口,从外面还是连不上。想了一下,觉得是端口没有正常开放,用nc -z -vv一试果然如此。新建一个防火墙规则开放相应的端口就好了,代码是这样的

1
2
3
4
5
config rule
option name 'Allow-6000-8000'
option src 'wan'
option dest_port 6000:8000
option target ACCEPT

上面的代码放在/etc/config/firewall然后/etc/init.d/firewall reload,就好了。如果想安全可以限定连接的IP,就是加一条option src_ip '111.111.111.111,限定来源IP,这样彻底安全了。

一些写firewall规则的参考送给感兴趣的读者

https://oldwiki.archive.openwrt.org/doc/uci/firewall

K2P上安装配置frps

K2P内存太小了,根本安不上frps,我只能把它放在/tmp里。具体的下载安装方法不赘述,需要注意的是K2P需要下载mipsle版本。

配置按照最简单的来,也容易。难的是要写一个启动脚本,下面的是我写的,我觉得还比较优雅。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/bin/sh /etc/rc.common

START=90

start() {
# icount=`ps -w|grep frps|grep -v grep|wc -l`
# [ $icount -gt 0 ] && stop

# sleep 2

/tmp/frps -c /etc/frps.ini &
}

stop() {
/tmp/frps stop -c /etc/frps.ini
killall -9 frps
}

restart() {
/tmp/frps restart -c /etc/frps.ini &
}

上面的代码存为/etc/init.d/frps,然后/etc/init.d/frps start等等就可以了。

自动更新IP

用的是Duck DNS,就叫它鸭鸭DNS吧。

配置方法看官方的文档就好。

http://www.duckdns.org/install.jsp

配置内网的服务器

内网的服务器当然是Arch Linux啦,frp在AUR上有,安装就好了,不多说了。需要注意的是配置文件里每一项的含义,我解释一下

1
2
3
4
5
6
7
8
9
[common]
server_addr = yaya.duckdns.org # 这个域名动态解析成路由器的IP。
server_port = 7000 # 路由器开放的端口。

[ssh]
type = tcp # 走TCP。
local_ip = 127.0.0.1 # 转发到本地。
local_port = 39999 # 对应SSH的端口,如果改过SSH端口(改端口是好习惯),要体现。
remote_port = 6000 # 现在连这个端口就相当于连SSH端口了。

试着解释一下原理:

  1. 有公网IP的路由器开放7000端口。
  2. 服务器在内网,主动连路由器的7000端口。
  3. 建立连接后,路由器开6000端口,把收到的包转给在内网的服务器。
  4. 我在其他地方连路由器的6000端口,相当于连到内网服务器上,实现了穿透。

实际效果

如果用VPN,延迟要50 ms,实际使用的延迟更高。用frp后延迟可以忍受,因为我的服务器和家里的路由器直线距离才2 km,ping的延迟5 ms,可如果走糟糕的VPN,慢太多了。

心得是,纸上得来终觉浅,绝知此事要躬行。