pATAq 发表于 2024-6-14 21:17:46

跟思兼学Klipper(32):修复 CrealityOS IP 地址经常改变的问题

本帖最后由 pATAq 于 2024-6-14 21:19 编辑

址经常改变的问题

# 前言

原创文章,转载引用务必著名链接,水平有限,如有疏漏,欢迎指正交流。

文章如有更新请访问 (https://mc.dfrobot.com.cn/thread-319347-1-1.html?fromuid=725344)及 (https://www.cnblogs.com/sjqlwy/p/cos_fix_ip.html),前者内容较全,后者排版及阅读体验更佳。

使用 K1C 时有个问题,过个一天或者一段时间再开机它的IP地址会发生改变,很是恼人。本文试图探究可能的原因及多种解决方法。

软硬件测试环境:

* Creality K1C 3D 打印机
* CrealityOS,以下简称CoS

本文涉及的内容:

* DHCP 基础知识

![](https://www.ecured.cu/images/2/23/ISC-DHCP-SERVER_logo.png)

# 1、常见解决方法

1. **使用 mdns**

   CoS会启动一个精简版的 mdns 服务,地址为 .local,不论设备 IP 地址如何改变,此域名不变。目前测试 OrcaSlicer、MobaXterm 可以使用,但是网页打不开也 ping 不通。

2. **绑定 MAC 地址**

   在路由器中,将设备网卡 MAC 地址和指定 IP 地址绑定。但是有些朋友没有路由器管理权。

3. **设置静态 IP 地址**

   在设备上设置静态 IP 地址而非从 DHCP 服务器上自动获取 IP 地址,但是存在设备地址冲突的可能,同时更换不同网段的网络时会出问题。

# 2、可能的原因

查看 CoS 相关服务,`/etc/init.d/S44wifi_bcm_up` ——> `/usr/bin/wifi_up.sh` ,可以看到 CoS 使用 `udhcpc -i wlan0 -x hostname:$(hostname) &`来从 DHCP 服务器处获取网络配置。我默认由 BusyBox 自带的 udhcpc 背锅,怀疑没有正确续约。当然之前也怀疑过无线网卡 MAC 地址变化导致,观察后排除。

# 3、可能的解决方法:使用 dhclient 取代 udhcpc

**前提**:需要启用 root 后安装 chs,并安装 entware 软件仓库

```shell
# 安装 dhclient
sed -i.bak 's|https\?://bin.entware.net|http://mirrors.cernet.edu.cn/entware|g' /opt/etc/opkg.conf
opkg update
opkg install isc-dhcp-client-ipv4

# 创建租约文件及 resolv.conf 软链接
mkdir /opt/var/db/ && touch /opt/var/db/dhclient.leases
ln -sf /etc/resolv.conf /opt/etc/resolv.conf

# 修改默认 dhcp 客户端程序
# 注释 udhcpc -i wlan0 -x hostname:$(hostname) &
# 在其下添加一行:/opt/sbin/dhclient -nw -v --no-pid wlan0
sed -i '/hostname:/s/^/# /' /usr/bin/wifi_up.sh
sed -i '/hostname:/a \    /opt/sbin/dhclient -nw --no-pid wlan0' /usr/bin/wifi_up.sh

# 重启生效
```

# 4、与 DHCP 服务器交互过程

```shell
root@K1Max-5BC9 /root [#] dhclient -v wlan0
Internet Systems Consortium DHCP Client 4.4.3-P1
Copyright 2004-2022 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/

Listening on LPF/wlan0/fc:ee:28:01:5b:c9
Sending on   LPF/wlan0/fc:ee:28:01:5b:c9
Sending on   Socket/fallback
# Client:DHCP 发现
DHCPDISCOVER on wlan0 to 255.255.255.255 port 67 interval 6
# Server: DHCP 提供
DHCPOFFER of 192.168.0.118 from 192.168.0.1
# Client: DHCP 请求/续租
DHCPREQUEST for 192.168.0.118 on wlan0 to 255.255.255.255 port 67
# Server: DHCP 确认
DHCPACK of 192.168.0.118 from 192.168.0.1

bound to 192.168.0.118 -- renewal in 3173 seconds.
```

`udhcpc` 是一个简单的 DHCP 客户端,用于在 Unix-like 系统上自动获取网络配置。以下是 `udhcpc` 续租 IP 地址的基本步骤和原理:

1. **DHCP 发现(DHCPDISCOVER)**:

\- 当 `udhcpc` 启动时,它会发送一个 DHCPDISCOVER 广播消息,以发现网络上可用的 DHCP 服务器。

2. **DHCP 提供(DHCPOFFER)**:

\- DHCP 服务器收到 DHCPDISCOVER 消息后,会发送一个 DHCPOFFER 消息,提供给客户端一个 IP 地址和其他网络配置信息。

3. **DHCP 请求(DHCPREQUEST)**:

\- `udhcpc` 收到 DHCPOFFER 消息后,会发送 DHCPREQUEST 消息,请求分配提供的 IP 地址。

4. **DHCP 确认(DHCPACK)**:

\- 如果 DHCP 服务器确认请求,它会发送一个 DHCPACK 消息,正式分配 IP 地址和相关配置。

5. **续租(DHCPREQUEST)**:

\- 在租期过半(通常为50%)时,`udhcpc` 会自动发送 DHCPREQUEST 消息给之前分配 IP 地址的 DHCP 服务器,请求续租当前的 IP 地址。

6. **续租成功或失败**:

\- 如果 DHCP 服务器响应 DHCPACK,表示续租成功,租期将被重置。
\- 如果 DHCP 服务器响应 DHCPNACK,表示续租失败,`udhcpc` 将重新发送 DHCPDISCOVER 消息以获取新的 IP 地址。

7. **租期结束**:

\- 如果在租期结束前没有收到 DHCP 服务器的响应,`udhcpc` 将放弃当前 IP 地址,并重新进入 DHCP 发现阶段。

8. **释放 IP 地址(DHCPRELEASE)**:

\- 如果用户希望主动放弃 IP 地址,`udhcpc` 可以发送 DHCPRELEASE 消息给 DHCP 服务器,释放当前的 IP 地址。

`udhcpc` 的续租行为通常是自动的,不需要用户干预。但是,用户可以通过配置文件或命令行参数来调整续租行为,例如设置租期长度或禁用自动续租。

如果您发现 `udhcpc` 没有续租 IP 地址,可能的原因包括:

\- DHCP 服务器没有响应续租请求。
\- 网络配置问题导致 `udhcpc` 无法与 DHCP 服务器通信。
\- `udhcpc` 配置错误或版本问题。
\- 系统防火墙或安全设置阻止了 DHCP 通信。

【以上内容部分由 kimi 生成】

# 5、leases 租约文件内容

```shell

root@K1Max-5BC9 /root [#] cat /opt/var/db/dhclient.leases
lease {
interface "wlan0";
fixed-address 192.168.0.118;
option subnet-mask 255.255.255.0;
option routers 192.168.0.1;
option dhcp-lease-time 7200;
option dhcp-message-type 5;
option domain-name-servers 223.5.5.5,114.114.114.114;
option dhcp-server-identifier 192.168.0.1;
renew 5 2024/06/14 00:55:30;
rebind 5 2024/06/14 01:50:31;
expire 5 2024/06/14 02:05:31;
}

```

## renew、rebind 和 expire 概念介绍

由上面内容可知路由器的 DHCP 服务租约时长为 7200s,即 2h。

在DHCP(动态主机配置协议)中,`renew`、`rebind`和`expire`是与IP地址租期管理相关的三个概念,它们的含义如下:

- **renew**:当DHCP客户端的IP地址租期达到50%时,会自动以单播的方式向DHCP服务器发送`DHCP REQUEST`报文,请求更新IP地址租期。如果收到DHCP服务器回应的`DHCP ACK`报文,则租期更新成功(即租期从0开始计算);如果收到`DHCP NAK`报文,则重新发送`DHCP DISCOVER`报文请求新的IP地址。
- **rebind**:当DHCP客户端的IP地址租期达到87.5%时,如果仍未收到DHCP服务器的应答,DHCP客户端会自动以广播的方式向DHCP服务器发送`DHCP REQUEST`报文,请求更新IP地址租期。如果收到DHCP服务器回应的`DHCP ACK`报文,则租期更新成功(即租期从0开始计算);如果收到`DHCP NAK`报文,则重新发送`DHCP DISCOVER`报文请求新的IP地址。
- **expire**:如果DHCP客户端的IP地址租期到期时都没有收到服务器的回应,客户端将停止使用此IP地址,并重新发送`DHCP DISCOVER`报文请求新的IP地址。

`renew`和`rebind`都是DHCP(动态主机配置协议)中的概念,它们的主要区别在于触发的时间和发送的目标服务器不同。

`renew`报文是在DHCP客户端的IP地址租期达到50%时触发的,此时客户端会以单播的方式向最初提供IP地址的DHCP服务器发送`renew`报文,请求延长IP地址的租期。如果客户端在租期的50%时发送了`renew`报文,但没有收到服务器的响应,那么它将在租期的87.5%时触发`rebind`报文。

`rebind`报文是在`renew`报文没有得到响应的情况下触发的,客户端会以广播的方式向任何可用的DHCP服务器发送`rebind`报文,请求延长IP地址的租期。

总的来说,`renew`报文是在租期的中期发送给特定的服务器,而`rebind`报文是在`renew`报文没有得到响应时发送给所有可用的服务器。这样可以确保客户端在IP地址租期到期之前能够及时续租,避免IP地址被收回。

【以上内容部分由 豆包 生成】

# Bonus

## entware 的路径问题

我们发现 opkg 安装的软件包都在 /opt 目录,配置文件亦如是,导致很多软件从 /etc 载入默认配置时报错。考虑和 entware 有关

查看 `Creality-Helper-Script/files/entware/generic.sh` 可知如下:

```shell
ln -nsf /usr/data/opt /opt
# echo '#!/bin/sh\n/opt/etc/init.d/rc.unslung "$1"' > /etc/init.d/S50unslung
# 这里有错误,应该为如下内容:
echo -e '#!/bin/sh\n/opt/etc/init.d/rc.unslung "$1"' > /etc/init.d/S50unslung

ln -sf /etc/localtime /opt/etc/localtime
ln -sf /etc/resolv.conf /opt/etc/resolv.conf
# 目录则是额外 -n 参数
```

## 其他调试命令

```shell
# 时区设置:/etc/localtime
# 搜索并关闭进程
ps aux |grep udhcpc
kill
# 测试 DNS 解析
nslookup example.com
```

## 文档链接

1. (https://mirror.nju.edu.cn/entware/mipselsf-k3.4/isc-dhcp-client-ipv4_4.4.3-P1-7_mipsel-3.4.ipk)
2. (https://bashcommandnotfound.cn/article/linux-dhclient-command)
3. https://man.archlinux.org/man/dhclient.8.en
页: [1]
查看完整版本: 跟思兼学Klipper(32):修复 CrealityOS IP 地址经常改变的问题