[tproxy] Transparent proxying - different approach - NAT on demand.

Balazs Scheidler bazsi at balabit.hu
Wed Feb 11 12:17:46 CET 2009


On Fri, 2009-01-23 at 10:26 +0100, KOVACS Krisztian wrote:
> Hi,
> 
> On sze, jan 21, 2009 at 01:42:38 +0100, NTPT wrote:
> > Hi all.
> > 
> > I have some proposition about squid and tproxy. I call it "NAT ON
> > DEMAND". I am not really a good C programmer or kernel hacker, but...
> > 
> > AFAIK in early tproxy days a dynamically created SNAT and DNAT rules,
> > was considered but this idea was abandon as unfeasible. 
> > 
> > My idea is to allow "setting nat on application explicit demand". To
> > create a infrastructure in with userspace application (squid for
> > example) can send a "demand"  for source address to witch their outgoing
> > connections should be natted to - on per socket basis.Usage in
> > transparent proxying of all kind. Especially useful for SQUID and realy
> > transparent proxy scenario.
> >  
> > 
> > The idea is roughly inspired and is analogic to  "setting FWMARK from
> > userspace", an old kernel patch that implement ioctl for setting fwmark
> > on local originated packets on per socket basis. See
> > http://oss.sgi.com/archives/netdev/2001-12/msg00053.html
> > 
> > 
> > 1:applications should be able  to explicitly set on per socket basis, on
> > wich IP address they need outgoin connection to be SNATed. Probably add
> > one 32bit item to skbuff and appropriate mechanizm for setting it from
> > userspace
> > 
> > 2: change netfilter / iptables to allow "-j SNAT --to-demand" option to
> > witch set a source of the connection to address that application
> > demanded
> > 
> > 3: add "-m natdemand" iptables match  to  find if local originator of
> > this connection demand NAT for it (ie if the additional field in skbuff
> > is not 0x0 ).
> > 
> > 4: patch squid to request a nat for its outgoing connections. Only thing
> > that it should to take a client ip address and "demand it"
> > 
> > Usage like this
> > 
> > in squid conf
> > 
> > acl src 192.168.1.0/24      transparent_clients # set ACL for clients
> > network that we need handled transparently nat_on_demand
> > transparent_clients          # demand specific SNAT for all outgoing
> > connections (ie connections that fetching content) it made on proxying
> > clients from this network. ie take IP of the squid client and demand
> > SNAT to this IP for outgoing sockets that fetching data for that client
> > on cache miss (sorry my bad english)  
> >  
> > in iptables:
> > 
> > iptables -t nat -I OUTPUT (or POSTROUTING ?) -m natdemand -j SNAT
> > --to-demand # to tell netfilter to SNAT source address of that
> > connection to what application demanded. ie copy address stored in
> > additional skbbuff field 
> 
> You've just described how tproxy 2 worked, with a slightly different
> interface.
> 
> > From that point, all the hard work for us is done  automatically by
> > netfilter.No need to worry about fancy routing setup etc. No need
> > additional overhead for socket match. Does not interfer with connection
> > tracking as tproxy afaik does. Should work for related (icmp etc)
> > packets as well. Should instantly work for every protocol that have nat
> > helper too. Should be easy to implement  and less intrusive (afaik most
> > of tproxy patch is to circumvent some kernel safety measurements and
> > control checks on various places)
> 
> I'd expect the overhead of Netfilter NAT *much* larger than the overhead
> of the socket match. Also, the need for the 'fancy' routing setup is just
> because we would have liked to avoid intrusive changes to the kernel.
> 
> We had a patchset with some changes in the core ipv4 routing code so that
> absolutely no modifications were necessary to the routing config. We
> transitioned to the new approach because
> 
>   * it required no changes to routing code, and thus had a better
>     possibility of merging upstream,
> 
>   * it's slightly more flexible (ie. now that the kernel can do policy
>     routing for IPv6 implementing tproxy support for that protocol should
>     be easier.
> 
> As far as I know the current upstream implementation does not have any
> problems with (related) ICMP and does not usually interfere with
> connection tracking. (Unfortunately, because of the way conntrack works
> you cannot have full connection tracking and do transparent proxying in
> certain corner cases.)
> 
> Most of the modifications of the tproxy patch weren't necessary to
> 'circumvent kernel safety measurements and control checks', but to make it
> possible to have a TCP endpoint with a non-local IP address in the Linux
> stack. It *almost* worked out-of-the-box, it's just that the code
> contained a few checks which interfered with tproxy. This does not mean in
> any way that the security of the network stack is breached, however: you
> need to be highly privileged to set the IP_TRANSPARENT flag to make the
> kernel omit those checks in the IPv4 output path.
> 
> On the contrary, there were all kinds of complications with tproxy2, all
> coming from the fact that the local socket table and the connection
> tracking database of the kernel were out-of-sync (by design). Having been
> there and done that, I don't think we should go back to that approach...
> 

Very well put :)

-- 
Bazsi



More information about the tproxy mailing list