远程访问树莓派

远程访问树莓派

引言

第一次使用树莓派时,一般会配置两个东西:一个是ssh,一个是无线网络。配置好后,再用自己的电脑通过ssh连接树莓派就可以使用了。例如

1
2
> ssh pi@192.168.3.1
pi@192.168.3.1's password:

在本例中,需要注意树莓派的IP地址为192.168.3.1,是一个本地IP地址。这意味着我的电脑只有在该局域网中才能访问树莓派,在其他网络中是不行的。例如,我的个人电脑和树莓派连上我家的WiFi,那么我可以使用我的电脑与树莓派建立ssh连接。

graph LR;
subgraph 我的家
我家中的路由器-->PI0("192.168.3.1(树莓派)")
我家中的路由器-->PC0("192.168.3.2(我的电脑)")
我家中的路由器-->OD0(...)
end

当我周末去朋友家,想要用我的电脑访问树莓派时,以上方法便会失效,因为我的电脑和树莓派在不同的局域网中。

graph LR;
subgraph 我的家
我家中的路由器-->PI0("192.168.3.1(树莓派)")
我家中的路由器-->ND0("192.168.3.2(我家的设备,或者局域网中不存在该IP地址)")
我家中的路由器-->OD0(...)
end
subgraph 朋友家
朋友家的路由器-->ND1("192.168.3.1(朋友的设备,或者局域网中不存在该IP地址)")
朋友家的路由器-->PC0("192.168.3.2(我的电脑)")
朋友家的路由器-->OD1(...)
end
1
2
> ssh pi@192.168.3.1
connect to host 192.168.3.1 port 22: Connection timed out

为了在任意地点访问树莓派,必须使用一个公网IP进行中转。简单点说,公网IP是互联网中那些真正具有互联网通信能力的IP地址。在上文例子中,192.168.3.1就不是一个这样的地址,因为当我处于其他的网络中时,我便无法与之通信。对于一个公网IP,我可以在任何地点、任何网络中与之通信。

因此,为了在任意网络中访问树莓派,必须使用一个公网IP进行中转。我们把那些具有公网IP的电脑(机器)称为服务器

开始

工具准备:

  • 一台电脑
  • 树莓派
  • 服务器
  • frp(重量级)

什么是frp

以下内容摘自frp的GitHub仓库

frp 是一个专注于内网穿透的高性能的反向代理应用,支持 TCP、UDP、HTTP、HTTPS 等多种协议。可以将内网服务以安全、便捷的方式通过具有公网 IP 节点的中转暴露到公网。

借助frp,我们可以像访问公网IP那样访问在内网中的树莓派。

安装

在frp的release页面上可以找到最新的frp下载包。可以使用archlscpu命令来查看服务器或树莓派的CPU架构,下载对应的正确版本。

这是我的服务器信息:

1
2
3
4
5
6
7
8
9
> arch
x86_64
> lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
...
Model name: AMD EPYC 7K62 48-Core Processor
...

因此我的服务器上需要下载linux_amd64的版本。

这是我的树莓派信息:

1
2
3
4
5
6
7
8
> arch
armv7l
> lscpu
Architecture: armv7l
Byte Order: Little Endian
...
Model name: Cortex-A72
...

因此我的树莓派上需要下载linux_arm的版本。

配置和启动

解压后进入frp文件夹,查看内容:

1
2
> ls
frpc frpc_full.ini frpc.ini frps frps_full.ini frps.ini LICENSE systemd

其中frpsfrpc分别是frp的服务端和客户端。同理,frps.inifrpc.ini分别是frp的服务端配置文件和客户端配置文件。初始时frps.ini的内容如下:

1
2
3
> cat frps.ini
[common]
bind_port = 7000

在服务器中启动frps

1
./frps -c frps.ini

在树莓派中启动frpc时,要先修改frpc.ini中的server_addr字段。初始时frpc.ini的内容如下:

1
2
3
4
5
6
7
8
9
10
> cat frpc.ini
[common]
server_addr = 127.0.0.1
server_port = 7000

