14

I'm looking for a linux utility that can alter the payloads of network packets based on a set of rules. Ideally, I'd use iptables and the netfilter kernel module, but they don't support generic payload mangling: iptables will alter various header fields (addresses, ports, TOS, etc), and it can match arbitrary bytes within a packet, but it apparently is unable to alter arbitrary data within the packet.

A kernel module would be a big plus, as efficiency is a concern, but I'm happy to explore any other options that would get the job done.

Thanks for your ideas!


Long-overdue Update:

We chose to use the NFQUEUE module, which is the latest implementation of the QUEUE modules that Robert Gamble suggested. It appeared to be fairly simple, with a safety bonus for allowing our code to run in user, not kernel, space.

The implementation would have been almost trivial if we'd simply wanted to alter the payload without changing its size. In that case, we'd define an iptables rule to select the "interesting" packets for us and send them an NFQUEUE target. We'd write a callback function that would inspect the packets from NFQUEUE, modify the data as required, and recalculate the checksums in their TCP and IP headers.

However, our use case involves injecting additional characters into the data stream. This has the somewhat obvious side-effect of increasing the corresponding SEQ/ACK numbers in the TCP stream, and the not-so-obvious side-effect of confusing the conntrack module enough that it breaks NAT entirely. After a lot of research, head-scratching, and experimentation, the most expedient solution was to disable connection tracking for these particular packets (with the NOTRACK target in the raw table) and handle it in our callback. Save your tomatoes and hate mail; I'm not at all proud to let you under the hood, but it was the only way to get a reliable product to the customer before the next Ice Age. And it's a good story. But I truly appreciate, and share, your heartfelt sentiments.

Version 2 will leverage our newfound enlightenment by replacing our callback and several iptables rules with a custom NAT and/or conntrack helper. We're confident that the current exercise has given us enough experience to create a kernel module that will fit organically into the netfilter architecture to solve the problems we encountered.

frogatto
  • 28,539
  • 11
  • 83
  • 129
Adam Liss
  • 47,594
  • 12
  • 108
  • 150
  • 1
    It's about 3rd priority on my To-Do list. In the meantime, we're also looking at fixing the netfilter module itself, as that would be the best answer. Will update when I have info, probably not for a couple weeks. :-( – Adam Liss Nov 13 '08 at 22:08
  • @Adam, do you increase ACK/SEQ for modified packets only, or indeed need to track whole ACK/SEQ chat? Thanks. – kagali-san Feb 24 '11 at 23:18
  • 1
    The SEQ/ACK numbers count the bytes in the entire stream on that port. So once you change the size of a packet, you need to maintain the new SEQ/ACK numbers until the connection is closed. – Adam Liss Feb 25 '11 at 01:48
  • @Adam Liss, thanks.. is your product public available? Interested to see what you've chose to put into those packets.. I ran small research project, which collects such software, and attempt to hack Netfilter too.. – kagali-san Feb 25 '11 at 19:20
  • 1
    (No nastiness assumed. Folks awaiting answers tend to check more often than the folks posting them!) I'm no longer associated with the company that built this product and haven't followed its availability, so I'm afraid I can't help with that. As far as the packet content, we inserted a short tag after encountering a target sequence of bytes in a low-throughput stream. – Adam Liss Feb 27 '11 at 14:36
  • (:)) It was not OpTier, right? also, did you recalculated the seq/ack using NFQUEUE only? – kagali-san Mar 02 '11 at 03:32
  • Btw, this project may be interesing for you - http://stegbox.net/index.php?option=com_content&view=frontpage&Itemid=1 - search for MTU (they gave up at it) – kagali-san Mar 02 '11 at 03:33
  • As I remember, NFQUEUE passes each packet to userspace in its entirety: header, payload, and all. Then the user routine is free to modify any of the bytes that end up on the wire, including SEQ/ACK and checksums. Again, we had a very simple use case with short packets and low throughput requirements, so we didn't need to worry about MTU or most other complications. Thanks for the link -- interesting project! – Adam Liss Mar 02 '11 at 23:54
  • Offtopic, to make this thread richier: the seq/ack problem was solved at my little workshop with a bit of conntracking in userspace, too :), but, still no know way to get over MTU without ugly kernel code hacks (that even not fits to external module, sitting over IPv4 code), so will go with SystemTap traces - probably will find some rotten hole to inject. – kagali-san Mar 29 '11 at 00:02

2 Answers2

6

I haven't used it, but the QUEUE netfilter target looks like it might work. It uses an nflink socket and a userspace application registered to the socket to perform the payload modifications.

The libipq man page contains details on how to use this and provides a simple example.

Robert Gamble
  • 106,424
  • 25
  • 145
  • 137
1

Resolution:

We ended up with a custom module for netfilter, which is clearly the "right" tool for the job.

Adam Liss
  • 47,594
  • 12
  • 108
  • 150