diff --git a/dom0/qvm-core/qubes.py b/dom0/qvm-core/qubes.py index 26f32f46..fa68b161 100755 --- a/dom0/qvm-core/qubes.py +++ b/dom0/qvm-core/qubes.py @@ -1459,6 +1459,7 @@ class QubesProxyVm(QubesNetVm): "{0}".format(self.netvm_vm.get_xid())) def write_iptables_xenstore_entry(self): + xs.rm('', "/local/domain/{0}/qubes_iptables_domainrules".format(self.get_xid())) iptables = "# Generated by Qubes Core on {0}\n".format(datetime.now().ctime()) iptables += "*filter\n" iptables += ":INPUT DROP [0:0]\n" @@ -1477,9 +1478,12 @@ class QubesProxyVm(QubesNetVm): iptables += "-A FORWARD -i vif0.0 -j ACCEPT\n" # Deny inter-VMs networking iptables += "-A FORWARD -i vif+ -o vif+ -j DROP\n" + iptables += "COMMIT\n" + xs.write('', "/local/domain/{0}/qubes_iptables_header".format(self.get_xid()), iptables) vms = [vm for vm in self.connected_vms.values()] for vm in vms: + iptables="*filter\n" if vm.has_firewall(): conf = vm.get_firewall_conf() else: @@ -1522,16 +1526,14 @@ class QubesProxyVm(QubesNetVm): iptables += "-A FORWARD -i vif{0}.+ -p icmp -j ACCEPT\n".format(xid) iptables += "-A FORWARD -i vif{0}.+ -j {1}\n".format(xid, default_action) - - iptables += "#End of VM rules\n" - iptables += "-A FORWARD -j DROP\n" - - iptables += "COMMIT" + iptables += "COMMIT\n" + xs.write('', "/local/domain/"+str(self.get_xid())+"/qubes_iptables_domainrules/"+str(xid), iptables) + # no need for ending -A FORWARD -j DROP, cause default action is DROP self.write_netvm_domid_entry() self.rules_applied = None - xs.write('', "/local/domain/{0}/qubes_iptables".format(self.get_xid()), iptables) + xs.write('', "/local/domain/{0}/qubes_iptables".format(self.get_xid()), 'reload') def get_xml_attrs(self): attrs = super(QubesProxyVm, self).get_xml_attrs() diff --git a/proxyvm/bin/qubes_firewall b/proxyvm/bin/qubes_firewall index fbac2959..13f5ba24 100755 --- a/proxyvm/bin/qubes_firewall +++ b/proxyvm/bin/qubes_firewall @@ -3,9 +3,9 @@ set -e PIDFILE=/var/run/qubes/qubes_firewall.pid XENSTORE_IPTABLES=qubes_iptables +XENSTORE_IPTABLES_HEADER=qubes_iptables_header XENSTORE_ERROR=qubes_iptables_error OLD_RULES="" - # PIDfile handling [[ -e $PIDFILE ]] && kill -s 0 $(<$PIDFILE) 2>/dev/null && exit 0 echo $$ >$PIDFILE @@ -13,24 +13,26 @@ echo $$ >$PIDFILE trap 'exit 0' SIGTERM while true; do - RULES=$(/usr/bin/xenstore-read $XENSTORE_IPTABLES) - - if [[ "$RULES" != "$OLD_RULES" ]]; then - IPTABLES_SAVE=$(/sbin/iptables-save | sed '/^\*filter/,/^COMMIT/d') - OUT=`echo -e "$RULES\n$IPTABLES_SAVE" | /sbin/iptables-restore 2>&1 || :` - /usr/bin/xenstore-write $XENSTORE_ERROR "$OUT" - if [ "$OUT" ]; then - DISPLAY=:0 /usr/bin/notify-send -t 3000 "Firewall loading error ($HOSTNAME)" "$OUT" || : - fi - - if [[ -z "$OUT" ]]; then - # If OK save it for later - /sbin/service iptables save >/dev/null - fi - - OLD_RULES="$RULES" - fi - # Wait for changes in xenstore file /usr/bin/xenstore-watch-qubes $XENSTORE_IPTABLES + TRIGGER=$(/usr/bin/xenstore-read $XENSTORE_IPTABLES) + + if ! [ "$TRIGGER" = "reload" ]; then continue ; fi + RULES=$(/usr/bin/xenstore-read $XENSTORE_IPTABLES_HEADER) + IPTABLES_SAVE=$(/sbin/iptables-save | sed '/^\*filter/,/^COMMIT/d') + OUT=`echo -e "$RULES\n$IPTABLES_SAVE" | /sbin/iptables-restore 2>&1 || :` + + for i in $(xenstore-list qubes_iptables_domainrules) ; do + RULES=$(/usr/bin/xenstore-read qubes_iptables_domainrules/"$i") + ERRS=`echo -e "$RULES" | /sbin/iptables-restore -n 2>&1 || :` + OUT="$OUT""$ERRS" + done + /usr/bin/xenstore-write $XENSTORE_ERROR "$OUT" + if [ "$OUT" ]; then + DISPLAY=:0 /usr/bin/notify-send -t 3000 "Firewall loading error ($HOSTNAME)" "$OUT" || : + fi + if [[ -z "$OUT" ]]; then + # If OK save it for later + /sbin/service iptables save >/dev/null + fi done