From 2564e407d26d45ecc68befa7a3d1786dbb5982b5 Mon Sep 17 00:00:00 2001 From: aTanW Date: Tue, 10 Mar 2015 16:24:22 +0300 Subject: [PATCH] ipsec-tools: racoon uci integration Signed-Off-By: Vitaly Protsko --- b/net/ipsec-tools/Makefile | 16 - b/net/ipsec-tools/files/functions.sh | 137 +++++++++ b/net/ipsec-tools/files/p1client-down | 41 ++ b/net/ipsec-tools/files/p1client-up | 41 ++ b/net/ipsec-tools/files/racoon | 109 +++++++ b/net/ipsec-tools/files/racoon.init | 478 +++++++++++++++++++++++++++++++++- b/net/ipsec-tools/files/vpnctl | 19 + net/ipsec-tools/files/racoon.conf | 36 -- 8 files changed, 824 insertions(+), 53 deletions(-) --- net/ipsec-tools/Makefile | 16 +- net/ipsec-tools/files/functions.sh | 137 ++++++++ net/ipsec-tools/files/p1client-down | 41 +++ net/ipsec-tools/files/p1client-up | 41 +++ net/ipsec-tools/files/racoon | 109 +++++++ net/ipsec-tools/files/racoon.conf | 36 --- net/ipsec-tools/files/racoon.init | 478 +++++++++++++++++++++++++++- net/ipsec-tools/files/vpnctl | 19 ++ 8 files changed, 824 insertions(+), 53 deletions(-) create mode 100644 net/ipsec-tools/files/functions.sh create mode 100644 net/ipsec-tools/files/p1client-down create mode 100644 net/ipsec-tools/files/p1client-up create mode 100644 net/ipsec-tools/files/racoon delete mode 100644 net/ipsec-tools/files/racoon.conf create mode 100644 net/ipsec-tools/files/vpnctl diff --git a/net/ipsec-tools/Makefile b/net/ipsec-tools/Makefile index ae9c83c00..405a95ee2 100644 --- a/net/ipsec-tools/Makefile +++ b/net/ipsec-tools/Makefile @@ -1,6 +1,6 @@ # # Copyright (C) 2006-2011 OpenWrt.org -# 2014 Noah Meyerhans +# 2014-2015 Noah Meyerhans # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -11,7 +11,7 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=ipsec-tools PKG_VERSION:=0.8.2 -PKG_RELEASE:=2 +PKG_RELEASE:=3 PKG_MAINTAINER := "Noah Meyerhans " PKG_LICENSE := BSD-3-Clause @@ -76,12 +76,15 @@ endif endef define Package/ipsec-tools/install - $(INSTALL_DIR) $(1)/etc - $(INSTALL_CONF) ./files/racoon.conf $(1)/etc/racoon.conf $(INSTALL_DIR) $(1)/etc/racoon - $(INSTALL_CONF) $(PKG_BUILD_DIR)/src/racoon/samples/psk.txt $(1)/etc/racoon/ + $(INSTALL_CONF) ./files/functions.sh $(1)/etc/racoon/ + $(INSTALL_BIN) ./files/p1client-up $(1)/etc/racoon/ + $(INSTALL_BIN) ./files/p1client-down $(1)/etc/racoon/ + $(INSTALL_BIN) ./files/vpnctl $(1)/etc/racoon/ $(INSTALL_DIR) $(1)/etc/init.d $(INSTALL_BIN) ./files/racoon.init $(1)/etc/init.d/racoon + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_CONF) ./files/racoon $(1)/etc/config/ $(INSTALL_DIR) $(1)/usr/lib $(CP) $(PKG_INSTALL_DIR)/usr/lib/libipsec.so.* $(1)/usr/lib/ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libracoon.so.* $(1)/usr/lib/ @@ -93,8 +96,7 @@ define Package/ipsec-tools/install endef define Package/ipsec-tools/conffiles -/etc/racoon.conf -/etc/racoon/psk.txt +/etc/config/racoon endef $(eval $(call BuildPackage,ipsec-tools)) diff --git a/net/ipsec-tools/files/functions.sh b/net/ipsec-tools/files/functions.sh new file mode 100644 index 000000000..e3e739b93 --- /dev/null +++ b/net/ipsec-tools/files/functions.sh @@ -0,0 +1,137 @@ +#!/bin/sh +# +# Copyright (C) 2015 Vitaly Protsko + +errno=0 + +get_fieldval() { + local __data="$3" + local __rest + + test -z "$1" && return + + while true ; do + __rest=${__data#* } + test "$__rest" = "$__data" && break + + if [ "${__data/ *}" = "$2" ]; then + eval "$1=${__rest/ *}" + break + fi + + __data="$__rest" + done +} + +manage_fw() { + local cmd=/usr/sbin/iptables + local mode + local item + + if [ -z "$4" ]; then + $log "Bad usage of manage_fw" + errno=3; return 3 + fi + + case "$1" in + add|up|1) mode=A ;; + del|down|0) mode=D ;; + *) return 3 ;; + esac + + for item in $4 ; do + $cmd -$mode forwarding_$2_rule -s $item -j ACCEPT + $cmd -$mode output_$3_rule -d $item -j ACCEPT + $cmd -$mode forwarding_$3_rule -d $item -j ACCEPT + $cmd -t nat -$mode postrouting_$3_rule -d $item -j ACCEPT + done +} + +manage_sa() { + local spdcmd + local rtcmd + local gate + local litem + local ritem + + if [ -z "$4" ]; then + $log "Bad usage of manage_sa" + errno=3; return 3 + fi + + case "$1" in + add|up|1) spdcmd=add; rtcmd=add ;; + del|down|0) spdcmd=delete; rtcmd=del ;; + *) errno=3; return 3 ;; + esac + + get_fieldval gate src "$(/usr/sbin/ip route get $4)" + if [ -z "$gate" ]; then + $log "Can not find outbound IP for $4" + errno=3; return 3 + fi + + + for litem in $2 ; do + for ritem in $3 ; do + echo " +spd$spdcmd $litem $ritem any -P out ipsec esp/tunnel/$gate-$4/require; +spd$spdcmd $ritem $litem any -P in ipsec esp/tunnel/$4-$gate/require; +" | /usr/sbin/setkey -c 1>&2 + done + done + + test -n "$5" && gate=$5 + + for ritem in $3 ; do + (sleep 3; /usr/sbin/ip route $rtcmd $ritem via $gate) & + done +} + + +. /lib/functions/network.sh + +get_zoneiflist() { + local item + local data + local addr + + item=0 + data=$(uci get firewall.@zone[0].name) + while [ -n "$data" ]; do + test "$data" = "$1" && break + let "item=$item+1" + data=$(uci get firewall.@zone[$item].name) + done + + if [ -z "$data" ]; then + errno=1 + return $errno + fi + data=$(uci get firewall.@zone[$item].network) + + echo "$data" +} + +get_zoneiplist() { + local item + local addr + local data + local result + + data=$(get_zoneiflist $1) + test $? -gt 0 -o $errno -gt 0 -o -z "$data" && return $errno + + for item in $data ; do + if network_is_up $item ; then + network_get_ipaddrs addr $item + test $? -eq 0 && result="$result $addr" + fi + done + + result=$(echo $result) + echo "$result" +} + + +# EOF /etc/racoon/functions.sh diff --git a/net/ipsec-tools/files/p1client-down b/net/ipsec-tools/files/p1client-down new file mode 100644 index 000000000..8c5a19514 --- /dev/null +++ b/net/ipsec-tools/files/p1client-down @@ -0,0 +1,41 @@ +#!/bin/sh +# + +log="logger -t p1client-down[$$]" + +. /lib/functions.sh +. /etc/racoon/functions.sh + +if [ -z "$SPLIT_INCLUDE_CIDR" ]; then + $log "Connection without server-pushed routing is not supported" + exit 1 +fi + +$log "Shutting down tunnel to server $REMOTE_ADDR" +$log "Closing tunnel(-s) to $SPLIT_INCLUDE_CIDR through $INTERNAL_ADDR4" + +config_load racoon +config_get confIntZone racoon int_zone lan +config_get confExtZone racoon ext_zone wan + +manage_fw del $confIntZone $confExtZone "$INTERNAL_ADDR4 $SPLIT_INCLUDE_CIDR" + +data=$(get_zoneiflist $confIntZone) +if [ -n "$data" ]; then + for item in $data ; do + network_get_subnet locnet $item + if [ -n "$locnet" ]; then + manage_sa del "$locnet" "$SPLIT_INCLUDE_CIDR" $REMOTE_ADDR $INTERNAL_ADDR4 + else + $log "Can not find subnet on interface $item" + fi + done +else + $log "Can not find subnets in zone $confIntZone" +fi + +get_fieldval data dev "$(/usr/sbin/ip route get $REMOTE_ADDR)" +ip address del $INTERNAL_ADDR4/32 dev $data + + +# EOF /etc/racoon/p1client-down diff --git a/net/ipsec-tools/files/p1client-up b/net/ipsec-tools/files/p1client-up new file mode 100644 index 000000000..8a9678a46 --- /dev/null +++ b/net/ipsec-tools/files/p1client-up @@ -0,0 +1,41 @@ +#!/bin/sh +# + +log="logger -t p1client-up[$$]" + +. /lib/functions.sh +. /etc/racoon/functions.sh + +if [ -z "$SPLIT_INCLUDE_CIDR" ]; then + $log "Connection without server-pushed routing is not supported" + exit 1 +fi + +$log "Setting up tunnel to server $REMOTE_ADDR" +$log "Making tunnel(-s) to $SPLIT_INCLUDE_CIDR through $INTERNAL_ADDR4" + +get_fieldval data dev "$(/usr/sbin/ip route get $REMOTE_ADDR)" +ip address add $INTERNAL_ADDR4/32 dev $data + +config_load racoon +config_get confIntZone racoon int_zone lan +config_get confExtZone racoon ext_zone wan + +data=$(get_zoneiflist $confIntZone) +if [ -n "$data" ]; then + for item in $data ; do + network_get_subnet locnet $item + if [ -n "$locnet" ]; then + manage_sa add "$locnet" "$SPLIT_INCLUDE_CIDR" $REMOTE_ADDR $INTERNAL_ADDR4 + else + $log "Can not find subnet on interface $item" + fi + done +else + $log "Can not find interfaces in zone $confIntZone" +fi + +manage_fw add $confIntZone $confExtZone "$INTERNAL_ADDR4 $SPLIT_INCLUDE_CIDR" + + +# EOF /etc/racoon/p1client-up diff --git a/net/ipsec-tools/files/racoon b/net/ipsec-tools/files/racoon new file mode 100644 index 000000000..11cd2f23a --- /dev/null +++ b/net/ipsec-tools/files/racoon @@ -0,0 +1,109 @@ +#/etc/config/racoon +# +# Copyright 2015 Vitaly Protsko + +# * WARNING: this is "not working" example +# * Defaults are commented out +# * Resuting config will appear in /var/racoon/ + +config racoon +# option debug 0 +# option ext_zone 'wan' +# option int_zone 'lan' +# option port 500 +# option natt_port 4500 +# following 4 or 6, no default +# option ipversion 4 + +config p1_proposal 'example_prop1' +# option lifetime 28800 + option enc_alg 'aes' + option hash_alg 'sha1' + option auth_method 'rsasig' + option dh_group 2 + +config p1_proposal 'example_anon' +# option lifetime 28800 + option enc_alg 'aes' + option hash_alg 'sha1' + option auth_method 'xauth_rsa_server' + option dh_group 2 + +config p1_proposal 'example_xauth' +# option lifetime 28800 + option enc_alg 'aes' + option hash_alg 'sha1' + option auth_method 'xauth_rsa_client' + option dh_group 2 + +config p2_proposal 'example_prop2' + option pfs_group 2 + option enc_alg 'aes' + option auth_alg 'hmac_sha1' + +config p2_proposal 'example_in2' + option pfs_group 2 +# option lifetime 14400 + option enc_alg 'aes' + option auth_alg 'hmac_sha1' + +config sainfo 'office' + option p2_proposal 'example_prop2' + option local_net '192.168.8.0/24' + option remote_net '192.168.1.0/24' + +config sainfo 'welcome' + option p2_proposal 'example_in2' + option local_net '192.168.8.0/24' + option remote_net '192.168.10.0/24' + option dns4 '192.168.8.1' + option defdomain 'myhome.local' + +config sainfo 'client' + p2_proposal 'std_p2' + +config tunnel 'Office' + option enabled 1 +# initial_contact +# option init 1 + option remote 'vpn.example.tld' + option exchange_mode 'main' + option certificate 'example_cert' +# option peer_id_type 'asn1dn' +# option prop_check 'obey' +# option verify_id 1 +# option weak_p1check 1 +# option dpd_delay '' + list p1_proposal 'example_prop1' + list sainfo 'office' + +# WARNING: Only ONE tunnel with remote anonymous +# can be configured and it can have only +# ONE sainfo. Otherwise resulting racoon +# configuration will be unusable +config tunnel 'Incoming' + option enabled 1 + option remote 'anonymous' + option pre_shared_key 'testitnow' + option exchange_mode 'aggressive,main' + option my_id_type 'fqdn' + option my_id 'myserver.homeip.net' + list p1_proposal 'example_anon' + list sainfo 'welcome' + +config tunnel 'Client' + option enabled 1 + option remote 'vpn.example.tld' + option username 'testuser' + option password 'testW0rD' +# option mode_cfg 1 + list p1_proposal 'example_xauth' + list sainfo 'client' + +# Insert corresponding data in PEM format as one line +config 'certificate' 'example_cert' + option 'key' '-----BEGIN PRIVATE KEY----- ~ -----END PRIVATE KEY-----' + option 'crt' '-----BEGIN CERTIFICATE----- ~ -----END CERTIFICATE-----' + +config 'certificate' 'example_ca_cert' + option 'crt' '-----BEGIN CERTIFICATE----- ~ -----END CERTIFICATE-----' diff --git a/net/ipsec-tools/files/racoon.conf b/net/ipsec-tools/files/racoon.conf deleted file mode 100644 index 5c05bcd34..000000000 --- a/net/ipsec-tools/files/racoon.conf +++ /dev/null @@ -1,36 +0,0 @@ -# Simple racoon.conf -# -# Refer to http://wiki.openwrt.org/doc/howto/vpn.ipsec.basics.racoon for -# details about configuring racoon in OpenWRT. -# -# Also read the Linux IPSEC Howto up at -# http://www.ipsec-howto.org/t1.html -# -# Manual pages for ipsec-tools are not included with OpenWRT. Refer to -# the following locations to view them online: -# http://linux.die.net/man/8/racoon -# http://linux.die.net/man/5/racoon.conf -# http://linux.die.net/man/8/setkey -# - -log notify; -path pre_shared_key "/etc/racoon/psk.txt"; -path certificate "/etc/racoon/certs"; - -#remote 172.31.1.1 { -# exchange_mode main,aggressive; -# proposal { -# encryption_algorithm 3des; -# hash_algorithm sha1; -# authentication_method pre_shared_key; -# dh_group modp1024; -# } -# generate_policy off; -#} -# -#sainfo address 192.168.203.10[any] any address 192.168.22.0/24[any] any { -# pfs_group modp768; -# encryption_algorithm 3des; -# authentication_algorithm hmac_md5; -# compression_algorithm deflate; -#} diff --git a/net/ipsec-tools/files/racoon.init b/net/ipsec-tools/files/racoon.init index 68053c91e..6520d5bde 100644 --- a/net/ipsec-tools/files/racoon.init +++ b/net/ipsec-tools/files/racoon.init @@ -1,17 +1,475 @@ #!/bin/sh /etc/rc.common -# Copyright (C) 2009-2011 OpenWrt.org -# Copyright (C) 2011 Artem Makhutov -# Copyright (C) 2014 Noah Meyerhans +# +# Copyright (C) 2015 Vitaly Protsko + +#set -vx USE_PROCD=1 -START=49 +START=60 +STOP=40 + +let connWait=2/2 +confDir=/var/racoon +confExtZone= +confIntZone= +confPort= +confNATPort= +confIPMode= + +confPh1ID=0 + +log="logger -t init.d/racoon[$$] " + +. /etc/racoon/functions.sh + +setup_load() { + config_get confExtZone "$1" ext_zone wan + config_get confIntZone "$1" int_zone lan + config_get confPort "$1" port 500 + config_get confNATPort "$1" natt_port 4500 + config_get confIPMode "$1" ipversion "" + + case X$confIPMode in + X4|X6) ;; + *) unset confIPMode ;; + esac +} + +write_header() { + echo " +# autogenerated, don't edit, look at /etc/config/racoon +# +path certificate \"$confDir/cert\"; +path script \"/etc/racoon\"; +path pre_shared_key \"$confDir/psk.txt\"; +path pidfile \"$confDir/racoon.pid\"; +padding { maximum_length 20; randomize off; strict_check off; exclusive_tail off; } +timer { counter 5; interval 20 sec; persend 1; phase1 30 sec; phase2 15 sec; } +" +} + +setup_conf() { + local conf=$confDir/racoon.conf + local peerconf=$confDir/peers.txt + local pskconf=$confDir/psk.txt + local item + local data + + data="$(get_zoneiplist $confExtZone)" + if [ "X$data" = X ]; then + $log "No IP addresses found for zone $confExtZone, exitng" + errno=2; return 2 + fi + + write_header > $conf + echo -n > $peerconf + echo -n > $pskconf + chmod 0600 $conf $peerconf $pskconf + + echo "listen {" >> $conf + for item in $data ; do + echo " isakmp $item [$confPort]; isakmp_natt $item [$confNATPort];" >> $conf + done + echo "}" >> $conf + + config_get_bool item "$1" debug 0 + data=warning + test $item -ne 0 && data=debug + echo "log $data;" >> $conf + + setup_fw add +} + +setup_p1() { + local conf=$confDir/racoon.conf + local data + + echo " proposal {" >> $conf + config_get data "$1" lifetime 28800 + echo " lifetime time $data sec;" >> $conf + + config_get data "$1" enc_alg + test -n "$data" && echo " encryption_algorithm $data;" >> $conf + + config_get data "$1" hash_alg + test -n "$data" && echo " hash_algorithm $data;" >> $conf + + config_get data "$1" auth_method + test -n "$data" && echo " authentication_method $data;" >> $conf + + config_get data "$1" dh_group 2 + echo -e " dh_group $data;\n }" >> $conf +} + +setup_fw() { + local cmd=/usr/sbin/iptables + local mode + + case "$1" in + add|up|1) mode=A ;; + del|down|0) mode=D ;; + *) return 3 ;; + esac + + $cmd -$mode input_${confExtZone}_rule -p AH -j ACCEPT + $cmd -$mode input_${confExtZone}_rule -p ESP -j ACCEPT + $cmd -$mode input_${confExtZone}_rule -p UDP --dport $confPort -j ACCEPT + $cmd -$mode input_${confExtZone}_rule -p UDP --dport $confNATPort -j ACCEPT +} + +setup_sa() { + local conf=$confDir/racoon.conf + local remote="${2/ *}" + local client="${2#* }" + local locnet + local remnet + local p2 + local data + + test "$2" = "$client" && unset client + + if [ -z "$client" ]; then + config_get locnet "$1" local_net + config_get remnet "$1" remote_net + if [ -z "$locnet" ] || [ -z "$remnet" ]; then + $log "Remote and local networks for $1 must be configured ($2)" + errno=4; return 4 + fi + + if [ "$remote" = "anonymous" ]; then + echo "sainfo anonymous {" >> $conf + else + echo "sainfo address $locnet any address $remnet any {" >> $conf + fi + else + echo "sainfo anonymous {" >> $conf + fi + + config_get p2 "$1" p2_proposal + if [ -z "$p2" ]; then + $log "Phase2 proposal must be configured in $1 sainfo" + errno=5; return 5 + fi + + echo " remoteid $confPh1ID;" >> $conf + + config_get data "$p2" pfs_group + test -n "$data" && echo " pfs_group $data;" >> $conf + config_get data "$p2" lifetime 14400 + test -n "$data" && echo " lifetime time $data sec;" >> $conf + config_get data "$p2" enc_alg + test -n "$data" && echo " encryption_algorithm $data;" >> $conf + config_get data "$p2" auth_alg + test -n "$data" && echo " authentication_algorithm $data;" >> $conf + + echo -e " compression_algorithm deflate;\n}" >> $conf + + if [ "$remote" = "anonymous" ]; then + echo -e "mode_cfg {\n auth_source system;\n conf_source local;" >> $conf + + config_get data "$1" dns4 + test -n "$data" && echo " dns4 $data;" >> $conf + config_get data "$1" defdomain + test -n "$data" && echo " default_domain \"$data\";" >> $conf + + data=${remnet%/*} + let "data=${data##*.}+1" + echo " network4 ${remnet%.*}.$data;" >> $conf + + let "data=255<<(24-${remnet#*/}+8)&255" + echo " netmask4 255.255.255.$data;" >> $conf + + echo -e " split_network include $locnet;\n}" >> $conf + + elif [ -z "$client" ]; then + manage_sa add $locnet $remnet $remote + test $? -gt 0 -o $errno -gt 0 && return $errno + + manage_fw add $confIntZone $confExtZone $remnet + fi +} + +setup_tunnel() { + local conf=$confDir/racoon.conf + local peerconf=$confDir/peers.txt + local data + local remote + local xauth + + config_get_bool data "$1" enabled 0 + test "$data" = "0" && return 0 + + config_get remote "$1" remote + if [ "$remote" = "anonymous" ]; then + echo -e "remote anonymous {\n generate_policy on;" >> $conf + else + data=$(nslookup "$remote" | awk 'NR == 5 {print $3}') + test -n "$data" && remote="$data" + echo -e "remote \"$1\" {\n remote_address $remote;" >> $conf + echo "$data" >> $peerconf + fi + + config_get data "$1" pre_shared_key "" + if [ -n "$data" ]; then + if [ "$remote" != "anonymous" ]; then + echo "$remote $data" >> $confDir/psk.txt + else + echo "* $data" >> $confDir/psk.txt + fi + fi + + let confPh1ID=$confPh1ID+1 + echo " ph1id $confPh1ID;" >> $conf + + config_get xauth "$1" username "" + + config_get data "$1" certificate "" + if [ -n "$data" ]; then + echo -en " verify_cert on;\n my_identifier asn1dn;\n certificate_type x509 " >> $conf + echo -en "\"$data.crt\" \"$data.key\";\n send_cr off;\n peers_identifier " >> $conf + else + config_get data "$1" my_id_type "" + if [ -n "$data" ]; then + echo -n " my_identifier $data" >> $conf + config_get data "$1" my_id "" + if [ -n "$data" ]; then + echo " \"$data\";" >> $conf + elif [ -n "$xauth" ]; then + echo " \"$xauth\";" >> $conf + else + echo ";" >> $conf + fi + elif [ -n "$xauth" ]; then + echo " my_identifier user_fqdn \"$xauth\";" >> $conf + fi + echo -n " peers_identifier " >> $conf + fi + + if [ "$remote" = "anonymous" ]; then + echo "user_fqdn;" >> $conf + else + config_get data "$1" peer_id_type "asn1dn" + echo -n "$data" >> $conf + + config_get data "$1" peer_id "" + test -n "$data" && echo -n " \"$data\"" >> $conf + + echo ";" >> $conf + fi + + if [ -n "$xauth" ]; then + config_get data "$1" password + if [ -z "$data" ]; then + $log "Password must be given in $1 tunnel" + errno=7; return 7 + fi + echo "$xauth $data" >> $confDir/psk.txt + + echo " xauth_login \"$xauth\";" >> $conf + echo -e " script \"p1client-up\" phase1_up;\n script \"p1client-down\" phase1_down;" >> $conf + fi + + config_get data "$1" exchange_mode + if [ -z "$data" ]; then + data=main + test -n "$xauth" && data="${data},aggressive" + fi + echo -e " exchange_mode $data;\n nat_traversal on;\n support_proxy on;" >> $conf + + config_get data "$1" prop_check "obey" + test -n "$data" && echo " proposal_check $data;" >> $conf + + config_get_bool data "$1" weak_p1check 1 + if [ $data -eq 0 ]; then data=off; else data=on; fi + echo " weak_phase1_check $data;" >> $conf + + config_get_bool data "$1" verify_id 1 + if [ $data -eq 0 ]; then data=off; else data=on; fi + echo " verify_identifier $data;" >> $conf + + config_get data "$1" dpd_delay "" + test -n "$data" && echo " dpd_delay $data;" >> $conf + + unset data + test -n "$xauth" && data="on" + config_get data "$1" mode_cfg "$data" + test -n "$data" && echo " mode_cfg $data;" >> $conf + + config_get_bool data "$1" init 0 + if [ $data -eq 0 ]; then data=off; else data=on; fi + echo " initial_contact $data;" >> $conf + + + config_list_foreach "$1" p1_proposal setup_p1 + echo "}" >> $conf + + config_list_foreach "$1" sainfo setup_sa "$remote $xauth" +} + +setup_cert() { + local item + local data + + for item in key crt ; do + config_get data "$1" $item "" + test -z "$data" && continue + + echo "$data" |\ + sed 's/-\+[A-Z ]\+-\+/\n&\n/g' | sed 's/.\{50,50\}/&\n/g' | sed '/^$/d'\ + > $confDir/cert/$1.$item + + chmod 600 $confDir/cert/$1.$item + done + + if [ -s $confDir/cert/$1.crt ]; then + data=$(openssl x509 -noout -hash -in $confDir/cert/$1.crt) + ln -sf $confDir/cert/$1.crt $confDir/cert/$data.0 + fi +} + +destroy_sa() { + local locnet + local remnet + + config_get locnet "$1" local_net + config_get remnet "$1" remote_net + if [ -z "$locnet" ] || [ -z "$remnet" ]; then + $log "Remote and local networks for $1 must be configured" + errno=4; return 4 + fi + + manage_sa del $locnet $remnet $2 + manage_fw del $confIntZone $confExtZone $remnet +} + +destroy_tunnel() { + local data + + config_get_bool data "$1" enabled 0 + test "$data" = "0" && return 0 + + config_get remote "$1" remote + data=$(nslookup "$remote" | awk 'NR == 5 {print $3}') + test -n "$data" && remote="$data" + + config_get data "$1" username "" + if [ -z "$data" ]; then + config_list_foreach "$1" sainfo destroy_sa $remote + fi +} + +destroy_conf() { + setup_fw del +} + +check_software() { + local item + + for item in /usr/sbin/setkey /usr/bin/openssl /usr/sbin/ip ; do + if [ ! -x $item ]; then + $log "Needed program $item not found, exiting" + errno=9; return 9 + fi + done +} + +cleanup_conf() { + config_load racoon + config_foreach setup_load racoon + config_foreach destroy_conf racoon + config_foreach destroy_tunnel tunnel + + /usr/sbin/setkey -P -F + /usr/sbin/setkey -F +} + +check_dir() { + local item + + for item in $confDir $confDir/cert ; do + if [ ! -d $item ]; then + mkdir -m 0700 -p $item + fi + done +} + +wait4wanzone() { + local item=$connWait + local data + + data="$(get_zoneiplist $confExtZone)" + while [ $item -gt 0 ]; do + test -n "$data" && break + sleep 2 + let "item=$item-1" + data="$(get_zoneiplist $confExtZone)" + done + + test -z "$data" && return 10 +} start_service() { - mkdir -m 0700 -p /var/racoon - [ -f /etc/ipsec.conf ] && /usr/sbin/setkey -f /etc/ipsec.conf - procd_open_instance - procd_set_param command /usr/sbin/racoon -F -f /etc/racoon.conf - procd_set_param respawn - procd_close_instance + check_software + test $? -gt 0 -o $errno -gt 0 && exit $errno + + check_dir + + config_load racoon + config_foreach setup_load racoon + + config_foreach wait4wanzone racoon + if [ $? -gt 0 ] || [ $errno -gt 0 ]; then + $log "No active interfaces in $confExtZone zone found, exiting" + exit $errno + fi + + config_foreach setup_conf racoon + test $? -gt 0 -o $errno -gt 0 && exit $errno + + config_foreach setup_tunnel tunnel + test $? -gt 0 -o $errno -gt 0 && exit $errno + + config_foreach setup_cert certificate + + procd_open_instance + procd_set_param command /usr/sbin/racoon + test -n "$confIPMode" && procd_append_param command -$confIPMode + procd_append_param command -F -f $confDir/racoon.conf + procd_set_param file $confDir/racoon.conf + procd_close_instance + + if [ -x /etc/racoon/vpnctl ]; then + let connWait=$connWait*2+2 + ( sleep $connWait; /etc/racoon/vpnctl up ) & + fi +} + +service_triggers() { + local item + local data + + procd_add_reload_trigger "racoon" "network" + + config_load racoon + config_foreach setup_load racoon + + data=$(get_zoneiflist $confExtZone) + if [ $? -gt 0 ] || [ $errno -gt 0 ] || [ -z "$data" ]; then + $log "Can not find interfaces for $confExtZone zone" + else + for item in $data ; do + procd_add_reload_interface_trigger $item + done + fi +} + +stop_service() { + cleanup_conf + procd_kill racoon } + +trap "cleanup_conf" 1 2 3 4 5 6 7 8 9 10 + + +# EOF /etc/init.d/racoon diff --git a/net/ipsec-tools/files/vpnctl b/net/ipsec-tools/files/vpnctl new file mode 100644 index 000000000..5fb66679e --- /dev/null +++ b/net/ipsec-tools/files/vpnctl @@ -0,0 +1,19 @@ +#!/bin/sh +# + +case X$1 in + Xup|X1|Xstart) connMode=vpn-connect ;; + Xdown|X0|Xstop) connMode=vpn-disconnect ;; + *) + echo "Usage: $0: up|1|start || down|0|stop" + exit 1 ;; +esac + +if [ -s /var/racoon/peers.txt ]; then + (while read ipa ; do + racoonctl $connMode $ipa + done) < /var/racoon/peers.txt +fi + + +# EOF /usr/bin/vpnctl