#!/bin/sh # STACK startup script # Copyright (C) 2007 Ken Bantoft # Copyright (C) 2007-2008 Paul Wouters # Copyright (C) 2008-2014 Tuomo Soini # Copyright (C) 2012-2014 Paul Wouters # # 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 . # # 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. # # nothing to do if the kernel has no module loading/unloading support [ ! -f /proc/modules ] && exit 0 IPSEC_CONF="${IPSEC_CONF:-@FINALCONFFILE@}" PATH=@FINALSBINDIR@:${PATH} export PATH test ${IPSEC_INIT_SCRIPT_DEBUG} && set -v -x kamepfkey=/proc/net/pfkey ipsecpfkey=/proc/net/ipsec/version action="${1}" if [ -z "${action}" ]; then echo "no action specified - aborted" >&2 exit 1 fi stopnetkey() { local wait larval_drop wait="" larval_drop="" # Validate wait option [ "${1}" = "--wait" -o "${1}" = "-w" ] && wait="${1}" if [ -f ${kamepfkey} ]; then ip xfrm state flush ip xfrm policy flush if [ -n "$(ip xfrm state)" -o -n "$(ip xfrm policy)" ]; then echo "NETKEY IPsec stack could not be cleared" >&2 fi if [ -f /proc/modules ]; then # check if we can write our own settings if [ -n "${wait}" -a -w /proc/sys/net/core/xfrm_larval_drop ]; then # read previous state so we can restore it larval_drop=$(cat /proc/sys/net/core/xfrm_larval_drop) if [ -n "${larval_drop}" ]; then # set to 0 so we can unload modules echo 0 >/proc/sys/net/core/xfrm_larval_drop fi fi # netkey stack found, let's unload. for mod in xfrm_ipcomp ipcomp ipcomp6 ip_vti xfrm6_tunnel \ xfrm6_mode_tunnel xfrm6_mode_beet xfrm6_mode_ro \ xfrm6_mode_transport xfrm4_mode_transport xfrm4_mode_tunnel \ xfrm4_tunnel xfrm4_mode_beet esp4 esp6 ah4 ah6 af_key \ xfrm_user do # first try and unload the modules without the 10s wait pause if [ -n "$(egrep ^${mod} /proc/modules)" ]; then # echo "unloading module ${mod}" >&2 rmmod ${mod} 2>/dev/null fi # We only run rmmod again with --wait if requested if [ -n "${wait}" -a \ -n "$(egrep ^${mod} /proc/modules)" ]; then # echo "unloading module ${mod} using --wait" >&2 # we start rmmod to backgroud so unloading one module # won't block rmmod ${wait} ${mod} 2>/dev/null & fi done # Finally we wait for background executed rmmods to complete if [ -n "${wait}" ]; then wait if [ -n "${larval_drop}" -a \ -w /proc/sys/net/core/xfrm_larval_drop ]; then # restore original value of xfrm_larval_drop echo "${larval_drop}" >/proc/sys/net/core/xfrm_larval_drop larval_drop="" fi fi fi fi # if we were executed with --wait or -w option we inform about unload # failure if [ -n "${wait}" -a -n "$(lsmod | grep ^esp)" ]; then echo "FAIL" >&2 exit 1 fi } startnetkey() { cryptomodules if [ -f ${ipsecpfkey} ]; then echo "Warning: found KLIPS/MAST stack loaded - attempting to unload..." >&2 stopklips if [ -f ${ipsecpfkey} ]; then echo "FAILURE to unload KLIPS/MAST module" >&2 exit 1 fi fi if [ -f /proc/modules ]; then # load all NETKEY modules for mod in ipcomp6 xfrm_ipcomp ipcomp xfrm6_tunnel xfrm6_mode_tunnel \ xfrm6_mode_beet xfrm6_mode_ro xfrm6_mode_transport \ xfrm4_mode_transport xfrm4_mode_tunnel xfrm4_tunnel \ xfrm4_mode_beet esp4 esp6 ah4 ah6 af_key ip_vti do # echo -n "${mod} " >&2 @MODPROBE@ ${mod} 2>/dev/null done # xfrm_user is the old name for xfrm4_tunnel - backwards compatibility @MODPROBE@ xfrm_user 2>/dev/null fi # Required for Labeled IPsec echo 0 >/proc/sys/net/ipv4/conf/lo/disable_xfrm echo 0 >/proc/sys/net/ipv4/conf/lo/disable_policy } stopklips() { if [ -f ${ipsecpfkey} ]; then # Bring down ipsecX and mast0 interfaces ifl=$(grep -v NULL /proc/net/ipsec_tncfg 2>/dev/null | sed -n -e "/^ipsec/s/ .*//p") if [ -n "${ifl}" ]; then for iface in ${ifl}; do ip link set ${iface} down ip addr flush dev ${iface} ipsec tncfg --detach --virtual ${iface} # ipsec0 won't let itself be deleted ipsec tncfg --delete ${iface} done # mast0 is not listed in ipsec_tncfg if [ -d /proc/sys/net/ipv4/conf/mast0 ]; then ipsec tncfg --delete mast0 fi [ -r /proc/net/ipsec_klipsdebug ] && ipsec klipsdebug --none [ -d /proc/net/ipsec/eroute ] && ipsec eroute --clear [ -d /proc/net/ipsec/spi ] && ipsec spi --clear fi if [ -f /proc/modules ]; then rmmod ipsec 2>/dev/null fi fi if [ -f ${ipsecpfkey} -o -n "$(lsmod | grep ^ipsec)" ]; then echo "FAILURE to unload KLIPS/MAST module" >&2 exit 1 fi } stopmast() { stopklips # Flush policy out in case of mast - NEW_IPSEC_CONN and IPSEC # tables are created in _updown.mast on demand grep ^mangle /proc/net/ip_tables_names >/dev/null 2>&1 && \ iptables -t mangle -F IPSEC >/dev/null 2>&1 grep ^mangle /proc/net/ip_tables_names >/dev/null 2>&1 && \ iptables -t mangle -F NEW_IPSEC_CONN >/dev/null 2>&1 grep ^mangle /proc/net/ip6_tables_names >/dev/null 2>&1 && \ ip6tables -t mangle -F IPSEC >/dev/null 2>&1 grep ^mangle /proc/net/ip6_tables_names >/dev/null 2>&1 && \ ip6tables -t mangle -F NEW_IPSEC_CONN >/dev/null 2>&1 } stop() { stopnetkey stopklips } cryptomodules() { # load hardware random and crypto related modules. # some changed names over time @MODPROBE@ hw_random 2>/dev/null @MODPROBE@ hwrng 2>/dev/null @MODPROBE@ virtio-rng 2>/dev/null @MODPROBE@ amd-rng 2>/dev/null @MODPROBE@ intel-rng 2>/dev/null @MODPROBE@ geode-rng 2>/dev/null @MODPROBE@ timeriomem-rng 2>/dev/null @MODPROBE@ tpm-rng 2>/dev/null # load any OCF and CryptoAPI modules we might need for acceleration # (OCF works for NETKEY and KLIPS/MAST) # OCF cryptosoft is for kernel acceleration (ESP/AH) @MODPROBE@ cryptosoft 2>/dev/null # We skip cryptodev.ko because we no longer support /dev/crypto offloading # (the overhead of cryptodev is not worth it even on embedded platforms) if [ -d /sys/module/ocf ]; then # OCF tuning - If we have enough bogomips and RAM, # use bigger OCF queues bogomips=$(grep -i bogomips /proc/cpuinfo | head -1 | awk '{print $3;}' | sed "s/\..*$//") ram=$(head -1 /proc/meminfo | awk '{print $2;}') limit=1000 if [ ${bogomips} -gt 1000 ]; then if [ ${ram} -gt 262143 ]; then limit=10000 #echo "OCF limit set to ${limit}" >&2 fi fi echo ${limit} >/sys/module/ocf/parameters/crypto_q_max fi # load the most common ciphers/algo's # padlock must load before aes module - though does not exist on newer # kernels # padlock-aes must load before padlock-sha for some reason @MODPROBE@ padlock 2>/dev/null @MODPROBE@ padlock-aes 2>/dev/null @MODPROBE@ padlock-sha 2>/dev/null # load the most common ciphers/algo's # aes-x86_64 has higher priority in via crypto api # kernel directory does not match uname -m on x86_64 :( modules=$(ls /lib/modules/$(uname -r)/kernel/arch/*/crypto/* 2>/dev/null) modules="aesni-intel aes-x86_64 geode-aes aes aes_generic des sha512 \ sha256 md5 cbc xcbc ecb twofish blowfish serpent ccm gcm ctr cts \ deflate cast5 cast6 lzo sha256_generic sha512_generic camellia \ ${modules}" for module in ${modules} do module=$(basename ${module} | sed "s/\.ko$//") # echo -n "${module} " >&2 @MODPROBE@ ${module} 2>/dev/null done } startmast() { startklips } startklips() { cryptomodules if [ -f ${kamepfkey} ]; then echo "Warning: found NETKEY/XFRM stack loaded - attempting to unload..." >&2 stopnetkey --wait if [ -f ${kamepfkey} ]; then echo "FAILURE to unload KLIPS/MAST module" >&2 exit 1 fi fi if [ ! -f ${ipsecpfkey} ]; then # KLIPS-related paths bareversion=$(uname -r | sed -e 's/\.nptl//' | sed -e 's/^\(2\.[0-9]\.[1-9][0-9]*-[1-9][0-9]*\(\.[0-9][0-9]*\)*\(\.x\)*\).*$/\1/') case ${bareversion} in 2.4*) modulename=ipsec.o ;; *) modulename=ipsec.ko ;; esac # modprobe does not like specifying .o or .ko, but insmod needs it if [ "$(basename @MODPROBE@)" = "modprobe" ]; then @MODPROBE@ ipsec else @MODPROBE@ ${modulename} fi if [ ! -f ${ipsecpfkey} ]; then echo "FAILURE to load KLIPS/MAST module" >&2 exit 1 fi if [ -d /sys/module/ocf ]; then echo ${limit} >/sys/module/ipsec/parameters/ipsec_irs_cache_allocated_max echo ${limit} >/sys/module/ipsec/parameters/ipsec_ixs_cache_allocated_max fi fi # If present, need to change for all interfaces (ipsecX, mastX) eval $(ipsec addconn --config ${IPSEC_CONF} --configsetup --noexport | grep overridemtu); if [ ${stack} = "mast" ]; then # we really just ignore the interfaces= line completely # make sure this mast device exists, if not create it virt="mast0" if [ ! -d /sys/devices/virtual/net/${virt} ]; then # in mast mode we just create the virtual interface ipsec tncfg --create ${virt} fi # ensure the link is up, even if module was already loaded ip link set ${virt} up # detach all ipsecX devices ipsec tncfg --clear # remove any ipsecX interfaces, as we are using mastX # Note: currently it seems klips cannot delete ipsec0 for device in $(ip -oneline link show | grep ipsec | cut -d: -f2 | sort -r) do ipsec tncfg --delete ${device} done # PAUL: Shouldn't we configure an ip for mast0, but which one? # best guess is the defaultroute one? # PAUL: We tell in the man page for ipsec.conf protostack= that # the user should do this if [ "${overridemtu}" != "" ]; then ip link set mtu ${overridemtu} dev ${virt} else # Double check the mtu is not 0 # if it is set it to a saner default ip link show dev ${virt} | grep -q 'mtu 0 ' RETVAL=$? if [ "${RETVAL}" -eq 0 ]; then echo "Fixup of mtu on ${virt} to 16260" >&2 ip link set mtu 16260 dev ${virt} fi fi elif [ ${stack} = "klips" ]; then # in klips mode we attach it to the physical device # clear tables out in case dregs have been left over ipsec eroute --clear ipsec spi --clear # remove mast0 interface, as we are using ipsecX for device in $(ip -oneline link show | grep mast0 | cut -d: -f2 | sort -r) do ipsec tncfg --delete ${device} done # detach all ipsecX devices ipsec tncfg --clear phys=$(ip ro li | grep default | sed "s/^.* dev \([^ ]*\) .*$/\1/") eval $(ipsec addconn --config ${IPSEC_CONF} --configsetup --noexport |grep interfaces); if [ -z "${interfaces}" ]; then interfaces="%defaultroute" if [ -z "$phys" ]; then echo "ERROR: no default route found and no interfaces= option set" exit 1 fi fi for iface in ${interfaces}; do if [ "${iface}" = "%none" ]; then echo "ignoring obsolete interface %none" >&2 continue elif [ "${iface}" = "%defaultroute" ]; then virt="ipsec0" else virt="$(expr ${iface} : '\([^=]*\)=.*')" phys="$(expr ${iface} : '[^=]*=\(.*\)')" fi # ipsecX might not exist yet if [ ! -d /sys/devices/virtual/net/${virt} ]; then ipsec tncfg --create ${virt} fi ipsec tncfg --attach --virtual ${virt} --physical ${phys} # configure all the IPv4/IPv6 addresses (including point-to-point) ip addr show dev ${phys} label ${phys} | \ awk '$1 == "inet" || ($1 == "inet6" && !/ dynamic/) { cmd = "ip addr add" if ($1 == "inet") sub(" [^ ]+:[^ ]+"," ") sub("secondary","","") sub("/.*","",$2) sub("dynamic","") for (i = 2; i < NF; i++) { if ($i == "brd" || $i == "peer" || $i == "secondary") i++ else cmd = cmd " " $i } if ($NF != phys) cmd = cmd " " $NF cmd = cmd " dev " virt ">/dev/null 2>/dev/null" system(cmd) }' phys=${phys} virt=${virt} ip link set up dev ${virt} if [ "${overridemtu}" != "" ]; then ip link set mtu ${overridemtu} dev ${virt} else # Double check the mtu is not 0 # if it is set it to a saner default ip link show dev ${virt} | grep -q 'mtu 0 ' RETVAL=$? if [ "${RETVAL}" -eq 0 ]; then echo "Fixup of mtu on ${virt} to 16260" >&2 ip link set mtu 16260 dev ${virt} fi fi done elif [ ${stack} = "none" ]; then echo "protostack=none selected - No IPsec SA's will be injected into the kernel" >&2 fi # global module options for KLIPS eval $(ipsec addconn --config ${IPSEC_CONF} --configsetup --noexport | grep fragicmp); if [ "${fragicmp}" = "yes" ]; then echo 1 >/proc/sys/net/ipsec/icmp fi eval $(ipsec addconn --config ${IPSEC_CONF} --configsetup --noexport | grep hidetos); if [ "${hidetos}" = "no" ]; then echo 0 >/proc/sys/net/ipsec/tos fi } # Start the actual work if [ $(id -u) -ne 0 ]; then echo "permission denied (must be superuser)" >&2 exit 4 fi stack="$(ipsec addconn --config ${IPSEC_CONF} --liststack)" case ${stack} in netkey|klips|mast|none) ;; auto) echo "protostack=auto is not longer supported, defaulting to netkey" >&2 stack=netkey ;; *) echo "unknown stack ${stack}" >&2 exit 1 ;; esac case ${action} in stop) # We don't unload NETKEY/XFRM on stop - only when we detect a stack change. if [ -f ${ipsecpfkey} ]; then ipsec eroute --clear # this clears all IP addresses on ipsecX interfaces by unloading the module stopklips elif [ -f ${kamepfkey} ]; then ip xfrm state flush ip xfrm policy flush # module unloading skipped on purpose - can hang for a long time or fail fi ;; start) case ${stack} in netkey) startnetkey ;; klips) startklips ;; mast) startmast ;; esac ;; restart) stop start ;; *) echo "unknown action ${action}" >&2 exit 1 ;; esac exit 0