通过执行以上命令,在运行在内存中的临时 Linux 环境中,成功配置 IPv4 网络、安装完系统后,在正式系统中的网络配置文件中,把 IPv4 网关写回去。
以上伪代码存在一个不完善的地方,就是“ip route add default via IPv4 网关 dev IPv4 网卡”部分,最后应当添加一个“onlink”,规定主机直接与网关进行通信,当做公联通信处理的那种,因为在某些环境中,不添加“onlink”,本机仍然会试图以内网主机的方式和网关通信,从而造成网络配置失败,所以改动的地方仅涉及添加“onlink”即可:
ip link set IPv4 网卡 up;
ip addr add IPv4/掩码后缀 dev IPv4 网卡;
ip route add IPv4 网关 dev IPv4 网卡;
ip route add default via IPv4 网关 dev IPv4 网卡 onlink
复制代码
这串伪代码极其重要,因为它就是一套绝杀天下的《独孤九剑》,只要将其放在适合的环境中,灵活运用,配合以上几条注意点,理论上能解决所有 Linux 发行版网络安装程序应对不规则 IPv4 配置时,网关配置失败的问题 。
除了知道要插,还得知道往哪儿插,怎么插,这套剑法才能发挥其无敌的效用。
首先把插法解决的,自然是我脚本中的 Debian,不过不规则 IPv4 虽然仅安装 Debian 是没问题了,但用 Debian dd Windows 的时候还是会存在一些问题。
软 hack 处理不规则 IPv4 网关时,肯定是按静态配置的,既然要让 ip route add 们运行得尽可能“早”,那么“# manual configuration”就是一个绝佳的“锚点”,用 sed 命令在该注释后方把 ip route add 哥几个逐条加上即可:
sed -i '/manual configuration/a\ip link set '$interface4' up\nip addr add '$IPv4'/'$ipPrefix' dev '$interface4'\nip route add '$actualIp4Gate' dev '$interface4'\nip route add default via '$actualIp4Gate' dev '$interface4' onlink\necho '\''nameserver '$ipDNS1''\'' > /etc/resolv.conf\necho '\''nameserver '$ipDNS2''\'' >> /etc/resolv.conf' /tmp/boot/init
sed -i '/manual configuration/a\\t\tip link set '$interface4' up\n\t\tip addr add '$IPv4'/'$ipPrefix' dev '$interface4'\n\t\tip route add '$actualIp4Gate' dev '$interface4'\n\t\tip route add default via '$actualIp4Gate' dev '$interface4' onlink\n\t\techo '\''nameserver '$ipDNS1''\'' > /etc/resolv.conf\n\t\techo '\''nameserver '$ipDNS2''\'' >> /etc/resolv.conf' /tmp/boot/init
}
复制代码
于是我们再来看一下 init 中被修改后的“configure_ip()”函数:
configure_ip() {
[ -n "$MAC_ADDRESS" ] && return
local IFS=':'
set -- ${KOPT_ip:-dhcp}
unset IFS
local client_ip="$1"
local gw_ip="$3"
local netmask="$4"
local device="$6"
local autoconf="$7"
local dns1="$8"
local dns2="$9"
case "$client_ip" in
off|none) return;;
dhcp) autoconf="dhcp";;
esac
[ -n "$device" ] || device=$(ip_choose_if)
if [ -z "$device" ]; then
echo "ERROR: IP requested but no network device was found"
return 1
fi
if [ "$autoconf" = "dhcp" ]; then
# automatic configuration
if [ ! -e "$ROOT"/usr/share/udhcpc/default.script ]; then
echo "ERROR: DHCP requested but not present in initrd"
return 1
fi
ebegin "Obtaining IP via DHCP ($device)"
$MOCK ifconfig "$device" 0.0.0.0
$MOCK udhcpc -i "$device" -f -q
eend $?
else
# manual configuration
ip link set eth0 up
ip addr add 51.75.213.94/29 dev eth0
ip route add 141.95.72.254 dev eth0
ip route add default via 141.95.72.254 dev eth0 onlink
echo 'nameserver 8.8.8.8' > /etc/resolv.conf
echo 'nameserver 1.1.1.1' >> /etc/resolv.conf
[ -n "$client_ip" -a -n "$netmask" ] || return
ebegin "Setting IP ($device)"
if ifconfig "$device" "$client_ip" netmask "$netmask"; then
[ -z "$gw_ip" ] || ip route add 0.0.0.0/0 via "$gw_ip" dev "$device"
fi
eend $?
fi
# Never executes if variables are empty
for i in $dns1 $dns2; do
echo "nameserver $i" >> /etc/resolv.conf
done
MAC_ADDRESS=$(cat /sys/class/net/$device/address)
}
复制代码
显然,我们要软 hack 的命令,即:
# manual configuration
ip link set eth0 up
ip addr add 51.75.213.94/29 dev eth0
ip route add 141.95.72.254 dev eth0
ip route add default via 141.95.72.254 dev eth0 onlink
Hetzner arm64 机器 dd win 就不测了,dd 包都是基于 amd64 的,dd 完了也启动不了。况且 Windows 超强的兼容性,就是来自基于 x86 x86_64 架构上开发的各种新老应用程序的支持,即使能在 arm 上安装专门为 arm 开发的 Windows ,除了 UI 界面和 x86 的 Windows 一致,很多 x86 的程序无法在 arm Windows 下兼容,除非再安装一个 x86 虚拟机来模拟运行,但运行效率相比在原生 x86 上运行降低 90% 也不是没有可能,目前为原生 arm Windows 开发的应用数量很有限,丰富程度甚至还不如 Linux,所以 arm64 的机器还是用 arm64 Linux 比较好。