Remote access
远程访问简介
Edit this on GitHub
有时,您需要在不连接显示器的情况下访问Raspberry Pi。也许Raspberry Pi被嵌入到类似机器人的东西中,或者您可能想从其他地方查看它的一些信息。或者你根本没有备用显示器!
您可以从另一台机器连接到Raspberry Pi。但为了做到这一点,你需要知道它的IP地址。
任何连接到局域网的设备都会被分配一个IP地址。为了使用 SSH 或 VNC从另一台机器连接到您的Raspberry Pi,您需要知道Raspberry Pi的IP地址。如果您连接了显示器,这很容易,并且有许多方法可以从网络上的另一台机器远程找到它。
如何查找IP地址
使用以下方法之一可以在不连接到屏幕的情况下找到Raspberry Pi的 IP 地址:
Note
|
如果您将显示器与Raspberry Pi一起使用,并且如果您启动到命令行而不是桌面,则您的 IP 地址应显示在登录提示之前的最后几条消息中。否则,打开终端窗口并输入 hostname -I 将显示您的Raspberry Pi的 IP 地址。
|
路由器设备列表
在Web浏览器中导航到路由器的IP地址,例如 http://192.168.1.1
,该地址通常印在路由器的标签上;这将带您进入控制面板。然后使用您的凭据登录,该凭据通常也打印在路由器上或在随附的文件中发送给您。浏览到已连接设备或类似设备的列表(所有路由器都不同),您应该会看到一些您识别的设备。某些设备被检测为 PC、平板电脑、手机、打印机等。所以你应该认出一些并排除它们,以确定哪个是你的Raspberry Pi。另请注意连接类型;如果您的Raspberry Pi是用电线连接的,那么可供选择的设备应该更少。
使用mDNS进行解析 raspberrypi.local
在Raspberry Pi操作系统上,Avahi服务支持即时可用的多播DNS。
如果您的设备支持 mDNS,您可以使用其主机名和 .local
后缀。
Raspberry Pi操作系统安装的默认主机名是 raspberrypi
, 因此默认情况下,任何运行Raspberry Pi操作系统的Raspberry Pi都会响应:
ping raspberrypi.local
如果Raspberry Pi可访问, ping
将显示其 IP 地址:
PING raspberrypi.local (192.168.1.131): 56 data bytes 64 bytes from 192.168.1.131: icmp_seq=0 ttl=255 time=2.618 ms
如果您更改Raspberry Pi的系统主机名 (例如,通过编辑 /etc/hostname
), Avahi 也会更改 .local
的 mDNS 地址。
如果您不记得Raspberry Pi的主机名,但安装了Avahi的系统,则可以使用 avahi-browse
命令浏览LAN上的所有主机和服务。
nmap 命令
`nmap` 命令(Network Mapper)是一个免费的开源网络发现工具,可用于Linux、macOS和Windows。
-
在 Linux 上安装, 请安装
nmap
软件包,例如apt install nmap
。 -
在 macOS 或 Windows 上安装, 参见 nmap.org 下载页面。
要使用 nmap
扫描网络上的设备,您需要知道您所连接的子网。首先找到你自己的IP地址,换句话说就是你用来找到你的Raspberry Pi的IP地址的那台电脑的IP地址:
-
在 Linux 上,在终端窗口中输入
hostname -I
-
在 macOS 上, 选择您的活动网络连接,以查看IP地址
系统首选项
网络 -
在 Windows 上, 转到控制面板,然后在下
网络和共享中心
下单击查看网络连接
,选择你的网络连接并单击查看连接状态
来查看IP地址。
现在您有了计算机的IP地址,您将扫描整个子网寻找其它设备。例如,如果您的IP地址是 192.168.1.5
, ,其他设备将位于 192.168.1.2
、 192.168.1.3
、 192.168.1.4`等地址。 此子网范围是 `192.168.1.0/24
(包括 192.168.1.0
到 192.168.1.255
)。
现在,在整个子网范围内使用带有 -sn
标志的 nmap
命令(ping scan)。这可能需要几秒钟时间:
nmap -sn 192.168.1.0/24
Ping scan just pings all the IP addresses to see if they respond. For each device that responds to the ping, the output shows the hostname and IP address like so:
Starting Nmap 6.40 ( http://nmap.org ) at 2014-03-10 12:46 GMT Nmap scan report for hpprinter (192.168.1.2) Host is up (0.00044s latency). Nmap scan report for Gordons-MBP (192.168.1.4) Host is up (0.0010s latency). Nmap scan report for ubuntu (192.168.1.5) Host is up (0.0010s latency). Nmap scan report for raspberrypi (192.168.1.8) Host is up (0.0030s latency). Nmap done: 256 IP addresses (4 hosts up) scanned in 2.41 seconds
在这里,您可以看到主机名为 raspberrypi
的设备的IP地址为 192.168.1.8
。注意,要查看主机名,您必须通过将 sudo
添加到命令前面来以root用户身份运行nmap。
通过从第2台设备pinging来获取IPV6地址
首先找到你自己的IP地址,换句话说,就是你用来通过 hostname -I
找到你的Raspberry Pi的IP地址的计算机的IP地址。
fd00::ba27:ebff:feb6:f293 2001:db8:494:9d01:ba27:ebff:feb6:f293
该示例显示了两个IP地址。第一个是所谓的唯一本地单播地址(fc00::/7
)。第二个是全局单播地址(2000::/3
)。根据您的网络(路由器)配置,也可能只看到其中一个。这两个地址对于到达局域网内的Raspberry Pi都是有效的。 2000::/3
之外的地址可以在全球范围内访问,前提是您的路由器的防火墙已打开。
现在使用第一步中的一个IP ping所有本地节点:
ping -c 2 -I 2001:db8:494:9d01:ba27:ebff:feb6:f293 ff02::1 ping -c 2 -I 2001:db8:494:9d01:ba27:ebff:feb6:f293 ff02::1%eth0
-c 2
代表发送两个回应请求
-I
用IP地址,它设置了接口和echo请求的源地址,有必要选择接口的IP地址,
eth0
是不够的-答案应该是本地链路地址(fe80::/10
),我们需要全局或本地单播地址。
ff02::1
是链路上所有节点的众所周知的多播地址,因此它的行为类似于本地广播,通常在 /etc/hosts
中定义,因此您也可以使用名称 (ip6-allnodes
或 ipv6-allnodes
) 来代替文字地址。
一些较新的系统希望多播地址后面有接口ID。
ping -c 2 -I 2001:db8:494:9d01:ba27:ebff:feb6:f293 ip6-allnodes PING ip6-allnodes(ip6-allnodes (ff02::1)) from 2001:db8:494:9d01:ba27:ebff:feb6:f293 : 56 data bytes 64 bytes from 2001:db8:494:9d01:ba27:ebff:feb6:f293: icmp_seq=1 ttl=64 time=0.597 ms 64 bytes from witz.fritz.box (2001:db8:494:9d01:728b:cdff:fe7d:a2e): icmp_seq=1 ttl=255 time=1.05 ms (DUP!) 64 bytes from raspberrypi4.fritz.box (2001:db8:494:9d01:dea6:32ff:fe23:6be1): icmp_seq=1 ttl=64 time=1.05 ms (DUP!) 64 bytes from 2001:db8:494:9d01:da37:beff:fefd:f09d (2001:db8:494:9d01:da37:beff:fefd:f09d): icmp_seq=1 ttl=255 time=1.05 ms (DUP!) 64 bytes from fusion.fritz.box (2001:db8:494:9d01:1e6f:65ff:fec9:8746): icmp_seq=1 ttl=255 time=2.12 ms (DUP!) 64 bytes from fritz.box (2001:db8:494:9d01:464e:6dff:fe72:8a08): icmp_seq=1 ttl=64 time=2.62 ms (DUP!) 64 bytes from raspberrypi.fritz.box (2001:db8:494:9d01:ba27:ebff:feb6:f293): icmp_seq=2 ttl=64 time=0.480 ms --- ip6-allnodes ping statistics --- 2 packets transmitted, 2 received, +5 duplicates, 0% packet loss, time 1001ms rtt min/avg/max/mdev = 0.480/1.283/2.623/0.735 ms
这将导致您的(W)LAN链路上所有节点的回复,以及相关的DNS名称。
排除您自己的IP( 这里是 2001:db8:494:9d01:ba27:ebff:feb6:f293
),
然后检查其他IP,尝试通过SSH连接它们。
ssh pi@2001:db8:494:9d01:dea6:32ff:fe23:6be1 The authenticity of host '2001:db8:494:9d01:dea6:32ff:fe23:6be1 (2001:db8:494:9d01:dea6:32ff:fe23:6be1)' can't be established. ECDSA key fingerprint is SHA256:DAW68oen42TdWDyrOycDZ1+y5ZV5D81kaVoi5FnpvoM. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '2001:db8:494:9d01:dea6:32ff:fe23:6be1' (ECDSA) to the list of known hosts. pi@2001:db8:494:9d01:dea6:32ff:fe23:6be1's password: Linux raspberrypi4 4.19.75-v7l+ #1270 SMP Tue Sep 24 18:51:41 BST 2019 armv7l ... pi@raspberrypi4:~ $
设置SSH 服务器
Edit this on GitHub
您可以使用安全shell(SSH)协议从同一网络上的另一台计算机或设备远程访问Raspberry Pi的命令行。
您只能访问命令行,而不能访问整个桌面环境。如需完整的远程桌面,请参见 VNC。
设置本地网络
确定您的Raspberry Pi已正确设置和连接。如果您使用无线网络,可以通过桌面用户界面或从命令行使用来启用。如果您不使用无线连接,请将您的Raspberry Pi直接插入路由器。
Note
|
您需要记下您的Raspberry Pi的IP地址,以便以后连接到它。使用 ifconfig 命令将显示有关当前网络状态的信息,包括IP地址,或者您可以使用 hostname -I 来显示与设备相关联的IP地址。
|
启用服务器Server
Raspberry Pi OS默认禁用SSH服务器。可以从桌面手动启用它:
-
从
Preferences
菜单启动Raspberry Pi Configuration
-
导航至
Interfaces
选项卡 -
选择
Enabled
旁边的SSH
-
单击
OK
或者,您可以使用 raspi-config 应用程序从终端启用它,
-
在终端窗口输入
sudo raspi-config
-
选择
Interfacing Options
-
导航并选择
SSH
-
选择
Yes
-
选择
Ok
-
选择
Finish
Note
|
对于无头设置,可以通过将名为 ssh`的文件(没有任何扩展名)放在SD卡的启动分区上来启动SSH。 当Raspberry Pi启动时,它会寻找 `ssh 文件。 如果找到了,SSH将被启用,文件将被删除。文件的内容无关紧要;它可以包含文本,也可以什么都不包含。
|
Note
|
对于除 ssh 外的无头设置,你还需要一个 userconf.txt 文件, 其中包含一个字符串 username:encryptedpassword 。 请参考Raspberry Pi的无头设置的讨论中关于 配置用户r 的部分。
|
Warning
|
当在可能连接到互联网的Raspberry Pi上启用SSH时,您应该确保您的密码不会被轻易破解。 |
来自 Linux 或 Mac OS的安全Shell
Edit this on GitHub
您可以使用SSH从Linux桌面、另一个Raspberry Pi或Apple Mac连接到您的Raspberry Pi,而无需安装其他软件。
在您的电脑上打开一个终端窗口,将 <IP>
替换为您尝试连接的Raspberry Pi的IP地址
ssh pi@<IP>
当连接正常时,您会看到一个安全/真实性警告。输入 yes
继续。您只会在第一次连接时看到此告警。
Note
|
如果您收到 连接超时错误 ,很可能您输入了错误的Raspberry Pi IP地址。
|
Warning
|
如果您的Raspberry Pi获取了您的电脑之前连接过的设备的IP地址(即使这是在另一个网络上),您可能会收到警告,并被要求从已知设备列表中清除该记录。遵循这个指令并再次尝试ssh命令应该会成功。 |
接下来将提示您输入 pi
登录的密码: Raspberry Pi操作系统上的默认密码是 raspberry
。
出于安全原因,强烈建议在Raspberry Pi上更改默认密码(另外,如果密码为空,则不能通过ssh登录)。您现在应该能够看到Raspberry Pi提示符,它与Raspberry Pi上的提示符完全相同。
如果您已经在Raspberry Pi上设置了另一个用户,您可以用同样的方式连接到它,用您自己的用户名替换用户名,例如 eben@192.168.1.5
。
pi@raspberrypi ~ $
您现在远程连接到Raspberry Pi,并且可以执行命令。
转发 X11
您还可以通过SSH转发X会话,以允许使用图形应用程序,方法是使用 -Y
标志:
ssh -Y pi@192.168.1.5
现在您像以前一样在命令行上,但是您能够打开图形窗口。例如,输入:
geany &
将在本地桌面的窗口中打开Geany编辑器。
来自 Windows 10的Shell
Edit this on GitHub
您可以使用SSH从使用2018年10月更新或更高版本的Windows 10电脑连接到您的Raspberry Pi,而无需使用第三方客户端。
在您的电脑上打开一个终端窗口,将 <IP>
替换为您尝试连接的Raspberry Pi的IP地址,
ssh pi@<IP>
当连接正常时,您会看到一个安全/真实性警告。输入 yes
继续。您只会在第一次连接时看到此告警。
Note
|
如果你收到 连接超时 错误, 很可能您输入了错误的Raspberry Pi的IP地址。
|
Warning
|
如果您的Raspberry Pi获取了您的电脑之前连接过的设备的IP地址(即使这是在另一个网络上),您可能会收到警告,并被要求从已知设备列表中清除该记录。遵循这个指令并再次尝试ssh命令应该会成功。 |
接下来将提示您输入 pi
登录的密码:Raspberry Pi操作系统上的默认密码是 raspberry
。
出于安全原因,强烈建议在Raspberry Pi上更改默认密码(另外,如果密码为空,则不能通过ssh登录)。您现在应该能够看到Raspberry Pi提示符,它与Raspberry Pi上的提示符完全相同。
如果您已经在Raspberry Pi上设置了另一个用户,您可以用同样的方式连接到它,用您自己的用户名替换用户名,例如 eben@192.168.1.5
。
pi@raspberrypi ~ $
您现在远程连接到Raspberry Pi,并且可以执行命令。
无密码 SSH访问
Edit this on GitHub
可以将您的Raspberry Pi配置为允许从另一台计算机访问,而无需在每次连接时提供密码。为此,您需要使用SSH密钥而不是密码。要生成SSH密钥:
检查现有的 SSH 密钥
首先,检查您用来连接Raspberry Pi的计算机上是否已经有密钥:
ls ~/.ssh
如果您看到名为 id_rsa.pub
或 id_dsa.pub
的文件,那么您已经设置了密钥,因此您可以跳过下面的 '生成新的SSH密钥' 操作步骤。
生成新的SSH密钥
要生成新的SSH密钥,请输入以下命令:
ssh-keygen
输入该命令后,将询问您保存密钥的位置。我们建议将其保存在默认位置 (~/.ssh/id_rsa
) 。
您还将被要求输入一个密码,这是可选的。密码短语用于加密私有SSH密钥,这样,如果其他人复制了密钥,他们就无法冒充您来获得访问权限。如果您选择使用密码,请在此处键入并按 `Enter`键,然后在出现提示时再次键入。如果没有密码,请将该字段留空。
现在看看你的 .ssh
目录:
ls ~/.ssh
您应该会看到文件 id_rsa
和 id_rsa.pub
:
authorized_keys id_rsa id_rsa.pub known_hosts
`id_rsa` 文件是您的私钥。把这个保存在你的电脑上。
`id_rsa.pub` 文件是您的公钥。这是您与所连接的机器共享的内容:在本例中是您的Raspberry Pi。当您尝试连接的机器匹配您的公钥和私钥时,它将允许您连接。
看一看您的公钥,看看它是什么样子的:
cat ~/.ssh/id_rsa.pub
它应该采用以下形式:
ssh-rsa <REALLY LONG STRING OF RANDOM CHARACTERS> user@host
将你的密钥复制到 Raspberry Pi上
使用您将要连接的计算机,通过SSH将公钥附加到Raspberry Pi上的 authorized_keys
文件:
ssh-copy-id <USERNAME>@<IP-ADDRESS>
Note
|
在此步骤中,您需要使用您的密码进行身份验证。 |
或者,如果您的系统上没有 ssh-copy-id
,您可以通过ssh手动复制文件:
cat ~/.ssh/id_rsa.pub | ssh <USERNAME>@<IP-ADDRESS> 'mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys'
如果您看到消息 ssh: 连接到主机 <IP-地址> 端口22: 连接被拒绝,并且您知道 `IP-地址
是正确的, 那么您可能没有在您的Raspberry Pi上启用SSH。 在Raspberry Pi的终端窗口中运行 sudo raspi-config
,启用SSH,然后再次尝试复制文件。
现在尝试 ssh <USER>@<IP-ADDRESS>
,您应该可以在没有密码提示的情况下连接。
如果您看到消息 "Agent admitted failure to sign using the key" ,则将您的RSA或DSA身份添加到身份认证代理 ssh-agent
,然后执行以下命令:
ssh-add
Note
|
您还可以使用 scp (安全复制) 命令通过SSH发送文件。
|
调整目录权限
如果您在完成上述步骤后仍无法建立连接,则您的目录权限可能有问题。首先,您需要检查日志中是否有错误:
tail -f /var/log/secure
# might return:
Nov 23 12:31:26 raspberrypi sshd[9146]: Authentication refused: bad ownership or modes for directory /home/pi
如果日志显示 认证被拒绝: 目录 /home/pi
的所有权或模式不正确,则您的主目录存在权限问题。SSH需要
主目录和 ~/.ssh
目录没有组的写访问权限。你可以使用 `chmod`调整权限。
chmod g-w $HOME
chmod 700 $HOME/.ssh
chmod 600 $HOME/.ssh/authorized_keys
现在只有用户自己可以访问 .ssh
和 .ssh/authorized_keys
,其中存储了远程机器的公钥。
将密码存储在macOS密钥串中
如果您使用的是macOS,并且在验证您的新密钥允许您连接后,您可以选择将密钥的密码储存在macOS密钥串中。这允许您无需输入密码即可连接到您的Raspberry Pi。
运行以下命令将其储存在密钥串中:
ssh-add -K ~/.ssh/id_rsa
Note
|
从macOS Monterey开始 |
使用安全拷贝
Edit this on GitHub
安全复制 (scp
) 是通过SSH发送文件的命令。 这意味着你可以在电脑之间复制文件,比如从你的Raspberry Pi到你的台式机或笔记本电脑,反之亦然。
首先,你需要知道你的 Raspberry Pi IP 地址 。
将文件复制到Raspberry Pi
使用以下命令,将 myfile.txt
文件从您的计算机复制到您的Raspberry Pi的 pi
用户主文件夹且IP地址为 192.168.1.3
:
scp myfile.txt pi@192.168.1.3:
将文件复制到Raspberry Pi上的 /home/pi/project/
目录中 ( 项目
文件夹必须已存在):
scp myfile.txt pi@192.168.1.3:project/
Using rsync
Edit this on GitHub
您可以使用 rsync
工具在计算机之间同步文件夹。例如,您可能想要将一些文件从台式电脑或笔记本电脑传输到您的Raspberry Pi,并使它们保持最新,或者您可能想要将您的Raspberry Pi拍摄的照片自动传输到您的电脑。
通过SSH使用 rsync
允许您自动将文件传输到您的电脑。
以下是如何将Raspberry Pi上的图片文件夹同步到电脑的示例:
在您的电脑上,创建一个名为 camera
的文件夹:
mkdir camera
通过登录并运行 hostname -I
. 来查找Raspberry Pi的IP地址。在本例中,Raspberry Pi通过每分钟捕捉一张照片来创建延时,并将带有时间戳的照片保存在其SD卡上的本地文件夹 camera
中。
现在运行以下命令(替换您自己的Raspberry Pi的IP地址):
rsync -avz -e ssh pi@192.168.1.10:camera/ camera/
这将把所有文件从Raspberry Pi的相机文件夹复制到您计算机的新 camera
文件夹。
网络文件系统 (NFS)
Edit this on GitHub
网络文件系统(NFS)允许您与同一网络上的其他计算机或设备共享位于一台联网计算机上的目录。目录所在的计算机称为 服务器, 连接到该服务器的计算机或设备称为客户端。客户端通常 挂载
共享目录,使其成为自己目录结构的一部分。共享目录是共享资源或网络共享的一个例子。
对于较小的网络,NFS非常适合在Linux/Unix环境中创建简单的NAS(网络连接存储)。
NFS可能最适合于更永久的网络安装目录,比如 /home
目录或经常访问的共享资源。如果您想要一个访客用户可以轻松连接到的网络共享,Samba更适合这个任务。这是因为在旧的和专有的操作系统中,临时挂载和分离Samba共享的工具更容易获得。
在部署NFS之前,您应该熟悉:
-
Linux文件和目录权限
-
挂载和卸载文件系统
设置基本的 NFS 服务器
使用以下命令安装所需的软件包:
sudo apt install nfs-kernel-server
为了便于维护,我们将把所有NFS导出隔离在一个目录中,实际的目录将使用 --bind
选项挂载到这个目录中。
假设我们想要导出用户的主目录,它位于 `/home/users`中。首先,我们创建导出文件系统:
sudo mkdir -p /export/users
请注意 /export
和 /export/users
将需要777权限,因为我们将从客户端访问NFS共享,而无需 LDAP/NIS 身份验证。如果使用身份验证,这将不适用(见下文)。现在,使用以下命令挂载真实 用户
目录:
sudo mount --bind /home/users /export/users
为了避免我们在每次重新启动后重新键入,我们在 /etc/fstab
中添加了下面一行:
/home/users /export/users none bind 0 0
有三个与NFS服务器相关的配置文件:
-
/etc/default/nfs-kernel-server
-
/etc/default/nfs-common
-
/etc/exports
目前 /etc/default/nfs-kernel-server
中唯一重要的选项是 NEED_SVCGSSD
。默认情况下,它被设置为`"no"` 这很好,因为我们这次没有激活NFSv4安全性。
为了自动映射ID名称,文件 /etc/idmapd.conf
必须存在于客户机和服务器上,具有相同的内容和正确的域名。此外,该文件的 映射
部分应该有以下几行:
[Mapping] Nobody-User = nobody Nobody-Group = nogroup
但是,请注意,客户端可能对Nobody-User和Nobody-Group有不同的要求。例如,在RedHat变体上,两者都是 nfsnobody
。如果您不确定,请通过以下命令检查是否为 nobody
和 nogroup
。
cat /etc/passwd
cat /etc/group
这样,服务器和客户端不需要用户共享相同的UID/GUID。对于使用基于LDAP的身份验证的用户,将以下行添加到客户端的 idmapd.conf
中:
[Translation] Method = nsswitch
这将使 idmapd
知道查看 nsswitch.conf
以确定应该在哪里查找凭据信息。如果您已经有了LDAP身份验证, nsswitch
应该不需要进一步的解释。
为了将我们的目录导出到本地网络 192.168.1.0/24
, 我们在 /etc/exports
中添加以下两行:
/export 192.168.1.0/24(rw,fsid=0,insecure,no_subtree_check,async) /export/users 192.168.1.0/24(rw,nohide,insecure,no_subtree_check,async)
端口映射锁定(可选)
NFS上的文件对网络上的任何人都是开放的。作为一种安全措施,您可以限制对指定客户端的访问。
将下面一行添加到 /etc/hosts.deny
中:
rpcbind mountd nfsd statd lockd rquotad : ALL
通过首先阻止所有客户端,只有 /etc/hosts.allow
(添加在下面) 中的客户端才被允许访问服务器。
现在将下面一行添加到 /etc/hosts.allow
中:
rpcbind mountd nfsd statd lockd rquotad : <list of IPv4s>
其中 <IPv4 列表>
是服务器和所有客户端的IP地址列表。 (这些必须是IP地址,因为 `rpcbind`中有一个限制,它不喜欢主机名。) 请注意,如果您设置了NIS,您可以将它们添加到同一行中。
请确保授权IP地址列表包括 本地主机
IP地址 (127.0.0.1
),因为最新版本的Ubuntu中的启动脚本使用 rpcinfo
命令来发现NFSv3支持,如果 本地主机
无法连接,此功能将被禁用。
最后,要使您的更改生效,请重新启动服务:
sudo systemctl restart nfs-kernel-server
配置 NFS 客户端
现在您的服务器正在运行,您需要设置任何客户端来访问它。首先,安装所需的软件包:
sudo apt install nfs-common
在客户端,我们可以用一个命令挂载完整的导出树:
mount -t nfs -o proto=tcp,port=2049 <nfs-server-IP>:/ /mnt
您还可以指定NFS服务器的主机名,而不是其IP地址,但是在这种情况下,您需要确保主机名可以在客户端解析为IP。确保这一问题始终得到解决的可靠方法是使用 /etc/hosts
文件。
请注意 <nfs-server-IP>:/export
在NFSv4中不是必需的,在NFSv3中是这样的。根导出 :/` 默认为 fsid=0
的导出。
我们还可以使用以下命令挂载导出的子树:
mount -t nfs -o proto=tcp,port=2049 <nfs-server-IP>:/users /home/users
要确保在每次重新引导时都装载该文件,请在 /etc/fstab
中添加行:
<nfs-server-IP>:/ /mnt nfs auto 0 0
如果在挂载之后, /proc/mounts appears
中的条目显示为 <nfs-server-IP>://
(嗲有2个斜杠), 那么您可能需要在 /etc/fstab
中指定2个斜杠,否则 umount
可能会报错它找不到挂载。
更复杂的NFS服务器
NFS用户权限基于用户ID (UID)。客户端上任何用户的uid都必须与服务器上的uid相匹配,以便用户能够访问。典型的做法是:
-
手动密码文件同步
-
LDAP的使用
-
DNS的使用
-
NIS的使用
请注意,在主用户拥有root访问权限的系统上,您必须小心:该用户可以更改系统上的uid,以允许自己访问任何人的文件。该页面假设管理团队是唯一具有root访问权限的组,并且他们都是可信的。其他任何东西都代表一种更高级的配置,这里就不讨论了。
群组权限
用户的文件访问权限由他们在客户端上的组成员身份决定,而不是由他们在服务器上的组成员身份决定。但是,有一个重要的限制:从客户端到服务器最多传递16个组,如果用户是客户端上超过16个组的成员,一些文件或目录可能会意外地不可访问。
DNS (可选,仅当使用DNS时)
将任何客户机名称和IP地址添加到 /etc/hosts
. (服务器的IP地址应该已经在那里了。) 这确保了即使DNS关闭,NFS仍将工作。或者,如果你愿意,你也可以依靠DNS这取决于你。
NIS (可选,仅当使用NIS时)
这适用于使用NIS的客户端。否则不能使用网络组,应该在 /etc/exports`中指定单独的IP或主机名。有关更多信息,请阅读 `man netgroup
中的错误部分。
首先,编辑 /etc/netgroup
并添加一行来对您的客户端进行分类(这一步不是必需的,只是为了方便):
myclients (client1,,) (client2,,) ...
其中 myclients
是网络组名称。
接下来运行以下命令来重建NIS数据库:
sudo make -C /var/yp
文件名 yp
指的是黄页,NIS以前的名字。
端口映射锁定(可选)
将下面一行添加到 /etc/hosts.deny
中:
rpcbind mountd nfsd statd lockd rquotad : ALL
通过首先阻止所有客户端,只有 /etc/hosts.allow
(添加在下面) 中的客户端才被允许访问服务器。
考虑将下面一行添加到 /etc/hosts.allow
:
rpcbind mountd nfsd statd lockd rquotad : <list of IPs>
其中 <IP列表>
是服务器和所有客户端的IP地址列表。 由于 rpcbind
中的限制,这些必须是IP地址。请注意,如果您设置了NIS,您可以将它们添加到同一行中。
软件包安装和配置
安装必要的软件包:
sudo apt install rpcbind nfs-kernel-server
编辑 /etc/exports
并添加共享:
/home @myclients(rw,sync,no_subtree_check) /usr/local @myclients(rw,sync,no_subtree_check)
上面的示例将 /home
和 /usr/local
共享给 myclients
网络组中的所有客户端。
/home 192.168.0.10(rw,sync,no_subtree_check) 192.168.0.11(rw,sync,no_subtree_check) /usr/local 192.168.0.10(rw,sync,no_subtree_check) 192.168.0.11(rw,sync,no_subtree_check)
上面的示例将 /home
和 /usr/local
共享给两个具有静态IP地址的客户端。 如果您希望允许访问专用网络中位于指定IP地址范围内的所有客户端,请考虑以下情况:
/home 192.168.0.0/255.255.255.0(rw,sync,no_subtree_check) /usr/local 192.168.0.0/255.255.255.0(rw,sync,no_subtree_check)
在这里, rw
使共享读/写和 sync
要求服务器仅在任何更改被刷新到磁盘后才回复请求。 这是最安全的选择; 异步
比较快,但是很危险。 如果您正在考虑其他选择,强烈建议您阅读 man exports
。
设置 /etc/exports
后, 导出共享:
sudo exportfs -ra
每当修改 /etc/exports
时,你都需要运行这个命令。
故障排除
只有在成功登录并且您的主目录被解密后,在加密的主目录中挂载 NFS 共享才有效。这意味着使用 /etc/fstab 在启动时挂载 NFS 共享将不起作用,因为您的家在挂载时尚未解密。使用符号链接有一个简单的解决方法:
-
创建一个备用目录以挂载 NFS 共享:
sudo mkdir /nfs
sudo mkdir /nfs/music
-
编辑
/etc/fstab
以将 NFS 共享挂载到该目录中:
nfsServer:music /nfs/music nfs auto 0 0
-
在家中创建一个符号链接,指向实际的安装位置。例如,在这种情况下,首先删除
Music
那里已经存在的目录:
rmdir /home/user/Music
ln -s /nfs/music/ /home/user/Music
Samba (SMB/CIFS)
Edit this on GitHub
Samba 是 SMB/CIFS 网络协议的实现,Microsoft Windows 设备使用它来提供对文件、打印机和串行端口的共享访问。
您可以使用Samba挂载从Windows计算机共享的文件夹,使其显示在Raspberry Pi上,或者从Raspberry Pi共享文件夹,以便Windows机器可以访问它。
安装 Samba 支持
默认情况下,Raspberry Pi OS不包括CIFS / Samba支持,但可以添加。以下命令将安装使用 Samba 作为服务器或客户端所需的所有组件。
sudo apt update
sudo apt install samba samba-common-bin smbclient cifs-utils
挂载从窗口共享的文件夹
首先,您需要在Windows设备上共享一个文件夹。这是一个相当复杂的过程!
开启共享
-
打开网络和共享中心,方法是右键单击系统菜单并选择它
-
单击 Change advanced sharing settings
-
选择 Turn on network discovery
-
选择 Turn on file and printer sharing
-
保存更改
共享文件夹
您可以共享所需的任何文件夹,但对于此示例,只需创建一个名为 `share`的文件夹。
-
在桌面上创建文件夹
share
。 -
右键单击此文件夹然后选择 Properties.
-
单击 Sharing 页签, 然后选择 Advanced Sharing 按键
-
选择 Share this folder; 默认情况下,共享名称是文件夹的名称
-
单击 Permissions 按键
-
6. 对于此示例,请选择 Everyone 和 Full Control (如果需要,可以将访问权限限制为特定用户); 完成后单击 OK w, 然后再次单击 OK 以离开 Advanced Sharing 页面
-
单击 Security 页签, 因为我们现在需要配置相同的权限
-
选择与 Permissions 页签相同的设置, 并在必要时添加所选用户
-
单击 OK
该文件夹现在应该已共享。
Windows 10 共享向导
在 Windows 10 上,有一个共享向导可以帮助完成其中一些步骤。
-
从“开始”栏运行“计算机管理”应用程序
-
选择 共享文件夹 文件夹, 然后选择 共享
-
右键单击并选择 新建共享, 这将启动共享向导;单击 下一步
-
选择要共享的文件夹,然后单击 下一步
-
单击 下一步 以使用所有共享默认值
-
选择 自定义 并设置所需的权限,然后选择 OK, 最后单击 Finish
将文件夹挂载在 Raspberry Pi上
在 Linux 中 挂载 是将文件夹附加到某个位置的过程,因此首先我们需要该位置。
mkdir windowshare
现在,我们需要将远程文件夹挂载到该位置。远程文件夹是 Windows PC 的主机名或 IP 地址,以及共享时使用的共享名称。我们还需要提供将用于访问远程计算机的 Windows 用户名。
sudo mount.cifs //<hostname or IP address>/share /home/pi/windowshare -o user=<name>
您现在应该能够在Raspberry Pi上查看Windows共享的内容。
cd windowshare
ls
"主机已关闭" 错误
此错误是由两种因素共同导致的:SMB 协议版本不匹配,以及 Linux 上的 CIFS 客户端返回误导性错误消息。为了解决这个问题,需要将版本条目添加到 mount 命令中。默认情况下,Raspberry Pi OS 将仅使用与 Windows 7 及更高版本兼容的 2.1 及更高版本。较旧的设备(包括某些 NAS)可能需要版本 1.0:
sudo mount.cifs //IP/share /mnt/point -o user=<uname>,vers=1.0
您可能需要尝试不同的版本以与服务器版本匹配。可能的值为:
版本 | 描述 |
---|---|
1.0 |
经典 CIFS/SMBv1 协议 |
2.0 |
SMBv2.002 协议。Windows Vista Service Pack 1 和 Windows Server 2008 |
2.1 |
SMBv2.1 协议。 Microsoft Windows 7 和 Windows Server 2008R2 |
3.0 |
SMBv3.0 协议。 Microsoft Windows 8 和 Windows Server 2012 |
3.02 |
SMBv3.0.2 协议。 Microsoft Windows 8.1 和 Windows Server 2012R2 |
3.11 |
SMBv3.1.1 协议。 Microsoft Windows 10 和 Windows Server 2016 |
3 |
SMBv3.0 协议版本及以上 |
为Raspberry Pi共享文件夹
首先,创建一个共享文件夹。本示例在当前用户的 home
文件夹中创建一个名为 `shared`的文件夹,并假设当前用户是pi。
cd ~
mkdir shared
chmod 0740 shared
现在我们需要告诉Samba有一个 pi
用户在访问那个文件夹。当被询问时,输入 pi
用户的密码 - 这可以是默认密码,但这是众所周知的,为了更好的安全性应该更改。
sudo smbpasswd -a pi
现在我们需要告诉 Samba 使用 Samba 配置文件共享此文件夹。
sudo nano /etc/samba/smb.conf
在文件末尾,添加以下内容以共享文件夹,并授予远程用户读/写权限:
[share] path = /home/pi/shared read only = no public = yes writable = yes
在同一文件中,找到该 workgroup
行,如有必要,将其更改为本地 Windows 网络的工作组的名称。
workgroup = <your workgroup name here>
这应该足以共享文件夹。在您的 Windows 设备上,当您浏览网络时,应该会出现该文件夹,并且您应该能够连接到它。
虚拟网络计算 (VNC)
Edit this on GitHub
有时直接在Raspberry Pi上工作并不方便。也许您想通过遥控器从另一台设备对其进行处理。
VNC 是一种图形桌面共享系统,允许您从另一台计算机或移动设备(运行 VNC 查看器)远程控制一台计算机(运行 VNC 服务器)的桌面界面。VNC 查看器将键盘和鼠标或触摸事件传输到 VNC 服务器,并接收屏幕更新作为回报。
您将在计算机或移动设备的窗口中看到Raspberry Pi的桌面。您将能够控制它,就像您在处理Raspberry Pi本身一样。
RealVNC 的 VNC Connect 包含在 Raspberry Pi OS 中。它由VNC服务器和VNC Viewer组成,VNC服务器允许您远程控制Raspberry Pi,后者允许您根据需要从Raspberry Pi远程控制台式计算机。
您必须先启用 VNC 服务器,然后才能使用它。默认情况下,VNC 服务器可让您远程访问在 Raspberry Pi 上运行的图形桌面,就像您坐在它前面一样。
但是,您也可以使用 VNC 服务器来获取对 Raspberry Pi 的图形远程访问,如果它是无头的或未运行图形桌面。有关此内容的更多信息,请参阅下面的 创建虚拟桌面。
在 Raspberry Pi上安装VNC
VNC已经安装在完整的Raspberry Pi操作系统映像上,可以通过其他版本的首选项菜单中的 推荐软件
进行安装。
如果您不使用桌面,则可以从命令行安装它,如下所示:
sudo apt update
sudo apt install realvnc-vnc-server realvnc-vnc-viewer
启用 VNC 服务器
您可以通过图形方式或在命令行中执行此操作。
以命令行方式启用VNC服务器
您可以使用 raspi-config在命令行启用 VNC 服务器:
sudo raspi-config
现在,通过执行以下操作启用 VNC 服务器:
-
导航至 Interfacing Options。
-
向下滚动并选择
。
连接到 Raspberry Pi
有两种方法可以连接到Raspberry Pi。您可以使用其中之一或两者,具体取决于最适合您的方法。
建立云连接
您有权免费使用RealVNC的云服务,前提是远程访问仅用于教育或非商业目的。
云连接方便且端到端加密。强烈建议使用它们通过互联网连接到Raspberry Pi。没有防火墙或路由器重新配置,您不需要知道Raspberry Pi的 IP 地址,也不需要提供静态地址。
-
注册一个 RealVNC 账户 : 它是免费的,只需要几秒钟。
-
在Raspberry Pi上使用新的 RealVNC 帐户凭据登录 VNC 服务器:
-
在您将用于控制的设备上,下载 VNC 查看器。您 必须 使用RealVNC的 兼容性应用程序 。
-
使用相同的 RealVNC 帐户凭据登录 VNC 查看器,然后点击或单击以连接到您的Raspberry Pi:
向 VNC 服务器进行身份验证
要完成直接连接或云连接,您必须向 VNC 服务器进行身份验证。
如果您从 RealVNC 兼容的VNC Viewer 应用程序 进行连接,请输入您通常用于登录 Raspberry Pi 上的用户帐户的用户名和密码。默认情况下,这些凭据是 pi
和 raspberry
。
如果您从非 RealVNC Viewer 应用程序进行连接,则首先需要降级 VNC 服务器的身份验证方案,指定 VNC Server 独有的密码,然后输入该密码。
-
如果您在Raspberry Pi前面并且可以看到其屏幕,请打开Raspberry Pi上的 VNC 服务器对话框,选择
, 再从 Authentication 下拉列表中选择 VNC password 。 -
或者 如果您要从命令行远程配置Raspberry Pi,则要对服务模式(Raspberry Pi的默认配置)进行更改:
-
打开
/root/.vnc/config.d/vncserver-x11
配置文件。 -
替换
Authentication=SystemAuth
为Authentication=VncAuth
并保存文件。 -
在命令行中运行
sudo vncpasswd -service
。这将提示您设置密码,并将其插入到以服务模式运行的VNC服务器的正确配置文件中。 -
重启 VNC 服务器。
-
使用直接呈现的应用程序
您可以远程访问使用直接渲染叠加的应用程序,例如:文本控制台、Raspberry Pi相机模块等。
要启用此功能,请执行以下操作:
-
在Raspberry Pi上, 打开 VNC 服务器对话框。
-
导航至
并选择 Enable experimental direct capture mode. -
在您将用于控制的设备上,运行 VNC 查看器并连接。
Note必须重新启动现有连接才能使这些更改生效。
请注意,直接屏幕捕获是一项实验性功能。 如果您从台式计算机进行连接,并且鼠标移动似乎不稳定,请尝试按 F8 打开 VNC 查看器快捷菜单并选择 Relative Pointer Motion。
创建虚拟桌面
如果您的Raspberry Pi是无头的(即没有插入显示器)或控制机器人,则它不太可能运行图形桌面。
VNC 服务器可以为您创建 虚拟桌面 ,让您按需进行图形远程访问。此虚拟桌面仅存在于Raspberry Pi的内存中:
要创建并连接到虚拟桌面,请执行以下操作:
-
在 Raspberry Pi上(使用终端或通过 SSH), 运行
vncserver
。 记下VNC服务器将打印到您的终端的IP地址/显示编号 (例如192.167.5.149:1
). -
在您将用于控制的设备上,将此信息输入 VNC 查看器。
要销毁虚拟桌面,请运行以下命令:
vncserver -kill :<display-number>
这还将停止与此虚拟桌面的任何现有连接。
设置 Apache Web 服务器
Edit this on GitHub
Apache是一个流行的Web服务器应用程序,你可以安装在Raspberry Pi上,允许它为网页提供服务。
就其本身而言,Apache可以通过HTTP提供HTML文件,并且使用其他模块可以使用PHP等脚本语言提供动态网页。
安装 Apache
首先,通过在终端中键入以下命令来更新可用软件包:
sudo apt update
然后,使用以下 apache2
命令安装软件包:
sudo apt install apache2 -y
测试 Web 服务器
默认情况下,Apache将一个测试HTML文件放在web文件夹中。当您在Raspberry Pi本身上浏览到 http://localhost/
时,或者从网络上的另一台计算机浏览到 http://192.168.1.10
(无论Raspberry Pi的IP地址是什么)时,将提供此默认网页。要查找Raspberry Pi的IP地址,请在命令行中键入 hostname -I
(IP 地址信息)。
浏览到 Raspberry Pi 上的默认网页或网络上的另一台计算机,您应该看到以下内容:
这意味着你有 Apache 工作!
更改默认网页
此默认网页只是文件系统上的一个 HTML 文件。它位于 /var/www/html/index.html
。
在终端窗口中导航到此目录,并查看其中的内容:
cd /var/www/html ls -al
这将向您展示:
total 12
drwxr-xr-x 2 root root 4096 Jan 8 01:29 .
drwxr-xr-x 12 root root 4096 Jan 8 01:28 ..
-rw-r--r-- 1 root root 177 Jan 8 01:29 index.html
这表明,默认情况下,在 /var/www/html/
中有一个名为 index.html
的文件,它由 root
用户拥有(包含的文件夹也是如此)。为了编辑该文件,您需要将其所有权更改为您自己的用户名。使用 sudo chown pi: index.html
更改文件的所有者 (这里假设默认的`pi` 用户)。
您现在可以尝试编辑此文件,然后刷新浏览器以查看网页更改。如果您了解 HTML,您可以将自己的 HTML 文件和其他资产放在此目录中,并将它们作为本地网络上的网站提供。
为Apache安装PHP
要允许你的Apache服务器处理PHP文件,你需要安装最新版本的PHP和Apache的PHP模块。键入以下命令以安装这些:
sudo apt install php libapache2-mod-php -y
现在删除该 index.html
文件:
sudo rm index.html
并创建文件 index.php
:
sudo nano index.php
把一些PHP内容放进去:
<?php echo "hello world"; ?>
现在保存并刷新您的浏览器。您应该看到 "hello world"。这不是动态的,但仍由 PHP 提供。尝试一些动态的东西:
<?php echo date('Y-m-d H:i:s'); ?>
或显示您的 PHP 信息:
<?php phpinfo(); ?>
网络启动 Raspberry Pi
Edit this on GitHub
您可以设置DHCP / TFTP服务器,该服务器将允许您从网络启动Raspberry Pi 3或Raspberry Pi 4。
这些说明假定您有一个现有的家庭网络,并且您希望将Raspberry Pi用于 服务器。 您还需要一个额外的Raspberry Pi 3 或 Raspberry Pi 4 作为要启动的 客户端 。只需要一个 SD 卡,因为在初始客户端配置后,客户端将从服务器引导。
Note
|
由于可用的网络设备和路由器种类繁多,我们无法保证网络启动适用于任何设备。我们收到报告称,如果无法使网络引导正常工作,则在网络上禁用 STP 帧可能会有所帮助。 |
客户端配置
Raspberry Pi 3 Model B
Note
|
本节仅适用于Raspberry Pi 3 Model B,因为网络启动在出厂时已在Raspberry Pi 3 Model B+ 上启用。 |
在Raspberry Pi 3 Model B网络启动之前,需要从SD卡启动,并带有配置选项以启用USB启动模式。这将在Raspberry Pi SoC 中的 OTP(一次性可编程)内存中设置一个位,以启用网络启动。完成此操作后,Raspberry Pi Model 3B将尝试从USB启动,如果无法从SD卡启动,则从网络启动。
以通常的方式在SD卡上安装Raspberry Pi OS Lite或带桌面的Raspberry Pi OS。接下来,使用以下命令启用 USB 启动模式:
echo program_usb_boot_mode=1 | sudo tee -a /boot/config.txt
这会将 program_usb_boot_mode=1
添加到 `/boot/config.txt`的末尾。使用 `sudo reboot`重新启动Raspberry Pi。一旦客户端Raspberry Pi重新启动,检查OTP是否已被编程为:
vcgencmd otp_dump | grep 17:
17:3020000a
确保 0x3020000a
输出正确。
客户端配置已经基本完成。最后要做的是从 config.txt
中删除 program_usb_boot_mode
行。最后,用 sudo poweroff
关闭客户端Raspberry Pi。
Raspberry Pi 4 Model B
可以使用 raspi-config
工具在Raspberry Pi 4上启用网络引导。首先,运行 raspi-config
,如下所示:
sudo raspi-config
在 raspi-config
中选择 Advanced Options
, 再选择 Boot Order
, 最后选择 Network Boot
。然后,您必须重新启动设备,以便将对启动顺序的更改编程到启动加载程序EEPROM中。一旦Raspberry Pi重新启动,检查启动顺序现在是`0xf21`:
vcgencmd bootloader_config
有关配置Raspberry Pi 4 启动加载程序的更多详细信息,请参见 Raspberry Pi 4 启动加载程序配置.
以太网MAC地址
在配置网络启动之前,请记下序列号和 mac 地址,以便 TFTP/DHCP 服务器可以识别主板。
在Raspberry Pi 4 上,MAC 地址在制造时进行编程,MAC 地址和序列号之间没有链接。MAC 地址和序列号都显示在启动加载程序 HDMI 诊断 屏幕上。
要查找以太网 MAC 地址:
ethtool -P eth0
要查找序列号:
grep Serial /proc/cpuinfo | cut -d ' ' -f 2 | cut -c 8-16
服务器配置
将 SD 卡插入服务器Raspberry Pi,然后启动服务器。客户端 Raspberry Pi 需要一个根文件系统来引导:我们将使用服务器的根文件系统的副本并将其放在 /nfs/client1
中:
sudo mkdir -p /nfs/client1
sudo apt install rsync
sudo rsync -xa --progress --exclude /nfs / /nfs/client1
通过对客户机文件系统进行 chrooting 操作,在客户机文件系统上重新生成 SSH 主机密钥:
cd /nfs/client1
sudo mount --bind /dev dev
sudo mount --bind /sys sys
sudo mount --bind /proc proc
sudo chroot .
rm /etc/ssh/ssh_host_*
dpkg-reconfigure openssh-server
exit
sudo umount dev sys proc
查找本地网络的设置。您需要找到路由器(或网关)的地址,这可以通过以下方式完成:
ip route | awk '/default/ {print $3}'
然后运行:
ip -4 addr show dev eth0 | grep inet
这应该给出如下输出:
inet 10.42.0.211/24 brd 10.42.0.255 scope global eth0
第一个地址是网络上服务器Raspberry Pi的 IP 地址,斜杠后面的部分是网络大小。您的极有可能是 /24
。还要注意网络的 brd
(广播) 地址。 记下上一个命令的输出,该命令将包含Raspberry Pi的 IP 地址和网络的广播地址。
最后,记下 DNS 服务器的地址,该地址与网关的地址相同。您可以通过以下方式找到它:
cat /etc/resolv.conf
通过网络在服务器Raspberry Pi上配置静态网络地址,该网络用作 systemd
网络处理程序和DHCP服务器。
为此,您需要创建一个 10-eth0.netdev
和一个 11-eth0.network
,如下所示:
sudo nano /etc/systemd/network/10-eth0.netdev
添加以下行:
[Match] Name=eth0 [Network] DHCP=no
然后创建一个网络文件:
sudo nano /etc/systemd/network/11-eth0.network
添加以下内容:
[Match] Name=eth0 [Network] Address=10.42.0.211/24 DNS=10.42.0.1 [Route] Gateway=10.42.0.1
此时,您将没有有效的DNS,因此您需要将之前记下的服务器添加到 `systemd/resolved.conf`中。在本例中,网关地址是 10.42.0.1。
sudo nano /etc/systemd/resolved.conf
取消注释 DNS 行并在此处添加 DNS IP 地址。此外,如果您有回退 DNS 服务器,请将其也添加到该服务器。
[Resolve]
DNS=10.42.0.1
#FallbackDNS=
启用 systemd-networkd
并重新启动以使更改生效:
sudo systemctl enable systemd-networkd
sudo reboot
现在开始 tcpdump
,以便您可以从客户端Raspberry Pi搜索DHCP数据包:
sudo apt install tcpdump dnsmasq
sudo systemctl enable dnsmasq
sudo tcpdump -i eth0 port bootpc
将客户端Raspberry Pi连接到您的网络并打开电源。检查客户端上的 LED 是否在大约 10 秒后亮起,然后您应该从客户端收到一个数据包 "DHCP/BOOTP, 来自 …"
IP 0.0.0.0.bootpc > 255.255.255.255.bootps: BOOTP/DHCP, Request from b8:27:eb...
现在,您需要修改 dnsmasq
配置,使DHCP能够回复设备。按 CTRL + C 退出 tcpdump
程序,然后输入以下内容:
echo | sudo tee /etc/dnsmasq.conf
sudo nano /etc/dnsmasq.conf
然后将 dnsmasq.conf
的内容替换为:
# Note: comment out port if you want DNS services for systems on the network. port=0 dhcp-range=10.42.0.255,proxy log-dhcp enable-tftp tftp-root=/tftpboot pxe-service=0,"Raspberry Pi Boot"
在 dhcp-range
线路的第一个地址所在的地方,使用您之前记下的广播地址。
现在创建一个`/tftpboot` 目录:
sudo mkdir /tftpboot
sudo chmod 777 /tftpboot
sudo systemctl enable dnsmasq.service
sudo systemctl restart dnsmasq.service
现在监视 dnsmasq
日志:
tail -F /var/log/daemon.log
您应该看到如下所示的内容:
raspberrypi dnsmasq-tftp[1903]: file /tftpboot/bootcode.bin not found
接下来,您需要将引导文件夹的内容复制到 /tftpboot
目录中。
首先,按下 CTRL + C 退出监视状态。然后输入以下内容:
cp -r /boot/* /tftpboot
由于 tftp 位置已更改,请重新启动 dnsmasq
:
sudo systemctl restart dnsmasq
设置 NFS 根目录
现在,这应该允许您的 Raspberry Pi 客户端尝试启动,直到它尝试加载根文件系统(它没有)。
此时,导出之前创建的文件系统 /nfs/client1
和 TFTP 启动导文件夹。
sudo apt install nfs-kernel-server
echo "/nfs/client1 *(rw,sync,no_subtree_check,no_root_squash)" | sudo tee -a /etc/exports
echo "/tftpboot *(rw,sync,no_subtree_check,no_root_squash)" | sudo tee -a /etc/exports
重新启动 RPC-Bind 和 NFS 服务器,以便让它们检测新文件。
sudo systemctl enable rpcbind
sudo systemctl restart rpcbind
sudo systemctl enable nfs-kernel-server
sudo systemctl restart nfs-kernel-server
编辑 /tftpboot/cmdline.txt
和 root=
onwards,并将其替换为:
root=/dev/nfs nfsroot=10.42.0.211:/nfs/client1,vers=4.1,proto=tcp rw ip=dhcp rootwait
您应该将此处的 IP 地址替换为您记下的 IP 地址。同时删除以 init= 开头的命令行的任何部分。
最后,编辑 /nfs/client1/etc/fstab
并删除 /dev/mmcblk0p1
和 p2
行 (仅留下 proc
)。然后, 将启动分区添加回:
echo "10.42.0.211:/tftpboot /boot nfs defaults,vers=4.1,proto=tcp 0 0" | sudo tee -a /nfs/client1/etc/fstab
祝你好运!如果第一次尝试时无法启动,请继续尝试。Raspberry Pi可能需要一分钟左右才能启动,所以请耐心等待。
使用 pxetools
我们已经创建了一个Python脚本,用于在内部快速设置将进行网络启动的Raspberry Pi。
该脚本带有一个序列号(可以在 cat /proc/cpuinfo
中找到) 、一个所有者名称和Raspberry Pi的名称。 它从Raspberry Pi操作系统映像为该Raspberry Pi创建一个根文件系统。还有一个 --list
选项可以打印出Raspberry Pi的IP地址,还有一个 --remove
选项。
Note
|
以下说明描述了如何从新的Raspberry Pi操作系统精简版映像开始设置脚本所需的环境。最好安装硬盘或闪存驱动器/nfs,这样您的 SD 卡就不会向多个Raspberry Pi提供文件系统。这是留给读者的练习。 |
sudo apt update sudo apt full-upgrade -y sudo reboot wget https://datasheets.raspberrypi.com/soft/prepare_pxetools.sh bash prepare_pxetools
当系统提示保存 iptables`规则时,请说 `no
。
`prepare_pxetools` 脚本应该准备好使用 `pxetools` 所需的一切。
我们发现,在第一次使用 pxetools
之后,我们需要重新启动 nfs
服务器。使用以下工具执行此操作:
sudo systemctl restart nfs-kernel-server
然后插入你的 Raspberry Pi,它应该会启动。
使用 IPv6进行网络启动
Edit this on GitHub
通过网络启动Raspberry Pi计算机有 4 个阶段:
-
启动加载程序协商使用 DHCP 获取 TFTP 服务器的 IP 地址和详细信息。
-
启动加载程序通过 TFTP 加载固件,并将引导过程移交给固件,向其传递网络的详细信息。
-
固件通过 TFTP 加载内核和命令行。
-
内核启动系统的其余部分,通过 NFS 或其他机制加载根文件系统 (rootfs)。
启动加载程序和固件(阶段 1 到 3)已得到增强,以支持通过 IPv6 引导。
Important
|
IPv6 网络启动是一个 实验性 alpha 特性 ,根据反馈,我们可能需要在未来改变它的工作方式。这仅适用于Raspberry Pi 4 和处理器模块CM4。 |
工作原理
要通过 IPv6 启动,您需要更新版本的固件 (例如 start4.elf
) 和启动加载程序。使用Raspberry Pi OS的Bullseye版本和最新的稳定引导加载程序应该就足够了。
Note
|
常用的 dnsmasq DHCP服务器目前不支持IPv6网络引导所需的网络引导参数,因此暂时必须使用不同的DHCP服务器,例如 ISC DHCP。
|
要通过网络挂载 rootfs
, IPv4 网络启动教程 建议使 nfsroot
。这不支持IPv6,因此需要另一种方法来通过网络挂载 rootfs
。
如果您的ISP和路由器不支持IPv6,您将受到限制。
====网络地址
启动加载程序做的第一件事是发送路由器请求以获取网络的详细信息。路由器使用标识其以太网地址的通告数据包进行响应,如果 TFTP 服务器位于不同的网络上,启动加载程序可能需要该地址。
路由器通告包含一个标志,告诉它是对其 IP 地址使用有状态(托管)还是无状态(非托管)配置。无状态配置意味着设备配置自己的 IP 地址。目前,引导加载程序生成一个派生自其以太网 MAC 地址和路由器提供的网络前缀的地址。
如果路由器指示启用了有状态配置,则DHCP用于获取设备的IP地址。这涉及设备向DHCP服务器发送请求请求,该服务器以通告响应。然后,客户端在从服务器获得回复确认之前请求地址。
DHCP 服务器和客户端使用可变长度的 DUID(设备唯一 ID)标识自己。在Raspberry Pi上,这是从MAC地址(DUID_LL)派生的。
TFTP 地址
无论使用无状态还是有状态配置,DHCP服务器都用于获取TFTP服务器地址。这是在 BOOTFILE-URL
参数中编码的。我们发送客户端架构类型值 0x29
来标识设备。
参见 RFC 5970 and the IANA IPv6 动态主机配置协议 文档。
测试设置
如果你想尝试一下,你需要另一个Raspberry Pi来充当TFTP和DHCP服务器。
从理论上讲,TFTP 服务器可以位于任何可路由网络上,但 DHCP 服务器必须与它将服务的设备位于同一网络上。
TFTP 服务器
如果您有有效的 IPv4 网络引导设置,则可以在 dnsmasq 中重用 TFTP 服务器来提供文件(它可以与 IPv4 和 IPv6)。
或者,您也可以使用独立的 TFTP 服务器,例如 tftpd-hpa
。
$ sudo apt-get install tftpd-hpa
$ sudo systemctl start tftpd-hpa
DHCP 服务器
IPv6中的DHCP已经发生了很大变化。我们需要DHCP至少告诉我们TFTP服务器的地址,在这种情况下是同一台机器。
$ sudo apt-get install isc-dhcp-server
修改 /etc/default/isc-dhcp-server
中的配置
DHCPDv6_CONF=/etc/dhcp/dhcpd6.conf
INTERFACESv6="eth0"
在 /etc/dhcp/dhcpd6.conf
中,您需要指定TFTP服务器地址并设置一个子网。这里,DHCP服务器被配置为提供一些虚构的唯一本地地址(ULA)。主机 host test-rpi4
线路告诉DHCP给测试设备一个固定的地址。
not authoritative; # Check if the client looks like a Raspberry Pi if option dhcp6.client-arch-type = 00:29 { option dhcp6.bootfile-url "tftp://[fd49:869:6f93::1]/"; } subnet6 fd49:869:6f93::/64 { host test-rpi4 { host-identifier option dhcp6.client-id 00:03:00:01:e4:5f:01:20:24:0b; fixed-address6 fd49:869:6f93::1000; } }
您的服务器必须在 /etc/dhcpcd.conf
中分配 IPv6 地址。
interface eth0 static ip6_address=fd49:869:6f93::1/64
现在启动 DHCP 服务器。
$ sudo systemctl restart isc-dhcp-server.service
启动加载程序
修改配置以告知它尝试通过 IPv6 而不是 IPv4 进行网络引导。
BOOT_ORDER=0xf21 # 2=Network boot USE_IPV6=1 # Enable IPv6 network boot BOOT_UART=1 # Debug
要恢复到 IPv4 网络引导,只需从 boot.conf
中删除 USE_IPV6
行。
路由器
要使用IPv6,您确实需要一个支持IPv6的路由器和ISP。互联网上有一些网站可以为您检查这一点,或者运行以下命令。
sudo apt-get install ndisc6
rdisc6 -1 eth0
这会向路由器发送路由器请求,询问您的网络详细信息,例如网络前缀、路由器以太网地址以及是否使用 DHCP 进行寻址。如果对此命令没有响应,则可能是您的网络和ISP仅支持IPv4。如果支持 IPv6,则很可能将其配置为使用无状态配置,其中客户端生成自己的地址。
Soliciting ff02::2 (ff02::2) on eth0... Hop limit : 64 ( 0x40) Stateful address conf. : No Stateful other conf. : Yes Mobile home agent : No Router preference : medium Neighbor discovery proxy : No Router lifetime : 180 (0x000000b4) seconds Reachable time : unspecified (0x00000000) Retransmit time : unspecified (0x00000000)
您可能能够将路由器配置为有状态配置,这意味着它将使用 DHCP 获取 IP 地址。
Hop limit : 64 ( 0x40) Stateful address conf. : Yes Stateful other conf. : Yes Mobile home agent : No Router preference : medium Neighbor discovery proxy : No Router lifetime : 180 (0x000000b4) seconds Reachable time : unspecified (0x00000000) Retransmit time : unspecified (0x00000000)
调试
日志和跟踪
如果启用了引导uart,您应该从串行端口看到类似的东西。以 RX6 开头的行表示正在使用 IPv6。
这里 dc:a6:32:6f:73:f4
是TFTP服务器的MAC地址,其IPv6地址为 fd49:869:6f93::1
。设备本身具有MAC地址 e4:5f:01:20:24:0b
和IPv6地址 fd49:869:6f93::1000
。
Boot mode: NETWORK (02) order f GENET: RESET_PHY PHY ID 600d 84a2 NET_BOOT: e4:5f:01:20:24:0b wait for link TFTP6: (null) LINK STATUS: speed: 100 full duplex Link ready GENET START: 64 16 32 GENET: UMAC_START 0xe45f0120 0x240b0000 RX6: 12 IP: 1 MAC: 1 ICMP: 1/1 UDP: 0/0 ICMP_CSUM_ERR: 0 UDP_CSUM_ERR: 0 NET fd49:869:6f93::1000 tftp fd49:869:6f93::1 RX6: 17 IP: 4 MAC: 4 ICMP: 2/2 UDP: 2/2 ICMP_CSUM_ERR: 0 UDP_CSUM_ERR: 0 TFTP_GET: dc:a6:32:6f:73:f4 fd49:869:6f93::1 ab5a4158/start4.elf RX6: 17 IP: 4 MAC: 4 ICMP: 2/2 UDP: 2/2 ICMP_CSUM_ERR: 0 UDP_CSUM_ERR: 0 RX6: 18 IP: 5 MAC: 5 ICMP: 2/2 UDP: 3/3 ICMP_CSUM_ERR: 0 UDP_CSUM_ERR: 0 TFTP_GET: dc:a6:32:6f:73:f4 fd49:869:6f93::1 ab5a4158/config.txt
最后,引导加载程序移交给应该加载内核的固件。
有状态配置
您可以使用 tcpdump 检查网络活动。
$ sudo tcpdump -i eth0 -e ip6 -XX -l -v -vv
下面是 TCP 转储的摘录,其中路由器配置为使用有状态 (DHCP) 网络配置。
设备发送路由器请求。
12:23:35.387046 e4:5f:01:20:24:0b (oui Unknown) > 33:33:00:00:00:02 (oui Unknown), ethertype IPv6 (0x86dd), length 70: (hlim 255, next-header ICMPv6 (58) payload length: 16) fe80::e65f:1ff:fe20:240b > ip6-allrouters: [icmp6 sum ok] ICMP6, router solicitation, length 16 source link-address option (1), length 8 (1): e4:5f:01:20:24:0b 0x0000: e45f 0120 240b
路由器发送响应,告知设备使用有状态配置。
12:23:35.498902 60:8d:26:a7:c1:88 (oui Unknown) > 33:33:00:00:00:01 (oui Unknown), ethertype IPv6 (0x86dd), length 110: (hlim 255, next-header ICMPv6 (58) payload length: 56) bthub.home > ip6-allnodes: [icmp6 sum ok] ICMP6, router advertisement, length 56 hop limit 64, Flags [managed, other stateful], pref medium, router lifetime 180s, reachable time 0ms, retrans timer 0ms rdnss option (25), length 24 (3): lifetime 60s, addr: bthub.home 0x0000: 0000 0000 003c fe80 0000 0000 0000 628d 0x0010: 26ff fea7 c188 mtu option (5), length 8 (1): 1492 0x0000: 0000 0000 05d4 source link-address option (1), length 8 (1): 60:8d:26:a7:c1:88 0x0000: 608d 26a7 c188
设备发送 DHCP 请求。
12:23:35.502517 e4:5f:01:20:24:0b (oui Unknown) > 33:33:00:01:00:02 (oui Unknown), ethertype IPv6 (0x86dd), length 114: (hlim 255, next-header UDP (17) payload length: 60) fe80::e65f:1ff:fe20:240b.dhcpv6-client > ff02::1:2.dhcpv6-server: [udp sum ok] dhcp6 solicit (xid=8cdd56 (client-ID hwaddr type 1 e45f0120240b) (IA_NA IAID:0 T1:0 T2:0) (option-request opt_59) (opt_61) (elapsed-time 0))
DHCP 服务器回复播发。
12:23:35.510478 dc:a6:32:6f:73:f4 (oui Unknown) > e4:5f:01:20:24:0b (oui Unknown), ethertype IPv6 (0x86dd), length 172: (flowlabel 0xad54d, hlim 64, next-header UDP (17) payload length: 118) fe80::537a:52c:c647:b184.dhcpv6-server > fe80::e65f:1ff:fe20:240b.dhcpv6-client: [bad udp cksum 0xd886 -> 0x6d26!] dhcp6 advertise (xid=8cdd56 (IA_NA IAID:0 T1:3600 T2:7200 (IA_ADDR fd49:869:6f93::1000 pltime:604800 vltime:2592000)) (client-ID hwaddr type 1 e45f0120240b) (server-ID hwaddr/time type 1 time 671211709 dca6326f73f4) (opt_59))
设备向 DHCP 服务器发送地址和 TFTP 详细信息请求。
12:23:35.510763 e4:5f:01:20:24:0b (oui Unknown) > 33:33:00:01:00:02 (oui Unknown), ethertype IPv6 (0x86dd), length 132: (hlim 255, next-header UDP (17) payload length: 78) fe80::e65f:1ff:fe20:240b.dhcpv6-client > ff02::1:2.dhcpv6-server: [udp sum ok] dhcp6 request (xid=8cdd56 (client-ID hwaddr type 1 e45f0120240b) (server-ID hwaddr/time type 1 time 671211709 dca6326f73f4) (IA_NA IAID:0 T1:0 T2:0) (option-request opt_59) (opt_61) (elapsed-time 1))
DHCP 服务器回复, opt_59
用于传递 TFTP 服务器的地址。
12:23:35.512122 dc:a6:32:6f:73:f4 (oui Unknown) > e4:5f:01:20:24:0b (oui Unknown), ethertype IPv6 (0x86dd), length 172: (flowlabel 0xad54d, hlim 64, next-header UDP (17) payload length: 118) fe80::537a:52c:c647:b184.dhcpv6-server > fe80::e65f:1ff:fe20:240b.dhcpv6-client: [bad udp cksum 0xd886 -> 0x6826!] dhcp6 reply (xid=8cdd56 (IA_NA IAID:0 T1:3600 T2:7200 (IA_ADDR fd49:869:6f93::1000 pltime:604800 vltime:2592000)) (client-ID hwaddr type 1 e45f0120240b) (server-ID hwaddr/time type 1 time 671211709 dca6326f73f4) (opt_59))
设备向 FTP 服务器发送邻居请求,因为它需要其 MAC 地址。
12:23:36.510768 e4:5f:01:20:24:0b (oui Unknown) > 33:33:ff:00:00:01 (oui Unknown), ethertype IPv6 (0x86dd), length 86: (hlim 255, next-header ICMPv6 (58) payload length: 32) fe80::e65f:1ff:fe20:240b > ff02::1:ff00:1: [icmp6 sum ok] ICMP6, neighbor solicitation, length 32, who has fd49:869:6f93::1 source link-address option (1), length 8 (1): e4:5f:01:20:24:0b 0x0000: e45f 0120 240b
FTP 服务器使用其 MAC 地址进行回复。
12:23:36.510854 dc:a6:32:6f:73:f4 (oui Unknown) > e4:5f:01:20:24:0b (oui Unknown), ethertype IPv6 (0x86dd), length 86: (hlim 255, next-header ICMPv6 (58) payload length: 32) fd49:869:6f93::1 > fe80::e65f:1ff:fe20:240b: [icmp6 sum ok] ICMP6, neighbor advertisement, length 32, tgt is fd49:869:6f93::1, Flags [solicited, override] destination link-address option (2), length 8 (1): dc:a6:32:6f:73:f4 0x0000: dca6 326f 73f4
TFTP 请求由现在应通过网络启动的设备发出。
12:23:36.530820 e4:5f:01:20:24:0b (oui Unknown) > dc:a6:32:6f:73:f4 (oui Unknown), ethertype IPv6 (0x86dd), length 111: (hlim 255, next-header UDP (17) payload length: 57) fd49:869:6f93::1000.61785 > fd49:869:6f93::1.tftp: [udp sum ok] 49 RRQ "ab5a4158/start4.elf" octet tsize 0 blksize 1024
无状态配置
下面是无状态(非 DHCP)网络配置的 tcp 转储摘录。
设备发送路由器请求。
12:55:27.541909 e4:5f:01:20:24:0b (oui Unknown) > 33:33:00:00:00:02 (oui Unknown), ethertype IPv6 (0x86dd), length 70: (hlim 255, next-header ICMPv6 (58) payload length: 16) fe80::e65f:1ff:fe20:240b > ip6-allrouters: [icmp6 sum ok] ICMP6, router solicitation, length 16 source link-address option (1), length 8 (1): e4:5f:01:20:24:0b 0x0000: e45f 0120 240b
路由器回复网络详细信息。
12:55:27.834684 60:8d:26:a7:c1:88 (oui Unknown) > 33:33:00:00:00:01 (oui Unknown), ethertype IPv6 (0x86dd), length 174: (hlim 255, next-header ICMPv6 (58) payload length: 120) bthub.home > ip6-allnodes: [icmp6 sum ok] ICMP6, router advertisement, length 120 hop limit 64, Flags [other stateful], pref medium, router lifetime 180s, reachable time 0ms, retrans timer 0ms prefix info option (3), length 32 (4): 2a00:23c5:ee00:5001::/64, Flags [onlink, auto, router], valid time 300s, pref. time 120s 0x0000: 40e0 0000 012c 0000 0078 0000 0000 2a00 0x0010: 23c5 ee00 5001 0000 0000 0000 0000 prefix info option (3), length 32 (4): fd4d:869:6f93::/64, Flags [onlink, auto, router], valid time 10080s, pref. time 2880s 0x0000: 40e0 0000 2760 0000 0b40 0000 0000 fd4d 0x0010: 0869 6f93 0000 0000 0000 0000 0000 rdnss option (25), length 24 (3): lifetime 60s, addr: bthub.home 0x0000: 0000 0000 003c fe80 0000 0000 0000 628d 0x0010: 26ff fea7 c188 mtu option (5), length 8 (1): 1492 0x0000: 0000 0000 05d4 source link-address option (1), length 8 (1): 60:8d:26:a7:c1:88 0x0000: 608d 26a7 c188
设备向 DHCP 组播地址发送信息请求,要求提供 TFTP 详细信息。
12:55:27.838300 e4:5f:01:20:24:0b (oui Unknown) > 33:33:00:01:00:02 (oui Unknown), ethertype IPv6 (0x86dd), length 98: (hlim 255, next-header UDP (17) payload length: 44) fe80::e65f:1ff:fe20:240b.dhcpv6-client > ff02::1:2.dhcpv6-server: [udp sum ok] dhcp6 inf-req (xid=e5e0a4 (client-ID hwaddr type 1 e45f0120240b) (option-request opt_59) (opt_61) (elapsed-time 0))
DHCP 服务器回复 TFTP 服务器详细信息 (opt_59
)。
12:55:27.838898 dc:a6:32:6f:73:f4 (oui Unknown) > e4:5f:01:20:24:0b (oui Unknown), ethertype IPv6 (0x86dd), length 150: (flowlabel 0xd1248, hlim 64, next-header UDP (17) payload length: 96) fe80::537a:52c:c647:b184.dhcpv6-server > fe80::e65f:1ff:fe20:240b.dhcpv6-client: [bad udp cksum 0xd870 -> 0x78bb!] dhcp6 reply (xid=e5e0a4 (client-ID hwaddr type 1 e45f0120240b) (server-ID hwaddr/time type 1 time 671211709 dca6326f73f4) (opt_59))
设备要求输入 TFTP 服务器 MAC 地址,因为它可以判断它位于同一网络上。
12:55:28.834796 e4:5f:01:20:24:0b (oui Unknown) > 33:33:ff:1d:fe:2a (oui Unknown), ethertype IPv6 (0x86dd), length 86: (hlim 255, next-header ICMPv6 (58) payload length: 32) fe80::e65f:1ff:fe20:240b > ff02::1:ff1d:fe2a: [icmp6 sum ok] ICMP6, neighbor solicitation, length 32, who has 2a00:23c5:ee00:5001:57f1:7523:2f1d:fe2a source link-address option (1), length 8 (1): e4:5f:01:20:24:0b 0x0000: e45f 0120 240b
FTP 服务器使用其 MAC 地址进行回复。
12:55:28.834875 dc:a6:32:6f:73:f4 (oui Unknown) > e4:5f:01:20:24:0b (oui Unknown), ethertype IPv6 (0x86dd), length 86: (hlim 255, next-header ICMPv6 (58) payload length: 32) 2a00:23c5:ee00:5001:57f1:7523:2f1d:fe2a > fe80::e65f:1ff:fe20:240b: [icmp6 sum ok] ICMP6, neighbor advertisement, length 32, tgt is 2a00:23c5:ee00:5001:57f1:7523:2f1d:fe2a, Flags [solicited, override] destination link-address option (2), length 8 (1): dc:a6:32:6f:73:f4 0x0000: dca6 326f 73f4
设备开始发出 TFTP 请求。
12:55:28.861097 e4:5f:01:20:24:0b (oui Unknown) > dc:a6:32:6f:73:f4 (oui Unknown), ethertype IPv6 (0x86dd), length 111: (hlim 255, next-header UDP (17) payload length: 57) 2a00:23c5:ee00:5001:e65f:1ff:fe20:240b.46930 > 2a00:23c5:ee00:5001:57f1:7523:2f1d:fe2a.tftp: [udp sum ok] 49 RRQ "ab5a4158/start4.elf" octet tsize 0 blksize 1024