Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: new version of update-firewall.pl

...

As an alternative, you can advertise your current external address, as it can be found out using services like VPN Mentor. Some dynamic DNS provides supply a client for your workstations which updates the address automatically. An example is the DynDNS Updater.

Let's assume that you have applied for the dynamic DNS name "my-ip.dyndns.org". In the following examples you must replace this name by your actual dynamic DNS name.

...

Create the script "update-firewall.pl" 

This script captures changes to the addresses represented by IP names in /etc/sysconfig/iptables. It restarts the firewall and fail2ban as required.

Login as root.

mkdir -p ~/scripts
cd ~/scripts
vi update-firewall.pl
Code Block
languageperl
titleupdate-firewall.pl
#!/usr/bin/perl -w

# restart the firewall if thea dynamically assigned address of my-ip.dyndns.orgin /etc/sysconfig/iptables has changed

# 2016-01-02 15:30
# 2016-05-29 rewritten to capture changes to /etc/sysconfig/iptables without the need to modify this procedure
# 2016-06-07 stop/start fail2ban if necessary

use strict;

pAllow("my-ip.dyndns.org");
pAllow("any-other-ip.dyndns.org");

sub pAllow {
  my ($aName) = @_;
  #print "aName: $aNameuse warnings;

use POSIX;
use Socket;

my $vReload = "no"; # restart only once

# create a name/address hash from all ip names in /etc/sysconfig/iptables
open (IPTABLES, '/etc/sysconfig/iptables')
    or die "Could not open /etc/sysconfig/iptables: $!";
my %vIPNames;
while (my $vLine = <IPTABLES>)  {
    # only lines containing ip names (at least aaa.bbb)
    if ($vLine =~ m/([a-zA-Z][^\s]+\.[^\s]+)/) {
        my $vIPName = $1;
        # ns lookup once only
        if (! exists $vIPNames{$vIPName}) {
            my $vIPAddress = "127.0.0.1";
            my @vHostInfo = gethostbyname($vIPName);
            if (scalar(@vHostInfo) == 0) {
                print "gethostbyname: Can't resolve $vIPName: $!\n";
  my $vAddress = readpipe("host $aName | cut -d \" \" -f4");
  chomp $vAddress;
  #print "vAdress: $vAddress\n";
  my $vName = readpipe("host $vAddress | cut -d \" \" -f5");
  chomp $vName;
  if ($vName =~ "SERVFAIL"         } else {
                $vIPAddress = inet_ntoa(inet_aton($vIPName))
                    or die "inet_ntoa: Can't resolve $vIPName: $!\n";
                chomp $vIPAddress;
                $vIPNames{$vIPName} = $vIPAddress;
            }
        } else {
            # print "duplicate $vIPName = $vIPNames{$vIPName} \n";
        }
    }
}
close IPTABLES;

# check against actual numeric values in /sbin/iptables -nL
for my $vIPName (sort (keys %vIPNames)) {
    my $vIPAddress = $vIPNames{$vIPName};
    # print "$vIPName = $vIPAddress\n";
    if (system("/sbin/iptables -nL -v | grep -i $vIPAddress > /dev/null ") != 0) {
         print "\n", strftime("%F %T", localtime) , " $vIPName has the new address $vIPAddress\n";
         $vReload = "yes";
    }
}

# build hash of services loaded in runlevel 3
open (CHKCONFIG, "LANG=en /sbin/chkconfig --list |")
    or die "Could not run chkconfig: $!";
my %vChkConfig;
while (my $vLine = <CHKCONFIG>) {
    $vNameif ($vLine = $vAddress;
  }
  #print "vName: $vName ~m/^([^\s]+)(\s+\d:([^\s]+)){7}/) {
        chomp $vLine;
        my @vColumns = split /\s+/, $vLine;
        $vChkConfig{$vColumns[0]} = substr($vColumns[4], 2);
    }
}

# foreach my $vService (sort {$vChkConfig{$a} cmp $vChkConfig{$b}} sort keys %vChkConfig) {
#     print $vChkConfig{$vService} . "\t" . $vService . "\n";
# }

# reload iptables
if ($vName$vReload neeq "yes") {
    print "\n", strftime("%F %T", localtime) , " Reloading tptables\n";
    # resatrt fail2ban only if it has been loaded in runlevel 3
    if (system($vChkConfig{"fail2ban"} eq "on") {
        system "/sbin/iptablesservice -L -v | grep -i $vName > /dev/null ") != 0fail2ban stop" ;
    }
    system "/sbin/service iptables reload" ;
    if ($vChkConfig{"fail2ban"} eq "on") {
        system "/sbin/service iptablesfail2ban restartstart" ;
    }
  }
}

Keep in mind that you have to replace the IP names in the calls to pAllow with the actual names you received from your dynamic DNS provider. You can add all your dynamic DNS names in this script, even if they are not listed in your IPTables configuration.

The script must be made root-executable:

...