You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

475 lines
11 KiB

  1. #!/bin/sh /etc/rc.common
  2. #
  3. # Copyright (C) 2015 Vitaly Protsko <villy@sft.ru>
  4. #set -vx
  5. USE_PROCD=1
  6. START=60
  7. STOP=40
  8. let connWait=2/2
  9. confDir=/var/racoon
  10. confExtZone=
  11. confIntZone=
  12. confPort=
  13. confNATPort=
  14. confIPMode=
  15. confPh1ID=0
  16. log="logger -t init.d/racoon[$$] "
  17. . /etc/racoon/functions.sh
  18. setup_load() {
  19. config_get confExtZone "$1" ext_zone wan
  20. config_get confIntZone "$1" int_zone lan
  21. config_get confPort "$1" port 500
  22. config_get confNATPort "$1" natt_port 4500
  23. config_get confIPMode "$1" ipversion ""
  24. case X$confIPMode in
  25. X4|X6) ;;
  26. *) unset confIPMode ;;
  27. esac
  28. }
  29. write_header() {
  30. echo "
  31. # autogenerated, don't edit, look at /etc/config/racoon
  32. #
  33. path certificate \"$confDir/cert\";
  34. path script \"/etc/racoon\";
  35. path pre_shared_key \"$confDir/psk.txt\";
  36. path pidfile \"$confDir/racoon.pid\";
  37. padding { maximum_length 20; randomize off; strict_check off; exclusive_tail off; }
  38. timer { counter 5; interval 20 sec; persend 1; phase1 30 sec; phase2 15 sec; }
  39. "
  40. }
  41. setup_conf() {
  42. local conf=$confDir/racoon.conf
  43. local peerconf=$confDir/peers.txt
  44. local pskconf=$confDir/psk.txt
  45. local item
  46. local data
  47. data="$(get_zoneiplist $confExtZone)"
  48. if [ "X$data" = X ]; then
  49. $log "No IP addresses found for zone $confExtZone, exitng"
  50. errno=2; return 2
  51. fi
  52. write_header > $conf
  53. echo -n > $peerconf
  54. echo -n > $pskconf
  55. chmod 0600 $conf $peerconf $pskconf
  56. echo "listen {" >> $conf
  57. for item in $data ; do
  58. echo " isakmp $item [$confPort]; isakmp_natt $item [$confNATPort];" >> $conf
  59. done
  60. echo "}" >> $conf
  61. config_get_bool item "$1" debug 0
  62. data=warning
  63. test $item -ne 0 && data=debug
  64. echo "log $data;" >> $conf
  65. setup_fw add
  66. }
  67. setup_p1() {
  68. local conf=$confDir/racoon.conf
  69. local data
  70. echo " proposal {" >> $conf
  71. config_get data "$1" lifetime 28800
  72. echo " lifetime time $data sec;" >> $conf
  73. config_get data "$1" enc_alg
  74. test -n "$data" && echo " encryption_algorithm $data;" >> $conf
  75. config_get data "$1" hash_alg
  76. test -n "$data" && echo " hash_algorithm $data;" >> $conf
  77. config_get data "$1" auth_method
  78. test -n "$data" && echo " authentication_method $data;" >> $conf
  79. config_get data "$1" dh_group 2
  80. echo -e " dh_group $data;\n }" >> $conf
  81. }
  82. setup_fw() {
  83. local cmd=/usr/sbin/iptables
  84. local mode
  85. case "$1" in
  86. add|up|1) mode=A ;;
  87. del|down|0) mode=D ;;
  88. *) return 3 ;;
  89. esac
  90. $cmd -$mode input_${confExtZone}_rule -p AH -j ACCEPT
  91. $cmd -$mode input_${confExtZone}_rule -p ESP -j ACCEPT
  92. $cmd -$mode input_${confExtZone}_rule -p UDP --dport $confPort -j ACCEPT
  93. $cmd -$mode input_${confExtZone}_rule -p UDP --dport $confNATPort -j ACCEPT
  94. }
  95. setup_sa() {
  96. local conf=$confDir/racoon.conf
  97. local remote="${2/ *}"
  98. local client="${2#* }"
  99. local locnet
  100. local remnet
  101. local p2
  102. local data
  103. test "$2" = "$client" && unset client
  104. if [ -z "$client" ]; then
  105. config_get locnet "$1" local_net
  106. config_get remnet "$1" remote_net
  107. if [ -z "$locnet" ] || [ -z "$remnet" ]; then
  108. $log "Remote and local networks for $1 must be configured ($2)"
  109. errno=4; return 4
  110. fi
  111. if [ "$remote" = "anonymous" ]; then
  112. echo "sainfo anonymous {" >> $conf
  113. else
  114. echo "sainfo address $locnet any address $remnet any {" >> $conf
  115. fi
  116. else
  117. echo "sainfo anonymous {" >> $conf
  118. fi
  119. config_get p2 "$1" p2_proposal
  120. if [ -z "$p2" ]; then
  121. $log "Phase2 proposal must be configured in $1 sainfo"
  122. errno=5; return 5
  123. fi
  124. echo " remoteid $confPh1ID;" >> $conf
  125. config_get data "$p2" pfs_group
  126. test -n "$data" && echo " pfs_group $data;" >> $conf
  127. config_get data "$p2" lifetime 14400
  128. test -n "$data" && echo " lifetime time $data sec;" >> $conf
  129. config_get data "$p2" enc_alg
  130. test -n "$data" && echo " encryption_algorithm $data;" >> $conf
  131. config_get data "$p2" auth_alg
  132. test -n "$data" && echo " authentication_algorithm $data;" >> $conf
  133. echo -e " compression_algorithm deflate;\n}" >> $conf
  134. if [ "$remote" = "anonymous" ]; then
  135. echo -e "mode_cfg {\n auth_source system;\n conf_source local;" >> $conf
  136. config_get data "$1" dns4
  137. test -n "$data" && echo " dns4 $data;" >> $conf
  138. config_get data "$1" defdomain
  139. test -n "$data" && echo " default_domain \"$data\";" >> $conf
  140. data=${remnet%/*}
  141. let "data=${data##*.}+1"
  142. echo " network4 ${remnet%.*}.$data;" >> $conf
  143. let "data=255<<(24-${remnet#*/}+8)&255"
  144. echo " netmask4 255.255.255.$data;" >> $conf
  145. echo -e " split_network include $locnet;\n}" >> $conf
  146. elif [ -z "$client" ]; then
  147. manage_sa add $locnet $remnet $remote
  148. test $? -gt 0 -o $errno -gt 0 && return $errno
  149. manage_fw add $confIntZone $confExtZone $remnet
  150. fi
  151. }
  152. setup_tunnel() {
  153. local conf=$confDir/racoon.conf
  154. local peerconf=$confDir/peers.txt
  155. local data
  156. local remote
  157. local xauth
  158. config_get_bool data "$1" enabled 0
  159. test "$data" = "0" && return 0
  160. config_get remote "$1" remote
  161. if [ "$remote" = "anonymous" ]; then
  162. echo -e "remote anonymous {\n generate_policy on;" >> $conf
  163. else
  164. data=$(nslookup "$remote" | awk 'NR == 5 {print $3}')
  165. test -n "$data" && remote="$data"
  166. echo -e "remote \"$1\" {\n remote_address $remote;" >> $conf
  167. echo "$data" >> $peerconf
  168. fi
  169. config_get data "$1" pre_shared_key ""
  170. if [ -n "$data" ]; then
  171. if [ "$remote" != "anonymous" ]; then
  172. echo "$remote $data" >> $confDir/psk.txt
  173. else
  174. echo "* $data" >> $confDir/psk.txt
  175. fi
  176. fi
  177. let confPh1ID=$confPh1ID+1
  178. echo " ph1id $confPh1ID;" >> $conf
  179. config_get xauth "$1" username ""
  180. config_get data "$1" certificate ""
  181. if [ -n "$data" ]; then
  182. echo -en " verify_cert on;\n my_identifier asn1dn;\n certificate_type x509 " >> $conf
  183. echo -en "\"$data.crt\" \"$data.key\";\n send_cr off;\n peers_identifier " >> $conf
  184. else
  185. config_get data "$1" my_id_type ""
  186. if [ -n "$data" ]; then
  187. echo -n " my_identifier $data" >> $conf
  188. config_get data "$1" my_id ""
  189. if [ -n "$data" ]; then
  190. echo " \"$data\";" >> $conf
  191. elif [ -n "$xauth" ]; then
  192. echo " \"$xauth\";" >> $conf
  193. else
  194. echo ";" >> $conf
  195. fi
  196. elif [ -n "$xauth" ]; then
  197. echo " my_identifier user_fqdn \"$xauth\";" >> $conf
  198. fi
  199. echo -n " peers_identifier " >> $conf
  200. fi
  201. if [ "$remote" = "anonymous" ]; then
  202. echo "user_fqdn;" >> $conf
  203. else
  204. config_get data "$1" peer_id_type "asn1dn"
  205. echo -n "$data" >> $conf
  206. config_get data "$1" peer_id ""
  207. test -n "$data" && echo -n " \"$data\"" >> $conf
  208. echo ";" >> $conf
  209. fi
  210. if [ -n "$xauth" ]; then
  211. config_get data "$1" password
  212. if [ -z "$data" ]; then
  213. $log "Password must be given in $1 tunnel"
  214. errno=7; return 7
  215. fi
  216. echo "$xauth $data" >> $confDir/psk.txt
  217. echo " xauth_login \"$xauth\";" >> $conf
  218. echo -e " script \"p1client-up\" phase1_up;\n script \"p1client-down\" phase1_down;" >> $conf
  219. fi
  220. config_get data "$1" exchange_mode
  221. if [ -z "$data" ]; then
  222. data=main
  223. test -n "$xauth" && data="${data},aggressive"
  224. fi
  225. echo -e " exchange_mode $data;\n nat_traversal on;\n support_proxy on;" >> $conf
  226. config_get data "$1" prop_check "obey"
  227. test -n "$data" && echo " proposal_check $data;" >> $conf
  228. config_get_bool data "$1" weak_p1check 1
  229. if [ $data -eq 0 ]; then data=off; else data=on; fi
  230. echo " weak_phase1_check $data;" >> $conf
  231. config_get_bool data "$1" verify_id 1
  232. if [ $data -eq 0 ]; then data=off; else data=on; fi
  233. echo " verify_identifier $data;" >> $conf
  234. config_get data "$1" dpd_delay ""
  235. test -n "$data" && echo " dpd_delay $data;" >> $conf
  236. unset data
  237. test -n "$xauth" && data="on"
  238. config_get data "$1" mode_cfg "$data"
  239. test -n "$data" && echo " mode_cfg $data;" >> $conf
  240. config_get_bool data "$1" init 0
  241. if [ $data -eq 0 ]; then data=off; else data=on; fi
  242. echo " initial_contact $data;" >> $conf
  243. config_list_foreach "$1" p1_proposal setup_p1
  244. echo "}" >> $conf
  245. config_list_foreach "$1" sainfo setup_sa "$remote $xauth"
  246. }
  247. setup_cert() {
  248. local item
  249. local data
  250. for item in key crt ; do
  251. config_get data "$1" $item ""
  252. test -z "$data" && continue
  253. echo "$data" |\
  254. sed 's/-\+[A-Z ]\+-\+/\n&\n/g' | sed 's/.\{50,50\}/&\n/g' | sed '/^$/d'\
  255. > $confDir/cert/$1.$item
  256. chmod 600 $confDir/cert/$1.$item
  257. done
  258. if [ -s $confDir/cert/$1.crt ]; then
  259. data=$(openssl x509 -noout -hash -in $confDir/cert/$1.crt)
  260. ln -sf $confDir/cert/$1.crt $confDir/cert/$data.0
  261. fi
  262. }
  263. destroy_sa() {
  264. local locnet
  265. local remnet
  266. config_get locnet "$1" local_net
  267. config_get remnet "$1" remote_net
  268. if [ -z "$locnet" ] || [ -z "$remnet" ]; then
  269. $log "Remote and local networks for $1 must be configured"
  270. errno=4; return 4
  271. fi
  272. manage_sa del $locnet $remnet $2
  273. manage_fw del $confIntZone $confExtZone $remnet
  274. }
  275. destroy_tunnel() {
  276. local data
  277. config_get_bool data "$1" enabled 0
  278. test "$data" = "0" && return 0
  279. config_get remote "$1" remote
  280. data=$(nslookup "$remote" | awk 'NR == 5 {print $3}')
  281. test -n "$data" && remote="$data"
  282. config_get data "$1" username ""
  283. if [ -z "$data" ]; then
  284. config_list_foreach "$1" sainfo destroy_sa $remote
  285. fi
  286. }
  287. destroy_conf() {
  288. setup_fw del
  289. }
  290. check_software() {
  291. local item
  292. for item in /usr/sbin/setkey /usr/bin/openssl /usr/sbin/ip ; do
  293. if [ ! -x $item ]; then
  294. $log "Needed program $item not found, exiting"
  295. errno=9; return 9
  296. fi
  297. done
  298. }
  299. cleanup_conf() {
  300. config_load racoon
  301. config_foreach setup_load racoon
  302. config_foreach destroy_conf racoon
  303. config_foreach destroy_tunnel tunnel
  304. /usr/sbin/setkey -P -F
  305. /usr/sbin/setkey -F
  306. }
  307. check_dir() {
  308. local item
  309. for item in $confDir $confDir/cert ; do
  310. if [ ! -d $item ]; then
  311. mkdir -m 0700 -p $item
  312. fi
  313. done
  314. }
  315. wait4wanzone() {
  316. local item=$connWait
  317. local data
  318. data="$(get_zoneiplist $confExtZone)"
  319. while [ $item -gt 0 ]; do
  320. test -n "$data" && break
  321. sleep 2
  322. let "item=$item-1"
  323. data="$(get_zoneiplist $confExtZone)"
  324. done
  325. test -z "$data" && return 10
  326. }
  327. start_service() {
  328. check_software
  329. test $? -gt 0 -o $errno -gt 0 && exit $errno
  330. check_dir
  331. config_load racoon
  332. config_foreach setup_load racoon
  333. config_foreach wait4wanzone racoon
  334. if [ $? -gt 0 ] || [ $errno -gt 0 ]; then
  335. $log "No active interfaces in $confExtZone zone found, exiting"
  336. exit $errno
  337. fi
  338. config_foreach setup_conf racoon
  339. test $? -gt 0 -o $errno -gt 0 && exit $errno
  340. config_foreach setup_tunnel tunnel
  341. test $? -gt 0 -o $errno -gt 0 && exit $errno
  342. config_foreach setup_cert certificate
  343. procd_open_instance
  344. procd_set_param command /usr/sbin/racoon
  345. test -n "$confIPMode" && procd_append_param command -$confIPMode
  346. procd_append_param command -F -f $confDir/racoon.conf
  347. procd_set_param file $confDir/racoon.conf
  348. procd_close_instance
  349. if [ -x /etc/racoon/vpnctl ]; then
  350. let connWait=$connWait*2+2
  351. ( sleep $connWait; /etc/racoon/vpnctl up ) &
  352. fi
  353. }
  354. service_triggers() {
  355. local item
  356. local data
  357. procd_add_reload_trigger "racoon" "network"
  358. config_load racoon
  359. config_foreach setup_load racoon
  360. data=$(get_zoneiflist $confExtZone)
  361. if [ $? -gt 0 ] || [ $errno -gt 0 ] || [ -z "$data" ]; then
  362. $log "Can not find interfaces for $confExtZone zone"
  363. else
  364. for item in $data ; do
  365. procd_add_reload_interface_trigger $item
  366. done
  367. fi
  368. }
  369. stop_service() {
  370. cleanup_conf
  371. procd_kill racoon
  372. }
  373. trap "cleanup_conf" 1 2 3 4 5 6 7 8 9 10
  374. # EOF /etc/init.d/racoon