diff --git a/dom0/qvm-core/qubes.py b/dom0/qvm-core/qubes.py index 1171501e..4556c3e7 100755 --- a/dom0/qvm-core/qubes.py +++ b/dom0/qvm-core/qubes.py @@ -1055,10 +1055,14 @@ class QubesNetVm(QubesCowVm): "/usr/bin/xenstore-write", "/local/domain/{0}/qubes_netvm_external_ip".format(xid), ""]) - self.update_external_ip_permissions() + self.update_external_ip_permissions(xid) + + def update_external_ip_permissions(self, xid = -1): + if xid < 0: + xid = self.get_xid() + if xid < 0: + return - def update_external_ip_permissions(self): - xid = self.get_xid() command = [ "/usr/bin/xenstore-chmod", "/local/domain/{0}/qubes_netvm_external_ip".format(xid) @@ -1104,13 +1108,19 @@ class QubesProxyVm(QubesNetVm): def __init__(self, **kwargs): super(QubesProxyVm, self).__init__(uses_default_netvm=False, **kwargs) self.rules_applied = None - if self.netvm_vm is not None: - self.netvm_vm.add_external_ip_permission(self.get_xid()) @property def type(self): return "ProxyVM" + def start(self, debug_console = False, verbose = False, preparing_dvm = False): + if dry_run: + return + retcode = super(QubesFirewallVm, self).start(debug_console=debug_console, verbose=verbose, preparing_dvm=preparing_dvm) + self.netvm_vm.add_external_ip_permission(self.get_xid()) + self.write_netvm_domid_entry() + return retcode + def force_shutdown(self): if dry_run: return @@ -1122,10 +1132,6 @@ class QubesProxyVm(QubesNetVm): return super(QubesProxyVm, self).create_xenstore_entries(xid) - retcode = subprocess.check_call ([ - "/usr/bin/xenstore-write", - "/local/domain/{0}/qubes_netvm_domid".format(xid), - "{0}".format(self.netvm_vm.get_xid())]) retcode = subprocess.check_call ([ "/usr/bin/xenstore-write", "/local/domain/{0}/qubes_iptables_error".format(xid), @@ -1136,6 +1142,15 @@ class QubesProxyVm(QubesNetVm): "r{0}".format(xid), "w{0}".format(xid)]) self.write_iptables_xenstore_entry() + def write_netvm_domid_entry(self, xid = -1): + if xid < 0: + xid = self.get_xid() + + return subprocess.check_call ([ + "/usr/bin/xenstore-write", "--", + "/local/domain/{0}/qubes_netvm_domid".format(xid), + "{0}".format(self.netvm_vm.get_xid())]) + def write_iptables_xenstore_entry(self): iptables = "# Generated by Qubes Core on {0}\n".format(datetime.now().ctime()) iptables += "*filter\n" @@ -1194,7 +1209,9 @@ class QubesProxyVm(QubesNetVm): iptables += " -j {0}\n".format(rules_action) if conf["allowDns"]: - iptables += "-A FORWARD -i vif{0}.0 -p udp --dport 53 -j ACCEPT\n".format(xid) + # PREROUTING does DNAT to NetVM DNSes, so we need self.netvm_vm. properties + iptables += "-A FORWARD -i vif{0}.0 -p udp -d {1} --dport 53 -j ACCEPT\n".format(xid,self.netvm_vm.gateway) + iptables += "-A FORWARD -i vif{0}.0 -p udp -d {1} --dport 53 -j ACCEPT\n".format(xid,self.netvm_vm.secondary_dns) iptables += "-A FORWARD -i vif{0}.0 -j {1}\n".format(xid, default_action) @@ -1204,6 +1221,8 @@ class QubesProxyVm(QubesNetVm): iptables += "COMMIT" + self.write_netvm_domid_entry() + self.rules_applied = None return subprocess.check_call ([ "/usr/bin/xenstore-write", diff --git a/proxyvm/bin/qubes_netwatcher b/proxyvm/bin/qubes_netwatcher new file mode 100755 index 00000000..8f9d2e9c --- /dev/null +++ b/proxyvm/bin/qubes_netwatcher @@ -0,0 +1,27 @@ +#!/bin/bash +set -e + +PIDFILE=/var/run/qubes/qubes_netwatcher.pid +CURR_NETCFG="" + +# PIDfile handling +[[ -e $PIDFILE ]] && kill -s 0 $(<$PIDFILE) 2>/dev/null && exit 0 +echo $$ >$PIDFILE + +trap 'exit 0' SIGTERM + +while true; do + NET_DOMID=$(/usr/bin/xenstore-read qubes_netvm_domid) + if [[ -n "$NET_DOMID" ]] && [[ $NET_DOMID -gt 0 ]]; then + NETCFG=$(/usr/bin/xenstore-read /local/domain/$NET_DOMID/qubes_netvm_external_ip) + if [[ "$NETCFG" != "$CURR_NETCFG" ]]; then + /sbin/service qubes_firewall stop + /sbin/service qubes_firewall start + CURR_NETCFG="$NETCFG" + fi + + /usr/bin/xenstore-watch /local/domain/$NET_DOMID/qubes_netvm_external_ip + else + /usr/bin/xenstore-watch qubes_netvm_domid + fi +done diff --git a/proxyvm/init.d/qubes_firewall b/proxyvm/init.d/qubes_firewall index 1d3c0266..2d1218ec 100755 --- a/proxyvm/init.d/qubes_firewall +++ b/proxyvm/init.d/qubes_firewall @@ -26,7 +26,7 @@ stop() type=$(/usr/bin/xenstore-read qubes_vm_type) if [ "$type" == "ProxyVM" ]; then echo -n "Stopping Qubes Firewall monitor:" - kill $(cat $PIDFILE) 2>/dev/null && success || failure + kill -9 $(cat $PIDFILE) 2>/dev/null && success || failure echo "" fi return 0 diff --git a/proxyvm/init.d/qubes_netwatcher b/proxyvm/init.d/qubes_netwatcher new file mode 100755 index 00000000..e8d9af46 --- /dev/null +++ b/proxyvm/init.d/qubes_netwatcher @@ -0,0 +1,48 @@ +#!/bin/sh +# +# chkconfig: 345 92 92 +# description: Starts Qubes Network monitor +# +# Source function library. +. /etc/rc.d/init.d/functions + +PIDFILE=/var/run/qubes/qubes_netwatcher.pid + +start() +{ + type=$(/usr/bin/xenstore-read qubes_vm_type) + if [ "$type" == "ProxyVM" ]; then + echo -n $"Starting Qubes Network monitor:" + /sbin/ethtool -K eth0 sg off + /usr/sbin/qubes_netwatcher & + success + echo "" + fi + return 0 +} + +stop() +{ + type=$(/usr/bin/xenstore-read qubes_vm_type) + if [ "$type" == "ProxyVM" ]; then + echo -n "Stopping Qubes Network monitor:" + kill -9 $(cat $PIDFILE) 2>/dev/null && success || failure + echo "" + fi + return 0 +} + +case "$1" in + start) + start + ;; + stop) + stop + ;; + *) + echo $"Usage: $0 {start|stop}" + exit 3 + ;; +esac + +exit $RETVAL