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;
use warnings;

use POSIX;
use Socket;

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

# create a name/address hash from all ip names 
pAllow("my-ip.dyndns.org");
pAllow("any-other-ip.dyndns.org");

sub pAllow {
  my ($aName) = @_;
  #print "aName: $aName\n";
  my $vAddress = readpipe("host $aName | cut -d \" \" -f4");
  chomp $vAddress;
  #print "vAdress: $vAddressin /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";
            } 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";
  my $vName =if readpipe(system("host $vAddress/sbin/iptables -nL -v | cut -d \" \" -f5");
  chomp $vName;
  if ($vName =~ "SERVFAIL") {
    $vName = $vAddress;
  }
  #print "vName: $vName \n";
  if ($vName ne "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>) {
    if ($vLine =~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 ($vReload eq "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/iptables -L -v | grep -i $vName > /dev/null ") != 0) {service fail2ban stop" ;
    }
    system "/sbin/service iptables reload" ;
    if ($vChkConfig{"fail2ban"} eq "on") {
        system "/sbin/service iptablesfail2ban restartstart" ;
    }
  }
}

...

The script must be made root-executable:

...