From 789eb511266d9e8bd812e40f952ec2bce6d7a414 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Tue, 27 Jan 2015 00:36:24 +0100 Subject: [PATCH] network: preliminary support for IPv6, disabled by default (#718) Currently qubes-firewall will try to load the same rules for both IPv4 and IPv6, so only those with names resolvable to both address families will work. The feature is disabled by default (besides some generic ip6tables rules, which are always loaded). It can be enabled using qubes-ipv6 qvm-service. To actually use IPv6 in an AppVM, the user needs to enable qubes-ipv6 service on the whole network chain from NetVM up to (inclusive) the AppVM. --- network/ip6tables | 29 +++++++++++++++++++++++++---- network/qubes-firewall | 28 +++++++++++++++++++++++++++- network/setup-ip | 25 ++++++++++++++++++++++--- network/vif-route-qubes | 8 +++++++- 4 files changed, 81 insertions(+), 9 deletions(-) diff --git a/network/ip6tables b/network/ip6tables index 8a906f5f0..43148c181 100644 --- a/network/ip6tables +++ b/network/ip6tables @@ -1,8 +1,29 @@ -# Generated by ip6tables-save v1.4.14 on Tue Sep 25 16:00:20 2012 +# Generated by iptables-save v1.4.5 on Mon Sep 6 08:57:46 2010 +*nat +:PREROUTING ACCEPT [0:0] +:OUTPUT ACCEPT [0:0] +:POSTROUTING ACCEPT [0:0] +:PR-QBS - [0:0] +:PR-QBS-SERVICES - [0:0] +-A PREROUTING -j PR-QBS +-A PREROUTING -j PR-QBS-SERVICES +-A POSTROUTING -o vif+ -j ACCEPT +-A POSTROUTING -o lo -j ACCEPT +-A POSTROUTING -j MASQUERADE +COMMIT +# Completed on Mon Sep 6 08:57:46 2010 +# Generated by iptables-save v1.4.5 on Mon Sep 6 08:57:46 2010 *filter -:INPUT DROP [1:72] -:FORWARD DROP [0:0] +:INPUT ACCEPT [0:0] +:FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] +-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT +-A INPUT -p ipv6-icmp -j ACCEPT -A INPUT -i lo -j ACCEPT +-A INPUT -j REJECT --reject-with icmp-host-prohibited +-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT +-A FORWARD -i vif+ -o vif+ -j DROP +-A FORWARD -i vif+ -j ACCEPT +-A FORWARD -j DROP COMMIT -# Completed on Tue Sep 25 16:00:20 2012 +# Completed on Mon Sep 6 08:57:46 2010 diff --git a/network/qubes-firewall b/network/qubes-firewall index 35a23a1ee..9648d4208 100755 --- a/network/qubes-firewall +++ b/network/qubes-firewall @@ -6,6 +6,10 @@ XENSTORE_IPTABLES=qubes-iptables XENSTORE_IPTABLES_HEADER=qubes-iptables-header XENSTORE_ERROR=qubes-iptables-error OLD_RULES="" + +ipv6_flagfile=/var/run/qubes-service/qubes-ipv6 +ipv6_prefix="fd09:24ef:4179:0000::" + # PIDfile handling [[ -e $PIDFILE ]] && kill -s 0 $(<$PIDFILE) 2>/dev/null && exit 0 echo $$ >$PIDFILE @@ -14,6 +18,14 @@ trap 'exit 0' SIGTERM FIRST_TIME=yes +convert_rules_ipv6() { + RULES_WORK="$1" + RULES_WORK="`echo "$RULES_WORK" | sed -e "s/ -s 10\./ -s ${ipv6_prefix}10./g"`" + RULES_WORK="`echo "$RULES_WORK" | sed -e "s/ -d \(10\.13[78]\.\)/ -d ${ipv6_prefix}\1/g"`" + RULES_WORK="`echo "$RULES_WORK" | sed -e "s/\/adm-prohibited/g"`" + echo "$RULES_WORK" +} + while true; do echo "1" > /proc/sys/net/ipv4/ip_forward @@ -37,14 +49,28 @@ while true; do RULES=$(xenstore-read $XENSTORE_IPTABLES_HEADER) IPTABLES_SAVE=$(iptables-save | sed '/^\*filter/,/^COMMIT/d') OUT=`echo -e "$RULES\n$IPTABLES_SAVE" | iptables-restore 2>&1 || true` + if [ -e "$ipv6_flagfile" ]; then + RULES6=`convert_rules_ipv6 "$RULES"` + IP6TABLES_SAVE=$(ip6tables-save | sed '/^\*filter/,/^COMMIT/d') + ERRS=`echo -e "$RULES6\n$IP6TABLES_SAVE" | ip6tables-restore 2>&1 || true` + OUT="$OUT$ERRS" + fi for i in $(xenstore-list qubes-iptables-domainrules) ; do RULES=$(xenstore-read qubes-iptables-domainrules/"$i") ERRS=`echo -e "$RULES" | /sbin/iptables-restore -n 2>&1 || true` if [ -n "$ERRS" ]; then - echo "Failed applying rules for $i: $ERRS" >&2 + echo "Failed applying ipv4 rules for $i: $ERRS" >&2 OUT="$OUT$ERRS" fi + if [ -e "$ipv6_flagfile" ]; then + RULES6=`convert_rules_ipv6 "$RULES"` + ERRS=`echo -e "$RULES6" | /sbin/ip6tables-restore -n 2>&1 || true` + if [ -n "$ERRS" ]; then + echo "Failed applying ipv6 rules for $i: $ERRS" >&2 + OUT="$OUT$ERRS" + fi + fi done xenstore-write $XENSTORE_ERROR "$OUT" if [ -n "$OUT" ]; then diff --git a/network/setup-ip b/network/setup-ip index 08d2d5ccc..1c9950601 100755 --- a/network/setup-ip +++ b/network/setup-ip @@ -1,5 +1,8 @@ #!/bin/sh +ipv6_flagfile=/var/run/qubes-service/qubes-ipv6 +ipv6_prefix="fd09:24ef:4179:0000::" + if [ -x /usr/sbin/xenstore-read ]; then XENSTORE_READ="/usr/sbin/xenstore-read" else @@ -12,6 +15,9 @@ if [ x$ip != x ]; then gateway=`$XENSTORE_READ qubes-gateway` secondary_dns=`$XENSTORE_READ qubes-secondary-dns` /sbin/ifconfig $INTERFACE $ip netmask 255.255.255.255 + if [ -e "$ipv6_flagfile" ]; then + /sbin/ip addr add "$ipv6_prefix$ip/128" dev $INTERFACE + fi /sbin/ifconfig $INTERFACE up /sbin/route add -host $gateway dev $INTERFACE if [ -f /var/run/qubes-service/set-default-route ]; then @@ -38,9 +44,6 @@ id=VM uplink $INTERFACE uuid=de85f79b-8c3d-405f-a652-cb4c10b4f9ef type=802-3-ethernet -[ipv6] -method=ignore - [ipv4] method=manual may-fail=false @@ -53,6 +56,22 @@ __EOF__ else echo "address1=$ip/32" >> $nm_config fi + if [ -e "$ipv6_flagfile" ]; then + cat >> $nm_config <<__EOF__ +[ipv6] +method=manual +__EOF__ + if [ -f /var/run/qubes-service/set-default-route ]; then + echo "address1=fd09:24ef:4179:0000::$ip/128,fe80::fcff:ffff:feff:ffff" >> $nm_config + else + echo "address1=fd09:24ef:4179:0000::$ip/128" >> $nm_config + fi + else + cat >> $nm_config <<__EOF__ +[ipv6] +method=ignore +__EOF__ + fi chmod 600 $nm_config fi network=$($XENSTORE_READ qubes-netvm-network 2>/dev/null) diff --git a/network/vif-route-qubes b/network/vif-route-qubes index 68fbf389c..5f5168211 100755 --- a/network/vif-route-qubes +++ b/network/vif-route-qubes @@ -23,6 +23,8 @@ dir=$(dirname "$0") . "$dir/vif-common.sh" +ipv6_prefix=fd09:24ef:4179:0000:: +ipv6_flagfile=/var/run/qubes-service/qubes-ipv6 #main_ip=$(dom0_ip) case "$command" in @@ -48,12 +50,16 @@ domid=${domid/.*/} metric=$[ 32752 - $domid ] if [ "${ip}" ] ; then - # If we've been given a list of IP addresses, then add routes from dom0 to + # If we've been given a list of IP addresses, then add routes to # the guest using those addresses. for addr in ${ip} ; do ${cmdprefix} ip route ${ipcmd} ${addr} dev ${vif} metric $metric + if [ -e "$ipv6_flagfile" ]; then + ${cmdprefix} ip -6 route ${ipcmd} ${ipv6_prefix}${ip} dev ${vif} metric $metric + fi done ${cmdprefix} iptables -t raw $iptables_cmd -i ${vif} \! -s ${ip} -j DROP + ${cmdprefix} ip6tables -t raw $iptables_cmd -i ${vif} \! -s ${ipv6_prefix}${ip} -j DROP back_ip=`xenstore-read qubes-netvm-gateway` ${cmdprefix} ip addr ${ipcmd} ${back_ip}/32 dev ${vif} fi