我有几个脚本需要确定我连接到哪个网络(使用我的 Linux 笔记本电脑),例如安装本地 NAS 或(禁用/)启用特定服务。增加的复杂性是,当通过不同的 SSID 或网络接口(有线/WiFi)连接时,某些(大多数)网络仍应被正确识别。另外,我不能依赖可用的特定主机。
我当前的脚本正在解析路由表以查找默认网关和关联的 MAC 地址,使用 IPv4 网关作为默认网关,使用 IPv6 网关作为后备:
#!/bin/sh
ROUTER=$(ip -4 route list | grep "default" | head -n 1 | cut -f 3 -d " ")
# echo "ROUTER=${ROUTER}" >&2
if [ "${ROUTER}" != "" ]; then
MAC=$(ip neigh | grep -E "^${ROUTER} " | cut -f 5 -d " ")
# echo "MAC=${MAC}" >&2
if [ ${MAC} != "" ]; then
echo "${MAC}"
exit 0
fi
fi
ROUTER6=$(ip neigh | grep -R "^fe80.* router " | head -n 1 | cut -f 1 -d " ")
# echo "ROUTER6=${ROUTER6}" >&2
if [ "${ROUTER6}" != "" ]; then
MAC6=$(ip neigh | grep -E "^fe80.* router " | head -n 1 | cut -f 5 -d " ")
# echo "MAC6=${MAC6}" >&2
if [ "${MAC6}" != "" ]; then
echo "${MAC6}"
exit 0
fi
fi
exit 1
到目前为止,它工作正常,但由于所有字段解析和对网关 MAC 的依赖,可能有点脆弱。
有没有更好的方法来获取可靠的网络 ID,无论连接方式如何,都可以识别网络?
答案1
没有可靠的网络标识符,IP地址应该以网络ID开头,但在专用网络中这不是唯一的,除非您使用非常随机的网络10.243.168.0/24,否则您可以检测到您自己的网络。 ipv6 消除了对专用网络的需要,因此如果您有全局唯一的前缀,您可以使用它,但您的前缀取决于本地 fe80。您可以使用 802.X 进行与 WIFI 类似的身份验证,以便您对已知网络进行身份验证并从那里触发脚本。
您可以通过仅列出默认路由来稍微优化,这样您就不必 grep,但您可以有多个默认网关 ip -4 Route list default
您可以依赖 mdns 进行服务发现或其他形式的信标。有一个主机身份协议可以充当信标,但由于您不想依赖单个主机,所以我个人会定期收集 arp 表(例如 arp -an 的输出)或直接从 /proc/ 收集net/arp 并计算连接到某个网络的可能性。
也许你最好还是坚持现有的剧本。