[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 4/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. 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: [no rules added] * ip="2001:aaaa:bbbb:cccc::1 eui64" iptables: [no rules added] 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 Signed-off-by: Sylvain Munaut <s.munaut@xxxxxxxxxxxxxxxxxxxx> --- docs/man/xl-network-configuration.markdown.5 | 16 +++++ tools/hotplug/Linux/vif-common.sh | 89 ++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+) diff --git a/docs/man/xl-network-configuration.markdown.5 b/docs/man/xl-network-configuration.markdown.5 index 3c439d4..5b86974 100644 --- a/docs/man/xl-network-configuration.markdown.5 +++ b/docs/man/xl-network-configuration.markdown.5 @@ -128,6 +128,21 @@ configured. A typically behaviour (exhibited by the example hotplug scripts) if set might be to configure firewall rules to allow only the specified IP address to be used by the guest (blocking all others). +The linux hotplug script supports both IPv4 and IPv6 in this field. When +the field is omitted or empty, both will be fully allowed. If only IPv4s +are listed, then IPv6 will be blocked completely. Symmetrically, if only +IPv6s are listed, then IPv4 will be blocked. If you wish to filter one +but not the other, you can use the wildcard addresses 0.0.0.0/0 and +::0/0 for IPv4/6 respectively. + +As a special case, you can use 'eui64' token as an IPv6 address and this +will allow traffic all traffic from the VM where the lower 64 bits are +matched against the [EUI64] generated from the mac address of the VIF. It +is up to the network administrator to filter the network part of the +address globally if necessary. This is of course only usable for the +vif-bridge script as the vif-route will require a fully defined address +in the 'ip' field. + ### backend Specifies the backend domain which this device should attach to. This @@ -166,3 +181,4 @@ on the underlying netback implementation. [oui]: http://en.wikipedia.org/wiki/Organizationally_Unique_Identifier [net]: http://wiki.xen.org/wiki/HostConfiguration/Networking [vifroute]: http://wiki.xen.org/wiki/Vif-route +[EUI64]: http://en.wikipedia.org/wiki/IPv6_address#Modified_EUI-64 diff --git a/tools/hotplug/Linux/vif-common.sh b/tools/hotplug/Linux/vif-common.sh index 3755f0a..b92c36c 100644 --- a/tools/hotplug/Linux/vif-common.sh +++ b/tools/hotplug/Linux/vif-common.sh @@ -121,6 +121,7 @@ ip=${ip:-} ip=$(xenstore_read_default "$XENBUS_PATH/ip" "$ip") chain_v4=FORWARD +chain_v6=FORWARD frob_iptable() { @@ -169,6 +170,71 @@ frob_iptable() 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] }') + # Refer to http://en.wikipedia.org/wiki/IPv6_address#Modified_EUI-64 + + # 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" "$chain_v6" -w $dev_in_match "$dev" \ + -s "$addr" -j ACCEPT 2>/dev/null || has_err="yes" + done + + # Always Allow all packets _to_ the domain + ip6tables "$c" "$chain_v6" -w $dev_out_match "$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" "$chain_v6" -w $dev_in_match "$dev" \ + -s "fe80::$eui64" -j ACCEPT 2>/dev/null || has_err="yes" + + # Always allow the domain to talk to a DHCP server + ip6tables "$c" "$chain_v6" -w $dev_in_match "$dev" \ + -p udp --sport 546 --dport 547 -j ACCEPT 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" }' +} + ## # Add or remove the appropriate entries in the iptables. With antispoofing @@ -198,19 +264,34 @@ handle_iptable() return fi + # User has a working IPv4 iptables, but maybe no IPv6 support ... + local do_ipv6="yes" + + if ! ip6tables -L -w -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 @@ -221,6 +302,14 @@ handle_iptable() frob_iptable $ipv4_addrs fi + if [ "$ipv6_addrs" != "" -a "$do_ipv6" = "yes" ] + then + frob_ip6table $ipv6_addrs + elif [ "$ipv6_addrs" != "" -a "$ipv6_addrs" != "any" ] + then + log err "ip6tables setup skipped. This may affect guest networking." + fi + release_lock "iptables" } -- 2.1.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |