FORWARD container traffic
This is a reminder on how to bypass containers being unable to forward traffic internally for connections behing a private network, while also avoiding opening up FORWARD to everything – at least I assume I’m avoiding it, since I’m specifying the network (still needs proper testing, I guess), relevant iptables documentation related to it can be found on RedHat docs.
Step 1. (it hangs!) trying to normally curl a container (podman) in one of my homelab’s machines:
[gustavo@wk00:~]$ curl 10.0.69.8:8081
^C
Step 2. Make sure the server is indeed listening to that port:
root@tatarana:~# netstat -atnp | grep 8081
tcp 0 0 0.0.0.0:8081 0.0.0.0:* LISTEN 146624/conmon
Step 3. Make sure the firewall is correctly set (or ufw is disabled, even)
Step 4. If everything seems correct, it’s time to tweak the firewall by allowing FORWARD on the private interface. On this server’s case, it’s the enp2s0, which is relative to the 10.0.69.0/24 private range:
root@tatarana:~# iptables -A FORWARD -i enp2s0 -j ACCEPT
root@tatarana:~# iptables -A FORWARD -o enp2s0 -j ACCEPT
The first command means that we are appending (-A) a FORWARD rule to the
in-interface
(-i) enp2s0 and, when the packet matches this rule, we’re
ACCEPTing (-j) it.
The second command means the same thing, except that we’re setting a FORWARD
rule to packets that matches the out-interface
(-o).
The relevant manual definitions are in man 8 iptables
, but here it goes for
the lazy ones:
COMMANDS
-A, --append chain rule-specification
Append one or more rules to the end of the selected chain. When the
source and/or destination names resolve to more than one ad‐ dress, a
rule will be added for each possible address combination.
PARAMETERS
-j, --jump target
This specifies the target of the rule; i.e., what to do if the packet
matches it. The target can be a user-defined chain (other than the one
this rule is in), one of the special builtin targets which decide the fate
of the packet immediately, or an exten‐ sion (see EXTENSIONS below).
If this option is omitted in a rule (and -g is not used), then matching
the rule will have no ef‐ fect on the packet's fate, but the counters on
the rule will be incremented.
[!] -i, --in-interface name
Name of an interface via which a packet was received (only for packets
entering the INPUT, FORWARD and PREROUTING chains). When the "!" argument
is used before the interface name, the sense is inverted. If the
interface name ends in a "+", then any inter‐ face which begins with this
name will match. If this option is omitted, any interface name will
match.
[!] -o, --out-interface name
Name of an interface via which a packet is going to be sent (for
packets entering the FORWARD, OUTPUT and POSTROUTING chains). When the
"!" argument is used before the interface name, the sense is inverted. If
the interface name ends in a "+", then any interface which begins with
this name will match. If this option is omitted, any interface name will
match.
Step 5. curl your server again to see if the rules had an effect:
[gustavo@wk00:~]$ curl 10.0.69.8:8081
<html><body><h1>It works!</h1></body></html>
It works!
Step 6. On Debian-based machines, it’s probably possible to persist this by
adding these two rules to /etc/ufw/before.rules
, before the COMMIT key.
Update
Tested it with the following rules added to /etc/ufw/before.rules
:
# Accepting in/out fwd traffic in the bond0.10 private net
-A ufw-before-forward -i bond0.10 -j ACCEPT
-A ufw-before-forward -o bond0.10 -j ACCEPT
And it works after disabling and re-enabling ufw.