Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I have three computers, linked like this:

box1 (ubuntu)   box2 router & gateway (debian)       box3 (opensuse)
[10.0.1.1] ---- [10.0.1.18,10.0.2.18,10.0.3.18] ---- [10.0.3.15]
                               |
                           box4, www
                           [10.0.2.1]

Among other things I want box2 to do nat and port forwarding, so that I can do

ssh -p 2223 box2

to reach box3. For this I have the following iptables script:

    #!/bin/bash

    # flush
    iptables -F INPUT
    iptables -F FORWARD
    iptables -F OUTPUT

    iptables -t nat  -F PREROUTING
    iptables -t nat  -F POSTROUTING
    iptables -t nat  -F OUTPUT

    # default
    default_action=DROP
    for chain in INPUT OUTPUT;do
    iptables -P $chain $default_action
    done
    iptables -P FORWARD DROP


    # allow ssh to local computer
    allowed_ssh_clients="10.0.1.1 10.0.3.15"
    for ip in $allowed_ssh_clients;do
    iptables -A OUTPUT -p tcp --sport 22 -d $ip -j ACCEPT
    iptables -A INPUT -p tcp --dport 22 -s $ip -j ACCEPT
    done

    # allow DNS
    iptables -A OUTPUT -p udp --dport 53 -m state \
    --state NEW,ESTABLISHED,RELATED -j ACCEPT
    iptables -A INPUT -p udp --sport 53 -m state \
    --state ESTABLISHED,RELATED -j ACCEPT

    # allow HTTP & HTTPS
    iptables -A OUTPUT -p tcp -m multiport --dports 80,443 -j ACCEPT
    iptables -A INPUT -p tcp  -m multiport --sports 80,443 -j ACCEPT

    #
    # ROUTING
    #

    # allow routing
    echo 1 >/proc/sys/net/ipv4/ip_forward
    # nat
    iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

    # http
    iptables -A FORWARD -p tcp --dport 80 -j ACCEPT
    iptables -A FORWARD -p tcp --sport 80 -j ACCEPT

    # ssh redirect
    iptables -t nat -A PREROUTING -p tcp -i eth1 --dport 2223 -j DNAT \
    --to-destination 10.0.3.15:22
    iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

    iptables -A FORWARD -p tcp --sport 22 -j ACCEPT
    iptables -A FORWARD -p tcp --dport 22 -j ACCEPT

    iptables -A FORWARD -p tcp --sport 1024:65535 -j ACCEPT
    iptables -A FORWARD -p tcp --dport 1024:65535  -j ACCEPT

    iptables -I FORWARD -j LOG --log-prefix "iptables denied: "

While this works, it takes about 10 seconds to get a password promt from my ssh command. Afterwards, the connection is as responsive as could be. If I change the default policy for my FORWARD chain to "ACCEPT", then the password promt is there imediatly.

I have tried analysing the logs, but I can not spot a difference in the logs for ACCEPT/DROP in my FORWARD chain. Also I have tried allowing all the unprivileged ports, as box1 uses thoses for doing ssh to box2.

Any hints?

(If the whole setup seems strange to you - the point of the exercise is to understand iptables ;))

share|improve this question

1 Answer 1

up vote 2 down vote accepted

Most likely this is caused by DNS failure in box3. When you change the FORWARD policy to ACCEPT you are allowing all traffic (include DNS). I can not see any rule allowing DNS traffic in your FORWARD chain.

You have two options to speedup ssh login:

  1. Allow DNS traffic to pass through your firewall.
  2. Configure SSH daemon to not do DNS lookups by changing the line UseDNS yes to read UseDNS no in /etc/ssh/sshd_config.
share|improve this answer
    
If I understand correctly, adding the following would let DNS pass: iptables -A FORWARD -p tcp --sport 53 -j ACCEPT iptables -A FORWARD -p tcp --dport 53 -j ACCEPT. But this did not help –  Isaac Sep 13 '12 at 10:49
1  
@Isaac: You need to allow UDP traffic destined to port 53. DNS resolve requests are sent using UDP. –  Khaled Sep 13 '12 at 11:01
    
Thank you Khaled! Of course, DNS uses udp ... working now. –  Isaac Sep 13 '12 at 11:40

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.