[TriLUG] why is it slow?

Ryan Leathers rleathers at americanri.com
Fri Sep 15 08:40:54 EDT 2006


Heheh... Aaron, I try to always read your posts, even when I'm not all
that interested in the topic.  Today was the sweet payoff.  What solemn
pride is mine in the knowledge that I have, in some small way,
contributed to your appreciation for doing things the "network guy"
way :)



On Thu, 2006-09-14 at 23:22 -0700, Aaron S. Joyner wrote:
> Rick DeNatale wrote:
> 
> > On 9/13/06, Aaron S. Joyner <aaron at joyner.ws> wrote:
> >
> >> So this post isn't entirely useless - my gut instinct is that the
> >> problem is related to the "u-turn" problem as described, but I'm at a
> >> loss to explain precisely the internals of why.  Assuming the NAT
> >> implementation is anything close to *sane* on the embedded router, this
> >> really shouldn't be a problem.  Then again, don't trust the Chinese or
> >> Korean guy who wrote the firmware to have done a sensible job on his
> >> first programming project.
> >
> >
> > I've had appliance routers (SMS I think) which refused to recognize
> > "U-turn" addressing.
> >
> > Unlike Brian, there are routers that do this, the Netgear I'm using
> > now has no problem with it.
> >
> > Just out of curiosity how would you set up NAT routing in Linux to do
> > this, with port forwarding?  For example say:
> >
> > wan-interface gets it's ip address from isp via dhcp
> > lan-interface 192.168.1.1
> > lan devices use 192.168.1.1 as gateway.
> >
> > for requests coming from either outside or inside:
> >     http connections to wan ip address get forwarded to 192.168.1.2
> >     wan ssh connections to wan ip address get forwarded to 192.168.1.3
> >
> Okay, so I started writing this like 30 mins ago, and discovered along 
> the way that this doesn't work for this case easily at all.  In fact, I 
> tried to cook up a way with just iptables, and failed miserably.  Allow 
> me to summarize what I was originally thinking, and then explain why 
> this case is messy, and provide a completely wacky solution or two.
> 
> In my mind, when you have a simple home network, and a Linux box, you 
> run the services on the gateway.  I don't typically have additional 
> servers behind my gateway which I push ports through to, via some 
> mechanism ala DNAT.  If you do run services on the inside, and DNAT into 
> them, you don't loop through the router for numerous reasons, including 
> a) inefficient use of network links, b) weird problems like we're about 
> to discuss, c) it just feels wrong.  :)  The typical way to handle this 
> problem is at the name space level.  If you're addressing service Foo as 
> foo.joyner.ws, then the external DNS view will return the external IP 
> address, and the internal DNS view will return the internal IP address.  
> In the days before views, you either ran two DNS servers with different 
> zone files, or you used two different domain names (foo.int.joyner.ws, 
> for example - where int is short for internal).  This way, you use the 
> names, life is happy, and traffic flows logically.  If you need to use 
> IPs to address the service, you better understand what IP to use from 
> where.  :)
> 
> Anyway, on with why this is messy in Linux.  If you originate traffic 
> internally from 192.168.1.5, and address your traffic to the external IP 
> address, and have the appropriate DNAT rule, your packet gets passed 
> back inside to 192.168.1.2 just fine.  The problem is that you can only 
> change the destination address, or the source address.  You can do 
> either one with the DNAT or SNAT targets in iptables, respectively.  
> Unfortunately, both of these targets terminate rule processing and 
> immediately deliver your packet on it's merry way, out the interface.  
> Choosing the DNAT rule is the logical choice, as that will at least get 
> your packet to where it needs to go.  The problem is, the source address 
> is still 192.168.1.5, so when 192.168.1.2 writes the response packet, it 
> delivers it directly to 192.168.1.5.  It does not send it back through 
> the gateway (as you would sort of hope it would).  Consequentially, when 
> that packet arrives, 192.168.1.5 doesn't recognize it as part of the 
> stream it originated to the external IP address (naturally), so it drops 
> it on the floor, and you get no where.  I googled, I looked through 
> Usenet archives, I searched for quite some time for a way to change both 
> the source and destination address of a packet with iptables.  Some 
> people seem to be suggesting that you can just use an additional SNAT to 
> fix the problem (and believe me, it seemed logical before reading the 
> iptables man page, and I did try - oh did I try), but my testing proves 
> out that this simply does not work.  Once the packet matches the DNAT 
> rule, you get no more opportunity to match any appropriate SNAT rules, 
> and vice versa.  If someone else out there knows of a way to make this 
> work via iptables alone, I'd be mighty interested in it, because I can't 
> come up with a way, and it sure feels like there should be one.
> 
> On to the truly wacky ways to actually make this work.  So, a few things 
> came to mind immediately, all of which are horribly ugly, and if you 
> implement them... well... I'm not to blame.  First off, make sure your 
> DNAT rule is sufficiently specific that it doesn't capture traffic from 
> the internal network (a simple -s ! 192.168.1.0/24 will suffice).  Then, 
> start tacking on rules like -j REDIRECT -port 8080, to capture that port 
> 80 traffic and redirect it to a local port 8080.  Then, run a 
> port-redirector on port 8080 which will capture the traffic, and 
> originate new traffic on to the destination box.  This will get the 
> right source IP address into the packet, and cause 192.168.1.2 to 
> respond to the gateway, which can then pass the packets back through the 
> port redirector, back to the REDIRECT session / rule, and then 
> eventually back to 192.168.1.5.  Don't blame me, I said it was ugly.  I 
> also promised to provide more than one ugly solution.
> 
> The other way to skin this cat, is to do weird things on the backend 
> servers.  You could do something akin to port based policy routing, such 
> that you add an iproute2 rule to match traffic originating from port 80 
> on the web server, traveling to any host on the local network, and shunt 
> it to a different route table, which only has an explicit nexthop set 
> for all hosts on the network to the default gateway.  The amusing thing 
> here is that you can't match packets with just iproute2 based on port, 
> you only get src and dst ip address.  You can match on fwmark, from 
> iptables, though.  So you mark the packets with iptables via the -j MARK 
> target, then apply the route to them with the `ip rule` command.  This 
> solution may or may not actually work, depending on how the gateway 
> handles that incoming traffic destined for another host on the same 
> network.  It's late, and I don't want to setup the above absurd solution 
> to see it if will work or not.  :)  If anyone's feeling bored, let me 
> know -- I think it'll work, but I'm not quite sure how you'd have to 
> specify the route(s) in the alt routing table, ie. can you do a simple 
> /24 with the nexthop set to the gateway, or do you need individual /32s 
> for everything but the machine itself and the gateway, or perhaps some 
> odd mix to make it easier to specify, with the same effect?
> 
> Let it be said that I'm a died in the wool Linux fan, and I don't think 
> many people on the list will question that.  But, I was thinking while 
> writing that last paragraph, that this is dramatically easier to do on 
> an honest-to-god router.  Not just part of it, but all of it.  Granted, 
> you have to think like a network guy, and the terminology is almost all 
> different, conceptually half of it is different, and the configuration 
> of things is 100% different, but once you beat the learning curve, man 
> is it easier.  On the flip side, all the things that seem easy and you 
> take for granted in the Linux world, become their own challenge in that 
> world.  *chuckle*  I'll stick with the things I know inside and out, and 
> jump through hurdles like above as required every once in a while.  In 
> this world, at least I know how to overcome the bizarre edge cases 
> better.  :)  Yes Ryan, this paragraph was for you.  I hope you made it 
> this far in.
> 
> It's late, I'm tired, enough typing.
> Aaron S. Joyner
> 




More information about the TriLUG mailing list