0

I've started on stackoverflow, then after some investigation asked on superuser, because it looks like network or kernel (mis)configuration, but probably I need some seasoned network engineer to help:)

I'm mangling packets with help of NFQUEUE, there's only single rule in iptables:

iptables -A OUTPUT -p tcp -m tcp --dport 80 -j NFQUEUE --queue-num 1

The script is simple (python, requires pypacker):

import re, time

from pypacker import interceptor
from pypacker.layer3 import ip
from pypacker.layer4 import tcp

def handle_packet(ll_data, ll_proto_id, data, ctx, *args):
    ip_part = ip.IP(data)
    tcp_part=ip_part[tcp.TCP]

    if body := tcp_part.body_bytes:        
        new_body=re.sub(b'/[a-z]+', b'/uuid', tcp_part.body_bytes)
        if new_body != tcp_part.body_bytes:
            tcp_part.body_bytes=new_body
            data=ip_part.bin() # Will be returned

    return data, interceptor.NF_ACCEPT

ictor = interceptor.Interceptor()
ictor.start(handle_packet, queue_ids=[0, 1, 2])
time.sleep(180)
ictor.stop()

Testing with curl:

curl http://httpbin.org/ip

When I increase the length, the response packet (200 OK) is dropped (I see it in tcpdump and nfqueue if I configure the PREROUTING rule). When the length of the modified packet is the same or smaller (for example, requesting /ipip or /ipaaa) the response is returned.

Can somebody give an idea where to look for the solution? dropwatch unfortunately says only this:

1 drops at _einittext+1dacb95a (0xffffffffa002584c)

I've tried on different servers (gentoo, ubuntu), with different kernels and settings (tried to play with connection tracking, disabling rp_filter etc), nothing makes it work.

aikipooh
  • 103
  • 6
  • Your approach looks ill-fated to me - you're trying to replace all instances of slash followed by any number of alphabetical characters in TCP datastream with some fixed value. From your tests it looks like you're trying to change HTTP URL with that. The proper way of doing so is using forced (transparent) forward proxy with rewrite. Your approach will render Accept headers and such completely broken.. – Peter Zhabin Jul 08 '22 at 16:23
  • @PeterZhabin, well, it's test only, the packet will be mangled beyond recognition in the final version:) But before that I need to make sure nothing breaks if I change one byte in the packet (checksums, etc), and it's not so:( – aikipooh Jul 08 '22 at 17:05
  • Well then, you need to describe what kind of a problem you're actually trying to solve. – Peter Zhabin Jul 08 '22 at 19:27
  • The final goal is a code on the server to incrementally compress packets and coalesce them, passing it all through a tunnel to a router, where they will be decompressed. Currently I'm dealing with one endpoint only to test. I've coded similar thing 10 years ago, but it was in C (on the router) and kernel module on the server. – aikipooh Jul 08 '22 at 20:59
  • @PeterZhabin, hi! Do you need any more information? I'll gladly provide! – aikipooh Jul 11 '22 at 12:16

0 Answers0