[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 3/5] hotplug/linux: Add IPv6 support to the iptables logic
This adds the same functions for ip6tables as the one for iptables. The 'ip' variable can now contain ipv6s for the domain and add appropriate rules - If the 'ip' var is empty then both full IPv4 and IPv6 are allowed. - If only IPv4 ips are present, then IPv6 will be completely disallowed. - If only IPv6 ips are present, then IPv4 will be completely disallowed. - You can use ::0/0 or 0.0.0.0/0 to allow v6 or v4 globally but filter the other one. (see below for examples of rules generated after this patch) This gracefully handles if the dom0 doesn't have IPv6. If the call to ip6tables doesn't succeed, it just ignores any IPv6 stuff. By default, domains aren't allows to send Router Advertisement or DHCP responses, see the ipv6_allow_ra to enable them. This is to limit the risk of a rogue VM sending RA and DHCPv6 response to try and intercept traffic by taking advantage of unconfigured VMs (where IPv6 autoconfig is enabled by default but not used) Examples of rules added : * ip="" iptables: ACCEPT all 0.0.0.0/0 0.0.0.0/0 PHYSDEV match --physdev-in vif91.0 --physdev-is-bridged ACCEPT all 0.0.0.0/0 0.0.0.0/0 PHYSDEV match --physdev-out vif91.0 --physdev-is-bridged ip6tables: DROP udp ::/0 ::/0 PHYSDEV match --physdev-in vif91.0 --physdev-is-bridged udp spt:547 dpt:546 DROP icmpv6 ::/0 ::/0 PHYSDEV match --physdev-in vif91.0 --physdev-is-bridged ipv6-icmptype 134 ACCEPT all ::/0 ::/0 PHYSDEV match --physdev-out vif91.0 --physdev-is-bridged ACCEPT all ::/0 ::/0 PHYSDEV match --physdev-in vif91.0 --physdev-is-bridged * ip="192.168.0.254" iptables: ACCEPT udp 0.0.0.0/0 0.0.0.0/0 PHYSDEV match --physdev-in vif92.0 --physdev-is-bridged udp spt:68 dpt:67 ACCEPT all 0.0.0.0/0 0.0.0.0/0 PHYSDEV match --physdev-out vif92.0 --physdev-is-bridged ACCEPT all 192.168.0.254 0.0.0.0/0 PHYSDEV match --physdev-in vif92.0 --physdev-is-bridged ip6tables: [nothing] * ip="2001:aaaa:bbbb:cccc::1 eui64" iptables: [nothing] ip6tables: DROP udp ::/0 ::/0 PHYSDEV match --physdev-in vif94.0 --physdev-is-bridged udp spt:547 dpt:546 DROP icmpv6 ::/0 ::/0 PHYSDEV match --physdev-in vif94.0 --physdev-is-bridged ipv6-icmptype 134 ACCEPT udp ::/0 ::/0 PHYSDEV match --physdev-in vif94.0 --physdev-is-bridged udp spt:546 dpt:547 ACCEPT all fe80::216:3eff:fed0:da2d/128 ::/0 PHYSDEV match --physdev-in vif94.0 --physdev-is-bridged ACCEPT all ::/0 ::/0 PHYSDEV match --physdev-out vif94.0 --physdev-is-bridged ACCEPT all 2001:aaaa:bbbb:cccc::1/128 ::/0 PHYSDEV match --physdev-in vif94.0 --physdev-is-bridged ACCEPT all ::216:3eff:fed0:da2d/::ffff:ffff:ffff:ffff ::/0 PHYSDEV match --physdev-in vif94.0 --physdev-is-bridged * ip="192.168.0.254 2001:aaaa:bbbb:cccc::1" (either ipv4 or ipv6 can be replaced by the 0.0.0.0/0 or ::0/0 address to allow any, the dhcp/nd rules might be redudant then). iptables: ACCEPT udp 0.0.0.0/0 0.0.0.0/0 PHYSDEV match --physdev-in vif95.0 --physdev-is-bridged udp spt:68 dpt:67 ACCEPT all 0.0.0.0/0 0.0.0.0/0 PHYSDEV match --physdev-out vif95.0 --physdev-is-bridged ACCEPT all 192.168.0.254 0.0.0.0/0 PHYSDEV match --physdev-in vif95.0 --physdev-is-bridged ip6tables: DROP udp ::/0 ::/0 PHYSDEV match --physdev-in vif95.0 --physdev-is-bridged udp spt:547 dpt:546 DROP icmpv6 ::/0 ::/0 PHYSDEV match --physdev-in vif95.0 --physdev-is-bridged ipv6-icmptype 134 ACCEPT udp ::/0 ::/0 PHYSDEV match --physdev-in vif95.0 --physdev-is-bridged udp spt:546 dpt:547 ACCEPT all fe80::216:3eff:fed0:da2d/128 ::/0 PHYSDEV match --physdev-in vif95.0 --physdev-is-bridged ACCEPT all ::/0 ::/0 PHYSDEV match --physdev-out vif95.0 --physdev-is-bridged WARNING: There is currently no way to set the ipv6_allow_ra option Support for this will come in a later patch. Signed-off-by: Sylvain Munaut <s.munaut@xxxxxxxxxxxxxxxxxxxx> --- tools/hotplug/Linux/vif-common.sh | 95 +++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/tools/hotplug/Linux/vif-common.sh b/tools/hotplug/Linux/vif-common.sh index b098630..6cbb963 100644 --- a/tools/hotplug/Linux/vif-common.sh +++ b/tools/hotplug/Linux/vif-common.sh @@ -121,6 +121,8 @@ fi ip=${ip:-} ip=$(xenstore_read_default "$XENBUS_PATH/ip" "$ip") +ipv6_allow_ra=$(xenstore_read_default "$XENBUS_PATH/ipv6_allow_ra" "false") + frob_iptable() { local has_err="no" @@ -167,6 +169,79 @@ frob_iptable() log err "iptables setup failed. This may affect guest networking." fi } + +frob_ip6table() +{ + local has_err="no" + local has_any="no" + local mac=$(xenstore_read "$XENBUS_PATH/mac") + local eui64=$(echo $mac | awk '{split($1,i,":"); print xor(i[1],2) i[2] ":" i[3] "ff:fe" i[4] ":" i[5] i[6] }') + + # Add or remove + if [ "$command" == "online" -o "$command" == "add" ] + then + local c="-I" + else + local c="-D" + fi + + # Add rules for each address + local addr + + for addr in $@; do + if [ "$addr" = "any" ]; then + addr="::0/0" + has_any="yes" + elif [ "$addr" = "eui64" ]; then + addr="::$eui64/::ffff:ffff:ffff:ffff" + fi + + ip6tables "$c" FORWARD -m physdev --physdev-is-bridged --physdev-in "$dev" \ + -s "$addr" -j ACCEPT 2>/dev/null || has_err="yes" + done + + # Always Allow all packets _to_ the domain + ip6tables "$c" FORWARD -m physdev --physdev-is-bridged --physdev-out "$dev" \ + -j ACCEPT 2>/dev/null || has_err="yes" + + # If 'any' isn't allowed, we needs to allow a few more things + if [ "$has_any" != "yes" ] + then + + # Always allow ICMP messages from link-local addresses (for ND) + ip6tables "$c" FORWARD -m physdev --physdev-is-bridged --physdev-in "$dev" \ + -s "fe80::$eui64" -j ACCEPT 2>/dev/null || has_err="yes" + + # Always allow the domain to talk to a DHCP server + ip6tables "$c" FORWARD -m physdev --physdev-is-bridged --physdev-in "$dev" \ + -p udp --sport 546 --dport 547 -j ACCEPT 2>/dev/null || has_err="yes" + + fi + + # Filter out RA and DHCP server responses if not explicitely allowed + if [ "$ipv6_allow_ra" != "true" ] + then + ip6tables "$c" FORWARD -m physdev --physdev-is-bridged --physdev-in "$dev" \ + -p icmpv6 --icmpv6-type router-advertisement -j DROP 2>/dev/null || has_err="yes" + + ip6tables "$c" FORWARD -m physdev --physdev-is-bridged --physdev-in "$dev" \ + -p udp --sport 547 --dport 546 -j DROP 2>/dev/null || has_err="yes" + fi + + # Error handling + if [ \( "$command" == "online" -o "$command" == "add" \) -a "$has_err" == "yes" ] + then + log err "ip6tables setup failed. This may affect guest networking." + fi +} + + +## +# Check if the given IP is IPv6 or not +# +is_ipv6() +{ + echo "$1" | awk '/:|eui64/ { print "yes" }' } @@ -188,19 +263,34 @@ handle_iptable() return fi + # User has a working IPv4 iptables, but maybe no IPv6 support ... + local do_ipv6="yes" + + if ! ip6tables -L -n >&/dev/null + then + do_ipv6="no" + fi + # Scan through the addresses local ipv4_addrs + local ipv6_addrs if [ "$ip" != "" ] then local addr for addr in $ip do + result=$(is_ipv6 "$addr") + if [ -z "$result" ] ; then ipv4_addrs="$addr $ipv4_addrs" + else + ipv6_addrs="$addr $ipv6_addrs" + fi done else # No IP addresses have been specified, so allow anything. ipv4_addrs="any" + ipv6_addrs="any" fi # Actually add the rules @@ -211,6 +301,11 @@ handle_iptable() frob_iptable $ipv4_addrs fi + if [ "$ipv6_addrs" != "" -a "$do_ipv6" = "yes" ] + then + frob_ip6table $ipv6_addrs + fi + release_lock "iptables" } -- 1.7.10.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |