Linux NAT with one network interface?

This morning I encountered a problem trying to setup IP masquerading with my ASUS notebook. Notebook has only one network interface and it is connected to my cable modem. No problem, I thought, I will connect my notebook, cable modem and my wife’s notebook to a small switch I have, and than create an interface alias for my primary network interface, and setup a simple IP masquerading so both notebooks have internet access. Simple as that. Network would look like:

Home Lan

First, I added interface alias so I can communicate with other notebook:

# ifconfig eth0:1 netmask
# ping
PING ( 56(84) bytes of data.
64 bytes from icmp_seq=1 ttl=128 time=0.177 ms
64 bytes from icmp_seq=2 ttl=128 time=0.159 ms
64 bytes from icmp_seq=3 ttl=128 time=0.148 ms
64 bytes from icmp_seq=4 ttl=128 time=0.198 ms
— ping statistics —
4 packets transmitted, 4 received, 0% packet loss, time 2998ms
rtt min/avg/max/mdev = 0.148/0.170/0.198/0.023 ms

That seems to work. On to the next step. We have to setup NAT between those two computers. The exact process should be, for my configuration:

# echo “1″ > /proc/sys/net/ipv4/ip_forward
# iptables -A FORWARD -i eth0 -o eth0:1 -m state \
# iptables -A FORWARD -i eth0:1 -o eth0 -j ACCEPT
# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

So lets do it:

# echo “1″ > /proc/sys/net/ipv4/ip_forward

No error so far. Next:

# iptables -A FORWARD -i eth0 -o eth0:1 -m state \
Warning: wierd character in interface `eth0:1′
(No aliases, :, ! or *).

What was that?! “Warning: wierd character in interface `eth0:1′ (No aliases, :, ! or *).” Hmm… maybe I made some typo? I don’t think so (although there is a typo in error message, weird is not spelled like that :)). Seems that NetFilter is not able to do NAT with only one interface, which is pretty reasonable. But, cheap as I am, I had no intention of buying new PCMCIA network card, so I had to find a way of doing this with only one interface.

After hour spent searching the google for answer, I started getting some ideas. If we can not use interface alias maybe we can use IP address of the other node in the network insted of it. Seemed like a wild guess but I was getting pretty desperate. :)

# iptables -A FORWARD -i eth0 -d -m state \

No error. That’s a good sign. So, let’s try the rest.

# iptables -A FORWARD -s -o eth0 -j ACCEPT
# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

Again, no error. Let’s test it from the other node.

# ping google.com
PING google.com ( 56(84) bytes of data.
64 bytes from icmp_seq=1 ttl=241 time=142 ms
64 bytes from icmp_seq=2 ttl=241 time=141 ms
64 bytes from icmp_seq=3 ttl=241 time=143 ms
— google.com ping statistics —
3 packets transmitted, 3 received, 0% packet loss, time 1999ms
rtt min/avg/max/mdev = 141.888/142.763/143.515/0.669 ms

Wow, it works. :) Sometimes being cheap pays off. :) So, one problem down. What about port forwarding. My wife is a huge e-mule fan, and if her incoming e-mule port is blocked she will get LowID which makes downloading painful. Again, first I tried iptables.

# iptables -t nat -A PREROUTING -p tcp -i eth0 \
> -d –dport 34567 -j DNAT –to
# iptables -A FORWARD -p tcp -i eth0 -d \
> –dport 34567 -j ACCEPT

And for some reason this was not working. At this point I gave up and tried something else. Something that works. :-p

I’m sure most of you know that one of the features of SSH is port forwarding.

# ssh -g -N -L 34567: localhost
root@localhost’s password:

And that’s it. With this we forwarded port 34567 on localhost to port 34567 on other notebook with address But there is still one problem. This way port forwarding can not be started at system boot since it demands user interaction (ssh asks for password when started). That problem is also easy to solve. We need to generate key that we will use instead of password.

# ssh-keygen -t dsa -b 1024 -f /root/ssh_key
Generating public/private dsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/ssh_key.
Your public key has been saved in /root/ssh_key.pub.
The key fingerprint is:
c7:05:e7:e6:38:77:82:79:a1:d9:b5:ab:2f:3a:84:02 root@localhost

Now all we need to do is to copy /root/ssh_key.pub into /root/.ssh/authorized_keys and next time we try to login using this key we will not be asked for password.

# cat /root/ssh_key.pub >>/root/.ssh/authorized_keys

For the sake of security we can restrict login with this key only to localhost, so our /root/.ssh/authorized_keys will look like:

from=”″ ssh-dss AAAAB3NzaC1kc3MAAACBAKtVMMBIqjAmXKkk…

We can test it to see if it works.

# telnet 34567
telnet: connect to address Connection refused
telnet: Unable to connect to remote host: Connection refused
# ssh -g -N -L 34567: \
> -i /root/ssh_key
root@′s password: ^C
# ssh -g -N -L 34567: localhost \
> -i /root/ssh_key # telnet 34567
Connected to (
Escape character is ‘^]’.
Connection closed by foreign host.

That’s all folks. :)

4 Responses to “Linux NAT with one network interface?”

  1. 1 Данило Dec 26th, 2006 at 7:00 pm

    Миљане, isn’t it better to use non-root ssh tunnelling for things like port 34567? ;)

    Anyway, nice tips there, maybe I’ll find some use for them in the future.

  2. 2 miljan Dec 26th, 2006 at 7:34 pm

    From security point of view, I agree with you Данило. Since it is not a privileged port there is no need for root here, but it looks so much more k00l this way, don’t you think? :-)))

  3. 3 bc Feb 8th, 2007 at 6:45 am

    lol linux lolololol

    pa crni miljane!!!!

  4. 4 miljan Feb 8th, 2007 at 6:56 am

    Nije to Linux, to je Fedora! :-p

Comments are currently closed.