[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000

修改server_addr字段为服务器的IP地址(假设服务器IP地址为x.x.x.x)。启动frpc

1
./frpc -c frpc.ini

查看双方的连接信息,如无报错则frp服务启动并连接成功。如果连接失败,一个可能的原因是服务器的防火墙阻止了frp的连接,此时可以到服务器的控制台查看和更改防火墙设置。

连接树莓派

在电脑上通过ssh连接树莓派。这次不是选择树莓派的本地IP地址,而是选择服务器的IP地址,加上frpc.ini中配置的remote_port字段(在本例中为6000):

1
2
> ssh pi@x.x.x.x -p 6000
pi@x.x.x.x's password:

这样,我们就可以在任何地方访问树莓派了。

设置frp系统服务

现在,虽然能通过公网IP访问树莓派,但是当服务器或者树莓派重启后,frp也因为设备重启关闭了。为了解决这一问题,我们要让frp开机自启动。一个非常好的解决方法是使用frp文件夹中的.service文件,让frp成为系统服务的一部分。

在上文中提到,frp的文件夹中有这些内容:

1
2
> ls
frpc frpc_full.ini frpc.ini frps frps_full.ini frps.ini LICENSE systemd

进入systemd文件夹:

1
2
3
> cd systemd
> ls
frpc.service frpc@.service frps.service frps@.service

这里以服务器设置frp系统服务为例。查看frps.service的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
> cat frps.service
[Unit]
Description=Frp Server Service
After=network.target

[Service]
Type=simple
User=nobody
Restart=on-failure
RestartSec=5s
ExecStart=/usr/bin/frps -c /etc/frp/frps.ini
LimitNOFILE=1048576

[Install]
WantedBy=multi-user.target

修改User选项

修改User=nobody为自己的用户名。当前用户名可以通过whoami命令查询。在本例中,假设我们的用户名是root

1
2
> whoami
root

因此,该行应为User=root

复制frps.service

将修改后的frps.service复制到/usr/lib/systemd/system目录下:

1
> sudo cp frps.service /usr/lib/systemd/system

同时,注意到frp默认的系统服务启动方式是这样的:

ExecStart=/usr/bin/frps -c /etc/frp/frps.ini

此时/usr/bin文件夹中并没有frps,也不存在/etc/frp目录,因此我们的工作还未结束。

添加软链接

我们在/usr/bin/目录为frps创建软链接。建议以frps的绝对路径创建软链接:

1
> sudo ln -s FULL_PATH_TO_FRP_FOLDER/frps /usr/bin/frps

复制frps.ini

/etc/路径下创建frp目录,并将frps.ini复制到该目录下::

1
2
> sudo mkdir /etc/frp
> sudo cp PATH_TO_FRP_FOLDER/frps.ini /etc/frp

启动frp系统服务

一切准备完毕,可以开启frp系统服务了:

1
> sudo systemctl start frps

查看frps服务状态:

1
2
3
4
5
6
> sudo systemctl status frps
● frps.service - Frp Server Service
Loaded: loaded (/usr/lib/systemd/system/frps.service; enabled; vendor preset: disabled)
Active: active (running) since Wed 2021-11-24 19:17:46 CST; 1s ago
...
...frps started successfully

如果状态信息中没有报错,且显示frps服务正在运行,说明启动成功。

要停止frps服务:

1
> sudo systemctl stop frps

开启frp系统服务自启动

打开frps服务自启动:

1
2
> sudo systemctl enable frps
Created symlink from /etc/systemd/system/multi-user.target.wants/frps.service to /usr/lib/systemd/system/frps.service.

服务器重启后,可以查询到frps的进程信息,说明frps已自启动:

1
2
3
4
... # 重启服务器并连接
> ps -ef | grep frps
root 836 1 0 Nov24 ? 00:06:47 /usr/bin/frps -c /etc/frp/frps.ini
root 1200010 1199976 0 18:32 pts/4 00:00:00 grep --color=auto frps

要关闭 frps 服务自启动:

1
2
> sudo systemctl disable frps
Removed symlink /etc/systemd/system/multi-user.target.wants/frps.service.

在树莓派上也需要开启frp系统服务,操作流程大同小异,这里不再赘述。(全文完)