From 3e4004e6b10bdb0235588293cd4b0d1539928b1b Mon Sep 17 00:00:00 2001 From: Joe Roback Date: Tue, 18 Nov 2025 07:46:50 -0700 Subject: [PATCH] iptables save/restore, attempting to fix connectivity if container restarts --- entrypoint.sh | 70 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 44 insertions(+), 26 deletions(-) diff --git a/entrypoint.sh b/entrypoint.sh index 7312e50..a209696 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -2,15 +2,25 @@ set -o errexit +info() { + printf "I %5d %s\n" "${$}" "${*}" +} + +fatal() { + printf "F %5d %s\n" "${$}" "${*}" >&2 + exit 1 +} + +iptables-save | tee /tmp/rules.v4.$$.conf +ip6tables-save | tee /tmp/rules.v6.$$.conf + default_route_ip=$(ip route | grep '^default' | awk '{print $3}') if [[ -z "${default_route_ip}" ]]; then - echo "Error: No default route configured" >&2 - exit 1 + fatal "Error: No default route configured" fi if [[ "$(cat /proc/sys/net/ipv4/conf/all/src_valid_mark)" != "1" ]]; then - echo "Error: sysctl net.ipv4.conf.all.src_valid_mark=1 is not set" >&2 - exit 1 + fatal "Error: sysctl net.ipv4.conf.all.src_valid_mark=1 is not set" fi # sysctl is set by container, wg-quick will then error @@ -19,19 +29,21 @@ sed -i "s:sysctl -q net.ipv4.conf.all.src_valid_mark=1:echo Skipping setting net WIREGUARD_INTERFACE="${WIREGUARD_INTERFACE:-wg0}" if [ ! -f "/etc/wireguard/${WIREGUARD_INTERFACE}.conf" ]; then - echo "Error: Configuration file /etc/wireguard/${WIREGUARD_INTERFACE}.conf does not exist" >&2 - exit 1 + fatal "Error: Configuration file /etc/wireguard/${WIREGUARD_INTERFACE}.conf does not exist" fi -echo "Bringing up wireguard interface: ${WIREGUARD_INTERFACE}..." +info "Bringing up wireguard interface: ${WIREGUARD_INTERFACE}..." wg-quick up ${WIREGUARD_INTERFACE} shutdown () { + info "shutting down wireguard interface: ${WIREGUARD_INTERFACE}..." wg-quick down ${WIREGUARD_INTERFACE} - exit 0 + info "restoring iptables..." + iptables-restore -n < /tmp/rules.v4.$$.conf + info "restoring ip6tables..." + ip6tables-restore -n < /tmp/rules.v6.$$.conf } - -trap shutdown SIGTERM SIGINT SIGQUIT +trap shutdown EXIT wg show WIREGUARD_FWMARK=$(wg show ${WIREGUARD_INTERFACE} fwmark) @@ -39,37 +51,40 @@ WIREGUARD_FWMARK=$(wg show ${WIREGUARD_INTERFACE} fwmark) # allow connections from container subnets for container_subnet in $(ip -o addr show | awk '/^(\d)+: eth(.+)inet / {print $4}') do - iptables -A INPUT -s ${container_subnet} -j ACCEPT - iptables -A OUTPUT -d ${container_subnet} -j ACCEPT + iptables -I INPUT -s ${container_subnet} -j ACCEPT + iptables -I OUTPUT -d ${container_subnet} -j ACCEPT done # allow connections to local subnets specified by user, need to add routes since wireguard interface has 0.0.0.0/0 allowed ips for local_subnet in ${LOCAL_IPV4_SUBNETS//,/$IFS} do - iptables -A INPUT -s ${local_subnet} -j ACCEPT - iptables -A OUTPUT -d ${local_subnet} -j ACCEPT + iptables -I INPUT -s ${local_subnet} -j ACCEPT + iptables -I OUTPUT -d ${local_subnet} -j ACCEPT ip route add ${local_subnet} via ${default_route_ip} done # established connections -iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -iptables -A OUTPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT +iptables -I INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT +iptables -I OUTPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT # kill switches for ipv4 -- @see wg-quick(8) -iptables -A OUTPUT ! -o ${WIREGUARD_INTERFACE} -m mark ! --mark ${WIREGUARD_FWMARK} -m addrtype ! --dst-type LOCAL -j REJECT +iptables -A OUTPUT ! -o ${WIREGUARD_INTERFACE} -m mark ! --mark ${WIREGUARD_FWMARK} -m addrtype ! --dst-type LOCAL -j REJECT --reject-with icmp-admin-prohibited for container_subnet in $(ip -o addr show | awk '/^(\d)+: eth(.+)inet6 / {print $4}') do - ip6tables -A INPUT -s ${container_subnet} -j ACCEPT - ip6tables -A OUTPUT -d ${container_subnet} -j ACCEPT + ip6tables -I INPUT -s ${container_subnet} -j ACCEPT + ip6tables -I OUTPUT -d ${container_subnet} -j ACCEPT done # established connections -ip6tables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -ip6tables -A OUTPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT +ip6tables -I INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT +ip6tables -I OUTPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT # kill switches for ipv6 -- @see wg-quick(8) -ip6tables -I OUTPUT ! -o ${WIREGUARD_INTERFACE} -m mark ! --mark ${WIREGUARD_FWMARK} -m addrtype ! --dst-type LOCAL -j REJECT +ip6tables -A OUTPUT ! -o ${WIREGUARD_INTERFACE} -m mark ! --mark ${WIREGUARD_FWMARK} -m addrtype ! --dst-type LOCAL -j REJECT --reject-with icmp6-adm-prohibited + +iptables-save | tee /tmp/rules.v4.${WIREGUARD_INTERFACE}.$$.conf +ip6tables-save | tee /tmp/rules.v6.${WIREGUARD_INTERFACE}.$$.conf sleep 8 & wait ${!} @@ -84,6 +99,9 @@ wait ${!} # qbittorrent webui host WEBUI_HOST="${WEBUI_HOST:-http://localhost:8080}" +# from this point on, its best effort, so just keep going and don't fail the container +set +o errexit + # loop now forever keeping port forward up to date (protonvpn) # https://protonvpn.com/support/port-forwarding-manual-setup while true; do @@ -94,14 +112,14 @@ while true; do udp_port=$(echo "${udp_output}" | sed -n 's/.*Mapped public port \([0-9]\+\).*/\1/p') if [[ "${tcp_port}" -ne "${udp_port}" ]]; then - echo "Warning: tcp_port (${tcp_port}) and udp_port (${udp_port}) are different" + info "Warning: tcp_port (${tcp_port}) and udp_port (${udp_port}) are different" fi # failure to connect to webui, we don't want to fail the loop, just log the error and try again current_port=$(curl --silent --header "Referer: ${WEBUI_HOST}" "${WEBUI_HOST}/api/v2/app/preferences" | jq .listen_port || true) if [[ "${tcp_port}" -ne "${current_port}" ]]; then - echo "Port changed from '${current_port}' to '${tcp_port}'. Updating app preferences..." + info "Port changed from '${current_port}' to '${tcp_port}'. Updating app preferences..." curl \ --silent \ @@ -111,9 +129,9 @@ while true; do "${WEBUI_HOST}/api/v2/app/setPreferences" || true fi - sleep 30 & + sleep 45 & wait ${!} done -echo "exiting" +info "exiting." exit 0