%any is IP family neutral
[strongswan.git] / src / _updown_espmark / _updown_espmark
1 #! /bin/sh
2 # iproute2 version, default updown script
3 #
4 # Copyright (C) 2003-2004 Nigel Meteringham
5 # Copyright (C) 2003-2004 Tuomo Soini
6 # Copyright (C) 2002-2004 Michael Richardson
7 # Copyright (C) 2005      Andreas Steffen <andreas.steffen@strongsec.com>
8
9 # This program is free software; you can redistribute it and/or modify it
10 # under the terms of the GNU General Public License as published by the
11 # Free Software Foundation; either version 2 of the License, or (at your
12 # option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
13
14 # This program is distributed in the hope that it will be useful, but
15 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 # or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17 # for more details.
18 #
19 # RCSID $Id$
20
21
22
23 # CAUTION:  Installing a new version of strongSwan will install a new
24 # copy of this script, wiping out any custom changes you make.  If
25 # you need changes, make a copy of this under another name, and customize
26 # that, and use the (left/right)updown parameters in ipsec.conf to make
27 # FreeS/WAN use yours instead of this default one.
28
29 # things that this script gets (from ipsec_pluto(8) man page)
30 #
31 #
32 #      PLUTO_VERSION
33 #              indicates  what  version of this interface is being
34 #              used.  This document describes version  1.1.   This
35 #              is upwardly compatible with version 1.0.
36 #
37 #       PLUTO_VERB
38 #              specifies the name of the operation to be performed
39 #              (prepare-host, prepare-client, up-host, up-client,
40 #              down-host, or down-client).  If the address family
41 #              for security gateway to security gateway communica¬≠
42 #              tions is IPv6, then a suffix of -v6 is added to the
43 #              verb.
44 #
45 #       PLUTO_CONNECTION
46 #              is the name of the  connection  for  which  we  are
47 #              routing.
48 #
49 #       PLUTO_NEXT_HOP
50 #              is the next hop to which packets bound for the peer
51 #              must be sent.
52 #
53 #       PLUTO_INTERFACE
54 #              is the name of the ipsec interface to be used.
55 #
56 #       PLUTO_ME
57 #              is the IP address of our host.
58 #
59 #       PLUTO_MY_ID
60 #              is the ID of our host.
61 #
62 #       PLUTO_MY_CLIENT
63 #              is the IP address / count of our client subnet.  If
64 #              the  client  is  just  the  host,  this will be the
65 #              host's own IP address / max (where max  is  32  for
66 #              IPv4 and 128 for IPv6).
67 #
68 #       PLUTO_MY_CLIENT_NET
69 #              is the IP address of our client net.  If the client
70 #              is just the host, this will be the  host's  own  IP
71 #              address.
72 #
73 #       PLUTO_MY_CLIENT_MASK
74 #              is  the  mask for our client net.  If the client is
75 #              just the host, this will be 255.255.255.255.
76 #
77 #       PLUTO_MY_SOURCEIP
78 #              if non-empty, then the source address for the route will be
79 #              set to this IP address.
80 #
81 #       PLUTO_MY_PROTOCOL
82 #              is the IP protocol that will be transported.
83 #
84 #       PLUTO_MY_PORT
85 #              is  the  UDP/TCP  port  to  which  the IPsec SA  is
86 #              restricted on our side.
87 #
88 #       PLUTO_PEER
89 #              is the IP address of our peer.
90 #
91 #       PLUTO_PEER_ID
92 #              is the ID of our peer.
93 #
94 #       PLUTO_PEER_CA
95 #              is the CA which issued the cert of our peer.
96 #
97 #       PLUTO_PEER_CLIENT
98 #              is the IP address / count of the peer's client sub¬≠
99 #              net.   If the client is just the peer, this will be
100 #              the peer's own IP address / max (where  max  is  32
101 #              for IPv4 and 128 for IPv6).
102 #
103 #       PLUTO_PEER_CLIENT_NET
104 #              is the IP address of the peer's client net.  If the
105 #              client is just the peer, this will  be  the  peer's
106 #              own IP address.
107 #
108 #       PLUTO_PEER_CLIENT_MASK
109 #              is  the  mask  for  the  peer's client net.  If the
110 #              client   is   just   the   peer,   this   will   be
111 #              255.255.255.255.
112 #
113 #       PLUTO_PEER_PROTOCOL
114 #              is the IP protocol that will be transported.
115 #
116 #       PLUTO_PEER_PORT
117 #              is  the  UDP/TCP  port  to  which  the IPsec SA  is
118 #              restricted on the peer side.
119 #
120
121 # logging of VPN connections
122 #
123 # tag put in front of each log entry:
124 TAG=vpn
125 #
126 # syslog facility and priority used:
127 FAC_PRIO=local0.notice
128 #
129 # to create a special vpn logging file, put the following line into
130 # the syslog configuration file /etc/syslog.conf:
131 #
132 # local0.notice                   -/var/log/vpn
133 #
134
135 # check interface version
136 case "$PLUTO_VERSION" in
137 1.[0])  # Older Pluto?!?  Play it safe, script may be using new features.
138         echo "$0: obsolete interface version \`$PLUTO_VERSION'," >&2
139         echo "$0:       called by obsolete Pluto?" >&2
140         exit 2
141         ;;
142 1.*)    ;;
143 *)      echo "$0: unknown interface version \`$PLUTO_VERSION'" >&2
144         exit 2
145         ;;
146 esac
147
148 # check parameter(s)
149 case "$1:$*" in
150 ':')                    # no parameters
151         ;;
152 ipfwadm:ipfwadm)        # due to (left/right)firewall; for default script only
153         ;;
154 custom:*)               # custom parameters (see above CAUTION comment)
155         ;;
156 *)      echo "$0: unknown parameters \`$*'" >&2
157         exit 2
158         ;;
159 esac
160
161 # utility functions for route manipulation
162 # Meddling with this stuff should not be necessary and requires great care.
163 uproute() {
164         doroute add
165         ip route flush cache
166 }
167 downroute() {
168         doroute delete
169         ip route flush cache
170 }
171
172 addsource() {
173         st=0
174         if ! ip -o route get ${PLUTO_MY_SOURCEIP%/*} | grep -q ^local
175         then
176             it="ip addr add ${PLUTO_MY_SOURCEIP%/*}/32 dev $PLUTO_INTERFACE"
177             oops="`eval $it 2>&1`"
178             st=$?
179             if test " $oops" = " " -a " $st" != " 0"
180             then
181                 oops="silent error, exit status $st"
182             fi
183             if test " $oops" != " " -o " $st" != " 0"
184             then
185                 echo "$0: addsource \`$it' failed ($oops)" >&2
186             fi
187         fi
188         return $st
189 }
190
191 doroute() {
192         st=0
193         parms="$PLUTO_PEER_CLIENT"
194
195         parms2=
196         if [ -n "$PLUTO_NEXT_HOP" ]
197         then
198            parms2="via $PLUTO_NEXT_HOP"
199         fi
200         parms2="$parms2 dev $PLUTO_INTERFACE"
201
202         if [ -z "$PLUTO_MY_SOURCEIP" ]
203         then
204             if [ -f /etc/sysconfig/defaultsource ]
205             then
206                 . /etc/sysconfig/defaultsource
207             fi
208
209             if [ -f /etc/conf.d/defaultsource ]
210             then
211                 . /etc/conf.d/defaultsource
212             fi
213
214             if [ -n "$DEFAULTSOURCE" ]
215             then
216                 PLUTO_MY_SOURCEIP=$DEFAULTSOURCE
217             fi
218         fi
219
220         parms3=
221         if test "$1" = "add" -a -n "$PLUTO_MY_SOURCEIP"
222         then
223             addsource
224             parms3="$parms3 src ${PLUTO_MY_SOURCEIP%/*}"
225         fi
226
227         case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
228         "0.0.0.0/0.0.0.0")
229                 # opportunistic encryption work around
230                 # need to provide route that eclipses default, without 
231                 # replacing it.
232                 it="ip route $1 0.0.0.0/1 $parms2 $parms3 &&
233                         ip route $1 128.0.0.0/1 $parms2 $parms3"
234                 ;;
235         *)      it="ip route $1 $parms $parms2 $parms3"
236                 ;;
237         esac
238         oops="`eval $it 2>&1`"
239         st=$?
240         if test " $oops" = " " -a " $st" != " 0"
241         then
242             oops="silent error, exit status $st"
243         fi
244         if test " $oops" != " " -o " $st" != " 0"
245         then
246             echo "$0: doroute \`$it' failed ($oops)" >&2
247         fi
248         return $st
249 }
250  
251 # define ESP mark
252 ESP_MARK=50
253
254 # add the following static rule to the INPUT chain in the mangle table
255 # iptables -t mangle -A INPUT -p 50 -j MARK --set-mark 50
256
257 # NAT traversal via UDP encapsulation is supported with the rule
258 # iptables -t mangle -A INPUT -p udp --dport 4500 -j MARK --set-mark 50
259
260 # in the presence of KLIPS and ipsecN interfaces do not use ESP mark rules
261 if [ `echo "$PLUTO_INTERFACE" | grep "ipsec"` ]
262 then
263         CHECK_MARK=""
264 else
265         CHECK_MARK="-m mark --mark $ESP_MARK"
266 fi
267
268 # are there port numbers?
269 if [ "$PLUTO_MY_PORT" != 0 ]
270 then
271         S_MY_PORT="--sport $PLUTO_MY_PORT"
272         D_MY_PORT="--dport $PLUTO_MY_PORT"
273 fi
274 if [ "$PLUTO_PEER_PORT" != 0 ]
275 then
276         S_PEER_PORT="--sport $PLUTO_PEER_PORT"
277         D_PEER_PORT="--dport $PLUTO_PEER_PORT"
278 fi
279
280 # resolve octal escape sequences
281 PLUTO_MY_ID=`printf "$PLUTO_MY_ID"`
282 PLUTO_PEER_ID=`printf "$PLUTO_PEER_ID"`
283
284 # the big choice
285 case "$PLUTO_VERB:$1" in
286 prepare-host:*|prepare-client:*)
287         # delete possibly-existing route (preliminary to adding a route)
288         case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
289         "0.0.0.0/0.0.0.0")
290                 # need to provide route that eclipses default, without 
291                 # replacing it.
292                 parms1="0.0.0.0/1"
293                 parms2="128.0.0.0/1"
294                 it="ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1"
295                 oops="`ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1`"
296                 ;;
297         *)
298                 parms="$PLUTO_PEER_CLIENT"
299                 it="ip route delete $parms 2>&1"
300                 oops="`ip route delete $parms 2>&1`"
301                 ;;
302         esac
303         status="$?"
304         if test " $oops" = " " -a " $status" != " 0"
305         then
306                 oops="silent error, exit status $status"
307         fi
308         case "$oops" in
309         *'RTNETLINK answers: No such process'*) 
310                 # This is what route (currently -- not documented!) gives
311                 # for "could not find such a route".
312                 oops=
313                 status=0
314                 ;;
315         esac
316         if test " $oops" != " " -o " $status" != " 0"
317         then
318                 echo "$0: \`$it' failed ($oops)" >&2
319         fi
320         exit $status
321         ;;
322 route-host:*|route-client:*)
323         # connection to me or my client subnet being routed
324         uproute
325         ;;
326 unroute-host:*|unroute-client:*)
327         # connection to me or my client subnet being unrouted
328         downroute
329         ;;
330 up-host:*)
331         # connection to me coming up
332         # If you are doing a custom version, firewall commands go here.
333         iptables -I INPUT 1 -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
334             -s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \
335             -d $PLUTO_ME $D_MY_PORT $CHECK_MARK -j ACCEPT
336         iptables -I OUTPUT 1 -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
337             -s $PLUTO_ME $S_MY_PORT \
338             -d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT -j ACCEPT
339         #
340         if [ "$PLUTO_PEER_CLIENT" = "$PLUTO_PEER/32" ]
341         then
342           logger -t $TAG -p $FAC_PRIO \
343             "+ $PLUTO_PEER_ID $PLUTO_PEER -- $PLUTO_ME"
344         else
345           logger -t $TAG -p $FAC_PRIO \
346             "+ $PLUTO_PEER_ID $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME"
347         fi
348         ;;
349 down-host:*)
350         # connection to me going down
351         # If you are doing a custom version, firewall commands go here.
352         # connection to me going down
353         # If you are doing a custom version, firewall commands go here.
354         iptables -D INPUT -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
355             -s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \
356             -d $PLUTO_ME $D_MY_PORT $CHECK_MARK -j ACCEPT
357         iptables -D OUTPUT -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
358             -s $PLUTO_ME $S_MY_PORT \
359             -d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT -j ACCEPT
360         #
361         if [ "$PLUTO_PEER_CLIENT" = "$PLUTO_PEER/32" ]
362         then
363           logger -t $TAG -p $FAC_PRIO -- \
364             "- $PLUTO_PEER_ID $PLUTO_PEER -- $PLUTO_ME"
365         else
366           logger -t $TAG -p $FAC_PRIO -- \
367           "- $PLUTO_PEER_ID $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME"
368         fi
369         ;;
370 up-client:)
371         # connection to my client subnet coming up
372         # If you are doing a custom version, firewall commands go here.
373         iptables -I FORWARD 1 -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
374             -s $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $S_MY_PORT \
375             -d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT -j ACCEPT
376         iptables -I FORWARD 1 -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
377             -s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \
378             -d $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $D_MY_PORT \
379                $CHECK_MARK -j ACCEPT
380         #
381         if [ "$PLUTO_PEER_CLIENT" = "$PLUTO_PEER/32" ]
382         then
383           logger -t $TAG -p $FAC_PRIO \
384             "+ $PLUTO_PEER_ID $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
385         else
386           logger -t $TAG -p $FAC_PRIO \
387             "+ $PLUTO_PEER_ID $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
388         fi
389         ;;
390 down-client:)
391         # connection to my client subnet going down
392         # If you are doing a custom version, firewall commands go here.
393         iptables -D FORWARD -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
394             -s $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $S_MY_PORT \
395             -d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT -j ACCEPT
396         iptables -D FORWARD -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
397             -s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \
398             -d $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $D_MY_PORT \
399                $CHECK_MARK -j ACCEPT
400         #
401         if [ "$PLUTO_PEER_CLIENT" = "$PLUTO_PEER/32" ]
402         then
403           logger -t $TAG -p $FAC_PRIO -- \
404             "- $PLUTO_PEER_ID $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
405         else
406           logger -t $TAG -p $FAC_PRIO -- \
407             "- $PLUTO_PEER_ID $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
408         fi
409         ;;
410 up-client:ipfwadm)
411         # connection to client subnet, with (left/right)firewall=yes, coming up
412         # This is used only by the default updown script, not by your custom
413         # ones, so do not mess with it; see CAUTION comment up at top.
414         ipfwadm -F -i accept -b -S $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK \
415                 -D $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK
416         ;;
417 down-client:ipfwadm)
418         # connection to client subnet, with (left/right)firewall=yes, going down
419         # This is used only by the default updown script, not by your custom
420         # ones, so do not mess with it; see CAUTION comment up at top.
421         ipfwadm -F -d accept -b -S $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK \
422                 -D $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK
423         ;;
424 #
425 # IPv6
426 #
427 prepare-host-v6:*|prepare-client-v6:*)
428         ;;
429 route-host-v6:*|route-client-v6:*)
430         # connection to me or my client subnet being routed
431         #uproute_v6
432         ;;
433 unroute-host-v6:*|unroute-client-v6:*)
434         # connection to me or my client subnet being unrouted
435         #downroute_v6
436         ;;
437 up-host-v6:*)
438         # connection to me coming up
439         # If you are doing a custom version, firewall commands go here.
440         ;;
441 down-host-v6:*)
442         # connection to me going down
443         # If you are doing a custom version, firewall commands go here.
444         ;;
445 up-client-v6:)
446         # connection to my client subnet coming up
447         # If you are doing a custom version, firewall commands go here.
448         ;;
449 down-client-v6:)
450         # connection to my client subnet going down
451         # If you are doing a custom version, firewall commands go here.
452         ;;
453 *)      echo "$0: unknown verb \`$PLUTO_VERB' or parameter \`$1'" >&2
454         exit 1
455         ;;
456 esac