在二级路由下用树莓派和frp折腾内网穿透

背景

买一个树莓派做开发,一直是我想做的事情。只可惜我一直没钱。直到今年双十一,我咬了咬牙,终于买了树莓派。

其实我当时买树莓派有一个直接原因,就是希望开发云打印项目。令人失望的是,由于驱动问题,办公室里面三台打印机,只有一台能连上树莓派,偏偏那一台是性能最差的那台。在这方面,树莓派还不如办公室里面一台我带来的十一年前的笔记本电脑——三台打印机均能够顺利连接。于是,这台树莓派一直插着电放在创业园的办公室里面吃灰。

当然,我要是想执行什么命令的话,拿着电脑到创业园,连上办公室的网络,开SSH连树莓派就可以了——甚至不用拿电脑,用那台十一年前的电脑就可以了。我很长时间都是这样,但是这个方法的弊端也很明显:你如果忘记带书和资料的话,就要在宿舍和办公室之间跑上一来回。虽然创业园离宿舍并不远,但是我的宿舍在六楼啊。这就让我有了远程操作树莓派的想法。

众所周知,运营商分配给用户的IP是变化的,这种情况下就需要DDNS,就是通过客户端将域名指向你现在的IP地址,动态检测变化。办公室的路由器是TP-LINK的,虽说不是智能路由器,不过也有DDNS。按理说,只要设置好DDNS和端口转发,就不成问题了。但是我发现行不通。后来我知道DDNS实现的前提是路由器有公网IP,而不巧的是办公室里面没有公网IP,处在校园网内,属于二级路由……

我在阿里云上用学生权益买了一年的入门级ECS,与此同时买了花生壳的内网穿透服务。虽然经过测试,花生壳能够在树莓派上运行并进行内网穿透,但是我购买的价位的功能实在太有限了,对于学生来说还是钱要紧。

这时候我自然而然地想到了那台ECS。ECS拥有固定的公网IP,完全可以通过它来实现内网穿透啊。我本来不需要再花钱的。

