[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

totally bizarre NAT behavior



Hi, everybody!

I just spent five totally frustrating hours debugging a problem that
shouldn't exist, and the problem was so baffling and its resolution so
disconcerting I thought I'd share my experience with everyone and see
if anyone has any words of wisdom for me.

For reasons that I've long since forgotten, I once thought it would be
an interesting learning experience to create a fully NATted private
network. I lease 4 IP addresses from my ISP (let's call them 10.0.2.1
- 10.0.2.4 for the sake of discussion), and conveniently enough I
have four hosts on my home network, which I've put on a
192.168.13.0/24 private network. The routing bastion host which deals
with the translation, located at 10.0.2.1, is a Netwinder running
woody, kernel 2.4.3 and all the appropriate modules.

After a _lot_ of experimentation (the Netfilter NAT HOWTO is an
admirably opaque document in places), I put together a little script
that I placed in /etc/init.d to deal with the IP address translation
between the private and external networks. I've attached the script to
this message. It's worked pretty well for the last month or so since I
upgraded to 2.4.x.

Today I upgraded the kernel on the NetWinder and rebooted. After
rebooting, my TiBook, located at 192.168.13.2, could no longer get
packets out to the world. The FreeBSD server at 192.168.13.4 had no
problem, and if I changed the TiBook's NIC configuration to instead
use 192.168.13.3 as its IP address, it would start working as
well. I tried shuffling the order of the iptables rules and it made no
difference. I tried a lot of things. Nothing worked.

Careful scrutiny of Ethereal captures showed that outgoing packets
from the TiBook were getting rewritten to appear as being from
10.0.2.2, but for that host _and that host only_, incoming packets
were not getting rewritten properly back to 192.168.13.2. I'm not
otherwise filtering packets, and as far as I can tell there are no
bizarre sysctls set on the Netwinder to make life miserable for only
that IP address.

Eventually, just for the hell of it, I added an extra iptables rule to
the list:

iptables -t nat -A PREROUTING -j DNAT -i eth0 --to 192.168.13.2 -d 10.0.0.1

For no good reason that I can ascertain, everything suddenly started
working! Here's the current output from 'iptables -t nat -L':

Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
DNAT       all  --  0.0.0.0/0            10.0.2.2           to:192.168.13.2 
DNAT       all  --  0.0.0.0/0            10.0.2.3           to:192.168.13.3 
DNAT       all  --  0.0.0.0/0            10.0.2.4           to:192.168.13.4 
DNAT       all  --  0.0.0.0/0            10.0.2.2           to:10.0.0.1 

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
SNAT       all  --  192.168.13.2         0.0.0.0/0          to:10.0.2.2 
SNAT       all  --  192.168.13.3         0.0.0.0/0          to:10.0.2.3 
SNAT       all  --  192.168.13.4         0.0.0.0/0          to:10.0.2.4 

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Does anyone have any idea what's going on here? Why would two
addresses work, but not a third? Why would adding a gratuitous and
possibly broken rule cause things to start working? Have I stumbled
upon some obscure bug? Have I done something utterly retarded? Has
anyone encountered anything like this before? What's the deal?

Thanks in advance for any feedback or wisdom. All I know is, I'm never
rebooting that machine again.

sincerely yours,
Forrest Norvell

       . . . the self-reflecting image of a narcotized mind . . .
ozymandias G desiderata     ogd@aoaioxxysz.net     desperate, deathless
(415)558-9064        http://www.aoaioxxysz.com/          ::AOAIOXXYSZ::
#!/bin/sh

PATH=/sbin

# ensure that necessary modules are loaded
modprobe iptable_nat
modprobe ip_nat_ftp

# set important IP properties
echo 1 > /proc/sys/net/ipv4/ip_forward
echo 1 > /proc/sys/net/ipv4/tcp_syncookies
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts

# When using the new NAT code, we have to tell the kernel
# to bind external addresses for ARP queries
ip address add 10.0.2.2 dev eth0
ip address add 10.0.2.3 dev eth0
ip address add 10.0.2.4 dev eth0

# flush NAT table
iptables -t nat -F

# Source modifications for outgoing packets
iptables -t nat -A POSTROUTING -j SNAT -o eth0 -s 192.168.13.2 --to 10.0.2.2
iptables -t nat -A POSTROUTING -j SNAT -o eth0 -s 192.168.13.3 --to 10.0.2.3
iptables -t nat -A POSTROUTING -j SNAT -o eth0 -s 192.168.13.4 --to 10.0.2.4

# Destination modifications for incoming packets
iptables -t nat -A PREROUTING -j DNAT -i eth0 --to 192.168.13.2 -d 10.0.2.2
iptables -t nat -A PREROUTING -j DNAT -i eth0 --to 192.168.13.3 -d 10.0.2.3
iptables -t nat -A PREROUTING -j DNAT -i eth0 --to 192.168.13.4 -d 10.0.2.4

Attachment: pgp3xDbeahre2.pgp
Description: PGP signature


Reply to: