Running gateway container as non-root

Hello all,

I am trying to run the gateway image (Package gateway · GitHub) as a container on Kubernetes but I am unable to do so unless I run it as root. Has anyone had any success in running it as rootless? I tried adding all the security context capabilities there are to no avail: the gateway will fail with the following error unless it is run as root: iptables v1.8.10 (nf_tables): Could not fetch rule set generation id: Permission denied (you must be root)
By reading this firezone/rust/gateway at main · firezone/firezone · GitHub I thought setting the NET_ADMIN capability should suffice.
Any suggestions?

Best regards,

Sebastian

Hi @sebastian.daberdaku - see here for an unofficial Helm chart for running the Gateway on k8s:

For Docker, NET_ADMIN should suffice, but we have had reports from users on k8s that privileged is needed there as well. If you’re pulling the ghcr.io/firezone/gateway image, the iptables complaint is likely coming from this script where we set up masquerading/NAT:

Thank you @jamil for your response.
I am guessing that if I re-build the image by including the iptables/ip6tables commands as RUN directives in a new dockerfile, I could avoid having to run the container as root.
Sth like:

...
USER root
ARG IFACE="tun-firezone"
RUN iptables -C FORWARD -i $IFACE -j ACCEPT >/dev/null 2>&1 || iptables -A FORWARD -i $IFACE -j ACCEPT && \
    iptables -C FORWARD -o $IFACE -j ACCEPT >/dev/null 2>&1 || iptables -A FORWARD -o $IFACE -j ACCEPT && \
    iptables -t nat -C POSTROUTING -o e+ -j MASQUERADE >/dev/null 2>&1 || iptables -t nat -A POSTROUTING -o e+ -j MASQUERADE && \
    iptables -t nat -C POSTROUTING -o w+ -j MASQUERADE >/dev/null 2>&1 || iptables -t nat -A POSTROUTING -o w+ -j MASQUERADE && \
    ip6tables -C FORWARD -i $IFACE -j ACCEPT >/dev/null 2>&1 || ip6tables -A FORWARD -i $IFACE -j ACCEPT && \
    ip6tables -C FORWARD -o $IFACE -j ACCEPT >/dev/null 2>&1 || ip6tables -A FORWARD -o $IFACE -j ACCEPT && \
    ip6tables -t nat -C POSTROUTING -o e+ -j MASQUERADE >/dev/null 2>&1 || ip6tables -t nat -A POSTROUTING -o e+ -j MASQUERADE && \
    ip6tables -t nat -C POSTROUTING -o w+ -j MASQUERADE >/dev/null 2>&1 || ip6tables -t nat -A POSTROUTING -o w+ -j MASQUERADE
USER 1000:1000
...

I would then simplify the docker-init-gateway.sh script to

#!/bin/sh

if [ -f "${FIREZONE_TOKEN}" ]; then
    FIREZONE_TOKEN="$(cat "${FIREZONE_TOKEN}")"
    export FIREZONE_TOKEN
fi

exec "$@"

Would this work in your opinion?

Hi @sebastian.daberdaku - unfortunately, that won’t work. The iptables rules need to be inserted at runtime because they need to be applied to the running system.

Thanks for the clarification!

What about using sth like iptables-persistent? I could then mount the iptables configurations as files from configmaps and have iptables-service automatically load them at startup.