firewall: call iptables-restore once per domain (#311)
qubes.py now places rules for each domain in a separate key under /local/domain/fw_XID/qubes_iptables_domainrules/ plus the header in /local/domain/fw_XID/qubes_iptables_header. /local/domain/fw_XID/qubes_iptables is now just a trigger. So, if iptables-restore fails dues to e.g. error resolving a domain name in a rules for a domain, then only this domain will not get connectivity, others will work fine.
This commit is contained in:
parent
4ad919bf6d
commit
8ecd6134d9
@ -1459,6 +1459,7 @@ class QubesProxyVm(QubesNetVm):
|
|||||||
"{0}".format(self.netvm_vm.get_xid()))
|
"{0}".format(self.netvm_vm.get_xid()))
|
||||||
|
|
||||||
def write_iptables_xenstore_entry(self):
|
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 = "# Generated by Qubes Core on {0}\n".format(datetime.now().ctime())
|
||||||
iptables += "*filter\n"
|
iptables += "*filter\n"
|
||||||
iptables += ":INPUT DROP [0:0]\n"
|
iptables += ":INPUT DROP [0:0]\n"
|
||||||
@ -1477,9 +1478,12 @@ class QubesProxyVm(QubesNetVm):
|
|||||||
iptables += "-A FORWARD -i vif0.0 -j ACCEPT\n"
|
iptables += "-A FORWARD -i vif0.0 -j ACCEPT\n"
|
||||||
# Deny inter-VMs networking
|
# Deny inter-VMs networking
|
||||||
iptables += "-A FORWARD -i vif+ -o vif+ -j DROP\n"
|
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()]
|
vms = [vm for vm in self.connected_vms.values()]
|
||||||
for vm in vms:
|
for vm in vms:
|
||||||
|
iptables="*filter\n"
|
||||||
if vm.has_firewall():
|
if vm.has_firewall():
|
||||||
conf = vm.get_firewall_conf()
|
conf = vm.get_firewall_conf()
|
||||||
else:
|
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}.+ -p icmp -j ACCEPT\n".format(xid)
|
||||||
|
|
||||||
iptables += "-A FORWARD -i vif{0}.+ -j {1}\n".format(xid, default_action)
|
iptables += "-A FORWARD -i vif{0}.+ -j {1}\n".format(xid, default_action)
|
||||||
|
iptables += "COMMIT\n"
|
||||||
iptables += "#End of VM rules\n"
|
xs.write('', "/local/domain/"+str(self.get_xid())+"/qubes_iptables_domainrules/"+str(xid), iptables)
|
||||||
iptables += "-A FORWARD -j DROP\n"
|
# no need for ending -A FORWARD -j DROP, cause default action is DROP
|
||||||
|
|
||||||
iptables += "COMMIT"
|
|
||||||
|
|
||||||
self.write_netvm_domid_entry()
|
self.write_netvm_domid_entry()
|
||||||
|
|
||||||
self.rules_applied = None
|
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):
|
def get_xml_attrs(self):
|
||||||
attrs = super(QubesProxyVm, self).get_xml_attrs()
|
attrs = super(QubesProxyVm, self).get_xml_attrs()
|
||||||
|
@ -3,9 +3,9 @@ set -e
|
|||||||
|
|
||||||
PIDFILE=/var/run/qubes/qubes_firewall.pid
|
PIDFILE=/var/run/qubes/qubes_firewall.pid
|
||||||
XENSTORE_IPTABLES=qubes_iptables
|
XENSTORE_IPTABLES=qubes_iptables
|
||||||
|
XENSTORE_IPTABLES_HEADER=qubes_iptables_header
|
||||||
XENSTORE_ERROR=qubes_iptables_error
|
XENSTORE_ERROR=qubes_iptables_error
|
||||||
OLD_RULES=""
|
OLD_RULES=""
|
||||||
|
|
||||||
# PIDfile handling
|
# PIDfile handling
|
||||||
[[ -e $PIDFILE ]] && kill -s 0 $(<$PIDFILE) 2>/dev/null && exit 0
|
[[ -e $PIDFILE ]] && kill -s 0 $(<$PIDFILE) 2>/dev/null && exit 0
|
||||||
echo $$ >$PIDFILE
|
echo $$ >$PIDFILE
|
||||||
@ -13,24 +13,26 @@ echo $$ >$PIDFILE
|
|||||||
trap 'exit 0' SIGTERM
|
trap 'exit 0' SIGTERM
|
||||||
|
|
||||||
while true; do
|
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
|
# Wait for changes in xenstore file
|
||||||
/usr/bin/xenstore-watch-qubes $XENSTORE_IPTABLES
|
/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
|
done
|
||||||
|
Loading…
Reference in New Issue
Block a user