说到内网穿透,我就想到了……ngrok(https://ngrok.com/)。但是ngrok第二版不再开源,第一版(https://github.com/inconshreveable/ngrok)不适合生产环境,而且经测试,无法运行。不管是我的操作有误还是本来就不行,那个没法放在后台的界面也是一个问题。

ngrok的情况

正当我失望之时,另一个内网穿透的工具进入了我的视线——frp(https://github.com/fatedier/frp)。经简单测试,frp对于我来说是可以运行的。

不过这里面的“测试”进行的时候,我对远程操作树莓派的需求没那么强烈,所以就暂时搁在一边了。直到最近气温骤降,我又因为急刹车导致手部受伤,实在无法在办公室停留太长时间(虽然办公室有空调,但电费是我出的啊),于是这个计划就又提上了日程。

实现这个计划足足花了我三天的时间。期间查了大量的资料,由于误操作重装了三次系统。不过最后总算成功了。我就把成功的操作说一下吧。

网络结构

首先,我在此之前就通过路由器的IP-MAC绑定为树莓派和笔记本电脑分配了固定的IP。路由器是192.168.1.1,树莓派是192.168.1.120,笔记本电脑是192.168.1.121。于是我们得出以下网络图:

网络

以下假定服务器的地址是example.com,且该域名可控。

下载

接下来到GitHub上下载frp的发行版本(https://github.com/fatedier/frp/releases)。下载时看好对应的平台。ECS对应的是linux_amd64,树莓派对应的是linux_arm(居然不是64位的……)。

frp发行版本

下载的时候,复制对应的文件的链接,进入一个方便的目录,然后执行(从下面开始,shell命令、脚本中被$()包裹的语句(包含$())替换成所述的部分):

$ wget $(链接)

稍后你就会看到目录里面多了一个对应的文件。

然后解压:

tar -xzv -f $(frp压缩包路径) -C $(要解压到的路径(不含frp文件夹本身))

之后你会在对应的目录中看到以frp开头的文件夹。由于名字太长不好记,我们最好把文件夹改一下名字:

mv $(frp文件夹路径) $(改名后的frp文件夹路径)

最终,我在ECS上解压到了/root/frps中,在树莓派上解压到了/home/pi/frpc中。

配置

我们在这里的目标就是能够在外网连接SSH。我们可以参考文档来对frp进行配置。frp的一个好处是官方文档有中文版的(https://github.com/fatedier/frp/blob/master/README_zh.md)。

编辑ECS上的frps.ini文件,这里面的路径是/root/frps/frps.ini

[common]
# 绑定的端口
bind_port = 6000
# 为了安全,可以增加一个身份验证码的设置(选填)
token = abc

另外,确保以上提到的这些端口号没有被其他应用占用。

然后编辑树莓派上的frpc.ini文件:

[common]
# 这里填frps所在服务器的地址
server_addr = example.com
# 与frps.ini中[common]中的bind_port一致
server_port = 6000
# 与frps.ini中[common]中的token一致(若没有可不填)
token = abc

# 建立SSH连接的内网穿透
[ssh]
# SSH使用TCP连接
type = tcp
# 填本机的IP就可以
local_ip = 127.0.0.1
# SSH服务的端口号,默认是22,如果更改了就填更改的端口号
local_port = 22
# 服务器对应的端口号,注意不能和服务器上的已有端口冲突
remote_port = 6022

阿里云的ECS中需要对网络安全组进行设置,允许出入站方向的端口。比如在上面的例子中,我们要允许出入站方向TCP连接6000、6022的端口。

阿里云的网络安全组默认是允许所有出站端口的,所以这种情况下允许对应的入站端口就行了。下同。

测试

我们在实际使用前,先进行测试。

先在ECS上运行frps:

# /root/frps/frps -c /root/frps/frps.ini

再在树莓派上运行frpc:

$ /home/pi/frpc/frpc -c /home/frpc/frpc.ini

为了方便讲解,上面的路径使用了绝对路径,使用对应的相对路径也是可以的。

观察输出,如果输出没有错误,那就用SSH连接一下example.com,记得把端口号改成6022。如果能够连上,就说明没有问题了。这时按Ctrl + C停掉两边的程序。

后台运行与自启动

我们实际运行中总不能运行这个命令,把这个窗口挂在电脑上吧,不然关掉了程序就停了。为此,我们还要想一个方法,让它后台运行。

让一个程序后台运行的方法比较多,我们这里使用比较方便的一个方法:将它做成服务。这样的好处是我们能够用一条命令实现它的启动、停止、重启、自启动和取消自启动。尤其是自启动,这也是是我们需要的。

创建服务的方式在两台机器上都差不多,我这里就以ECS上面的frps为例吧,在树莓派上操作的时候记得换成frpc及相关的内容。

首先我们在/lib/systemd/system/中创建一个文件frps.service(这里面.service之前的名字取一个能够记住的就行,但是要注意前后一致),内容如下,保存:

[Unit]
# 写一个比较容易理解的介绍,以后查日志的时候有用
Description=fraps service
After=network.target syslog.target
Wants=network.target

[Service]
Type=simple
# 这里写之前运行成功的frps命令
ExecStart=/root/frps/frps -c /root/frps/frps.ini

[Install]
WantedBy=multi-user.target

之后执行下面的命令开启服务:

# service frps start

之后在树莓派上进行类似操作,但是还要修改frpc.ini,在[common]字段增加如下条目:

# 由于树莓派没有时钟,开机后时间不对,frpc访问服务器时会发生错误,所以此项必填
authentication_timeout = 0
# 为防止网络错误导致服务退出,填上此项
login_fail_exit = false

这个操作非常重要。我之前没有进行设置,结果第二天树莓派开机了,frp却没有启动成功。当时我在宿舍,带着电脑去了办公室,查了日志才发现这个问题。

执行对应的frpc服务。测试一下,如果没有问题,继续以下操作。

在ECS上执行以下命令以实现自启动:

# systemctl enable frps.service

在树莓派上进行类似操作。再重启一下树莓派进行测试,如果重启后能够通过外网连接树莓派,那么就成功了。

远程桌面

既然SSH能够连接上,我们再考虑一下连接其他的东西吧,比如那台十一年前的笔记本电脑。

远程桌面和SSH一样,都是使用TCP进行连接的,不过远程桌面的默认端口号是3389。

在进行下面的操作之前,我已经设置了网络共享,而且把电脑的远程桌面打开了。

开启远程桌面连接

在树莓派的frpc.ini中添加以下内容:

[RDP] 
type = tcp
# 这里填笔记本电脑的IP
local_ip = 192.168.1.121
local_port = 3389
# 还是要注意不要和已有端口冲突
remote_port = 6389

到ECS的控制台中允许6389端口入站方向的TCP连接。

重启frpc服务:

# service frpc restart

然后使用远程桌面连接工具连接example.com:6389

远程桌面连接

如果成功的话,就没什么问题了。

我之前以为要让笔记本电脑在树莓派之下的网络才行,当时还费很大力气开了树莓派的无线热点,之后发现只要笔记本电脑与树莓派在同一网络即可……

之后我成功地使用远程桌面连接在宿舍为室友远程打印了准考证。

我之前在树莓派上安装了xrdp,可以使用远程桌面连接访问树莓派的图形环境。需要让它也能够远程连接,如法炮制即可,不过把[RDP]改一下,把对应的IP改成127.0.0.1,把对应的端口号改一下就行。不过xrdp的性能不如Windows原生的远程桌面好,但是总比VNC好多了吧。

分开服务

这里注意一下,如果你在外网使用SSH连接树莓派,在重启frpc服务的时候,SSH的连接会中断。虽然能够重新连接,但是如果没法重新连接的话就非常尴尬了。我就遇到过这种情况:配置文件写错,导致frp重启失败,不得不跑到办公室解决问题。

经过我的测试,发现在端口号不冲突的情况下,同一台设备上能够运行多个frpc。这样的话,我们可以尝试将SSH的部分另外写一个ini文件(注意[common]部分也要写上),将对应的命令写成frpc_ssh.service的服务,设置开启、自启动。这样一来,当我们在SSH上重启frpc的时候,就不会影响到SSH了。

运行树莓派上的网站

很多人用ngrok和frp的目的就是把本地的网站映射到公网地址上进行测试。我们假定在树莓派的80端口上运行着网站,希望将其映射到pi.example.com。

可以在ECS的frps.ini中的[common]字段中添加如下的配置:

# 映射到虚拟主机的HTTP端口,不要有冲突
vhost_http_port = 6080
# 这里填域名
subdomain_host = example.com

在树莓派的frp.ini中添加以下配置:

# 取一个易懂的不重复的名字
[web]
type = http
# 本地运行HTTP服务的端口
local_port = 80
# 子域名
subdomain = pi

到ECS的控制台中允许80、6080端口入站方向的TCP连接。

在example.com的域名解析配置中,添加A记录*到ECS的IP地址。

在两边重启frp相关的服务。这时候访问pi.example.com,即可访问树莓派上的网站。

类似的方法还可以以特定域名访问、运行HTTPS协议的网站,详细的话可以看看官方的文档。

实际操作中非常不建议使用*这样的A记录,可以建立*.test这样的A记录,对应的部分也要做修改。

结尾

frp的配置还有很多,可以看看官方文档。而且官方就有中文文档,相当方便。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,999评论 4 368
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,102评论 1 302
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,709评论 0 250
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,439评论 0 217
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,846评论 3 294
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,881评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,062评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,783评论 0 205
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,517评论 1 248
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,762评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,241评论 1 264
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,568评论 3 260
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,236评论 3 241
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,145评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,941评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,965评论 2 283
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,802评论 2 275

推荐阅读更多精彩内容