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.