Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I need to make some small modification to incoming traffic from a known tcp host:port before the process handling the connection get the stream.

For example, let 192.168.1.88 be a remote host which runs a web server.
I need that, when a process on my local host receives data from 192.168.1.88:80 (e.g. the browser), the data is first changed replacing text-A with text-B, like this:

  • 127.0.0.1:... connects to 192.168.1.88:80
  • 127.0.0.1:... sends to 192.168.1.88:80:

    GET /
    
  • 192.168.1.88:80 sends to 127.0.0.1:...:

    HTTP/1.0 200 OK
    Content-Type: text/plain
    
    Some text-A, some other text
    
  • That data is somewhat intercepted by the system and passed to a program whose output is:

    HTTP/1.0 200 OK
    Content-Type: text/plain
    
    Some text-B, some other text
    
  • the system gives the so changed data to the process handling 127.0.0.1:..., like if it comes from 192.168.1.88:80.

Assuming I have a stream-based way to make this changes (using sed for instance), what is the easiest way to pre-process the incoming tcp stream?

I guess this would involve iptables, but I'm not very good at it.

Note that the application should feel to deal with the original host, so setting up a proxy is not likely a solution.

share|improve this question
    
Are these HTTP requests? –  polynomial Oct 6 '11 at 6:36
    
Your question is not clear enough. You need to provide more details. –  Khaled Oct 6 '11 at 7:28
1  
You can't do it at the packet level. One packet might contain "text-" and the next might contain "A". You will have to develop an invisible proxy that follows the protocol. (You have to follow the protocol because if you get "text-" and it's part of "text-A", you need to wait for the next chunk before passing it on or your filter won't work. But if it's the end of a logical message, you can't wait because you'd be waiting forever.) I believe there is no easy way to do this. –  David Schwartz Oct 6 '11 at 8:06
    
There already exist stateful packet inspection systems that can do e.g. rewriting of FTP traffic so that it works across NAT. That's the sort of place to start. –  pjc50 Oct 6 '11 at 12:56
    
I need it to work with http response primarily but it would be good if it works on any application layer. –  etuardu Oct 6 '11 at 20:19

3 Answers 3

up vote 9 down vote accepted
+50

Use netsed and iptables proxying.

iptables -t nat -D PREROUTING -s yourhost -d desthost -p tcp --dport 80 -j REDIRECT --to 10101

Then run:

netsed tcp 10101 desthost 80 s/text-A/text-B

NetSED is a small and handy utility designed to alter, in real time, the contents of packets forwarded through your network. It is really useful for network packet alteration, forging, or manipulation. NetSED supports:

  • black-box protocol auditing - whenever there are two or more proprietary boxes communicating using some undocumented protocol. By enforcing changes in ongoing transmissions, you will be able to test if the examined application can be claimed secure.

  • fuzz generating experiments, integrity tests - whenever you do stability tests of an application to see how it cares for data integrity;

  • other common use-cases: deceptive transfers, content filtering, protocol conversion - whatever best fits your task at hand.

share|improve this answer
    
That's really simple and cool. –  mbrownnyc Oct 16 '11 at 3:27
    
I didn't know netsed, it fits almost perfectly for my purpose. The only thing I don't get is how to set up the "local transparent proxy" (see the question). Perhaps I ought to set up another (virtual) network interface to obtain that. By the way, for now this is the most satisfying answer. –  etuardu Oct 16 '11 at 14:32
    
Are you running a generic distribution kernel? If you are iptables support is probably already compiled in. In order to set up the transparent proxy you just need to fill in the appropriate details for your host/ports. Take a look at the readme and see if it fills in some of the details. silicone.homelinux.org/git/netsed.git/blob_plain/HEAD:/README –  dfc Oct 17 '11 at 5:10
    
I thought netsed would only work on one packet at a time? So if the http request were split across two packets the regex for the substitution won't match and the request will be passed to the server unmodified. –  paulos Oct 17 '11 at 12:39
    
from netsed readme: "For now, only TCP and UDP user-space filtering is possible no support for kernel firewalling / routing, raw packets, ICMP and other things." netsed operates at layer four, not layer three. –  dfc Oct 17 '11 at 20:49

You can do exactly this by using iptables to transparently proxy connections through a squid proxy, and then having squid re-write the http content for you.

share|improve this answer

iptables + the use of libnetfilter_qu is another option that will do what you wish:

"...[reinject] altered packets to the kernel nfnetlink_queue subsystem."

It likely will give you most extensibility as it's up to you to code software.

There's a python wrapper available as well.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.