iptables and dynamic DNS

Please read other posts in this section as well.
They may provide better options.

I just found back an old note about using iptables in combination with dyndns to open up access from a remote location. For instance, if you have a laptop that you take everywhere and you want to connect to your home or office. The script the other site suggested was broken, so let's write a new one.

Step 1: Create a new chain in the firewall

Create a new chain in the firewall where we can plug in the dynamic rules. On my Fedora machine, the firewall is located in /etc/sysconfig/iptables. I added the bold lines to this example.


*nat
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
COMMIT
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
<b>:DYNAMIC - [0:0]
-A INPUT -j DYNAMIC</b>
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT

Step 2: Write a script

#!/bin/bash
 
HOSTNAME=myname.dyndns.org
CHECK_INTERVAL=60 #once a minute
 
/sbin/iptables -F DYNAMIC #flush all existing rules
IP="" #initialize $IP
while [ true ]; do
    OIP=$IP
    IP=$(host $HOSTNAME | grep -iE "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" |cut -f4 -d' '|head -n 1)
    if [ "$OIP" != "$IP" -a "$IP" != "" ]; then
         echo "Changing ip to $IP"
         /sbin/iptables -F DYNAMIC #flush all old rules
         /sbin/iptables -I DYNAMIC -s $IP -j ACCEPT #the new rule
    fi
    sleep $CHECK_INTERVAL
done

In this case, the firewall accepts all traffic from $IP, but of course you could restrict it to 1 port. Also, I focussed on IPv4, but you could easily rewrite this script to IPv6 using ip6tables. I saved the file to /usr/local/bin/dynfirewall.sh

Step 3: Run the script

I'd prefer running the script from inittab, but since Fedora doesn't work like this anymore, I put the following line in /etc/rc.d/rc.local:

/usr/local/bin/dynfirewall.sh >>/var/log/dynfirewall 2>>/var/log/dynfirewall &

Please don't forget the ampersand at the end to fork the script!!

© GeekLabInfo iptables and dynamic DNS is a post from GeekLab.info. You are free to copy materials from GeekLab.info, but you are required to link back to http://www.geeklab.info

1 Star2 Stars3 Stars4 Stars5 Stars (2 votes, average: 5.00 out of 5)
Loading...

4 comments on “iptables and dynamic DNS”

  1. I got an error at iptables.

    [quote]iptables: Applying firewall rules: iptables-restore v1.4.7: iptables-restore: line 7 policy invalid

    Error occurred at line: 7
    Try `iptables-restore -h' or 'iptables-restore --help' for more information.
    [FAILED] [/quote]

    The line 7 is this code.

    [code]
    :DYNAMIC
    [/code]

  2. Thanks, that was a little mistake. The line should be:
    :DYNAMIC - [0:0]

  3. Thanks, the result is here.

    [quote]
    # service iptables restart
    iptables: Flushing firewall rules: [ OK ]
    iptables: Setting chains to policy ACCEPT: filter [ OK ]
    iptables: Unloading modules: [ OK ]
    iptables: Applying firewall rules: [ OK ]
    [/quote]

    And please check these code would work or not.

    [code]
    #!/bin/bash

    HOSTNAME=myname.dyndns.org
    CHECK_INTERVAL=60 #once a minute

    /sbin/iptables -F DYNAMIC #flush all existing rules
    IP="" #initialize $IP
    while [ true ]; do
    OIP=$IP
    IP=$(host $HOSTNAME | grep -iE "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" |cut -f4 -d' '|head -n 1)
    if [ "$OIP" != "$IP" -a "$IP" != "" ]; then
    echo "Changing ip to $IP"
    /sbin/iptables -F DYNAMIC #flush all old rules
    /sbin/iptables -I DYNAMIC -s $IP -p tcp -m state --state NEW -m tcp --dport 21 -j ACCEPT
    /sbin/iptables -I DYNAMIC -s $IP -p tcp -m state --state NEW -m tcp --dport 5769 -j ACCEPT
    /sbin/iptables -I DYNAMIC -s $IP -m state --state NEW -m tcp -p tcp --dport 5901 -j ACCEPT
    /sbin/iptables -I DYNAMIC -s $IP -m state --state NEW -m tcp -p tcp --dport 5902 -j ACCEPT
    /sbin/iptables -I DYNAMIC -s $IP -m state --state NEW -m tcp -p tcp --dport 5903 -j ACCEPT
    /sbin/iptables -I DYNAMIC -s $IP -p udp -m udp --dport 177 -j ACCEPT
    /sbin/iptables -I DYNAMIC -s $IP -m state --state NEW -m tcp -p tcp --dport 7100 -j ACCEPT
    fi
    sleep $CHECK_INTERVAL
    done
    [/code]

  4. the matching regex for the IP could be improved to something like:

    grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}'

    neat solution btw.

Leave a Reply