<html>
    <head>
      <base href="https://bugzilla.netfilter.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - tproxy with nftables collides with nat entries"
   href="https://bugzilla.netfilter.org/show_bug.cgi?id=1773">1773</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>tproxy with nftables collides with nat entries
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>netfilter/iptables
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>unspecified
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>x86_64
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>major
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P5
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>netfilter hooks
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>netfilter-buglog@lists.netfilter.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>antonio.ojea.garcia@gmail.com
          </td>
        </tr></table>
      <p>
        <div>
        <pre>It took me a while to figure out the problem when working with nftables tproxy
for UDP in a kubernetes environment, until I found the explanation on
<a href="https://patchwork.ozlabs.org/project/netfilter-devel/patch/20180628164258.25646-1-ecklm94@gmail.com/">https://patchwork.ozlabs.org/project/netfilter-devel/patch/20180628164258.25646-1-ecklm94@gmail.com/</a>


<span class="quote">>  - tproxy statement is not terminal here</span >

When trying to implement a transparent proxy for a DNS server, I could observe
that only the first connection was redirected, subsequent connections with the
same tuple were sent to the actual DNAT destination.

Assume a Pod/Namespace client with IP 100.96.1.14
A virtual IP for the DNS service 100.64.0.10 that forwards traffic to 100.96.1.
and 10.96.1.12 
An UDP transparent proxy server listening on port 12345
Rules to intercept the DNS traffic (fwmark rule and anyip route are ok)

table inet kindnet-dnscache {
        comment "rules for kindnet dnscache"
        chain prerouting {
                type filter hook prerouting priority dstnat - 10; policy
accept;
                meta mark 0x0000000c return
                ip saddr 100.96.1.0/24 ip daddr 100.64.0.10 udp dport 53 tproxy
ip to 127.0.0.1:12345 accept comment "DNS IPv4 pod originated traffic"
        }
}


When connecting from 100.96.1.14:8888 to 100.64.0.10:53, the tproxy rule
redirect the connection to localhost:12345

When tracing the nftables rules with "nft monitor" I could observe that the
tproxy statement verdict was accepted, but the subsequent rules were matched
and the corresponding conntrack entries for NAT were added


    [NEW] udp      17 30 src=100.96.1.14 dst=100.64.0.10 sport=42345 dport=53
[UNREPLIED] src=100.96.1.12 dst=100.96.1.14 s
port=53 dport=42345
    [NEW] udp      17 30 src=100.64.0.10 dst=100.96.1.14 sport=53 dport=42345
[UNREPLIED] src=100.96.1.14 dst=100.64.0.10 sport=42345 dport=81
[DESTROY] udp      17 src=100.64.0.10 dst=100.64.0.10 sport=34943 dport=53
src=100.96.1.12 dst=100.96.1.1 sport=53 dport=58102



A workaround that seems to work fine is to no track the tproxy traffic

table inet kindnet-dnscache {
        comment "rules for kindnet dnscache"
        chain prerouting {
                type filter hook prerouting priority raw - 10; policy accept;
                meta mark 0x0000000c return
                ip saddr 100.96.1.0/24 ip daddr 100.64.0.10 udp dport 53 tproxy
ip to 127.0.0.1:54136 meta mark set 0x0000000b notrack accept comment "DNS IPv4
pod originated traffic"
        }
}



I personally found surprising the tproxy action is not terminal, as it is
actually the intent of the user to steal the traffic and redirect to the port.

I don't know at this point if is feasible to break this behavior, as it sounds
strange that somebody relies on  it, although I'm sure we have seen worse :)
<a href="https://imgs.xkcd.com/comics/workflow.png">https://imgs.xkcd.com/comics/workflow.png</a>

It will be desirable for this tproxy action to be terminal, if not by default,
at least give the user some knob to opt-in to making it terminal</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are watching all bug changes.</li>
      </ul>
    </body>
</html>