当我的系统获得新的 IPv6 地址时,如何运行 systemd oneshot 服务?

当我的系统获得新的 IPv6 地址时,如何运行 systemd oneshot 服务?

我想运行一个systemd一次性服务每当我的系统从网络路由器获得分配给它的新 IPv6 地址时(这将在启动时,并在整个正常运行时间内定期进行)。

理想情况下,此事件仅适用于 IPv6 地址更新,而不包括潜在的 IPv4 地址更改。

是否可以使用 systemd 监控此类事件的网络 dbus 活动?

我的最终目标是在发生这种情况时命中动态 DNS 端点,以便该系统的 IPv6 DNS 记录避免过时。

答案1

我很多年前写过这样的东西,叫做(缺乏想象力)自动域名

它不调用 systemd 服务(我认为当时不存在 systemd!),但它确实调用外部进程来执行 DNS 更新(更新)。然而,它确实直接在网络链路级别监视 IP 地址的添加和删除,这意味着无论它们如何发生(手动管理配置、SLAAC、DHCP、网络管理器),它都会拾取它们。当发生变化时它会立即做出反应。它确实支持过滤器(设计用于自动排除链接本地地址等内容),因此您可以让它尊重 IPv6 地址更改并忽略 IPv4 地址更改,如您所愿。

也许您可以使用它或修改它来满足您的需求。检测 IP 地址变化并做出反应的大部分魔力在于watchip.c, 我认为。

答案2

使用持久的 systemd 服务,而不是一次性的:

[Unit]
Description=Dynamic DNS updater
DefaultDependencies=no
Wants=local-fs.target
After=local-fs.target
Wants=network-pre.target
Before=network-pre.target

[Service]
Type=exec
ExecStart=/usr/local/sbin/ddns-updater

[Install]
WantedBy=sysinit.target

相应的/usr/local/sbin/ddns-updater守护进程脚本,使用包ip中的工具iproute2

#!/bin/sh -e

ip -o -6 monitor address |
    while read index iface proto addr dummy scope temporary dummy; do
        case "$iface:$proto:$scope:$temporary" in
            enp2s0:inet6:global:dynamic)
                addr="${addr%/*}"
                if [ "$addr" != "$current" ]; then
                    nsupdate -k /etc/network/nsupdate/Kyour.dyn.domain.name.+157+58882.private <<EOF
update delete your.dyn.domain.name AAAA
update add your.dyn.domain.name 300 AAAA $addr
send
EOF
                    echo "AAAA record set to $addr"
                    current="$addr"
                fi;;
        esac
    done

这可以避免将经常变化的随机(隐私增强型、临时)地址写入 DNS 服务器,但如果您有多个全局非临时地址(例如静态配置的地址和 SLAAC 的地址),则会出现问题。根据需要进行调整(接口名称、域名、密钥文件路径、附加逻辑、TTL...)

相关内容