- Joined
- Jul 3, 2009
- Messages
- 1,160
I just got a VPS running Debian 12 with a public IPv4 address available. I started setting up docker containers via docker compose files. I discovered they were always publicly accessible via the IPv4: port and some things I don't want exposed. I initially tried UFW, only to find that it's incompatible with docker. I tried some basic iptables manipulation but in the end couldn't get it working.
As a workaround for now, I have a wireguard tunnel setup and I'm binding the ports to my wg0 interface. Instead of defining the port like "80:80" I'm defining it as "$vpnaddress:80:80". Netstat -ulpnt indeed shows the service is listening on the port bound to the wg0 interface ip not 0.0.0.0 (all interfaces on the host). A port scan shows port 80 is closed on the public IPv4 address, but I can access it via the Wireguard IP:80. On a container that I do want exposed to the Internet, I just define the ports regularly like "2456:2456". This binds it to 0.0.0.0 and without any iptables manipulation that service is publicly exposed and works as intended.
In the Docker docs they present this: Packet filtering and firewalls. I want to achieve this by iptables rules instead of binding to the VPN address. From my understanding I'll need to add these rules to the DOCKER-USER chain.
Let's assume I have multiple containers on various ports I only want to access via wg0, and then one on ports 2456-2458 udp with internal IP 172.20.0.2 I want publicly accessible. All containers run in the range 172.20.0.0/16 (the default bridge network) but I'm not sure if I need to define it or not. Would these rules work the way I'm thinking?
edit: these iptables rules did in fact work. My containers stopped working after I enabled them (not sure why??) but I changed the ports back to regular definitions of 80:80, etc... Can't access them from the public IP, can access them from VPN. Thing running on ports 2456:2458 (a Valheim server lol) is still connecting fine.
To get these rules to persist between reboots I'm using netfilter-persistent
As a workaround for now, I have a wireguard tunnel setup and I'm binding the ports to my wg0 interface. Instead of defining the port like "80:80" I'm defining it as "$vpnaddress:80:80". Netstat -ulpnt indeed shows the service is listening on the port bound to the wg0 interface ip not 0.0.0.0 (all interfaces on the host). A port scan shows port 80 is closed on the public IPv4 address, but I can access it via the Wireguard IP:80. On a container that I do want exposed to the Internet, I just define the ports regularly like "2456:2456". This binds it to 0.0.0.0 and without any iptables manipulation that service is publicly exposed and works as intended.
In the Docker docs they present this: Packet filtering and firewalls. I want to achieve this by iptables rules instead of binding to the VPN address. From my understanding I'll need to add these rules to the DOCKER-USER chain.
Let's assume I have multiple containers on various ports I only want to access via wg0, and then one on ports 2456-2458 udp with internal IP 172.20.0.2 I want publicly accessible. All containers run in the range 172.20.0.0/16 (the default bridge network) but I'm not sure if I need to define it or not. Would these rules work the way I'm thinking?
Bash:
iptables -A DOCKER-USER -i wg0 -j ACCEPT #allow all incoming traffic via wg0
iptables -A DOCKER-USER -o wg0 -j ACCEPT #allow all outgoing traffic via wg0
iptables -A DOCKER-USER -p udp -m multiport --dports 2456:2458 -j ACCEPT #allow access to these udp ports from every interface
iptables -A DOCKER-USER -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT #accept established/related traffic
iptables -A DOCKER-USER -j DROP #drop all other traffic
edit: these iptables rules did in fact work. My containers stopped working after I enabled them (not sure why??) but I changed the ports back to regular definitions of 80:80, etc... Can't access them from the public IP, can access them from VPN. Thing running on ports 2456:2458 (a Valheim server lol) is still connecting fine.
To get these rules to persist between reboots I'm using netfilter-persistent
Last edited: