There are many cases where the builtin IPSEC connection of IPFIRE does not restart itslelf, for example if there is a new dial in after 24 hours and you get a new ipadress.
Here I would like to present a possible solution, especially for IPFIRE. The host we check every five minutes (300 seconds) is 192.168.10.1.
Copy this file to /opt/ and name it "checkPing" without an extension:
#!/bin/bash
while [ ! $Internet ]
do
/usr/bin/php /opt/checkPing.php 192.168.10.1
sleep 300
done
Make it executable with:
chmod a+x /opt/checkPing
Copy this file also to /opt/ and name it "checkPing.php".
<?php
function PsExecute($command, $timeout = 60, $sleep = 2) {
// First, execute the process, get the process ID
$pid = PsExec($command);
if( $pid === false )
return false;
$cur = 0;
// Second, loop for $timeout seconds checking if process is running
while( $cur < $timeout ) {
sleep($sleep);
$cur += $sleep;
// If process is no longer running, return true;
if( !PsExists($pid) )
return true; // Process must have exited, success!
}
// If process is still running after timeout, kill the process and return false
PsKill($pid);
return false;
}
function PsExec($commandJob) {
$command = $commandJob.' > /dev/null 2>&1 & echo $!';
exec($command ,$op);
$pid = (int)$op[0];
if($pid!="") return $pid;
return false;
}
function PsExists($pid) {
exec("ps ax | grep $pid 2>&1", $output);
while( list(,$row) = each($output) ) {
$row_array = explode(" ", $row);
$check_pid = $row_array[0];
if($pid == $check_pid) {
return true;
}
}
return false;
}
function PsKill($pid) {
exec("kill -9 $pid", $output);
}
if(PsExecute("ping -c 1 ".$argv[1],5,1))
{ }
else
{ PsExec("/etc/init.d/ipsec restart"); }
?>
You might ask, why we need an external PHP script for doing that job. The reason is, that the IPFIRE's ping command does not support the -w option, and there is no timeout command available in the IPFIRE environment, so the PHP script takes care of the ping command timing out if a IPSEC connection is lost.
Finally, we need to create a service and let it start while booting. Therefore you need to copy this content to a new file in "/etc/init.d/" and name it "checkPing":
#! /bin/sh
### BEGIN INIT INFO
# Provides: checkPing
# Required-Start:
# Required-Stop:
# Should-Start:
# Default-Start: 3
# Default-Stop:
# Short-Description: check ipsec connection
# Description: check ipsec connection
### END INIT INFO
do_start () {
/opt/checkPing &
exit 0
}
case "$1" in
start|"")
do_start
;;
restart|reload|force-reload)
echo "Error: argument '$1' not supported" >&2
exit 3
;;
stop)
killall checkPing
;;
status)
exit 0
;;
*)
echo "Usage: checkPing [start|stop]" >&2
exit 3
;;
esac
:
After that, you have to execute:
chmod a+x /etc/init.d/checkPing
ln -s /etc/init.d/checkPing /etc/rc.d/rc3.d/S51checkPing
ln -s /etc/init.d/checkPing /etc/rc.d/rc6.d/K01checkPing
ln -s /etc/init.d/checkPing /etc/rc.d/rc0.d/K01checkPing
Reboot your IPFIRE and your IPSEC connection should be reinitialized after the connection gets lost.
Update 28.05.2013:
Use this as an alternative for /opt/checkPing if you have some kind of web interface (like router) available on your foreign network. The router's URL is 1.2.3.4 in my example.
#!/bin/bash
while [ ! $Internet ]
do
/usr/bin/wget -T 5 -t 1 http://1.2.3.4 -O /dev/null -o /dev/null
if [[ $? != 0 ]] ; then
date >> /var/log/checkPing
/etc/init.d/ipsec restart
fi
sleep 30
done
This script creates a log entry in /var/log/checkPing every time the IPSEC is restarted, too.