#!/usr/bin/perl $debug++; $IPCHAINS="/sbin/ipchains"; $LOGDIR="/var/log/ipsec"; $LOG="$LOGDIR/firewall.log"; $LOCAL_NET="192.168.0.0/16"; ############################################################################ # Loggin subroutines # sub logline{ local($text)=@_; $date=localtime; print LOG "$date: $text\n"; } sub debug{ local($text)=@_; if($debug){ $text=~s/\n$//; if($log){ logline($text); } if($odebug){ print "$text\n"; } } } sub log{ local($text)=@_; $text=~s/\n$//; logline($text) if($log); print "$text\n"; } ############################################################################ # Startup # mkdir($LOGDIR,0750); unless(open(LOG,">>$LOG")){ print "Failed to open logfile: $LOG\n"; $log=0; $odebug++; }else{ $log++; } unless($ENV{'PLUTO_VERB'}){ # not from from PLUTO, go to test case $ENV{'PLUTO_VERB'}="up-client"; $ENV{'PLUTO_PEER'}="212.247.86.26"; $ENV{'PLUTO_PEER_CLIENT'}="212.247.86.26/32"; $odebug++; } &debug("PLUTO_VERSION = $ENV{'PLUTO_VERSION'}"); &debug("PLUTO_VERB = $ENV{'PLUTO_VERB'}"); &debug("PLUTO_CONNECTION = $ENV{'PLUTO_CONNECTION'}"); &debug("PLUTO_NEXT_HOP = $ENV{'PLUTO_NEXT_HOP'}"); &debug("PLUTO_INTERFACE = $ENV{'PLUTO_INTERFACE'}"); &debug("PLUTO_ME = $ENV{'PLUTO_ME'}"); &debug("PLUTO_MY_CLIENT = $ENV{'PLUTO_MY_CLIENT'}"); &debug("PLUTO_MY_CLIENT_NET = $ENV{'PLUTO_MY_CLIENT_NET'}"); &debug("PLUTO_MY_CLIENT_MASK = $ENV{'PLUTO_MY_CLIENT_MASK'}"); &debug("PLUTO_PEER = $ENV{'PLUTO_PEER'}"); &debug("PLUTO_PEER_CLIENT = $ENV{'PLUTO_PEER_CLIENT'}"); &debug("PLUTO_PEER_CLIENT_NET = $ENV{'PLUTO_PEER_CLIENT_NET'}"); &debug("PLUTO_PEER_CLIENT_MASK = $ENV{'PLUTO_PEER_CLIENT_MASK'}"); &log("FIREWALL: Modifying rules for IPSec client $CLIENT_IP"); ############################################################################ # Delete any previous rules for this client address # sub downClient{ local($CLIENT_IP,$CLIENT_NET)=@_; $CLIENT_IP.="/$CLIENT_NET" unless($CLIENT_NET=~/32/); @prev=(); if(open(PIPE,"$IPCHAINS -L forward --line-numbers |")){ while(){ &debug("Processing ipchains output: $_"); if(/$CLIENT_IP/){ ($pos)=split(/\s+/,$_); push(@prev,$pos); &debug("Found previous rule at $pos: $_"); } } close(PIPE); } unless(scalar(@prev)){ &log("No previous forwarding rule for $CLIENT_IP found"); }else{ foreach $pos(@prev){ &log("FIREWALL: Deleting previous forwarding rule for $CLIENT_IP at position: $pos"); system("$IPCHAINS -D forward -s $LOCAL_NET -d $CLIENT_IP -j ACCEPT"); } } } ############################################################################ # Add a new rule for this client address *before* the masquerading rule # sub upClient{ local($CLIENT_IP,$CLIENT_NET)=@_; $CLIENT_IP.="/$CLIENT_NET" unless($CLIENT_NET=~/32/); @masq=(); if(open(PIPE,"$IPCHAINS -L forward --line-numbers |")){ while(){ &debug("Processing ipchains output: $_"); if(/MASQ/){ ($pos)=split(/\s+/,$_); push(@masq,$pos); &debug("Found masqurading rule at $pos: $_"); } } close(PIPE); } unless(scalar(@masq)){ &log("FIREWALL: Cannot find any masquerading rules"); &log("FIREWALL: Inserting client $CLIENT_IP rule at beginning of forward chain"); $pos=1; }else{ $pos=$masq[0]; # use first masquerading rule found &log("FIREWALL: Inserting client $CLIENT_IP rule before masquerading rule at position $pos"); } system("$IPCHAINS -I forward $pos -s $LOCAL_NET -d $CLIENT_IP -j ACCEPT"); system("$IPCHAINS -I forward $pos -s $CLIENT_IP -d $LOCAL_NET -j ACCEPT"); } ############################################################################ # Process PLUTO_VERB command # if($ENV{'PLUTO_VERB'}=~/up\-client/){ if($ENV{'PLUTO_PEER_CLIENT'}=~/(\d+\.\d+\.\d+\.\d+)\/(\d+)/){ &downClient($1,$2); &upClient($1,$2); }else{ &error("Unsupported PLUTO_PEER_CLIENT format: $ENV{'PLUTO_PEER_CLIENT'}"); } }elsif($ENV{'PLUTO_VERB'}=~/down\-client/){ if($ENV{'PLUTO_PEER_CLIENT'}=~/(\d+\.\d+\.\d+\.\d+)\/(\d+)/){ &downClient($1,$2); }else{ &error("Unsupported PLUTO_PEER_CLIENT format: $ENV{'PLUTO_PEER_CLIENT'}"); } }else{ &log("Unsupported command: $ENV{'PLUTO_VERB'}"); } ############################################################################ # Finish up # close(LOG) if($log); ############################################################################ # The end ############################################################################