Not sure how well this translates to UFW, but the iptables rules to perform these steps involve something like:
iptables -I DOCKER-USER -i eth0 -s 10.0.0.0/24 -p tcp \
-m conntrack --ctorigdstport 8080 -j ACCEPT
iptables -I DOCKER-USER -i eth0 ! -s 10.0.0.0/24 -p tcp \
-m conntrack --ctorigdstport 8080 -j DROP
Here are the details on the parts of these commands:
- The table needs to be
DOCKER-USER
which docker will provide, run all requests through, and will not modify this table the way it does other tables.
- You want to insert into
DOCKER-USER
rather than append because the default rule at the end of this table is to accept everything. Appending a rule after that would be ignored.
- The interface,
eth0
, is the external network interface. You often don't want to block requests internally, with either loopback or between containers.
- The source IP CIDR specifies what address range you wanted to allow, in this case
10.0.0.0/24
, or the class C network 10.0.0.*
. Everything else to the target port is blocked by the second rule.
- The
conntrack
and ctorigdstport
is needed to specify the original destination port, aka published port, rather than the container port. After the mangle rules have modified the packets to communicate to the container, the port seen by iptables would be the container port, and multiple containers could be listening on the same port internally, and publishing to different ports on the host.