利用frp给校园网打个洞

Posted by kevin on January 17, 2020

preface

那个,今天 17 号了,马上也该回家了,考虑到在家里可能有时挺无聊的,我就想着能不能在学校的服务器上穿个洞,这样在家里也可以访问到学校 4 路泰坦的服务器,就可以继续学习深度学习了,说干就干,很早就有这个想法了,要是成功的话,以后出去打比赛也可以用显卡训练模型,多爽

开始穿透

内网穿透的服务多种多样,有 ngork,frp,花生壳,nps,我用过花生壳,感觉并不好用,而且还得花钱,不如自己买个 vps ,所以最后根据网友反馈,frp 是最好用的穿透工具,我这里用的也是 frp ,它是一款开源的工具,GitHub 上的下载地址在这里 ,有对应不同系统的版本,我的内网主机和 vps 都是 Linux 系统,所以我下载了 Linux 版本的 frp ,解压后里面的内容是这样的

ubuntu:~/frp_0.31.1_linux_amd64$ ls                           
frpc  frpc_full.ini  frpc.ini  frps  frps_full.ini  frps.ini  LICENSE  systemd   

主要的就是 frpc.ini,frps.ini 这两个文件,我们要做的就是在内网主机上修改 frpc.ini 这个配置文件,然后运行 frpc 程序,c 代表的就是 client 客户端,在 vps 上修改 frps.ini 这个配置文件,然后运行 frps 程序,s 代表是 server 服务端,同时运行的话,让 frpc 连接上 frps 使得内网和公网之间形成一条通路,就相当于在内网中穿了个洞,这样原本对外封闭的内网就有了被公网访问的途径

说下我的配置吧,内网是一台 ubuntu 服务器,假设 ip 为 172.31.1.1,公网是一台阿里云 vps ,centOS 系统,假设 ip 为 1.2.3.4,开始搞起,首先服务端的配置先改一下,不用抄我的,作者在GitHub 的 readme 里面写得很清楚

[common]                                                                                 
dashboard_port = 7500                                                                     
dashboard_user = admin
dashboard_pwd = admin                                                                    
bind_port = 7000   

稍微解释一下,这就是说 frp 的服务端在监听着 7000 端口,用 7000 端口与客户端进行通信,dashboard_port 是 web 管理界面的端口,方便可视化查看连接数据,ini 文件还有很多其他的配置,有需要的话可以去官方 readme 查看,讲的非常详细

然后我们启动服务端的 frps 服务,用下面的命令

./frps -c ./frps.ini

就会有 log 输出来,说明 frps 服务已经开启,程序正在监听端口

2020/01/18 11:57:17 [I] [service.go:152] frps tcp listen on 0.0.0.0:7000                 
2020/01/18 11:57:17 [I] [service.go:251] Dashboard listen on 0.0.0.0:7500                 
2020/01/18 11:57:17 [I] [root.go:205] start frps success     

服务端配置并启动完成之后,就等着客户端来连接了,我们在内网的主机上修改 frpc.ini 文件如下

[common]                                                                                 
server_addr = 1.2.3.4                                                       
server_port = 7000                                                                                                                                                                 
[ssh]                                                                                     
type = tcp                                                                               
local_ip = 127.0.0.1                                                                     
local_port = 22                                                                           
remote_port = 6000 

这里我只开启了一个 ssh 服务,因为我只需要用到 ssh 连接服务器而已,并不需要干其他事,同样的,如果要干其他事的话就去看文档, frp 支持 tcp,udp,http,https,stcp 这些协议。所以这里可以看到我将本地的 22 端口映射到 vps 的 6000 端口,也就是说,连接了 vps 的 6000 端口就相当于和我内网的主机进行了通信

同样开启 frpc 程序,用下面这条命令

./frpc -c ./frpc.ini

如果连接成功了的话,同样会显示出 log,并且服务端也会有 log 输出证明有客户端连接到了服务器

2020/01/18 11:57:22 [I] [service.go:250] [4695975e20c370a9] login to server success, get run id [4695975e20c370a9], server udp port [0]                             
2020/01/18 11:57:22 [I] [proxy_manager.go:144] [4695975e20c370a9] proxy added: [web ssh] 
2020/01/18 11:57:22 [I] [control.go:164] [4695975e20c370a9] [web] start proxy success     
2020/01/18 11:57:22 [I] [control.go:164] [4695975e20c370a9] [ssh] start proxy success  

服务端和客户端都开开启成功之后,就在内网和公网之间形成了一条通路,然后用下面的命令,只要我们的网络环境可以连接到公网,我们就可以访问到身处内网的服务器了

ssh -oPort=6000 user@1.2.3.4

注意,这里的 user 是内网主机的用户名,但是后面的 ip 是服务端的公网 ip

tips

其实开始搞这个 frp 还是遇到了一些困难的,一直显示 no route to host ,在查阅了资料之后知道是我 vps 的防火墙没关,vps 的防火墙在我的记忆中就只需要放行端口就行了,但是我把所有的端口都放行了还是不能够连通,用 tracert 路由追踪查看确实是在最后连不上 vps ,说明前面的路由没问题,然后我找到了一个情况相同的帖子,说是 vps 上的防火墙还得用 systemctl 关闭,然后我就根据下面这条指令用 systemctl 将 vps 的防火墙关闭了

systemctl stop firewalld.service

然后就真的就可以了。。所以 vps 的话即使放行了端口还要检查一下防火墙是不是打开了,我已经吃了几回防火墙的亏了,下次出问题一定要先用 tracert 路由追踪再检查是不是防火墙的问题


如果不用 nohup 的话就用 systemctl 将 frp 写入守护进程吧,否则 ssh 断开了之后服务就失效了。另外,在 VSCode 上面连接远程服务器进行开发的话注意 username 和 port 不要写错了,举个例子:

ssh -oPort=6000 user@1.2.3.4

那么配置 ssh 的时候 User=user,Hostname=1.2.3.4,Port=6000