1 |
#!/usr/local/bin/bash |
2 |
# Recon |
3 |
# |
4 |
# Douglas Thrift |
5 |
# |
6 |
# $Id$ |
7 |
|
8 |
dat="$HOME/.recon.dat" |
9 |
ipsec='/etc/ipsec.conf' |
10 |
psk='/usr/local/etc/racoon/psk.txt' |
11 |
rc='/etc/rc.conf' |
12 |
|
13 |
declare -a confs |
14 |
|
15 |
for arg in $@; do |
16 |
if [[ "$arg" =~ ^-dat=(.+)$ ]]; then |
17 |
dat="${BASH_REMATCH[1]}" |
18 |
elif [[ "$arg" =~ ^-ipsec=(.+)$ ]]; then |
19 |
ipsec="${BASH_REMATCH[1]}" |
20 |
elif [[ "$arg" =~ ^-psk=(.+)$ ]]; then |
21 |
psk="${BASH_REMATCH[1]}" |
22 |
elif [[ "$arg" =~ ^-rc=(.+)$ ]]; then |
23 |
rc="${BASH_REMATCH[1]}" |
24 |
elif [[ "$arg" =~ ^-conf=(ipsec|psk|rc)$ ]]; then |
25 |
confs[${#confs[*]}]="${BASH_REMATCH[1]}" |
26 |
else |
27 |
echo "Usage: `basename $0` [-dat=.+] [-ipsec.+] [-psk=.+] [-rc=.+] [-conf=ipsec|psk|rc]" |
28 |
exit 2 |
29 |
fi |
30 |
done |
31 |
|
32 |
declare -a interfaces locals remotes |
33 |
|
34 |
while read interface local remote; do |
35 |
interfaces[${#interfaces[@]}]=$interface |
36 |
locals[${#locals[@]}]=$local |
37 |
remotes[${#remotes[@]}]=$remote |
38 |
done < "$dat" |
39 |
|
40 |
function address() |
41 |
{ |
42 |
host $1 | sed -Ee 's/^.* has address ([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})$/\1/p;d' |
43 |
} |
44 |
|
45 |
if [[ ${#confs[*]} -ne 0 ]]; then |
46 |
function generated() |
47 |
{ |
48 |
realpath $0 | sed -e 's#/home/#~#' |
49 |
} |
50 |
|
51 |
for conf in ${confs[*]}; do |
52 |
case $conf in |
53 |
(ipsec) |
54 |
echo "# $ipsec generated by `generated`" > "$ipsec" |
55 |
|
56 |
for ((index = 0; index != ${#interfaces[@]}; ++index)); do |
57 |
local=`address ${locals[$index]}` |
58 |
remote=`address ${remotes[$index]}` |
59 |
|
60 |
cat >> "$ipsec" <<-EOF |
61 |
spdadd $local/32 $remote/32 ipencap -P out ipsec esp/tunnel/$local-$remote/require; |
62 |
spdadd $remote/32 $local/32 ipencap -P in ipsec esp/tunnel/$remote-$local/require; |
63 |
EOF |
64 |
done |
65 |
;; |
66 |
(psk) |
67 |
echo "# $psk generated by `generated`" > "$psk" |
68 |
|
69 |
for remote in ${remotes[@]}; do |
70 |
echo -e "`address $remote`\tsecret" >> "$psk" |
71 |
done |
72 |
;; |
73 |
(rc) |
74 |
cat > "$rc" <<-EOF |
75 |
# $rc generated by `generated` |
76 |
gif_interfaces="${interfaces[@]}" |
77 |
static_routes="${interfaces[@]/%/vpn}" |
78 |
EOF |
79 |
|
80 |
for ((index = 0; index != ${#interfaces[@]}; ++index)); do |
81 |
interface=${interfaces[$index]} |
82 |
local=${locals[$index]} |
83 |
remote=${remotes[$index]} |
84 |
|
85 |
eval "network=`saxon network.xml recon.xsl local=$local remote=$remote`" |
86 |
|
87 |
cat >> "$rc" <<-EOF |
88 |
gifconfig_$interface="`address $local` `address $remote`" |
89 |
ifconfig_$interface="inet ${network[0]} ${network[1]} netmask 255.255.255.255" |
90 |
route_${interface}vpn="${network[2]} ${network[1]} ${network[3]}" |
91 |
EOF |
92 |
done |
93 |
;; |
94 |
esac |
95 |
done |
96 |
|
97 |
exit |
98 |
fi |
99 |
|
100 |
for ((index = 0; index != ${#interfaces[@]}; ++index)); do |
101 |
interface=${interfaces[$index]} |
102 |
|
103 |
eval `grep "^gifconfig_$interface=" "$rc" | sed -Ee "s/^gifconfig_$interface=\"([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}) ([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})\"$/declare old_local=\1 old_remote=\2/p;d"` |
104 |
|
105 |
new_local=`address ${locals[$index]}` |
106 |
new_remote=`address ${remotes[$index]}` |
107 |
|
108 |
if [[ -z $new_local ]] || [[ -z $new_remote ]]; then |
109 |
exit 1 |
110 |
fi |
111 |
|
112 |
if [[ $old_local != $new_local ]] || [[ $old_remote != $new_remote ]]; then |
113 |
sed -e "s/^gifconfig_$interface=\"$old_local $old_remote\"$/gifconfig_$interface=\"$new_local $new_remote\"/" -i '' "$rc" |
114 |
sed -e "s|^spdadd $old_local/32 $old_remote/32 ipencap -P out ipsec esp/tunnel/$old_local-$old_remote/require;$|spdadd $new_local/32 $new_remote/32 ipencap -P out ipsec esp/tunnel/$new_local-$new_remote/require;|;s|^spdadd $old_remote/32 $old_local/32 ipencap -P in ipsec esp/tunnel/$old_remote-$old_local/require;$|spdadd $new_remote/32 $new_local/32 ipencap -P in ipsec esp/tunnel/$new_remote-$new_local/require;|" -i '' "$ipsec" |
115 |
|
116 |
if [[ $old_remote != $new_remote ]]; then |
117 |
sed -e "s/^$old_remote /$new_remote /" -i '' /usr/local/etc/racoon/psk.txt |
118 |
|
119 |
# XXX: I don't know whether or not this is really necessary |
120 |
/usr/local/etc/rc.d/racoon restart |
121 |
fi |
122 |
|
123 |
/etc/rc.d/ipsec reload |
124 |
/sbin/ifconfig $interface tunnel $new_local $new_remote |
125 |
fi |
126 |
done |