initial commit of file from CVS for smeserver-libreswan on Wed 12 Feb 10:54:54 GMT 2025
This commit is contained in:
315
root/etc/e-smith/events/actions/ipsec-update
Normal file
315
root/etc/e-smith/events/actions/ipsec-update
Normal file
@@ -0,0 +1,315 @@
|
||||
#!/usr/bin/perl -w
|
||||
#----------------------------------------------------------------------
|
||||
# Ipsec actions
|
||||
# Copyright (C) 2015 John Crisp
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License or more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
# Feb 2025 this needs updating for systemd
|
||||
|
||||
# Note that we do not need to use the init ipsec script - we can start and
|
||||
# stop directly using /usr/sbin/ipsec which will call the init script
|
||||
|
||||
# Probably ought to check somewhere that the status of services is public
|
||||
# But if it is private then you have to re-expand masq someplace
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use esmith::ConfigDB;
|
||||
|
||||
my $configDB = esmith::ConfigDB->open or die("can't open Config DB");
|
||||
my $ipsecDB = esmith::ConfigDB->open('ipsec_connections')
|
||||
or die("Ipsec Error - cant connect to ipsec database");
|
||||
|
||||
my $ipsecDBkey = 'ipsec';
|
||||
my $xl2tpdDBkey = 'xl2tpd';
|
||||
my $xl2tpdipsecprop = "L2TPD-PSK";
|
||||
|
||||
# Check on access status - we'll use this later
|
||||
# If status goes to disabled we should set this private
|
||||
|
||||
my $ipsec_access = $configDB->get_prop( $ipsecDBkey, 'access' ) || 'private';
|
||||
print "Ipsec Information - IpsecAccessState: $ipsec_access\n";
|
||||
|
||||
# If the service is set disabled then make sure it is stopped
|
||||
# Note that ipsec is not a service so we cannot use the normal service commands
|
||||
|
||||
if ( $configDB->get_prop( $ipsecDBkey, 'status' ) eq 'disabled' ) {
|
||||
|
||||
# Always reset redirects on stop
|
||||
print "Ipsec Information - reset redirects";
|
||||
resetRedirects();
|
||||
|
||||
# Sort out xl2tpd - if ipsec is disabled it has to be stopped
|
||||
|
||||
print "Xl2tpd Information - ipsec is disabled - Stopping xl2tpd \n";
|
||||
my $myStopXl2tpd = qx(/etc/rc.d/init.d/xl2tpd stop) || die("xl2tpd Error - Unable to launch xl2tpd stop : $!\n");
|
||||
|
||||
if ( not defined $myStopXl2tpd ) {
|
||||
die("Ipsec Error - Unable to stop xl2tpd( error code $?)\n") if $?;
|
||||
}
|
||||
|
||||
# Do we check if it is already stopped ?
|
||||
# For now we stop it regardless
|
||||
|
||||
print "Ipsec Information - ipsec disabled - Stopping ipsec \n";
|
||||
my $myStopConnection = qx(/etc/rc.d/init.d/ipsec stop) || die("Ipsec Error - Unable to launch ipsec stop : $!\n");
|
||||
|
||||
if ( not defined $myStopConnection ) {
|
||||
die("Ipsec Error - Unable to stop ipsec( error code $?)\n") if $?;
|
||||
}
|
||||
|
||||
exit 0;
|
||||
}
|
||||
|
||||
# If the ipsec service is set to enabled AND running (then check the connections)
|
||||
|
||||
if ( $configDB->get_prop( $ipsecDBkey, 'status' ) eq 'enabled' ) {
|
||||
|
||||
# Sort out xl2tpd - if ipsec is enabled, AND xl2tpd then see if it is started
|
||||
my $xl2tpdstatus = $configDB->get_prop( $xl2tpdDBkey, 'status' ) || 'disabled';
|
||||
|
||||
if ( $xl2tpdstatus eq 'enabled' ) {
|
||||
my $xl2tpdService = (`ps ax | grep -v grep | grep xl2tpd`);
|
||||
|
||||
#If the service is not running then start it
|
||||
unless ( $xl2tpdService =~ m/xl2tpd/ ) {
|
||||
|
||||
print "Xl2tpd Information - xl2tpd enabled but stopped - restarting xl2tpd \n";
|
||||
my $myStartXl2tpd = qx(/etc/rc.d/init.d/xl2tpd restart)
|
||||
|| die("xl2tpd Error - Unable to launch xl2tpd restart : $!\n");
|
||||
|
||||
if ( not defined $myStartXl2tpd ) {
|
||||
die("Ipsec Error - Unable to stop xl2tpd( error code $?)\n") if $?;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
my $status = (`ps ax | grep -v grep | grep pluto`);
|
||||
|
||||
# If the ipsec service is running
|
||||
if ( $status =~ m/_plutorun/ ) {
|
||||
|
||||
# Lets do some stuff
|
||||
print "Ipsec Information - ipsec is running !\n";
|
||||
|
||||
# make sure reDirects are right
|
||||
setRedirects();
|
||||
|
||||
# Load the connections
|
||||
my @connections = $ipsecDB->keys;
|
||||
|
||||
foreach my $ipsecprop (@connections) {
|
||||
|
||||
#Check the individual connection status
|
||||
my $ipsecstatus = $ipsecDB->get_prop( "$ipsecprop", 'status' )
|
||||
|| "disabled";
|
||||
|
||||
# What type of connection are we ?
|
||||
my $connection = $ipsecDB->get_prop( "$ipsecprop", 'auto' ) || '';
|
||||
|
||||
# Lets check the last state and if it doesn't exist set it disabled
|
||||
if ( not defined( $ipsecDB->get_prop( $ipsecprop, 'PreviousState' ) ) ) {
|
||||
my $previpsecstatus = "disabled";
|
||||
$ipsecDB->set_prop( $ipsecprop, "PreviousState", $previpsecstatus );
|
||||
}
|
||||
|
||||
# Now we should have it
|
||||
my $previpsecstatus = $ipsecDB->get_prop( $ipsecprop, 'PreviousState' );
|
||||
|
||||
print "Ipsec Information - PrevState: $previpsecstatus CurrState: $ipsecstatus\n";
|
||||
|
||||
# Lets reread secrets anyway
|
||||
print "Ipsec Information - Restart - ReReading Secrets\n";
|
||||
my $reread = qx(/usr/sbin/ipsec auto --rereadsecrets);
|
||||
|
||||
die("Ipsec Error - Unable launch ipsec reread secrets : $!\n")
|
||||
if not defined $reread;
|
||||
die("Ipsec Error - Unable to reread ipsec secrets ( error code $?)\n")
|
||||
if $?;
|
||||
|
||||
# If we are enabled
|
||||
if ( ( $previpsecstatus eq "enabled" )
|
||||
&& ( $ipsecstatus eq "enabled" ) ) {
|
||||
|
||||
# Restart
|
||||
print "Ipsec Information - Restarting connection - $ipsecprop\n";
|
||||
|
||||
# Have to use system here as replace usually returns 1280
|
||||
# Replace just rereads the config and does --delete --add
|
||||
system("/usr/sbin/ipsec auto --replace $ipsecprop");
|
||||
print "Ipsec Information - Restart system - replace return code: $?\n";
|
||||
|
||||
# If connection = start then bring it up
|
||||
if ( $connection eq 'start' ) {
|
||||
print "Ipsec Information - En - En - Auto --async --up $ipsecprop\n";
|
||||
|
||||
# If it is start rather than add we try and force it to come up
|
||||
startConnection($ipsecprop);
|
||||
print "Ipsec Information - En - En auto --up\n";
|
||||
print "Ipsec Information - Restart system - up return code: $?\n";
|
||||
}
|
||||
|
||||
# Set Previous status
|
||||
changeState( $ipsecprop, $ipsecstatus );
|
||||
|
||||
}
|
||||
|
||||
# If status is disabled then stop it
|
||||
elsif (( $previpsecstatus eq "disabled" )
|
||||
&& ( $ipsecstatus eq "disabled" ) ) {
|
||||
|
||||
# Stop
|
||||
print "Ipsec Information - Stop connection - $ipsecprop\n";
|
||||
stopConnection($ipsecprop);
|
||||
|
||||
# Set Previous status
|
||||
changeState( $ipsecDBkey, $ipsecstatus );
|
||||
}
|
||||
|
||||
# If status was disabled and now enabled then start it
|
||||
elsif (( $previpsecstatus eq "disabled" )
|
||||
&& ( $ipsecstatus eq "enabled" ) ) {
|
||||
|
||||
# Start
|
||||
print "Enabling connection $ipsecprop\n";
|
||||
|
||||
# Have to use system here as replace usually returns 1280 and not 0
|
||||
system("/usr/sbin/ipsec auto --replace $ipsecprop");
|
||||
print "Ipsec Information - Restart system - return code: $?\n";
|
||||
|
||||
if ( $connection eq 'start' ) {
|
||||
|
||||
# Have to use exec here as system waits for a return and if the connection
|
||||
# does not come up it will just hang. So fire 'n forget
|
||||
print "Ipsec Information - Dis- En - - Auto --async --up $ipsecprop\n";
|
||||
|
||||
startConnection($ipsecprop);
|
||||
print "Ipsec Information - Dis - En auto --up\n";
|
||||
print "Ipsec Information - Restart system - up return code: $?\n";
|
||||
|
||||
#or die "exec failed!";
|
||||
}
|
||||
|
||||
# Set Previous status
|
||||
changeState( $ipsecprop, $ipsecstatus );
|
||||
}
|
||||
|
||||
# If status was enabled and now disabled then stop it
|
||||
elsif (( $previpsecstatus eq "enabled" )
|
||||
&& ( $ipsecstatus eq "disabled" ) ) {
|
||||
|
||||
# Stop and remove - do we need to ?
|
||||
print "Ipsec Information - Stopping connection $ipsecprop\n ";
|
||||
stopConnection($ipsecprop);
|
||||
|
||||
# Set Previous status
|
||||
changeState( $ipsecprop, $ipsecstatus );
|
||||
}
|
||||
|
||||
# Should never be here as it means the statuses are other than enabled or disabled
|
||||
else {
|
||||
print "Ipsec Error - Something went wrong with ipsec connection status\n";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# If it isn't running then start it up
|
||||
# Auto connections start themselves. Added connections wait
|
||||
else {
|
||||
print "Ipsec Information - Disable Reverse Path Filtering\n";
|
||||
setRedirects();
|
||||
|
||||
# Make sure access = public
|
||||
unless ( $ipsec_access eq 'public' ) {
|
||||
$configDB->set_prop( $ipsecDBkey, 'access', 'public' );
|
||||
}
|
||||
|
||||
print "Ipsec Information - ipsec enabled - Starting ipsec\n ";
|
||||
my $myStartConnection = qx(/usr/sbin/ipsec start);
|
||||
die("Ipsec Error - Unable to launch ipsec start : $!\n ")
|
||||
if not defined $myStartConnection;
|
||||
die("Ipsec Error - Unable to launch ipsec start ( error code $?)\n ") if $?;
|
||||
|
||||
exit 0;
|
||||
}
|
||||
|
||||
exit 0;
|
||||
|
||||
}
|
||||
|
||||
#### Subroutines here
|
||||
|
||||
sub changeState {
|
||||
|
||||
#@_ contains $ipsecDBkey and $ipsecstatus
|
||||
$ipsecDB->set_prop( $_[0], 'PreviousState', $_[1] );
|
||||
}
|
||||
|
||||
sub startConnection {
|
||||
system("/usr/sbin/ipsec auto --asynchronous --up $_[0]");
|
||||
}
|
||||
|
||||
sub stopConnection {
|
||||
print "Ipsec Information - SubRoutine - stop connection $_[0]\n ";
|
||||
system("/usr/sbin/ipsec auto --down $_[0]");
|
||||
print "Ipsec Information - system down code: $?\n";
|
||||
system("/usr/sbin/ipsec auto --delete $_[0]");
|
||||
print "Ipsec Information - system delete code: $?\n";
|
||||
}
|
||||
|
||||
sub setRedirects {
|
||||
|
||||
my $internalIf = $configDB->get_prop( 'InternalInterface', 'Name' );
|
||||
my $externalIf = $configDB->get_prop( 'ExternalInterface', 'Name' );
|
||||
|
||||
# Big warning - this is a potential security issue
|
||||
# Make sure you read and understand what happens !
|
||||
# If I knew which specific interfaces to change we could reduce the lines here
|
||||
system("/sbin/sysctl -w net.ipv4.conf.all.send_redirects=0") == 0
|
||||
or die("Ipsec Error - A problem occurred with sysctl: $?");
|
||||
system("/sbin/sysctl -w net.ipv4.conf.default.send_redirects=0") == 0
|
||||
or die("Ipsec Error - A problem occurred with sysctl: $?");
|
||||
|
||||
system("/sbin/sysctl -w net.ipv4.conf.all.accept_redirects=0") == 0
|
||||
or die("Ipsec Error - A problem occurred with sysctl: $?");
|
||||
system("/sbin/sysctl -w net.ipv4.conf.default.accept_redirects=0") == 0
|
||||
or die("Ipsec Error - A problem occurred with sysctl: $?");
|
||||
|
||||
system("/sbin/sysctl -w net.ipv4.conf.default.rp_filter=0") == 0
|
||||
or die("Ipsec Error - A problem occurred with sysctl: $?");
|
||||
system("/sbin/sysctl -w net.ipv4.conf.all.rp_filter=0") == 0
|
||||
or die("Ipsec Error - A problem occurred with sysctl: $?");
|
||||
system("/sbin/sysctl -w net.ipv4.conf.$externalIf.rp_filter=0") == 0
|
||||
or die("Ipsec Error - A problem occurred with sysctl: $?");
|
||||
system("/sbin/sysctl -w net.ipv4.conf.$internalIf.rp_filter=0") == 0
|
||||
or die("Ipsec Error - A problem occurred with sysctl: $?");
|
||||
|
||||
|
||||
}
|
||||
|
||||
sub resetRedirects {
|
||||
|
||||
# /etc/syctl.conf is expanded on ipsec-update
|
||||
# This should reload the file - if ipsec is disabled it should reset to defaults
|
||||
# If ipsec is enabled it should disable rp_filtering
|
||||
system("/sbin/sysctl -p") == 0
|
||||
or die("Ipsec Error - A problem occurred with sysctl: $?");
|
||||
}
|
||||
|
Reference in New Issue
Block a user