=======
== G ==
=======

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.