firewall: periodically re-resolve NTP servers

Google's Public NTP servers don't have static IP addresses, so the
addresses that clients resolve for them will change over time. Make sure
our firewall rules stay in step with this, at least most of the time.

Fixes b/29131559.

Change-Id: Ia27a36471fb39e8cceb2797d216f148ae38177c0
diff --git a/fs/skeleton/bin/update-ntp-filters b/fs/skeleton/bin/update-ntp-filters
new file mode 100755
index 0000000..9625b78
--- /dev/null
+++ b/fs/skeleton/bin/update-ntp-filters
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+. /etc/utils.sh
+
+FAILURE_DELAY="30"
+SUCCESS_DELAY="900"
+
+while :; do
+  ip46tables -F captive-portal-ntp
+
+  code="0"
+  for dst in $@; do
+    echo "Updating ntp server: $dst"
+    ip46tables -A captive-portal-ntp -p udp -d "$dst" --dport ntp -j ACCEPT
+    code=$(( $code | $? ))
+  done
+
+  if [ "$code" -eq "0" ]; then
+    echo "Success. Next update in $SUCCESS_DELAY s."
+    sleep "$SUCCESS_DELAY"
+  else
+    echo "Failure! Trying again in $FAILURE_DELAY s."
+    sleep "$FAILURE_DELAY"
+  fi
+done
diff --git a/fs/skeleton/etc/init.d/S41portal_firewall b/fs/skeleton/etc/init.d/S41portal_firewall
index eb0f706..bce1c8c 100755
--- a/fs/skeleton/etc/init.d/S41portal_firewall
+++ b/fs/skeleton/etc/init.d/S41portal_firewall
@@ -4,17 +4,17 @@
 # Servers used by CPE on the other side of the captive portal.
 IP4_DNS="8.8.8.8 8.8.4.4"
 IP6_DNS="2001:4860:4860::8888 2001:4860:4860::8844"
-# TODO(b/29131559): allow NTP servers to be dynamically updated
-NTP="216.239.32.15 216.239.34.15 216.239.36.15 216.239.38.15"
+NTP_SERVERS="time1.google.com time2.google.com time3.google.com time4.google.com"
 
 has_iptables() {
   runnable iptables && iptables -L 2>/dev/null
 }
 
 flush() {
-  ip46tables -F captive-portal-input
-  ip46tables -F captive-portal-filter
   ip46tables -F captive-portal-guests
+  ip46tables -F captive-portal-filter
+  ip46tables -F captive-portal-ntp
+  ip46tables -F captive-portal-input
 }
 
 case "$1" in
@@ -59,13 +59,12 @@
         ip6tables -A captive-portal-filter -p icmpv6 -d $dst --icmpv6-type echo-request -j ACCEPT
       done
 
-      for dst in $NTP; do
-        iptables -A captive-portal-filter -p udp -d $dst --dport ntp -j ACCEPT
-      done
+      nice babysit 60 update-ntp-filters $NTP_SERVERS 2>&1 | logos update-ntp-filters &
     fi
     ;;
   stop)
     if has_iptables && is-network-box; then
+      pkillwait -x update-ntp-filters
       flush
     fi
     ;;
diff --git a/fs/skeleton/etc/init.d/firewall b/fs/skeleton/etc/init.d/firewall
index 8261889..f4d718a 100755
--- a/fs/skeleton/etc/init.d/firewall
+++ b/fs/skeleton/etc/init.d/firewall
@@ -149,6 +149,7 @@
       # what services we're trying to provide with it.
       ip46tables -N captive-portal-guests
       ip46tables -N captive-portal-filter
+      ip46tables -N captive-portal-ntp
       ip46tables -N captive-portal-input
       ip46tables -N acs-captive-portal-input
       ip46tables -N sniproxy-input
@@ -177,6 +178,7 @@
 
       ip46tables -A FORWARD -i br1 -o wan0+ -j captive-portal-guests
       ip46tables -A FORWARD -i br1 -o wan0+ -j captive-portal-filter
+      ip46tables -A FORWARD -i br1 -o wan0+ -j captive-portal-ntp
 
       for ifc in lo br0; do
         ip46tables -A INPUT -i "$ifc" -j ACCEPT