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.

388 lines
10 KiB

  1. #!/bin/sh /etc/rc.common
  2. START=90
  3. STOP=10
  4. USE_PROCD=1
  5. PROG=/usr/lib/ipsec/starter
  6. . $IPKG_INSTROOT/lib/functions.sh
  7. . $IPKG_INSTROOT/lib/functions/network.sh
  8. IPSEC_SECRETS_FILE=/etc/ipsec.secrets
  9. IPSEC_CONN_FILE=/etc/ipsec.conf
  10. STRONGSWAN_CONF_FILE=/etc/strongswan.conf
  11. IPSEC_VAR_SECRETS_FILE=/var/ipsec/ipsec.secrets
  12. IPSEC_VAR_CONN_FILE=/var/ipsec/ipsec.conf
  13. STRONGSWAN_VAR_CONF_FILE=/var/ipsec/strongswan.conf
  14. WAIT_FOR_INTF=0
  15. file_reset() {
  16. : > "$1"
  17. }
  18. xappend() {
  19. local file="$1"
  20. shift
  21. echo "${@}" >> "${file}"
  22. }
  23. remove_include() {
  24. local file="$1"
  25. local include="$2"
  26. sed -i "\_${include}_d" "${file}"
  27. }
  28. remove_includes() {
  29. remove_include "${IPSEC_CONN_FILE}" "${IPSEC_VAR_CONN_FILE}"
  30. remove_include "${IPSEC_SECRETS_FILE}" "${IPSEC_VAR_SECRETS_FILE}"
  31. remove_include "${STRONGSWAN_CONF_FILE}" "${STRONGSWAN_VAR_CONF_FILE}"
  32. }
  33. do_include() {
  34. local conf="$1"
  35. local uciconf="$2"
  36. local backup=`mktemp -t -p /tmp/ ipsec-init-XXXXXX`
  37. [ ! -f "${conf}" ] && rm -rf "${conf}"
  38. touch "${conf}"
  39. cat "${conf}" | grep -v "${uciconf}" > "${backup}"
  40. mv "${backup}" "${conf}"
  41. xappend "${conf}" "include ${uciconf}"
  42. file_reset "${uciconf}"
  43. }
  44. ipsec_reset() {
  45. do_include "${IPSEC_CONN_FILE}" "${IPSEC_VAR_CONN_FILE}"
  46. }
  47. ipsec_xappend() {
  48. xappend "${IPSEC_VAR_CONN_FILE}" "$@"
  49. }
  50. swan_reset() {
  51. do_include "${STRONGSWAN_CONF_FILE}" "${STRONGSWAN_VAR_CONF_FILE}"
  52. }
  53. swan_xappend() {
  54. xappend "${STRONGSWAN_VAR_CONF_FILE}" "$@"
  55. }
  56. secret_reset() {
  57. do_include "${IPSEC_SECRETS_FILE}" "${IPSEC_VAR_SECRETS_FILE}"
  58. }
  59. secret_xappend() {
  60. xappend "${IPSEC_VAR_SECRETS_FILE}" "$@"
  61. }
  62. warning() {
  63. echo "WARNING: $@" >&2
  64. }
  65. add_crypto_proposal() {
  66. local encryption_algorithm
  67. local hash_algorithm
  68. local dh_group
  69. config_get encryption_algorithm "$1" encryption_algorithm
  70. config_get hash_algorithm "$1" hash_algorithm
  71. config_get dh_group "$1" dh_group
  72. [ -n "${encryption_algorithm}" ] && \
  73. crypto="${crypto:+${crypto},}${encryption_algorithm}${hash_algorithm:+-${hash_algorithm}}${dh_group:+-${dh_group}}"
  74. }
  75. set_crypto_proposal() {
  76. local conf="$1"
  77. local proposal
  78. crypto=""
  79. config_get crypto_proposal "$conf" crypto_proposal ""
  80. for proposal in $crypto_proposal; do
  81. add_crypto_proposal "$proposal"
  82. done
  83. [ -n "${crypto}" ] && {
  84. local force_crypto_proposal
  85. config_get_bool force_crypto_proposal "$conf" force_crypto_proposal
  86. [ "${force_crypto_proposal}" = "1" ] && crypto="${crypto}!"
  87. }
  88. crypto_proposal="${crypto}"
  89. }
  90. config_conn() {
  91. # Generic ipsec conn section shared by tunnel and transport
  92. local mode
  93. local local_subnet
  94. local local_nat
  95. local local_sourceip
  96. local local_updown
  97. local local_firewall
  98. local remote_subnet
  99. local remote_sourceip
  100. local remote_updown
  101. local remote_firewall
  102. local ikelifetime
  103. local lifetime
  104. local margintime
  105. local keyingtries
  106. local dpdaction
  107. local dpddelay
  108. local inactivity
  109. local keyexchange
  110. local reqid
  111. config_get mode "$1" mode "route"
  112. config_get local_subnet "$1" local_subnet ""
  113. config_get local_nat "$1" local_nat ""
  114. config_get local_sourceip "$1" local_sourceip ""
  115. config_get local_updown "$1" local_updown ""
  116. config_get local_firewall "$1" local_firewall ""
  117. config_get remote_subnet "$1" remote_subnet ""
  118. config_get remote_sourceip "$1" remote_sourceip ""
  119. config_get remote_updown "$1" remote_updown ""
  120. config_get remote_firewall "$1" remote_firewall ""
  121. config_get ikelifetime "$1" ikelifetime "3h"
  122. config_get lifetime "$1" lifetime "1h"
  123. config_get margintime "$1" margintime "9m"
  124. config_get keyingtries "$1" keyingtries "3"
  125. config_get dpdaction "$1" dpdaction "none"
  126. config_get dpddelay "$1" dpddelay "30s"
  127. config_get inactivity "$1" inactivity
  128. config_get keyexchange "$1" keyexchange "ikev2"
  129. config_get reqid "$1" reqid
  130. [ -n "$local_nat" ] && local_subnet=$local_nat
  131. ipsec_xappend "conn $config_name-$1"
  132. ipsec_xappend " left=%any"
  133. ipsec_xappend " right=$remote_gateway"
  134. [ -n "$local_sourceip" ] && ipsec_xappend " leftsourceip=$local_sourceip"
  135. [ -n "$local_subnet" ] && ipsec_xappend " leftsubnet=$local_subnet"
  136. [ -n "$local_firewall" ] && ipsec_xappend " leftfirewall=$local_firewall"
  137. [ -n "$remote_firewall" ] && ipsec_xappend " rightfirewall=$remote_firewall"
  138. ipsec_xappend " ikelifetime=$ikelifetime"
  139. ipsec_xappend " lifetime=$lifetime"
  140. ipsec_xappend " margintime=$margintime"
  141. ipsec_xappend " keyingtries=$keyingtries"
  142. ipsec_xappend " dpdaction=$dpdaction"
  143. ipsec_xappend " dpddelay=$dpddelay"
  144. [ -n "$inactivity" ] && ipsec_xappend " inactivity=$inactivity"
  145. [ -n "$reqid" ] && ipsec_xappend " reqid=$reqid"
  146. if [ "$auth_method" = "psk" ]; then
  147. ipsec_xappend " leftauth=psk"
  148. ipsec_xappend " rightauth=psk"
  149. [ "$remote_sourceip" != "" ] && ipsec_xappend " rightsourceip=$remote_sourceip"
  150. [ "$remote_subnet" != "" ] && ipsec_xappend " rightsubnet=$remote_subnet"
  151. ipsec_xappend " auto=$mode"
  152. else
  153. warning "AuthenticationMethod $auth_method not supported"
  154. fi
  155. [ -n "$local_identifier" ] && ipsec_xappend " leftid=$local_identifier"
  156. [ -n "$remote_identifier" ] && ipsec_xappend " rightid=$remote_identifier"
  157. [ -n "$local_updown" ] && ipsec_xappend " leftupdown=$local_updown"
  158. [ -n "$remote_updown" ] && ipsec_xappend " rightupdown=$remote_updown"
  159. ipsec_xappend " keyexchange=$keyexchange"
  160. set_crypto_proposal "$1"
  161. [ -n "${crypto_proposal}" ] && ipsec_xappend " esp=$crypto_proposal"
  162. [ -n "${ike_proposal}" ] && ipsec_xappend " ike=$ike_proposal"
  163. }
  164. config_tunnel() {
  165. config_conn "$1"
  166. # Specific for the tunnel part
  167. ipsec_xappend " type=tunnel"
  168. }
  169. config_transport() {
  170. config_conn "$1"
  171. # Specific for the transport part
  172. ipsec_xappend " type=transport"
  173. }
  174. config_remote() {
  175. local enabled
  176. local gateway
  177. local pre_shared_key
  178. local auth_method
  179. config_name=$1
  180. config_get_bool enabled "$1" enabled 0
  181. [ $enabled -eq 0 ] && return
  182. config_get gateway "$1" gateway
  183. config_get pre_shared_key "$1" pre_shared_key
  184. config_get auth_method "$1" authentication_method
  185. config_get local_identifier "$1" local_identifier ""
  186. config_get remote_identifier "$1" remote_identifier ""
  187. [ "$gateway" = "any" ] && remote_gateway="%any" || remote_gateway="$gateway"
  188. [ -z "$local_identifier" ] && {
  189. local ipdest
  190. [ "$remote_gateway" = "%any" ] && ipdest="1.1.1.1" || ipdest="$remote_gateway"
  191. local_gateway=`ip route get $ipdest | awk -F"src" '/src/{gsub(/ /,"");print $2}'`
  192. }
  193. [ -n "$local_identifier" ] && secret_xappend -n "$local_identifier " || secret_xappend -n "$local_gateway "
  194. [ -n "$remote_identifier" ] && secret_xappend -n "$remote_identifier " || secret_xappend -n "$remote_gateway "
  195. secret_xappend ": PSK \"$pre_shared_key\""
  196. set_crypto_proposal "$1"
  197. ike_proposal="$crypto_proposal"
  198. config_list_foreach "$1" tunnel config_tunnel
  199. config_list_foreach "$1" transport config_transport
  200. ipsec_xappend ""
  201. }
  202. config_ipsec() {
  203. local debug
  204. local rtinstall_enabled
  205. local routing_tables_ignored
  206. local routing_table
  207. local routing_table_id
  208. local interface
  209. local device_list
  210. ipsec_reset
  211. secret_reset
  212. swan_reset
  213. ipsec_xappend "# generated by /etc/init.d/ipsec"
  214. ipsec_xappend "version 2"
  215. ipsec_xappend ""
  216. secret_xappend "# generated by /etc/init.d/ipsec"
  217. config_get debug "$1" debug 0
  218. config_get_bool rtinstall_enabled "$1" rtinstall_enabled 1
  219. [ $rtinstall_enabled -eq 1 ] && install_routes=yes || install_routes=no
  220. # prepare extra charon config option ignore_routing_tables
  221. for routing_table in $(config_get "$1" "ignore_routing_tables"); do
  222. if [ "$routing_table" -ge 0 ] 2>/dev/null; then
  223. routing_table_id=$routing_table
  224. else
  225. routing_table_id=$(sed -n '/[ \t]*[0-9]\+[ \t]\+'$routing_table'[ \t]*$/s/[ \t]*\([0-9]\+\).*/\1/p' /etc/iproute2/rt_tables)
  226. fi
  227. [ -n "$routing_table_id" ] && append routing_tables_ignored "$routing_table_id"
  228. done
  229. local interface_list=$(config_get "$1" "interface")
  230. if [ -z "$interface_list" ]; then
  231. WAIT_FOR_INTF=0
  232. else
  233. for interface in $interface_list; do
  234. network_get_device device $interface
  235. [ -n "$device" ] && append device_list "$device" ","
  236. done
  237. [ -n "$device_list" ] && WAIT_FOR_INTF=0 || WAIT_FOR_INTF=1
  238. fi
  239. swan_xappend "# generated by /etc/init.d/ipsec"
  240. swan_xappend "charon {"
  241. swan_xappend " load_modular = yes"
  242. swan_xappend " install_routes = $install_routes"
  243. [ -n "$routing_tables_ignored" ] && swan_xappend " ignore_routing_tables = $routing_tables_ignored"
  244. [ -n "$device_list" ] && swan_xappend " interfaces_use = $device_list"
  245. swan_xappend " plugins {"
  246. swan_xappend " include /etc/strongswan.d/charon/*.conf"
  247. swan_xappend " }"
  248. swan_xappend " syslog {"
  249. swan_xappend " identifier = ipsec"
  250. swan_xappend " daemon {"
  251. swan_xappend " default = $debug"
  252. swan_xappend " }"
  253. swan_xappend " auth {"
  254. swan_xappend " default = $debug"
  255. swan_xappend " }"
  256. swan_xappend " }"
  257. swan_xappend "}"
  258. }
  259. prepare_env() {
  260. mkdir -p /var/ipsec
  261. remove_includes
  262. config_load ipsec
  263. config_foreach config_ipsec ipsec
  264. config_foreach config_remote remote
  265. }
  266. service_running() {
  267. ipsec status > /dev/null 2>&1
  268. }
  269. reload_service() {
  270. running && {
  271. prepare_env
  272. [ $WAIT_FOR_INTF -eq 0 ] && {
  273. ipsec rereadall
  274. ipsec reload
  275. return
  276. }
  277. }
  278. start
  279. }
  280. check_ipsec_interface() {
  281. local intf
  282. for intf in $(config_get "$1" interface); do
  283. procd_add_interface_trigger "interface.*" "$intf" /etc/init.d/ipsec reload
  284. done
  285. }
  286. service_triggers() {
  287. procd_add_reload_trigger "ipsec"
  288. config load "ipsec"
  289. config_foreach check_ipsec_interface ipsec
  290. }
  291. start_service() {
  292. prepare_env
  293. [ $WAIT_FOR_INTF -eq 1 ] && return
  294. procd_open_instance
  295. procd_set_param command $PROG --daemon charon --nofork
  296. procd_set_param file $IPSEC_CONN_FILE
  297. procd_append_param file $IPSEC_SECRETS_FILE
  298. procd_append_param file $STRONGSWAN_CONF_FILE
  299. procd_append_param file /etc/strongswan.d/*.conf
  300. procd_append_param file /etc/strongswan.d/charon/*.conf
  301. procd_set_param respawn
  302. procd_close_instance
  303. }