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
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>
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.
Tested it with the following rules added to
# 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.