Move network uplink setup to a separate service
Previously, network uplink (eth0) was configured in two places: - udev (asynchronously) - qubes-misc-post.service - at the very end of the boot process This caused multiple issues: 1. Depending on udev event processing (non-deterministic), network uplink could be enabled too early, for example before setting up firewall. 2. Again depending on udev processing, it can be enabled quite late in the boot process, after network.target is up and services assume network already configured. This for example causes qubes-firewall to fail DNS queries. 3. If udev happen try to enable enable networking even earlier, it may happend before qubesdb-daemon is started, in which case network setup fill fail. For this case, there was network re-setup in qubes-misc-post service - much later in the boot. Fix the above by placing network uplink setup in a dedicated qubes-network-uplink@${INTERFACE}.service unit ordered after network-pre.target and pulled in by udev based on vif device existence, to handle also dynamic network attach/detach. Then, create qubes-network-uplink.service unit waiting for appropriate interface-specific unit (if one is expected!) and order it before network.target. QubesOS/qubes-issues#5576
This commit is contained in:
parent
e344dcc4c9
commit
dd8de797e3
3
debian/qubes-core-agent-networking.install
vendored
3
debian/qubes-core-agent-networking.install
vendored
@ -11,9 +11,12 @@ etc/xen/scripts/vif-route-qubes
|
||||
lib/systemd/system/qubes-firewall.service
|
||||
lib/systemd/system/qubes-iptables.service
|
||||
lib/systemd/system/qubes-network.service
|
||||
lib/systemd/system/qubes-network-uplink.service
|
||||
lib/systemd/system/qubes-network-uplink@.service
|
||||
lib/systemd/system/qubes-updates-proxy.service
|
||||
usr/lib/qubes/init/network-proxy-setup.sh
|
||||
usr/lib/qubes/init/network-proxy-stop.sh
|
||||
usr/lib/qubes/init/network-uplink-wait.sh
|
||||
usr/lib/qubes/init/qubes-iptables
|
||||
usr/lib/qubes/iptables-updates-proxy
|
||||
usr/lib/qubes/qubes-setup-dnat-to-ns
|
||||
|
@ -173,6 +173,14 @@ qubes_ip_change_hook() {
|
||||
|
||||
have_qubesdb || exit 0
|
||||
|
||||
ACTION="$1"
|
||||
INTERFACE="$2"
|
||||
|
||||
if [ -z "$INTERFACE" ]; then
|
||||
echo "Missing INTERFACE argument" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -n "$INTERFACE" ]; then
|
||||
if [ "$ACTION" == "add" ]; then
|
||||
MAC="$(get_mac_from_iface "$INTERFACE")"
|
||||
@ -232,8 +240,16 @@ if [ -n "$INTERFACE" ]; then
|
||||
fi
|
||||
fi
|
||||
elif [ "$ACTION" == "remove" ]; then
|
||||
# make sure network is disabled, especially on shutdown, to prevent
|
||||
# leaks when firewall will get stopped too
|
||||
ip link set "$INTERFACE" down 2>/dev/null || :
|
||||
|
||||
# If exists, we delete NetworkManager configuration file to prevent duplicate entries
|
||||
nm_config="/etc/NetworkManager/system-connections/qubes-uplink-$INTERFACE"
|
||||
rm -rf "$nm_config"
|
||||
else
|
||||
echo "Invalid action '$ACTION'" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
fi
|
||||
|
@ -1,5 +1,5 @@
|
||||
# old udev has ENV{ID_NET_DRIVER}
|
||||
SUBSYSTEMS=="xen", KERNEL=="eth*", ACTION=="add", ENV{ID_NET_DRIVER}=="vif", RUN+="/usr/lib/qubes/setup-ip"
|
||||
SUBSYSTEMS=="net", KERNEL=="eth*", ACTION=="remove", ENV{ID_NET_DRIVER}=="vif", RUN+="/usr/lib/qubes/setup-ip"
|
||||
SUBSYSTEMS=="xen", KERNEL=="eth*", ACTION=="add", ENV{ID_NET_DRIVER}=="vif", ENV{SYSTEMD_WANTS}+="qubes-network-uplink@%k.service"
|
||||
SUBSYSTEMS=="net", KERNEL=="eth*", ACTION=="remove", ENV{ID_NET_DRIVER}=="vif", ENV{SYSTEMD_WANTS}+="qubes-network-uplink@%k.service"
|
||||
# new udev has DRIVERS
|
||||
SUBSYSTEMS=="xen", KERNEL=="eth*", ACTION=="add", DRIVERS=="vif", RUN+="/usr/lib/qubes/setup-ip"
|
||||
SUBSYSTEMS=="xen", KERNEL=="eth*", ACTION=="add", DRIVERS=="vif", ENV{SYSTEMD_WANTS}+="qubes-network-uplink@%k.service"
|
||||
|
@ -797,9 +797,12 @@ rm -f %{name}-%{version}
|
||||
/lib/systemd/system/qubes-firewall.service
|
||||
/lib/systemd/system/qubes-iptables.service
|
||||
/lib/systemd/system/qubes-network.service
|
||||
/lib/systemd/system/qubes-network-uplink.service
|
||||
/lib/systemd/system/qubes-network-uplink@.service
|
||||
/lib/systemd/system/qubes-updates-proxy.service
|
||||
/usr/lib/qubes/init/network-proxy-setup.sh
|
||||
/usr/lib/qubes/init/network-proxy-stop.sh
|
||||
/usr/lib/qubes/init/network-uplink-wait.sh
|
||||
/usr/lib/qubes/init/qubes-iptables
|
||||
/usr/lib/qubes/iptables-updates-proxy
|
||||
/usr/lib/qubes/qubes-setup-dnat-to-ns
|
||||
|
@ -91,6 +91,7 @@ enable qubes-update-check.timer
|
||||
enable qubes-misc-post.service
|
||||
enable qubes-updates-proxy.service
|
||||
enable qubes-network.service
|
||||
enable qubes-network-uplink.service
|
||||
enable qubes-qrexec-agent.service
|
||||
enable qubes-mount-dirs.service
|
||||
enable qubes-rootfs-resize.service
|
||||
|
@ -11,15 +11,6 @@ if [ -n "$(ls -A /usr/local/lib 2>/dev/null)" ] || \
|
||||
ldconfig
|
||||
fi
|
||||
|
||||
# Set IP address again (besides action in udev rules); this is needed by
|
||||
# DispVM (to override DispVM-template IP) and in case when qubes-ip was
|
||||
# called by udev before loading evtchn kernel module - in which case
|
||||
# qubesdb-read fails
|
||||
QUBES_MANAGED_IFACE="$(get_qubes_managed_iface)"
|
||||
if [ "x$QUBES_MANAGED_IFACE" != "x" ]; then
|
||||
INTERFACE="$QUBES_MANAGED_IFACE" ACTION="add" /usr/lib/qubes/setup-ip
|
||||
fi
|
||||
|
||||
if [ -x /rw/config/rc.local ] ; then
|
||||
/rw/config/rc.local
|
||||
fi
|
||||
|
16
vm-systemd/network-uplink-wait.sh
Normal file
16
vm-systemd/network-uplink-wait.sh
Normal file
@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Source Qubes library.
|
||||
# shellcheck source=init/functions
|
||||
. /usr/lib/qubes/init/functions
|
||||
|
||||
# Setup IP address at specific time of system boot, instead of asynchronously
|
||||
# by udev
|
||||
QUBES_MANAGED_IFACE="$(get_qubes_managed_iface)"
|
||||
if [ "x$QUBES_MANAGED_IFACE" != "x" ]; then
|
||||
# systemd does not support conditional After= dependencies, nor a tool to
|
||||
# just wait for the unit to be activated
|
||||
# if the network interface is expected, use `systemctl start` to wait for
|
||||
# it to be started - it would be started by udev (SYSTEMD_WANTS) anyway
|
||||
systemctl start "qubes-network-uplink@$QUBES_MANAGED_IFACE.service"
|
||||
fi
|
11
vm-systemd/qubes-network-uplink.service
Normal file
11
vm-systemd/qubes-network-uplink.service
Normal file
@ -0,0 +1,11 @@
|
||||
[Unit]
|
||||
Description=Qubes network uplink wait
|
||||
Before=network.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/usr/lib/qubes/init/network-uplink-wait.sh
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
11
vm-systemd/qubes-network-uplink@.service
Normal file
11
vm-systemd/qubes-network-uplink@.service
Normal file
@ -0,0 +1,11 @@
|
||||
[Unit]
|
||||
Description=Qubes network uplink (%i) setup
|
||||
After=network-pre.target qubes-iptables.service
|
||||
After=sys-subsystem-net-devices-%i.device
|
||||
BindsTo=sys-subsystem-net-devices-%i.device
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/usr/lib/qubes/setup-ip add "%i"
|
||||
ExecStop=/usr/lib/qubes/setup-ip remove "%i"
|
Loading…
Reference in New Issue
Block a user