Using IPTables with Dynamic IP hostnames like dyndns.org

Whenever IPTables has a hostname in a rule it looks up the hostname’s IP address and uses that instead of the actual hostname – so it’s stuck with the IP until the next time IPTables is flushed/restarted. Here’s a quick little python script to stick in a crontab which checks the IP of your dynamic IP hostname (free ones provided by dyndns.org) and will restart iptables if it catches a change in your hostname. The script was made for CentOS so should work on Red Hat based distributions – if you don’t have an /etc/init.d/iptables file you’ll have to modify the reload iptables command in the source. Viewable Source After Jump

I just set this up as root and in root’s crontab.

Download Source

Source:

#!/usr/bin/python
 
import os
 
def gettextoutput(cmd):
    """Return (status, output) of executing cmd in a shell."""
    pipe = os.popen('{ ' + cmd + '; } 2>&1', 'r')
    pipe = os.popen(cmd + ' 2>&1', 'r')
    text = pipe.read()
    if text[-1:] == '\n': text = text[:-1]
    return text
 
home_dyndns = "example.dyndns.org"
log_dyndns = "./new_home_ip_check.log"
last_dyndns = gettextoutput("cat " + log_dyndns)
cur_dyndns = gettextoutput("host " + home_dyndns)
 
print "Log: "+ last_dyndns
print "Cur: "+ cur_dyndns
 
if last_dyndns == cur_dyndns:
    print "IPs match, no restart necessary"
else:
    print "Updating last IP with current"
    os.system("echo '" + cur_dyndns + "' > " + log_dyndns)
    print "Restarting iptables to update"
    os.system("/etc/init.d/iptables restart")

Output looks like:

Log: example.dyndns.org has address 114.76.37.112
Cur: example.dyndns.org has address 114.76.37.112
IPs match, no restart necessary
 
Log: example.dyndns.org has address 114.76.37.113
Cur: example.dyndns.org has address 114.76.37.112
Updating last IP with current
Restarting iptables to update
Flushing firewall rules:                                   [  OK  ]
Setting chains to policy ACCEPT: filter                    [  OK  ]
Unloading iptables modules:                                [  OK  ]
Applying iptables firewall rules:                          [  OK  ]
Loading additional iptables modules: ip_conntrack_netbios_n[  OK  ]
Be Sociable, Share!
  • Google Reader
  • HackerNews
  • Reddit
  • email
  • StumbleUpon
  • Delicious
  • Posterous

11 thoughts on “Using IPTables with Dynamic IP hostnames like dyndns.org

  1. I have this script working except when it restarts the iptables the ip address that gets listed in my iptables doesn’t change. I’m adding the host to my iptables using
    iptables -I INPUT -i eth1 -s hostname -j ACCEPT
    if I check my iptables with
    iptables -L -n
    I get the rule and it has substituted the current IP address for the host name. and everything works. but if the IP for the host name changes this script detects it and restarts the iptables but the IP address listed doing an iptables -L -n doesn’t change. I’m pretty new to the whole IP tables so maybe I’m doing it wrong? any ideas? thanks

    • So I couldn’t get the dns name in the IP tables to work so I took your idea and wrtoe a bash script that looks up the host name adds it to the iptables and if the IP changes removes the old rule and adds a new one for the new ip.

      #!/bin/bash
      #allow a dyndns name

      HOSTNAME=HOST_NAME_HERE
      LOGFILE=LOGFILE_NAME_HERE

      Current_IP=$(host $HOSTNAME | cut -f4 -d' ')

      if [ $LOGFILE = "" ] ; then
      iptables -I INPUT -i eth1 -s $Current_IP -j ACCEPT
      echo $Current_IP > $LOGFILE
      else

      Old_IP=$(cat $LOGFILE)

      if [ "$Current_IP" = "$Old_IP" ] ; then
      echo IP address has not changed
      else
      iptables -D INPUT -i eth1 -s $Old_IP -j ACCEPT
      iptables -I INPUT -i eth1 -s $Current_IP -j ACCEPT
      echo $Current_IP > $LOGFILE
      echo iptables have been updated
      fi
      fi

      then just add this line to your crontab and it will check every 5 mins and keep your iptables up-to-date.
      */5 * * * * /root/NAME_OF_SCRIPT.sh > /dev/null 2>&1

      • Nice work.

        What flavor of linux are you running? If you didn’t have an iptables init.d script, that might have been the problem. does /etc/init.d/iptables exist?
        I see you’ve already come up with a work around though – I went ahead and edited the articles to add a note about the iptables reload command being Red Hat based and needing to probably be modified for other system types.

      • I’m no doubt missing something, but doesn’t the use of host imply that the IP change has to have made its way to the name servers? If my ISP changes my IP, my server will not be able to access external DNS until the firewall is reconfigured. Can somebody clue me in on what I’m missing?

      • In my experience ISPs using DHCP won’t need any reconfiguration to assign you a new IP. The way it works is you pull a DHCP lease for an IP from the ISP and that lease lasts some amount of time. For example say 2 days, and after the 2 days is up that IP will be up for grabs again for anyone to take – unless you keep renewing your lease of the IP. Eventually you loose power or something and the IP isn’t renewed and you’re instead assigned a new IP. When this happens your DynDNS router programming or computer dyndns program reports the new IP and dyndns updates their records. Then a remote server (or multiple servers) running this script would see that the host/dns entry for your dyndns has changed and automatically restarts the firewall in order to pull in the latest DNS to IP translation for your dyndns address.

  2. Thanks for the clarification, but I think I’m still missing something. How does the computer dyndns program get the new IP to report it to DynDNS–and if it’s already got it somehow, why is the host command even needed? I agree the new IP would have to be reported to DynDNS before it could be obtained from the DNS servers, but not seeing how that first step occurs. Sorry to be dense.

    • I think you’re confused about the usage case for this program. Say I have a remote off-site server I want to lock out port 22 on EXCEPT for my work’s static IP block and my home’s Dynamic IP address. That off-site server won’t know when my home’s IP sends the update to dyndns and that it should restart iptables unless it does a host/dns lookup to find out the IP every once in a while. Does that clear things up?

  3. Pingback: Anonymous

  4. Pingback: Criando regras para ips dinâmicos no iptables | Alexos Core Labs

Leave a Reply