From owner-freebsd-questions@FreeBSD.ORG Fri Aug 31 20:10:02 2007 Return-Path: Delivered-To: freebsd-questions@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id BEF1C16A417 for ; Fri, 31 Aug 2007 20:10:02 +0000 (UTC) (envelope-from fbsd.questions@rachie.is-a-geek.net) Received: from snoogles.rachie.is-a-geek.net (66-230-99-27-cdsl-rb1.nwc.acsalaska.net [66.230.99.27]) by mx1.freebsd.org (Postfix) with ESMTP id 65E4513C45A for ; Fri, 31 Aug 2007 20:10:02 +0000 (UTC) (envelope-from fbsd.questions@rachie.is-a-geek.net) Received: from localhost (localhost [127.0.0.1]) by snoogles.rachie.is-a-geek.net (Postfix) with ESMTP id 838521CC38 for ; Fri, 31 Aug 2007 12:09:44 -0800 (AKDT) From: Mel To: freebsd-questions@freebsd.org Date: Fri, 31 Aug 2007 22:09:42 +0200 User-Agent: KMail/1.9.7 References: <20070831202729.7e4c0f7a@localhost> <200708311740.07360.fbsd.questions@rachie.is-a-geek.net> <20070901022726.1e629b2c@localhost> In-Reply-To: <20070901022726.1e629b2c@localhost> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Content-Disposition: inline Message-Id: <200708312209.43216.fbsd.questions@rachie.is-a-geek.net> Subject: Re: pf rdr + netsed : reinject loop... X-BeenThere: freebsd-questions@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: User questions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 31 Aug 2007 20:10:02 -0000 On Friday 31 August 2007 18:27:26 Norberto Meijome wrote: > On Fri, 31 Aug 2007 17:40:06 +0200 > > Mel wrote: > > > netsed's output is (part ) : > > > --- > > > Script started on Fri Aug 31 07:52:12 2007 > > > [root@localhost /usr/home/luser]# netsed tcp 10101 0 0 s/FOO/BAR > > > netsed 0.01b by Michal Zalewski > > > [*] Parsing rule s/FOO/BAR ... > > > [+] Loaded 1 rules... > > > [+] Listening on port 10101/tcp. > > > [+] Using dynamic (transparent proxy) forwarding. > > > > > > [+] Got incoming connection from 172.16.82.81:1178 to 127.0.0.1:10101 > > > [*] Forwarding connection to 127.0.0.1:10101 > > > [+] Got incoming connection from 127.0.0.1:51337 to 127.0.0.1:10101 > > > [*] Forwarding connection to 127.0.0.1:10101 > > > [+] Caught client -> server packet. > > > > I think you need to figure out what this 'transparent proxy mode' of > > netsed does, cause it should under no circumstances forward to itself... > > it simply forwards the packet to the dst_ip:dst_port it originally had. > But, as Daniel H pointed out, those packets had been rewritten by pf's rdr > to go TO netsed's ip:port .... hence netsed wont change anything. It works > fine in non-proxy mode, but as I said in my first msg, that is not an > option for me. > > So the obvious question is how to get the packets to netsed's IP:PORT > without having the packet's original destination IP/PORT changed....maybe > incorporating the netsed code into a socks5-compatible server (in my case, > the app that generates the packets understands SOCKS). Alas, I am drawing a > blank here atm. > > Otherwise, i can only think that a new netgraph node would perform better > than my current pf + netsed approach.... Figured I'd take a shot at it and it works: # ./netsed tcp 10101 0 0 s/boo/GET/ netsed 0.01b by Michal Zalewski [*] Parsing rule s/boo/GET/... [+] Loaded 1 rules... [+] Listening on port 10101/tcp. [+] Using dynamic (transparent proxy) forwarding. [+] Got incoming connection from 11.22.33.44:27712 to 127.0.0.1:10101 [*] Forwarding connection to 55.66.77.88:80 [+] Caught client -> server packet. Renamed the ip's to protect the innocent, but that's all. I typed boo / HTTP/1.0 and got back a solid page of html. Patch inlined below sig. I'm surprised no one ever caught up on this, seeing the makefile is last modified in 2005 :) -- Mel --- orig/netsed.c 2007-08-31 21:51:51.000000000 +0200 +++ work/netsed.c 2007-08-31 21:51:31.000000000 +0200 @@ -11,6 +11,12 @@ #include #include #include +#ifdef USE_PF +#include +#include +#include +#include +#endif #define VERSION "0.01b" #define MAXRULES 50 @@ -254,11 +260,19 @@ signal(SIGCHLD,sig_chld); // Am I bad coder?;> + /* Yeah, comments should be useful and frequent and not in C++ format. */ while (1) { struct sockaddr_in s; int x,l=sizeof(struct sockaddr_in); int conho,conpo; +#ifdef USE_PF + struct pfioc_natlook natlook; + int fd; + socklen_t clen; /* client length */ + struct sockaddr_in *client; /* client socket */ +#endif + usleep(1000); // Do not wanna select ;P if ((csock=accept(lsock,(struct sockaddr*)&s,&l))>=0) { fcntl(csock,F_SETFL,O_NONBLOCK); @@ -266,8 +280,51 @@ l=sizeof(struct sockaddr_in); getsockname(csock,(struct sockaddr*)&s,&l); printf(" to %s:%d\n", inet_ntoa(s.sin_addr), ntohs(s.sin_port)); + /* The logic here is that it receives an unmodified dest address, + * however that's not the case with pf. */ +#ifdef USE_PF + /* We also need the client peer to look up the nat in pf, blatantly + * borrowed from ftp-proxy(8). */ + clen = sizeof(struct sockaddr_in); + client = (struct sockaddr_in *)malloc(clen); + getpeername(csock, (struct sockaddr *)client, &clen); + memset((void *)&natlook, 0, sizeof(natlook)); + natlook.af = AF_INET; + natlook.saddr.addr32[0] = client->sin_addr.s_addr; + natlook.daddr.addr32[0] = s.sin_addr.s_addr; + natlook.proto = IPPROTO_TCP; + natlook.sport = client->sin_port; + natlook.dport = s.sin_port; + /* NOTE: It works with PF_OUT, even though rdr rule is on incoming + * traffic in my tests. More research into natlook.direction is needed + * here. + */ + natlook.direction = PF_OUT; + /* + * Open the pf device and lookup the mapping pair to find + * the original address we were supposed to connect to. + */ + fd = open("/dev/pf", O_RDWR); + if (fd == -1) { + printf("No permission to open /dev/pf, see ya\n"); + exit(EX_UNAVAILABLE); + } + + if (ioctl(fd, DIOCNATLOOK, &natlook) == -1) { + printf( + "pf nat lookup failed %s:%hu\n", + inet_ntoa(client->sin_addr), + ntohs(client->sin_port)); + close(fd); + exit(EX_UNAVAILABLE); + } + close(fd); + conpo=ntohs(natlook.rdport); + conho=natlook.rdaddr.addr32[0]; +#else conpo=ntohs(s.sin_port); conho=s.sin_addr.s_addr; +#endif if (fixedport) conpo=fixedport; if (fixedhost) conho=fixedhost; s.sin_addr.s_addr=conho; --- orig/Makefile 2001-01-05 02:46:32.000000000 +0100 +++ work/Makefile 2007-08-31 21:35:32.000000000 +0200 @@ -1,4 +1,4 @@ -CFLAGS = -Wall -fomit-frame-pointer -O9 +CFLAGS = -Wall -fomit-frame-pointer -O9 -DUSE_PF all: netsed