123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475 |
- #!/bin/sh /etc/rc.common
- #
- # Copyright (C) 2015 Vitaly Protsko <villy@sft.ru>
- #set -vx
- USE_PROCD=1
- 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() {
- 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
|