From e4171acc6f48a4fffb60f7d877f00f92af5019d7 Mon Sep 17 00:00:00 2001 From: MegaBrutal Date: Fri, 5 Jan 2018 09:30:00 +0100 Subject: [PATCH] fix-ip6-default-route.sh: Added script to monitor IPv6 default route Added a Debian/Ubuntu specific script to check the IPv6 default route of the host, whether it is absent or configured from RA while it is supposed to be static. This is necessary because LXC containers are often affected by a race condition, when the interface has a static config, but it gets a default route through Router Advertisement before RAs get disabled. For reference: https://www.mail-archive.com/lxc-users@lists.linuxcontainers.org/msg07776.html https://github.com/lxc/lxd/issues/3582 Although a bit messy, this script is intended to be fool-proof, so it does not do any harm if it is run on a host where it has no use to run. So you can deploy it to all LXC containers in your uniform environment where RA, DHCPv6 and statically configured containers may co-exist. It is advised to schedule this script (e.g. with cron) to have it periodically check the IPv6 default route. Unless the -v (verbose) option is supplied, the script should only have output when it does some action, otherwise it's silent. The script checks whether there are only static IPv6 interface configurations listed in /etc/network/interfaces. If any interface is automatically configured on purpose, the script stops (as it is assumed the host is supposed to get its default route through automatic configuration). If only static inet6 interface configs exist and a default route is clearly defined, it checks the IPv6 default route. If there is no default route, or it is received from RA, the script resets the interface and reconfigures it with ifup. new file: host/fix-ip6-default-route.sh --- host/fix-ip6-default-route.sh | 61 +++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100755 host/fix-ip6-default-route.sh diff --git a/host/fix-ip6-default-route.sh b/host/fix-ip6-default-route.sh new file mode 100755 index 0000000..7eb91f2 --- /dev/null +++ b/host/fix-ip6-default-route.sh @@ -0,0 +1,61 @@ +#!/bin/sh +export PATH=${PATH}:/sbin +NETCFG=/etc/network/interfaces + +[ "$1" = "-v" ] && DEBUG="printf" || DEBUG="true" + +lastiface="" +lastgateway="" + +while read -r line +do + if echo "${line}" | grep -q "[ \t]*#" + then + false + elif echo "${line}" | grep -q "^iface [^ ]* inet6 [^ ]*$" + then + echo "${line}" | ( IFS=' ' read -r _ iface _ method + "${DEBUG}" "Found %s with method %s.\n" "${iface}" "${method}" + if [ "${method}" != "static" ] + then + "${DEBUG}" "Interface %s does not use static configuration. Ambiguous config, exiting.\n" "${iface}" + exit 2 + fi + ) || exit $? + lastiface="${line}" + elif [ -n "${lastiface}" ] + then + if gateway=$(echo "${line}" | grep -o "gateway *[0-9a-fA-F:]*:[0-9a-fA-F:]*") + then + if [ -z "${lastgateway}" ] + then + lastgateway="${gateway}" + "${DEBUG}" "Found %s for %s.\n" "${lastgateway}" "${lastiface}" + else + "${DEBUG}" "A gateway was already defined for another interface. Ambiguous situation, exiting.\n" + exit 3 + fi + fi + fi +done < "${NETCFG}" + +if [ -z "${lastiface}" ] +then + "${DEBUG}" "No inet6 interface config found.\n" + exit 1 +else + iface=$(echo "${lastiface}" | grep -oP "(?<=iface )[^ ]*(?= inet6)") + "${DEBUG}" "Checking if %s needs to be reconfigured...\n" "${iface}" +fi + +defroute=$(ip -6 route | grep "^default ") +if [ -z "${defroute}" ] || echo "${defroute}" | grep -q " proto ra " +then + # If we get here, we will provide output of our actions. It is not affected by verbose mode. + printf "No default route, or it is RA-configured. Reconfiguring %s...\n" "${iface}" + ifdown -v "${iface}" + ip link set "${iface}" down + ifup -v "${iface}" +else + "${DEBUG}" "Found healthy default route: %s.\nNo action is necessary.\n" "${defroute}" +fi -- 2.34.1