Even if you put DROP in the INPUT chain in iptables, those ports will still be visible over the Internet.
This happens because 'dockerd' inserts DNAT rules into the nat/PREROUTING and nat/DOCKER chains before your standard filter/INPUT chain.
Namely, a TCP/UDP packet comes from the Internet, goes through DNAT in nat/DOCKER, and ends up in filter/DOCKER.
Then the package is no longer intended for eth0 but for docker-bridge (docker0), so the package does not even reach the DROP action and the INPUT chain.
To ensure that no Docker ports are exposed to the Internet, do the following:
Code: Select all
wget -nv https://dl.myvestacp.com/install-docker-firewall.sh -O install-docker-firewall.sh
bash install-docker-firewall.sh
Code: Select all
#!/bin/bash
# Get network interface for the internet
iface=$(ip r get 8.8.8.8 | grep -oP 'dev \K\S+')
cat <<EOF > /usr/local/sbin/docker-fw.sh
#!/bin/sh
iptables -C DOCKER-USER -i $iface -p tcp -j DROP 2>/dev/null || \
iptables -I DOCKER-USER -i $iface -p tcp -j DROP
iptables -C DOCKER-USER -i $iface -p udp -j DROP 2>/dev/null || \
iptables -I DOCKER-USER -i $iface -p udp -j DROP
EOF
chmod +x /usr/local/sbin/docker-fw.sh
cat <<EOF > /etc/systemd/system/docker-fw.service
[Unit]
Description=Post-Docker firewall rules
After=docker.service network-online.target
Requires=docker.service
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/docker-fw.sh
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now docker-fw.service