1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
#!/usr/bin/perl
use Getopt::Long;
use strict;
my $config_file = "/etc/ipsec.conf";
my $secrets_file = "/etc/ipsec.secrets";
sub logger {
my $msg = pop(@_);
my $FACILITY = "daemon";
my $LEVEL = "notice";
my $TAG = "ipsec-dhclient-hook";
my $LOGCMD = "logger -t $TAG -p $FACILITY.$LEVEL";
system("$LOGCMD $msg");
}
my ($iface, $config_iface, $nip, $oip, $reason);
GetOptions("interface=s" => \$iface,
"new_ip=s" => \$nip,
"old_ip=s" => \$oip,
"reason=s" => \$reason);
# check if an update is needed
exit(0) if (($oip eq $nip) && ($reason ne "BOUND"));
logger("DHCP address updated to $nip from $oip: Updating ipsec configuration.");
# open ipsec config
open (my $FD, '<', $config_file);
my $header = '';
my $footer = '';
my $finheader = 0;
my %connhash = ();
my $curconn = '';
foreach my $line (<$FD>){
next if (($line =~/^\s*$/) && $finheader);
if ($line =~ /\#conn.*/){
$curconn = '';
next;
}
if ($line =~ /(peer-.*-tunnel.*)/){
$finheader = 1;
my $connid = $1;
$curconn = $connid;
if (not exists $connhash{$connid}){
$connhash{$connid} = {
_dhcp_iface => undef,
_lip => undef,
_lines => []
};
}
} elsif (($line =~ /dhcp-interface=(.*)/) && ($curconn ne '') ){
$connhash{$curconn}->{_dhcp_iface}=$1;
} elsif (($line =~ /left=(.*)/) && ($curconn ne '') ){
$connhash{$curconn}->{_lip}=$1;
} elsif (!$finheader){
$header .= $line;
} elsif ($curconn ne ''){
push (@{$connhash{"$curconn"}->{_lines}}, $line);
} elsif ($curconn eq ''){
$footer .= $line;
}
}
close($FD);
# output new ipsec.conf
open my $output_config, '>', $config_file
or die "Can't open $config_file: $!";
print ${output_config} "$header\n";
foreach my $connid ( keys (%connhash)){
print ${output_config} "conn $connid\n";
if (defined($connhash{$connid}->{_dhcp_iface})){
if ($connhash{$connid}->{_dhcp_iface} eq $iface){
$connhash{$connid}->{_lip} = $nip;
}
print ${output_config} "\t\#dhcp-interface=$connhash{$connid}->{_dhcp_iface}\n";
}
print ${output_config} "\tleft=$connhash{$connid}->{_lip}\n";
foreach my $line (@{$connhash{$connid}->{_lines}}){
print ${output_config} $line;
}
print ${output_config} "\#conn $connid\n\n";
}
print ${output_config} "$footer\n";
close $output_config;
# change ipsec.secrets
open (my $FD, '<', $secrets_file);
my @lines = <$FD>;
close FD;
open my $output_secrets, '>', $secrets_file
or die "Can't open $secrets_file";
foreach my $line (@lines){
if (($line =~ /\#dhcp-interface=(.*)\#/) && ($1 eq $iface)){
$line =~ s/^$oip/$nip/;
if (!($line =~ /^oip/)){
$line =~ s/^/$nip/;
}
}
print ${output_secrets} $line;
}
close $output_secrets;
system ("/usr/sbin/ipsec rereadall");
system ("/usr/sbin/ipsec update");
|