Linux – How to pass to NFQUEUE all incoming connection packets

conntrackiptableslinux

I develop an application to inspect packets arriving on a linux machine.
I would like to send in NFQUEUE all the incoming connection packets and only the incoming ones. Not only --state NEW but also --state ESTABLISHED, RELATED for connections that are initiated by a client.

One last thing, to make the tcp handshake for all ports I need this rule to works in addition:

iptables -A PREROUTING -t nat -p tcp -match multiport! --dport 64646 -j REDIRECT --to-ports 1234

Flow example:

  1. ssh connection (port 22) initiated by 1.2.3.4 to my server
  2. server passes in nfqueue the SYN and accept
  3. redirect rule (22 -> 1234)
  4. python script is listening on port 1234 so SYN/ACK is sent
  5. client gets SYN/ACK and returns ACK
  6. server passes in nfqueue the ACK and accept
  7. redirect rule (22 -> 1234)
  8. the client returns ACK, DATA
  9. server passes in nfqueue the ACK/DATA
  10. redirect rule (22 -> 1234)
  11. server does not know the protocol and always returns the same message, the connection is closed.

Any help would be very appreciated.

Thank you!

Best Answer

I found the solution if it interests someone.

# Accept our ssh on a modified port
iptables -A PREROUTING -t raw -p tcp --dport 64646 -j ACCEPT

# Mark all packets of incoming NEW connection with mark 1 (netfilter connmark)
iptables -A PREROUTING -t mangle -m state --state NEW -j CONNMARK --set-mark 1

# Push into nfqueue all marked packets (netfilter nfqueue)
iptables -A PREROUTING -t mangle -m connmark --mark 1 -j NFQUEUE --queue-num 0

# Redirect all incoming connections to the userland listener to make TCP handshake
iptables -A PREROUTING -t nat -p tcp --match multiport ! --dport 64646 -j REDIRECT --to-ports 1234

Finally all the incoming packets go into nfqueue but if I work on the machine (update, upgrade, install...) packets do not match the rules. In addition the redirection applies after nfqueue decision, so I log the base port (not 1234).