Skip to content

Commit d175b97

Browse files
committed
Fix: Fail closed on zero resolvers in enforce-redirect
Review follow-up: when /etc/resolv.conf yields no nameservers, the prior code logged a WARNING and proceeded, leaving a running-but-DNS-dead pod (UDP/53 dropped, TCP/53 captured) that is hard to triage. Exit non-zero instead so the init container surfaces as Init:Error. In a Kubernetes pod kubelet always populates resolv.conf, so this only fires on a genuine misconfiguration; the error message points outside-Kubernetes users at RESOLV_CONF. The guard runs before any iptables mutation. Adds a fail-closed test case. Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Hai Huang <huang195@gmail.com>
1 parent 343aed4 commit d175b97

2 files changed

Lines changed: 22 additions & 1 deletion

File tree

authbridge/proxy-init/init-iptables.sh

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,9 +264,17 @@ setup_enforce_redirect() {
264264
REDIR_CHAIN="AB_REDIRECT"
265265
NOTCP_CHAIN="AB_NOTCP"
266266

267+
# Fail closed and LOUD on zero resolvers: without a nameserver to exempt, the
268+
# rules below would drop UDP/53 and capture TCP/53, leaving a running-but-DNS-
269+
# dead pod that is far harder to triage than a failed init container. In a
270+
# Kubernetes pod kubelet always populates resolv.conf, so an empty result means
271+
# a real misconfiguration — surface it as Init:Error rather than silent breakage.
267272
NAMESERVERS=$(get_nameservers)
268273
if [ -z "${NAMESERVERS}" ]; then
269-
echo "enforce-redirect: WARNING: no nameservers found in ${RESOLV_CONF} — cluster DNS may break (UDP/53 dropped, TCP/53 captured)"
274+
echo "enforce-redirect: ERROR: no nameservers found in ${RESOLV_CONF}" >&2
275+
echo "enforce-redirect: refusing to start — DNS egress would be dropped (UDP/53) / captured (TCP/53), silently breaking name resolution." >&2
276+
echo "enforce-redirect: set RESOLV_CONF to a file with valid 'nameserver' entries if running outside Kubernetes." >&2
277+
exit 1
270278
fi
271279

272280
echo "enforce-redirect: installing fail-closed egress capture"

authbridge/proxy-init/test-enforce-redirect.sh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,19 @@ else
147147
echo "FAIL: external UDP not dropped (DROP=${dropc:-?})"; fail=1
148148
fi
149149

150+
echo "### Fail-closed test: empty resolv.conf must abort init (exit non-zero)"
151+
# The zero-resolver check runs before any iptables mutation, so this re-invocation
152+
# leaves the rules above untouched. A running-but-DNS-dead pod is worse than a
153+
# failed init, so enforce-redirect refuses to start without a resolver to exempt.
154+
EMPTY_RESOLV=$(mktemp) # created empty: no `nameserver` lines
155+
if env MODE=enforce-redirect PROXY_UID=1337 RESOLV_CONF="${EMPTY_RESOLV}" \
156+
TRANSPARENT_PORT="${TPORT}" IPTABLES_CMD="${IPT}" IP6TABLES_CMD=ip6tables-nft \
157+
sh "${INIT}" >/dev/null 2>&1; then
158+
echo "FAIL: init succeeded with empty resolv.conf (should exit non-zero)"; fail=1
159+
else
160+
echo "PASS: init aborts fail-closed when resolv.conf has no nameservers"
161+
fi
162+
150163
echo
151164
[ "${fail}" -eq 0 ] && echo "ALL TESTS PASSED" || echo "SOME TESTS FAILED"
152165
exit "${fail}"

0 commit comments

Comments
 (0)