Remote access

远程访问简介

有时,您需要在不连接显示器的情况下访问Raspberry Pi。也许Raspberry Pi被嵌入到类似机器人的东西中,或者您可能想从其他地方查看它的一些信息。或者你根本没有备用显示器!

您可以从另一台机器连接到Raspberry Pi。但为了做到这一点,你需要知道它的IP地址。

任何连接到局域网的设备都会被分配一个IP地址。为了使用 SSHVNC从另一台机器连接到您的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

  • macOSWindows 上安装, 参见 nmap.org 下载页面

要使用 nmap 扫描网络上的设备,您需要知道您所连接的子网。首先找到你自己的IP地址,换句话说就是你用来找到你的Raspberry Pi的IP地址的那台电脑的IP地址:

  • Linux 上,在终端窗口中输入 hostname -I

  • macOS 上, 选择您的活动网络连接,以查看IP地址 系统首选项 网络

  • Windows 上, 转到控制面板,然后在下 网络和共享中心 下单击 查看网络连接 ,选择你的网络连接并单击 查看连接状态 来查看IP地址。

现在您有了计算机的IP地址,您将扫描整个子网寻找其它设备。例如,如果您的IP地址是 192.168.1.5, ,其他设备将位于 192.168.1.2192.168.1.3192.168.1.4`等地址。 此子网范围是 `192.168.1.0/24 (包括 192.168.1.0192.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-allnodesipv6-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:~ $

通过你的智能手机获取Raspberry Pi的IP地址

Fing应用程序是一款免费的智能手机网络扫描仪。 在 AndroidiOS 系统中均可以使用。

您的手机和您的Raspberry Pi必须在同一个网络上,因此请将您的手机连接到正确的无线网络。

打开Fing应用程序时,触摸屏幕右上角的刷新按钮。几秒钟后,您将获得一个列表,其中包含连接到您网络的所有设备。向下滚动到制造商为 "Raspberry Pi" 的条目。您将在条目的左下角看到IP地址,在右下角看到MAC地址。

设置SSH 服务器

您可以使用安全shell(SSH)协议从同一网络上的另一台计算机或设备远程访问Raspberry Pi的命令行。

您只能访问命令行,而不能访问整个桌面环境。如需完整的远程桌面,请参见 VNC

设置本地网络

确定您的Raspberry Pi已正确设置和连接。如果您使用无线网络,可以通过桌面用户界面或从命令行使用来启用。如果您不使用无线连接,请将您的Raspberry Pi直接插入路由器。

Note
您需要记下您的Raspberry Pi的IP地址,以便以后连接到它。使用 ifconfig 命令将显示有关当前网络状态的信息,包括IP地址,或者您可以使用 hostname -I 来显示与设备相关联的IP地址。

启用服务器Server

Raspberry Pi OS默认禁用SSH服务器。可以从桌面手动启用它:

  1. Preferences 菜单启动 Raspberry Pi Configuration

  2. 导航至 Interfaces 选项卡

  3. 选择 Enabled 旁边的 SSH

  4. 单击 OK

或者,您可以使用 raspi-config 应用程序从终端启用它,

  1. 在终端窗口输入 sudo raspi-config

  2. 选择 Interfacing Options

  3. 导航并选择 SSH

  4. 选择 Yes

  5. 选择 Ok

  6. 选择 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

您可以使用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
Note
默认情况下, macOS上不再安装X11, 因此你必须 下载 并安装它。

现在您像以前一样在命令行上,但是您能够打开图形窗口。例如,输入:

geany &

将在本地桌面的窗口中打开Geany编辑器。

来自 Windows 10的Shell

您可以使用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访问

可以将您的Raspberry Pi配置为允许从另一台计算机访问,而无需在每次连接时提供密码。为此,您需要使用SSH密钥而不是密码。要生成SSH密钥:

检查现有的 SSH 密钥

首先,检查您用来连接Raspberry Pi的计算机上是否已经有密钥:

ls ~/.ssh

如果您看到名为 id_rsa.pubid_dsa.pub 的文件,那么您已经设置了密钥,因此您可以跳过下面的 '生成新的SSH密钥' 操作步骤。

生成新的SSH密钥

要生成新的SSH密钥,请输入以下命令:

ssh-keygen

输入该命令后,将询问您保存密钥的位置。我们建议将其保存在默认位置 (~/.ssh/id_rsa) 。

您还将被要求输入一个密码,这是可选的。密码短语用于加密私有SSH密钥,这样,如果其他人复制了密钥,他们就无法冒充您来获得访问权限。如果您选择使用密码,请在此处键入并按 `Enter`键,然后在出现提示时再次键入。如果没有密码,请将该字段留空。

现在看看你的 .ssh 目录:

ls ~/.ssh

您应该会看到文件 id_rsaid_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开始 -K 标志已被弃用,并被 --apple-use-keychain 标志所取代。

使用安全拷贝

安全复制 (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/

从 Raspberry Pi复制文件

myfile.txt 从您的Raspberry Pi复制到另一台计算机上的当前目录:

scp pi@192.168.1.3:myfile.txt .

复制多个文件

通过用空格分隔来复制多个文件:

scp myfile.txt myfile2.txt pi@192.168.1.3:

或者,使用通配符复制符合特定搜索的所有文件:

scp *.txt pi@192.168.1.3:

(所有文件都以 .txt 结尾)

scp m* pi@192.168.1.3:

(所有以 m 开头的文件)

scp m*.txt pi@192.168.1.3:

(所有文件以 m 开头和以 .txt 结尾)

Note

上面的一些例子不适用于包含空格的文件名。像这样的名字需要用引号括起来:

scp "my file.txt" pi@192.168.1.3:

复制整个目录

使用以下命令将目录 project/ 从你的计算机复制到位于IP地址 192.168.1.3 的Raspberry Pi 的 pi 用户主文件夹中:

scp -r project/ pi@192.168.1.3:

Using rsync

您可以使用 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)

网络文件系统(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服务器相关的配置文件:

  1. /etc/default/nfs-kernel-server

  2. /etc/default/nfs-common

  3. /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 。如果您不确定,请通过以下命令检查是否为 nobodynogroup

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 可能会报错它找不到挂载。

端口映射锁定(可选)

将下面一行添加到 `/etc/hosts.deny`中:

rpcbind : ALL

通过首先阻止所有客户端,只有 /etc/hosts.allow (添加在下面) 中的客户端才被允许访问服务器。

现在将下面一行添加到 /etc/hosts.allow 中:

rpcbind : <NFS server IP address>

其中 <NFS 服务器IP地址> 是服务器IP地址。

更复杂的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 时,你都需要运行这个命令。

重启服务

默认情况下, rpcbind 只绑定到环回接口。要允许从远程机器访问 rpcbind ,您需要更改 /etc/conf.d/rpcbind 以删除 -l-i 127.0.0.1

如果进行了任何更改,rpcbind和NFS将需要重新启动:

sudo systemctl restart rpcbind
sudo systemctl restart nfs-kernel-server

要考虑的安全项目

除了上面讨论的UID问题,应该注意的是,攻击者可能伪装成被允许映射共享的机器,这允许他们创建任意UID来访问您的文件。一个潜在的解决方案是IPSec。您可以设置您的所有域成员只通过IPSec相互通信,这将有效地验证您的客户端就是它所说的那个人。

IPSec 的工作原理是使用服务器的公钥加密发往服务器的流量,服务器发回使用客户端公钥加密的所有回复。流量使用相应的私钥解密。如果客户端没有它应该拥有的密钥,则无法发送或接收数据。

IPSec的替代方案是物理上独立的网络。这需要单独的网络交换机和单独的以太网卡,以及该网络的物理安全性。

故障排除

只有在成功登录并且您的主目录被解密后,在加密的主目录中挂载 NFS 共享才有效。这意味着使用 /etc/fstab 在启动时挂载 NFS 共享将不起作用,因为您的家在挂载时尚未解密。使用符号链接有一个简单的解决方法:

  1. 创建一个备用目录以挂载 NFS 共享:

sudo mkdir /nfs
sudo mkdir /nfs/music
  1. 编辑 /etc/fstab 以将 NFS 共享挂载到该目录中:

nfsServer:music    /nfs/music    nfs    auto    0 0
  1. 在家中创建一个符号链接,指向实际的安装位置。例如,在这种情况下,首先删除 Music 那里已经存在的目录:

rmdir /home/user/Music
ln -s /nfs/music/ /home/user/Music

Samba (SMB/CIFS)

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设备上共享一个文件夹。这是一个相当复杂的过程!

开启共享

  1. 打开网络和共享中心,方法是右键单击系统菜单并选择它

  2. 单击 Change advanced sharing settings

  3. 选择 Turn on network discovery

  4. 选择 Turn on file and printer sharing

  5. 保存更改

共享文件夹

您可以共享所需的任何文件夹,但对于此示例,只需创建一个名为 `share`的文件夹。

  1. 在桌面上创建文件夹 share

  2. 右键单击此文件夹然后选择 Properties.

  3. 单击 Sharing 页签, 然后选择 Advanced Sharing 按键

  4. 选择 Share this folder; 默认情况下,共享名称是文件夹的名称

  5. 单击 Permissions 按键

  6. 6. 对于此示例,请选择 EveryoneFull Control (如果需要,可以将访问权限限制为特定用户); 完成后单击 OK w, 然后再次单击 OK 以离开 Advanced Sharing 页面

  7. 单击 Security 页签, 因为我们现在需要配置相同的权限

  8. 选择与 Permissions 页签相同的设置, 并在必要时添加所选用户

  9. 单击 OK

该文件夹现在应该已共享。

Windows 10 共享向导

在 Windows 10 上,有一个共享向导可以帮助完成其中一些步骤。

  1. 从“开始”栏运行“计算机管理”应用程序

  2. 选择 共享文件夹 文件夹, 然后选择 共享

  3. 右键单击并选择 新建共享, 这将启动共享向导;单击 下一步

  4. 选择要共享的文件夹,然后单击 下一步

  5. 单击 下一步 以使用所有共享默认值

  6. 选择 自定义 并设置所需的权限,然后选择 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)

有时直接在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 服务器

  • 在Raspberry Pi上,启动到图形桌面。

  • 选择 Menu  Preferences  Raspberry Pi Configuration  Interfaces.

  • 确保已 启用 VNC

以命令行方式启用VNC服务器

您可以使用 raspi-config在命令行启用 VNC 服务器:

sudo raspi-config

现在,通过执行以下操作启用 VNC 服务器:

  • 导航至 Interfacing Options

  • 向下滚动并选择 VNC  Yes

连接到 Raspberry Pi

有两种方法可以连接到Raspberry Pi。您可以使用其中之一或两者,具体取决于最适合您的方法。

建立直接连接

直接连接既快速又简单,前提是您加入与Raspberry Pi相同的专用本地网络。例如,这可能是家中、学校或办公室中的有线或无线网络。

  • 在Raspberry Pi (使用终端窗口或通过SSH), 使用e 这些说明 或运行 ifconfig 以发现你的私有IP地址。

  • 在您将用于控制的设备上,下载 VNC 查看器。 为了获得最佳效果,请使用RealVNC的 兼容性应用程序

  • 在VNC查看器中输入Raspberry Pi的私有IP地址:

建立云连接

您有权免费使用RealVNC的云服务,前提是远程访问仅用于教育或非商业目的。

云连接方便且端到端加密。强烈建议使用它们通过互联网连接到Raspberry Pi。没有防火墙或路由器重新配置,您不需要知道Raspberry Pi的 IP 地址,也不需要提供静态地址。

  • 注册一个 RealVNC 账户 : 它是免费的,只需要几秒钟。

  • 在Raspberry Pi上使用新的 RealVNC 帐户凭据登录 VNC 服务器:

  • 在您将用于控制的设备上,下载 VNC 查看器。您 必须 使用RealVNC的 兼容性应用程序

  • 使用相同的 RealVNC 帐户凭据登录 VNC 查看器,然后点击或单击以连接到您的Raspberry Pi:

向 VNC 服务器进行身份验证

要完成直接连接或云连接,您必须向 VNC 服务器进行身份验证。

如果您从 RealVNC 兼容的VNC Viewer 应用程序 进行连接,请输入您通常用于登录 Raspberry Pi 上的用户帐户的用户名和密码。默认情况下,这些凭据是 piraspberry

如果您从非 RealVNC Viewer 应用程序进行连接,则首先需要降级 VNC 服务器的身份验证方案,指定 VNC Server 独有的密码,然后输入该密码。

  •  如果您在Raspberry Pi前面并且可以看到其屏幕,请打开Raspberry Pi上的 VNC 服务器对话框,选择 Menu  Options  Security, 再从 Authentication 下拉列表中选择 VNC password

  • 或者 如果您要从命令行远程配置Raspberry Pi,则要对服务模式(Raspberry Pi的默认配置)进行更改:

    • 打开 /root/.vnc/config.d/vncserver-x11 配置文件。

    • 替换 Authentication=SystemAuthAuthentication=VncAuth 并保存文件。

    • 在命令行中运行 sudo vncpasswd -service。这将提示您设置密码,并将其插入到以服务模式运行的VNC服务器的正确配置文件中。

    • 重启 VNC 服务器。

使用直接呈现的应用程序

您可以远程访问使用直接渲染叠加的应用程序,例如:文本控制台、Raspberry Pi相机模块等。

要启用此功能,请执行以下操作:

  • 在Raspberry Pi上, 打开 VNC 服务器对话框。

  • 导航至 Menu  Options  Troubleshooting 并选择 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 服务器

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 success message

这意味着你有 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

您可以设置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.txtroot= 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/mmcblk0p1p2 行 (仅留下 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进行网络启动

通过网络启动Raspberry Pi计算机有 4 个阶段:

  1. 启动加载程序协商使用 DHCP 获取 TFTP 服务器的 IP 地址和详细信息。

  2. 启动加载程序通过 TFTP 加载固件,并将引导过程移交给固件,向其传递网络的详细信息。

  3. 固件通过 TFTP 加载内核和命令行。

  4. 内核启动系统的其余部分,通过 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

要通过网络挂载 rootfsIPv4 网络启动教程 建议使 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 动态主机配置协议 文档。

启动过程

该设备现在应该有一个IP地址和TFTP详细信息。它从TFTP服务器下载固件二进制start4.elf并继续运行。固件被传递了IP地址和TFTP服务器的详细信息,因此它可以下载内核并引导系统的其余部分。

内核启动

对于IPv4网络启动, nfsroot 用于通过网络挂载 rootfs 。这不支持IPv6,因此需要另一种解决方案。它可能涉及一个小的RAM文件系统,可以在切换到适当的 rootfs 内容之前挂载适当的网络位置。

Note
通过IPv6使用NFS启动Linux内核的机制仍有待证明。

测试设置

如果你想尝试一下,你需要另一个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