Skip to content

Instantly share code, notes, and snippets.

@epsilon-0
Last active May 20, 2022 09:09
Show Gist options
  • Save epsilon-0/a83fcba1e8ee7ec212f27239111f727a to your computer and use it in GitHub Desktop.
Save epsilon-0/a83fcba1e8ee7ec212f27239111f727a to your computer and use it in GitHub Desktop.
run commands in podman container/pod namespace
#!/bin/bash
die() { echo "$*" 1>&2 ; exit 1; }
# run commands in podman container/pod namespace, even in rootless containers
# the first argument is the pod or container name
# the rest of the arguments are the command that needs to be run in the namespace of the container/pod
# this works for rootless containers and can also allow separate wireguard or nftables configuration for each
# container/pod. This is particularly useful if forwarding an IP from a VPS without having a firewall at the VPS.
_name="$1"
shift
_container_name=""
if podman pod exists "$_name" > /dev/null 2>&1 ; then
_container_name="$(podman pod inspect "${_name}" | jq -r '.InfraContainerID')"
if [ "${_container_name}" = "null" ] || [ -z "${_container_name}" ]; then
die "Could not get infra container for '${_name}'"
fi
elif podman container exists "$_name" > /dev/null 2>&1 ; then
_container_name="$_name"
else
die "No pod or container by the name of '$_name'"
fi
if [ "$(podman container inspect -f '{{.State.Status}}' "${_container_name}")" != "running" ]; then
die "Container '$_container_name' is not running"
fi
_cpid="$(podman container inspect -f '{{.State.Pid}}' "${_container_name}")"
exec nsenter --preserve-credentials --user --cgroup --ipc --uts --net --pid --target ${_cpid} "$@"

examples for a rootless container 'epsilonknot' by the user 'epsilon'

start wireguard network in the pod 'epsilonknot'

@epsilon ~/$ podman pod create --name epsilonknot
@epsilon ~/$ podman pod start epsilonknot
@epsilon ~/$ pns epsilonknot wg-quick up ~/wireguard/www.conf
[#] ip link add www type wireguard
[#] wg setconf www /dev/fd/63
[#] ip -4 address add xx.xx.xx.xx/32 dev www
[#] ip -6 address add xx:xx:xx:xx::xx/xx dev www
[#] ip link set mtu 65440 up dev www
[#] wg set www fwmark 51820
[#] ip -6 route add ::/0 dev www table 51820
[#] ip -6 rule add not fwmark 51820 table 51820
[#] ip -6 rule add table main suppress_prefixlength 0
[#] nft -f /dev/fd/63
[#] ip -4 route add 0.0.0.0/0 dev www table 51820
[#] ip -4 rule add not fwmark 51820 table 51820
[#] ip -4 rule add table main suppress_prefixlength 0
[#] sysctl -q net.ipv4.conf.all.src_valid_mark=1
[#] nft -f /dev/fd/63

show nftable rules in the pod 'epsilonknot'

@epsilon ~/$ pns epsilonknot nft -a list ruleset
table ip6 wg-quick-www { # handle 22
        chain preraw { # handle 1
                type filter hook prerouting priority raw; policy accept;
                iifname != "www" ip6 daddr xx:xx:xx:xx::xx fib saddr type != local drop # handle 4
        }

        chain premangle { # handle 2
                type filter hook prerouting priority mangle; policy accept;
                meta l4proto udp meta mark set ct mark # handle 6
        }

        chain postmangle { # handle 3
                type filter hook postrouting priority mangle; policy accept;
                meta l4proto udp meta mark 0x0000ca6c ct mark set meta mark # handle 5
        }
}
table ip wg-quick-www { # handle 23
        chain preraw { # handle 1
                type filter hook prerouting priority raw; policy accept;
                iifname != "www" ip daddr xx.xx.xx.xx fib saddr type != local drop # handle 4
        }

        chain premangle { # handle 2
                type filter hook prerouting priority mangle; policy accept;
                meta l4proto udp meta mark set ct mark # handle 6
        }

        chain postmangle { # handle 3
                type filter hook postrouting priority mangle; policy accept;
                meta l4proto udp meta mark 0x0000ca6c ct mark set meta mark # handle 5
        }
}

add nftables table, chain and rule in the pod 'epsilonknot'

@epsilon ~/$ pns epsilonknot nft add table inet wgq-www
@epsilon ~/$ pns epsilonknot nft add chain inet wgq-www preraw '{ type filter hook prerouting priority raw; policy accept; }'
@epsilon ~/$ pns epsilonknot nft add rule inet wgq-www preraw 'tcp dport != { 80, 443 } drop'
@epsilon ~/$ pns epsilonknot nft -a list ruleset
table ip6 wg-quick-www { # handle 22
        chain preraw { # handle 1
                type filter hook prerouting priority raw; policy accept;
                iifname != "www" ip6 daddr xx:xx:xx:xx::xx fib saddr type != local drop # handle 4
        }

        chain premangle { # handle 2
                type filter hook prerouting priority mangle; policy accept;
                meta l4proto udp meta mark set ct mark # handle 6
        }

        chain postmangle { # handle 3
                type filter hook postrouting priority mangle; policy accept;
                meta l4proto udp meta mark 0x0000ca6c ct mark set meta mark # handle 5
        }
}
table ip wg-quick-www { # handle 23
        chain preraw { # handle 1
                type filter hook prerouting priority raw; policy accept;
                iifname != "www" ip daddr xx.xx.xx.xx fib saddr type != local drop # handle 4
        }

        chain premangle { # handle 2
                type filter hook prerouting priority mangle; policy accept;
                meta l4proto udp meta mark set ct mark # handle 6
        }

        chain postmangle { # handle 3
                type filter hook postrouting priority mangle; policy accept;
                meta l4proto udp meta mark 0x0000ca6c ct mark set meta mark # handle 5
        }
}
table inet wgq-www { # handle 24
        chain preraw { # handle 1
                type filter hook prerouting priority raw; policy accept;
                tcp dport != { 80, 443 } drop # handle 3
        }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment