/programs/_updown.mast/_updown.mast.in
Autoconf | 598 lines | 323 code | 54 blank | 221 comment | 57 complexity | 4d10644517f01d907aeca7d674a8708d MD5 | raw file
- #! /bin/sh
- # iproute2 version, default updown script
- #
- # Copyright (C) 2003-2004 Nigel Metheringham
- # Copyright (C) 2002-2007 Michael Richardson <mcr@xelerance.com>
- # Copyright (C) 2003-2011 Tuomo Soini <tis@foobar.fi>
- # Copyright (C) 2008 Paul Wouters <paul@xelerance.com>
- #
- # 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. See <http://www.fsf.org/copyleft/gpl.txt>.
- #
- # 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
- # for more details.
- # CAUTION: Installing a new version of Openswan will install a new
- # copy of this script, wiping out any custom changes you make. If
- # you need changes, make a copy of this under another name, and customize
- # that, and use the (left/right)updown= parameters in ipsec.conf to make
- # Openswan use yours instead of this default one.
- test $IPSEC_INIT_SCRIPT_DEBUG && set -v -x
- LC_ALL=C export LC_ALL
- # things that this script gets (from ipsec_pluto(8) man page)
- #
- #
- # PLUTO_VERSION
- # indicates what version of this interface is being
- # used. This document describes version 1.1. This
- # is upwardly compatible with version 1.0.
- #
- # PLUTO_VERB
- # specifies the name of the operation to be performed
- # (prepare-host, prepare-client, up-host, up-client,
- # down-host, or down-client). If the address family
- # for security gateway to security gateway communications
- # is IPv6, then a suffix of -v6 is added to the
- # verb.
- #
- # PLUTO_CONNECTION
- # is the name of the connection for which we are
- # routing.
- #
- # PLUTO_CONN_POLICY
- # the policy of the connection, as in:
- # RSASIG+ENCRYPT+TUNNEL+PFS+DONTREKEY+OPPORTUNISTIC+failureDROP+lKOD+rKOD
- #
- # PLUTO_NEXT_HOP
- # is the next hop to which packets bound for the peer
- # must be sent.
- #
- # PLUTO_INTERFACE
- # is the name of the ipsec interface to be used.
- #
- # PLUTO_ME
- # is the IP address of our host.
- #
- # PLUTO_METRIC
- # is the metric to set for the route
- #
- # PLUTO_MTU
- # is the mtu to set for the route
- #
- # PLUTO_MY_CLIENT
- # is the IP address / count of our client subnet. If
- # the client is just the host, this will be the
- # host's own IP address / max (where max is 32 for
- # IPv4 and 128 for IPv6).
- #
- # PLUTO_MY_CLIENT_NET
- # is the IP address of our client net. If the client
- # is just the host, this will be the host's own IP
- # address.
- #
- # PLUTO_MY_CLIENT_MASK
- # is the mask for our client net. If the client is
- # just the host, this will be 255.255.255.255.
- #
- # PLUTO_MY_SOURCEIP
- # if non-empty, then the source address for the route will be
- # set to this IP address.
- #
- # PLUTO_MY_PROTOCOL
- # is the protocol for this connection. Useful for
- # firewalling.
- #
- # PLUTO_MY_PORT
- # is the port. Useful for firewalling.
- #
- # PLUTO_PEER
- # is the IP address of our peer.
- #
- # PLUTO_PEER_CLIENT
- # is the IP address / count of the peer's client subnet.
- # If the client is just the peer, this will be
- # the peer's own IP address / max (where max is 32
- # for IPv4 and 128 for IPv6).
- #
- # PLUTO_PEER_CLIENT_NET
- # is the IP address of the peer's client net. If the
- # client is just the peer, this will be the peer's
- # own IP address.
- #
- # PLUTO_PEER_CLIENT_MASK
- # is the mask for the peer's client net. If the
- # client is just the peer, this will be
- # 255.255.255.255.
- #
- # PLUTO_PEER_PROTOCOL
- # is the protocol set for remote end with port
- # selector.
- #
- # PLUTO_PEER_PORT
- # is the peer's port. Useful for firewalling.
- #
- # PLUTO_CONNECTION_TYPE
- #
- # PLUTO_CONN_ADDRFAMILY
- # is the family type, "ipv4" or "ipv6"
- #
- # PLUTO_STACK
- # IPsec stack used by pluto (eg protostack= values)
- #
- # PLUTO_NM_CONFIGURED
- # is NetworkManager used for resolv.conf update
- #
- # PLUTO_SAREF_TRACKING
- # If we need to manipulate any iptables for SAref tracking
- #
- # for debugging of the script
- #exec >/tmp/_updown.m$$
- #exec 2>&1
- #set -x
- # Import default _updown configs from the /etc/[sysconfig|default]pluto_updown file
- #
- # Two variables can be set in this file:
- #
- # DEFAULTSOURCE
- # is the default value for PLUTO_MY_SOURCEIP
- #
- # IPROUTEARGS
- # is the extra argument list for ip route command
- #
- # IPRULEARGS
- # is the extra argument list for ip rule command
- #
- # rpm based systems
- if [ -f /etc/sysconfig/pluto_updown ]
- then
- . /etc/sysconfig/pluto_updown
- # deb based systems
- elif [ -f /etc/default/pluto_updown ]
- then
- . /etc/default/pluto_updown
- fi
- use_comment=true
- # check interface version
- case "$PLUTO_VERSION" in
- 1.*) # Older Pluto?!? Play it safe, script may be using new features.
- echo "$0: obsolete interface version \`$PLUTO_VERSION'," >&2
- echo "$0: called by obsolete Pluto?" >&2
- exit 2
- ;;
- 2.*) ;;
- *) echo "$0: unknown interface version \`$PLUTO_VERSION'" >&2
- exit 2
- ;;
- esac
- # check parameter(s)
- case "$1:$*" in
- ':') # no parameters
- ;;
- custom:*) # custom parameters (see above CAUTION comment)
- ;;
- *) echo "$0: unknown parameters \`$*'" >&2
- exit 2
- ;;
- esac
- # function to see if iptables has an IPSEC chain already, and if not,
- # it will create one and insert it into the OUTPUT and FORWARD chains.
- checkipsec() {
- if [ -z "$PLUTO_SAREF_TRACKING" -o "$PLUTO_SAREF_TRACKING" = "no" ]; then
- echo "SAref table initialisation left to third party"
- else if [ -z "$PLUTO_CONN_ADDRFAMILY" -o "$PLUTO_CONN_ADDRFAMILY" = "ipv6" ]; then
- echo "SAref not activated for IPv6"
- else
- # make sure we have an IPSEC chain
- if ! ( iptables -n -t mangle -L IPSEC >/dev/null 2>&1) ; then
- iptables -t mangle -N IPSEC
- fi
- # we also need to have a NEW_IPSEC_CONN chain
- if ! ( iptables -n -t mangle -L NEW_IPSEC_CONN >/dev/null 2>&1) ; then
- iptables -t mangle -N NEW_IPSEC_CONN
- fi
- # initialize the IPSEC chain if needed
- if [ "$PLUTO_SAREF_TRACKING" = "conntrack" ]; then
- if [ "$(iptables -n -t mangle -L IPSEC | wc -l )" != 6 ] ; then
- iptables -t mangle -F IPSEC
- iptables -t mangle -A IPSEC -j CONNMARK --restore-mark
- iptables -t mangle -A IPSEC -m mark --mark 0x80000000/0x80000000 -j RETURN
- iptables -t mangle -A IPSEC -j NEW_IPSEC_CONN
- iptables -t mangle -A IPSEC -j CONNMARK --save-mark
- fi
- else
- if [ "$(iptables -n -t mangle -L IPSEC | wc -l )" != 3 ] ; then
- iptables -t mangle -F IPSEC
- iptables -t mangle -A IPSEC -j NEW_IPSEC_CONN
- fi
- fi
- # next, setup routing rules and tables:
- # we pick table 50, cause proto50=ESP
- if ! ( ip rule show | grep -qF 'from all fwmark 0x80000000/0x80000000 lookup 50' ) ; then
- # note "fwmarkmask" is an (obsolete) Openswan patch to "ip" command.
- # note2: iproute2-2.6.22-070710 supports mask via /mask notation instead
- # ip rule add fwmark 0x80000000 fwmarkmask 0x80000000 table 50
- ip rule add from all fwmark 0x80000000/0x80000000 lookup 50
- # This rule makes sure that packets originating from mast0 (ones that came
- # out of a tunnel) go directly to the main table. This makes sure that
- # rp_filter can find the right reverse path route.
- ip rule add from all iif $PLUTO_INTERFACE lookup main
- fi
- # the default route goes over the mast interface
- if ! ( ip route show table 50 | grep -qF "default dev $PLUTO_INTERFACE" ) ; then
- ip route add default dev $PLUTO_INTERFACE table 50
- fi
- # now look for -j IPSEC in OUTPUT chains.
- if ! (iptables -n -t mangle -L OUTPUT | grep -q '^IPSEC') ; then
- iptables -t mangle -I OUTPUT 1 -j IPSEC
- iptables -t mangle -I OUTPUT 1 -p udp --sport 500 -j ACCEPT
- iptables -t mangle -I OUTPUT 1 -p udp --dport 500 -j ACCEPT
- iptables -t mangle -I OUTPUT 1 -p udp --sport 4500 -j ACCEPT
- iptables -t mangle -I OUTPUT 1 -p udp --dport 4500 -j ACCEPT
- fi
- # now look for -j IPSEC in PREROUTING chains.
- if ! (iptables -n -t mangle -L PREROUTING | grep -q '^IPSEC') ; then
- iptables -t mangle -I PREROUTING 1 -j IPSEC
- fi
- if [ -w /proc/sys/net/ipv4/conf/$PLUTO_INTERFACE/src_valid_mark ] ; then
- # finally make sure that the top bit of source vmark for mast0 is set
- vmark=$(cat /proc/sys/net/ipv4/conf/$PLUTO_INTERFACE/src_valid_mark)
- vmark=$(( $vmark | 0x80000000 ))
- echo "$vmark" > /proc/sys/net/ipv4/conf/$PLUTO_INTERFACE/src_valid_mark
- else
- # In case that we don't have the means to get rp_filter to cooperate
- # with KLIPS nfmark based routing scheme, we disable rp_filter.
- for n in /proc/sys/net/ipv4/conf/*/rp_filter ; do
- echo 0 > $n
- done
- fi
- fi
- fi
- }
- # utility functions for route manipulation
- # called to add appropriate "erout'ing"
- uproute() {
- checkipsec
- doipsecrule add
- ip route flush cache
- }
- # called to remove any routing
- downroute() {
- checkipsec
- doipsecrule delete
- ip route flush cache
- }
- # called XXXX
- uprule() {
- doipsecrule delete
- doipsecrule add
- ip route flush cache
- }
- # called XXXX
- downrule() {
- doipsecrule delete
- }
- updateresolvconf() {
- if [ -n "$PLUTO_CISCO_DNS_INFO" ]; then
- if [ -n "`pidof unbound`" -a -n "$PLUTO_CISCO_DOMAIN_INFO" ]; then
- echo "updating local nameserver for $PLUTO_CISCO_DOMAIN_INFO with $PLUTO_CISCO_DNS_INFO"
- /usr/sbin/unbound-control forward_add $PLUTO_CISCO_DOMAIN_INFO $PLUTO_CISCO_DNS_INFO
- /usr/sbin/unbound-control flush_zone $PLUTO_CISCO_DOMAIN_INFO
- return
- fi
- fi
- if [ -z "$PLUTO_NM_CONFIGURED" -o "$PLUTO_NM_CONFIGURED" = 0 ]; then
- echo "updating resolvconf"
- if [ -e "$OPENSWAN_RESOLV_CONF" ]; then
- echo "Backup resolv.conf already exists, so doing nothing"
- return 1
- fi
- if [ ! -e "$ORIG_RESOLV_CONF" ]; then
- echo "resolv.conf does not exist, so doing nothing"
- return 1
- fi
- cp -- $ORIG_RESOLV_CONF $OPENSWAN_RESOLV_CONF
- RESOLVE_CONF="#Generated by Openswan (IPSec)"
- if [ -n "$PLUTO_CISCO_DOMAIN_INFO" ]; then
- if grep 'domain' $ORIG_RESOLV_CONF > /dev/null 2>&1
- then
- RESOLVE_CONF="$RESOLVE_CONF\ndomain $PLUTO_CISCO_DOMAIN_INFO\nsearch $PLUTO_CISCO_DOMAIN_INFO"
- else
- RESOLVE_CONF="$RESOLVE_CONF\nsearch $PLUTO_CISCO_DOMAIN_INFO"
- fi
- fi
- if [ -n "$PLUTO_CISCO_DNS_INFO" ]; then
- for i in $PLUTO_CISCO_DNS_INFO; do
- RESOLVE_CONF="$RESOLVE_CONF\nnameserver $i"
- done
- fi
- rm -f -- $ORIG_RESOLV_CONF
- printf "$RESOLVE_CONF" > $ORIG_RESOLV_CONF
- return $?
- else
- echo "Updating resolv.conf is controlled by Network Manager"
- return 0
- fi
- }
- restoreresolvconf() {
- if [ -n "`pidof unbound`" ]; then
- if [ -n "$PLUTO_CISCO_DNS_INFO" ]; then
- echo "flushing local nameserver of $PLUTO_CISCO_DOMAIN_INFO"
- /usr/sbin/unbound-control forward_remove $PLUTO_CISCO_DOMAIN_INFO
- /usr/sbin/unbound-control flush_zone $PLUTO_CISCO_DOMAIN_INFO
- fi
- return
- fi
- if [ -z "$PLUTO_NM_CONFIGURED" -o "$PLUTO_NM_CONFIGURED" = 0 ]; then
- echo "restoring resolvconf"
- if [ ! -e "$OPENSWAN_RESOLV_CONF" ]; then
- echo "Problem in restoring the resolv.conf, as there is no backup file"
- return 2
- fi
- if grep 'Openswan' $ORIG_RESOLV_CONF > /dev/null 2>&1
- then
- cp -- "$OPENSWAN_RESOLV_CONF" $ORIG_RESOLV_CONF
- else
- echo "Current resolv.conf is not generated by Openswan, so doing nothing"
- fi
- rm -f -- "$OPENSWAN_RESOLV_CONF"
- return 0
- else
- # Here disconnect signal is sent to NetworkManager
- # whenever an already established connection is being terminated.
- unset openswan_reason
- unset PLUTO_CISCO_DOMAIN_INFO
- unset PLUTO_CISCO_DNS_INFO
- unset PLUTO_PEER_BANNER
- unset PLUTO_MY_SOURCEIP
- unset PLUTO_PEER
- echo "Restoring resolv.conf is controlled by Network Manager"
- disconnectNM
- fi
- }
- disconnectNM() {
- # This will be called whenever a connection fails to establish
- # due to a state (either phase 1, xauth phase, or phase 2) fails.
- # This will send a singal to NetworkManager over dbus so that NM
- # can clear up coonnections.
- openswan_reason=disconnect
- export openswan_reason
- echo "sending disconnect signal to NetworkManager"
- /usr/libexec/nm-openswan-service-helper
- return 0
- }
- addsource() {
- st=0
- # check if given sourceip is local and add as alias if not
- if ! ip -o route get ${PLUTO_MY_SOURCEIP%/*} | grep -q ^local; then
- it="ip addr add ${PLUTO_MY_SOURCEIP%/*}/32 dev ${PLUTO_INTERFACE%:*}"
- oops="`eval $it 2>&1`"
- st=$?
- if [ " $oops" = " " -a " $st" != " 0" ]; then
- oops="silent error, exit status $st"
- fi
- case "$oops" in
- 'RTNETLINK answers: File exists'*)
- # should not happen, but ... ignore if the
- # address was already assigned on interface
- oops=""
- st=0
- ;;
- esac
- if [ " $oops" != " " -o " $st" != " 0" ]; then
- echo "$0: addsource \`$it' failed ($oops)" >&2
- fi
- fi
- return $st
- }
- # WARNING: changesource might not work as expected with mast
- changesource() {
- st=0
- parms="$PLUTO_PEER_CLIENT"
- parms2="dev $PLUTO_INTERFACE"
- parms3="src ${PLUTO_MY_SOURCEIP%/*}"
- if [ -n "$IPROUTETABLE" ]
- then
- parms3="$parms3 table $IPROUTETABLE"
- fi
- cmd=add
- if ! ip -o route get ${PLUTO_MY_SOURCEIP%/*} | grep mast0
- then
- cmd=change
- fi
- it="ip route $cmd $parms $parms2 $parms3"
- case "$PLUTO_PEER_CLIENT" in
- "0.0.0.0/0"|"::/0")
- # opportunistic encryption work around
- it=
- ;;
- esac
- oops="`eval $it 2>&1`"
- st=$?
- if test " $oops" = " " -a " $st" != " 0"
- then
- oops="silent error, exit status $st"
- fi
- if test " $oops" != " " -o " $st" != " 0"
- then
- echo "$0: changesource \`$it' failed ($oops)" >&2
- fi
- return $st
- }
- # the purpose of this command is to add an entry to the NEW_IPSEC_CONN chain
- # in the iptables system. It grabs the right packets and does a --set-mark
- # on them. An advanced routing rule then directs the packets to the
- # appropriate device with the right mark.
- #
- # This is not be done for OE packets --- they are supposed to get a
- # new netfilter module instead.
- doipsecrule() {
- if [ -z "$PLUTO_SAREF_TRACKING" -o "$PLUTO_SAREF_TRACKING" = "no" ]; then
- echo "SAref tracking left to third party"
- else if [ -z "$PLUTO_CONN_ADDRFAMILY" -o "$PLUTO_CONN_ADDRFAMILY" = "ipv6" ]; then
- echo "SAref not activated for IPv6"
- else
- saref=$PLUTO_PEER_REF
- nf_saref=$(printf "0x%x0000" $(( $saref | 0x8000 )))
- srcnet=$PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK
- dstnet=$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK
- #echo SAref: $saref '->' $nf_saref
- rulespec="--src $srcnet --dst $dstnet -m mark --mark 0/0x80000000 -j MARK --set-mark $nf_saref"
- if $use_comment ; then
- # WARNING: you should only edit use_comment while you have no established conns
- rulespec="$rulespec -m comment --comment '$PLUTO_CONNECTION'"
- fi
- case $1 in
- add)
- it="iptables -t mangle -I NEW_IPSEC_CONN 1 $rulespec"
- ;;
- delete)
- it="iptables -t mangle -D NEW_IPSEC_CONN $rulespec"
- ;;
- esac
- oops="`set +x; eval $it 2>&1`"
- st=$?
- if test " $oops" = " " -a " $st" != " 0"
- then
- oops="silent error, exit status $st"
- fi
- if test " $oops" != " " -o " $st" != " 0"
- then
- echo "$0: doroute \`$it' failed ($oops)" >&2
- fi
- return $st
- fi
- fi
- }
-
- # the big choice
- case "$PLUTO_VERB:$1" in
- spdadd-client:*|spdadd-host:*)
- checkipsec;
- doipsecrule add;;
- spddel-client:*|spddel-host:*)
- checkipsec
- doipsecrule delete;;
- prepare-host:*|prepare-client:*)
- # set up a "%trap" equivalent (we don't know how do this yet!)
- ;;
- route-host:*|route-client:*)
- # connection to me or my client subnet being routed
- # setup of %TRAP equivalent
- ;;
- unroute-host:*|unroute-client:*)
- # connection to me or my client subnet being unrouted
- # remove %TRAP equivalent
- ;;
- up-host:*)
- # If you are doing a custom version, firewall commands go here.
- ;;
- down-host:*)
- # If you are doing a custom version, firewall commands go here.
- ;;
- up-client:)
- # If you are doing a custom version, firewall commands go here.
- ;;
- down-client:)
- # If you are doing a custom version, firewall commands go here.
- ;;
- updateresolvconf-host|updateresolvconf-client)
- # updating resolv.conf using DNS info obtained from the server
- updateresolvconf
- ;;
- restoreresolvconf-host|restoreresolvconf-client)
- # restoring resolv.conf
- restoreresolvconf
- ;;
- disconnectNM-host|disconnectNM-client)
- # sending disconnect signal to NM, as something went wrong.
- disconnectNM
- ;;
- #
- # IPv6
- #
- prepare-host-v6:*|prepare-client-v6:*)
- ;;
- route-host-v6:*|route-client-v6:*)
- # connection to me or my client subnet being routed
- #uproute_v6
- ;;
- unroute-host-v6:*|unroute-client-v6:*)
- # connection to me or my client subnet being unrouted
- #downroute_v6
- ;;
- up-host-v6:*)
- # connection to me coming up
- # If you are doing a custom version, firewall commands go here.
- ;;
- down-host-v6:*)
- # connection to me going down
- # If you are doing a custom version, firewall commands go here.
- ;;
- up-client-v6:)
- # connection to my client subnet coming up
- # If you are doing a custom version, firewall commands go here.
- ;;
- down-client-v6:)
- # connection to my client subnet going down
- # If you are doing a custom version, firewall commands go here.
- ;;
- *) echo "$0: unknown verb \`$PLUTO_VERB' or parameter \`$1'" >&2
- exit 1
- ;;
- esac