Browse Source

network: setup anti-spoofing firewall rules before enabling the interface

Previously enabling the interface was the first action in the setup
steps. Linux theoretically do not forward the traffic until proper
IP address and route is added to the interface (depending on rp_filter
setting). But instead of relying on this opaque behavior better setup
anti-spoofing rules earlier. Also, add 'set -o pipefail' for more
reliable error handling.
Note the rules for actual VM traffic (qvm-firewall) are properly
enforced - until those rules are loaded, traffic from appropriate vif
interface is blocked. But this relies on proper source IP address,
anti-spoofing rules need to be setup race-free.

Reported-by: Demi M. Obenour <demiobenour@gmail.com>
Marek Marczykowski-Górecki 4 years ago
parent
commit
68b61c2c6d
1 changed files with 21 additions and 9 deletions
  1. 21 9
      network/vif-route-qubes

+ 21 - 9
network/vif-route-qubes

@@ -24,6 +24,7 @@ dir=$(dirname "$0")
 # shellcheck disable=SC1091,SC1090
 . "$dir/vif-common.sh"
 
+set -o pipefail
 #main_ip=$(dom0_ip)
 
 # Network Hooks for triggering supplementary actions on AppVM connect
@@ -95,7 +96,6 @@ fi
 # shellcheck disable=SC2154
 case "$command" in
     online)
-        ifconfig "${vif}" up
         echo 1 >"/proc/sys/net/ipv4/conf/${vif}/proxy_arp"
         ipcmd='add'
         iptables_cmd='-I PREROUTING 1'
@@ -118,17 +118,12 @@ domid=${domid/.*/}
 #  32752 is max XID aka domid
 metric=$(( 32752 - domid ))
 
-
+# add anti-spoofing rules before enabling the interface
 if [ "${ip}" ]; then
     # If we've been given a list of IP addresses, then add routes from dom0 to
     # the guest using those addresses.
     for addr in ${ip};
     do
-        if [[ "$addr" = *:* ]] && [[ "$ipv6_disabled" = 1 ]]; then
-            log error "Cannot set IPv6 route to ${addr}, IPv6 disabled in the kernel"
-            continue
-        fi
-        ${cmdprefix} ip route "${ipcmd}" "${addr}" dev "${vif}" metric "$metric"
         if [[ "$addr" = *:* ]]; then
             ipt=ip6tables-restore
         else
@@ -136,14 +131,31 @@ if [ "${ip}" ]; then
         fi
         echo -e "*raw\\n$iptables_cmd -i ${vif} ! -s ${addr} -j DROP\\nCOMMIT" | \
             ${cmdprefix} $ipt --noflush $ipt_arg
-
-        network_hooks "${command}" "${vif}" "${addr}"
     done
     # if no IPv6 is assigned, block all IPv6 traffic on that interface
     if ! [[ "$ip" = *:* ]]; then
         echo -e "*raw\\n$iptables_cmd -i ${vif} -j DROP\\nCOMMIT" | \
             ${cmdprefix} ip6tables-restore --noflush $ipt_arg
     fi
+fi
+
+if [ "$command" = "online" ]; then
+    ifconfig "${vif}" up
+fi
+
+if [ "${ip}" ]; then
+    # If we've been given a list of IP addresses, then add routes from dom0 to
+    # the guest using those addresses.
+    for addr in ${ip};
+    do
+        if [[ "$addr" = *:* ]] && [[ "$ipv6_disabled" = 1 ]]; then
+            log error "Cannot set IPv6 route to ${addr}, IPv6 disabled in the kernel"
+            continue
+        fi
+        ${cmdprefix} ip route "${ipcmd}" "${addr}" dev "${vif}" metric "$metric"
+
+        network_hooks "${command}" "${vif}" "${addr}"
+    done
     ${cmdprefix} ip addr "${ipcmd}" "${back_ip}/32" dev "${vif}"
     if [ "${back_ip6}" ] && [[ "${back_ip6}" != "fe80:"* ]] && [[ "$ipv6_disabled" != 1 ]]; then
         ${cmdprefix} ip addr "${ipcmd}" "${back_ip6}/128" dev "${vif}"