#!/bin/bash set -x set -e [ -f /root/strongswan-config ] && . /root/strongswan-config ||: ETC=${ETC:=/etc/strongswan} SWAND="$ETC/strongswan.d" IPSECD="$ETC/ipsec.d" SWANC="$ETC/swanctl" NOWSEC=`date +%s` SWAN_LIBX=${SWAN_LIBX:=/usr/libexec/strongswan} [ -d $SWAN_LIBX ] || { echo "SWAN_LIBX $SWAN_LIBX not found. Plese set SWAN_LIBX in /root/strongswan-config" exit 1 } export LD_LIBRARY_PATH="$SWAN_LIBX:$LD_LIBRARY_PATH" WAN_IF=${WAN_IF:=eth1} WAN_IP=${WAN_IP:=10.1.99.1} WAN_CONCENTRATOR_IP=${WAN_CONCENTRATOR_IP:=10.1.99.1} # most for the concentrator XIF_IP=${XIF_IP:=10.9.99.1} # for concentrator XIF_CLIENT_IP=${XIF_IP:=10.9.99.2} # for station CLIENT_OUTTER_IP=${CLIENT_OUTTER_IP:=10.4.99.1} CLIENT_NETNS_IP=${CLIENT_NETNS_IP:=10.4.99.2} function initialize_vrf() { local WANDEV=$WAN_IF local vrfid=$1 [[ $vrfid = _* ]] && vrfid=${vrfid#_} [[ $vrfid = vrf* ]] && vrfid=${vrfid#vrf} local vrf_if="vrf${vrfid}" local xfrm_if="xfrm${vrfid}" # do you need this? #sysctl -w net.ipv4.ip_forward=1 #sysctl -w net.ipv4.conf.all.rp_filter=0 # setup vrf ip link add $vrf_if type vrf table $vrfid ||: ip link set dev $vrf_if up ||: ip route add unreachable default metric 4278198272 vrf $vrf_if ||: # create tunnel device ip li del $xfrm_if >/dev/null 2>&1 ||: $SWAN_LIBX/xfrmi -n $xfrm_if -i $vrfid -d $WANDEV ||: ip li set dev $xfrm_if up ip li set dev $xfrm_if master $vrf_if ||: ip a add 169.254.24.201/32 dev $xfrm_if scope link ||: ip ro add default dev $xfrm_if vrf $vrf_if ||: #ip -6 ro add default dev $xfrm_if vrf $vrf_if } function initialize_client_if() { local intf=$1 local vrfid=`get_vrf_for_if $1` [[ $vrfid = _* ]] && vrfid=${vrfid#_} [[ $vrfid = vrf* ]] && vrfid=${vrfid#vrf} local vrf_if="vrf${vrfid}" local xfrm_if="xfrm${vrfid}" # do you need this? #sysctl -w net.ipv4.ip_forward=1 #sysctl -w net.ipv4.conf.all.rp_filter=0 # setup vrf ip link add $vrf_if type vrf table $vrfid ||: ip link set dev $vrf_if up ||: ip route add unreachable default metric 4278198272 vrf $vrf_if ||: # create tunnel device ip li del $xfrm_if >/dev/null 2>&1 ||: $SWAN_LIBX/xfrmi -n $xfrm_if -i $vrfid -d $intf ||: ip li set dev $xfrm_if up ip li set dev $xfrm_if master $vrf_if ||: ip a add 169.254.24.201/32 dev $xfrm_if scope link ||: ip ro add default dev $xfrm_if vrf $vrf_if ||: #ip -6 ro add default dev $xfrm_if vrf $vrf_if } function initialize_fake_client_netns() { local vrfid=$1 local wan_if=$1 [[ x$vrfid = x ]] && echo "cannot use blank argument" && exit 1 if [[ $1 != *vrf* ]]; then vrfid=`get_vrf_for_if $1` fi [[ $vrfid = _* ]] && vrfid=${vrfid#_} [[ $vrfid = vrf* ]] && vrfid=${vrfid#vrf} echo "VRFID $vrfid" sleep 5 sysctl net.ipv4.conf.all.rp_filter=0 sysctl net.ipv4.conf.default.rp_filter=0 ip netns add ts-vrf-${vrfid} ||: ip netns exec ts-vrf-${vrfid} ip li set dev lo up ||: ip li del ts-vrf-${vrfid}a ||: ip link add ts-vrf-${vrfid}a type veth peer name ts-vrf-${vrfid}b netns ts-vrf-${vrfid} ||: ip netns exec ts-vrf-${vrfid} ip link set dev ts-vrf-${vrfid}b up ||: ip netns exec ts-vrf-${vrfid} ip a add dev ts-vrf-${vrfid}b $CLIENT_NETNS_IP/24 ||: ip netns exec ts-vrf-${vrfid} ip ro add default via $CLIENT_OUTTER_IP ||: ip li set dev ts-vrf-${vrfid}a up ip li set dev ts-vrf-${vrfid}a master vrf${vrfid} ||: ip a add $CLIENT_OUTTER_IP/24 dev ts-vrf-${vrfid}a ||: } function initialize() { [ -d "$SWANC/peers-available" ] || mkdir "$SWANC/peers-available" [ -d "$SWANC/peers-enabled" ] || mkdir "$SWANC/peers-enabled" [ -f "$SWANC/secrets.conf" ] || touch "$SWANC/secrets.conf" systemctl enable strongswan systemctl daemon-reload systemct start strongswan || { journalctl -xe } } function vrf_ping() { local vrfid=$1 ip netns exec ts-vrf-$vrfid ping 10.0.201.2 } function backup_keys() { if [ -f $SWANC/secrets.conf ]; then cp $SWANC/secrets.conf $SWANC/.secrets.conf.$NOWSEC fi } function deactivate_peer() { [ -e "$SWANC/peers-enabled/${1}.conf" ] || { if [ -e "$SWANC/peers-available/${1}.conf" ]; then echo "Peer $1 deactivated." else echo "No peer config at $SWANC/peers-available/${1}.conf" fi exit 0 } echo -n "Deactivating $1..." rm "$SWANC/peers-enabled/${1}.conf" swanctl --load-all echo "done" } function activate_peer() { [ -f "$SWANC/peers-available/${1}.conf" ] || { echo "No peer config at $SWANC/peers-available/${1}.conf" exit 1 } if [ -e "$SWANC/peers-enabled/${1}.conf" ]; then echo "Peer $1 actiated." else echo -n "Activating $1..." ln -s" $SWANC/peers-available/${1}.conf" "$SWANC/peers-enabled/" swanctl --load-all echo "done" fi } function create_concentrator_peer() { if [ -f "$SWANC/peers-available/${1}.conf" ]; then echo "Peer $1 config already exists." return; fi cat > "$SWANC/peers-available/${1}.conf" < "$SWANC/peers-available/${1}.conf-remote" <> "$SWANC/secrets.conf" < $SWANC/${1}-secrets.conf-remote echo "created $SWANC/${1}-secrets.conf-remote" } function get_vrf_for_if() { local ifmaster=`ip -o li show $1 | egrep -o '(master \S+)'` [[ x${ifmaster} = x ]] && echo "\nNo master found for $1" && exit 1 echo ${ifmaster#master } } function enable_concentrator_ipsec_if() { local vrf_if=$1 if [[ $vrf_if != vrf* ]]; then vrf_if=$(get_vrf_for_if $1) fi local vrfnum=${vrf_if#vrf} local xif="xfrm${vrfnum}" sleep 1 $SWAN_LIBX/xfrmi -n $xif -i ${vrfnum} -d $WAN_IF ||: sleep 1 ip link set dev $xif up ||: ip link set dev $xif master $vrf_if ||: ip address add $XIF_IP/32 dev $xif scope link ||: #ip route add default dev $xif vrf $vrfnum ||: # doesn't work quite this way #ip route add 10.0.0.0/8 dev $xif vrf $vrfnum ||: # not quite ip route add default dev $xif vrf $vrf_if ||: sleep 1 } function enable_station_ipsec_if() { local vrf_if=$1 local wan_if=$1 if [[ $wan_if = *vrf* ]]; then echo "enable_station_ipsec_if wants L2 interface, not vrf" exit 1 fi if [[ $vrf_if != vrf* ]]; then vrf_if=$(get_vrf_for_if $1) fi [[ $vrf_if = _* ]] && vrf_if=${vrf_if#_} local vrfnum=${vrf_if#vrf} local xif="xfrm${vrfnum}" sleep 1 $SWAN_LIBX/xfrmi -n $xif -i ${vrfnum} -d $wan_if ||: sleep 1 ip link set dev $xif up ||: ip link set dev $xif master $vrf_if ||: ip address add $XIF_CLIENT_IP/32 dev $xif scope link ||: #ip route add default dev $xif vrf $vrfnum ||: # doesn't work quite this way #ip route add 10.0.0.0/8 dev $xif vrf $vrfnum ||: # not quite sleep 1 ip route add 10.4.99.1/32 dev $xif vrf $vrf_if ||: ip route add 10.9.99.1/32 dev $xif vrf $vrf_if ||: ip route add 10.1.99.0/24 dev $xif vrf $vrf_if ||: sleep 1 } function check_arg() { if [ ! -f "$SWANC/secrets.conf" ] ; then echo "$SWANC/secrets.conf not found. Suggest running $0 -i, bye." exit 1 fi [[ z$1 != z ]] || { echo "Please give me a peer name, bye." exit 1 } } function activate_all() { local f for f in $SWANC/*.conf; do echo "CONF $f" f=`basename $f` [[ $f = secrets.conf ]] && continue ||: [[ $f = swanctl.conf ]] && continue ||: [[ $f = *.conf ]] && f=${f%.conf} echo "f now $f" activate_peer $f done } function copy_config() { local vrf=`get_vrf_for_if $WAN_IF` ip vrf exec $vrf scp $WAN_IP:$SWANC/${1}-secrets.conf-remote $SWANC/${1}-secrets.conf ip vrf exec $vrf scp $WAN_IP:$SWANC/peers-available/${1}.conf-remote $SWANC/peers-available/${1}.conf } # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # M A I N # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - while getopts "a:c:d:f:g:p:v:b:ehi" arg; do case $arg in a) check_arg $OPTARG echo "Activating $OPTARG" activate_peer $OPTARG ;; b) check_arg $OPTARG initialize_vrf $OPTARG enable_concentrator_ipsec_if $OPTARG initialize_fake_client_netns $OPTARG swanctl --load-all sleep 1 swanctl --list-conns ;; c) check_arg $OPTARG echo "Creating $OPTARG" create_concentrator_peer $OPTARG create_station_peer $OPTARG create_concentrator_key $OPTARG create_station_key $OPTARG ;; d) check_arg $OPTARG echo "Deactivating $OPTARG" deactivate_peer $OPTARG ;; e) activate_all swanctl --load-all sleep 1 swanctl --list-conns ;; f) check_arg $OPTARG copy_config $OPTARG ;; g) check_arg $OPTARG initialize_client_if $OPTARG enable_station_ipsec_if $OPTARG initialize_fake_client_netns $OPTARG swanctl --load-all sleep 1 swanctl --list-conns ;; h) cat <