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.

385 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. config_get mode "$1" mode "route"
  111. config_get local_subnet "$1" local_subnet ""
  112. config_get local_nat "$1" local_nat ""
  113. config_get local_sourceip "$1" local_sourceip ""
  114. config_get local_updown "$1" local_updown ""
  115. config_get local_firewall "$1" local_firewall ""
  116. config_get remote_subnet "$1" remote_subnet ""
  117. config_get remote_sourceip "$1" remote_sourceip ""
  118. config_get remote_updown "$1" remote_updown ""
  119. config_get remote_firewall "$1" remote_firewall ""
  120. config_get ikelifetime "$1" ikelifetime "3h"
  121. config_get lifetime "$1" lifetime "1h"
  122. config_get margintime "$1" margintime "9m"
  123. config_get keyingtries "$1" keyingtries "3"
  124. config_get dpdaction "$1" dpdaction "none"
  125. config_get dpddelay "$1" dpddelay "30s"
  126. config_get inactivity "$1" inactivity
  127. config_get keyexchange "$1" keyexchange "ikev2"
  128. [ -n "$local_nat" ] && local_subnet=$local_nat
  129. ipsec_xappend "conn $config_name-$1"
  130. ipsec_xappend " left=%any"
  131. ipsec_xappend " right=$remote_gateway"
  132. [ -n "$local_sourceip" ] && ipsec_xappend " leftsourceip=$local_sourceip"
  133. [ -n "$local_subnet" ] && ipsec_xappend " leftsubnet=$local_subnet"
  134. [ -n "$local_firewall" ] && ipsec_xappend " leftfirewall=$local_firewall"
  135. [ -n "$remote_firewall" ] && ipsec_xappend " rightfirewall=$remote_firewall"
  136. ipsec_xappend " ikelifetime=$ikelifetime"
  137. ipsec_xappend " lifetime=$lifetime"
  138. ipsec_xappend " margintime=$margintime"
  139. ipsec_xappend " keyingtries=$keyingtries"
  140. ipsec_xappend " dpdaction=$dpdaction"
  141. ipsec_xappend " dpddelay=$dpddelay"
  142. [ -n "$inactivity" ] && ipsec_xappend " inactivity=$inactivity"
  143. if [ "$auth_method" = "psk" ]; then
  144. ipsec_xappend " leftauth=psk"
  145. ipsec_xappend " rightauth=psk"
  146. [ "$remote_sourceip" != "" ] && ipsec_xappend " rightsourceip=$remote_sourceip"
  147. [ "$remote_subnet" != "" ] && ipsec_xappend " rightsubnet=$remote_subnet"
  148. ipsec_xappend " auto=$mode"
  149. else
  150. warning "AuthenticationMethod $auth_method not supported"
  151. fi
  152. [ -n "$local_identifier" ] && ipsec_xappend " leftid=$local_identifier"
  153. [ -n "$remote_identifier" ] && ipsec_xappend " rightid=$remote_identifier"
  154. [ -n "$local_updown" ] && ipsec_xappend " leftupdown=$local_updown"
  155. [ -n "$remote_updown" ] && ipsec_xappend " rightupdown=$remote_updown"
  156. ipsec_xappend " keyexchange=$keyexchange"
  157. set_crypto_proposal "$1"
  158. [ -n "${crypto_proposal}" ] && ipsec_xappend " esp=$crypto_proposal"
  159. [ -n "${ike_proposal}" ] && ipsec_xappend " ike=$ike_proposal"
  160. }
  161. config_tunnel() {
  162. config_conn "$1"
  163. # Specific for the tunnel part
  164. ipsec_xappend " type=tunnel"
  165. }
  166. config_transport() {
  167. config_conn "$1"
  168. # Specific for the transport part
  169. ipsec_xappend " type=transport"
  170. }
  171. config_remote() {
  172. local enabled
  173. local gateway
  174. local pre_shared_key
  175. local auth_method
  176. config_name=$1
  177. config_get_bool enabled "$1" enabled 0
  178. [ $enabled -eq 0 ] && return
  179. config_get gateway "$1" gateway
  180. config_get pre_shared_key "$1" pre_shared_key
  181. config_get auth_method "$1" authentication_method
  182. config_get local_identifier "$1" local_identifier ""
  183. config_get remote_identifier "$1" remote_identifier ""
  184. [ "$gateway" = "any" ] && remote_gateway="%any" || remote_gateway="$gateway"
  185. [ -z "$local_identifier" ] && {
  186. local ipdest
  187. [ "$remote_gateway" = "%any" ] && ipdest="1.1.1.1" || ipdest="$remote_gateway"
  188. local_gateway=`ip route get $ipdest | awk -F"src" '/src/{gsub(/ /,"");print $2}'`
  189. }
  190. [ -n "$local_identifier" ] && secret_xappend -n "$local_identifier " || secret_xappend -n "$local_gateway "
  191. [ -n "$remote_identifier" ] && secret_xappend -n "$remote_identifier " || secret_xappend -n "$remote_gateway "
  192. secret_xappend ": PSK \"$pre_shared_key\""
  193. set_crypto_proposal "$1"
  194. ike_proposal="$crypto_proposal"
  195. config_list_foreach "$1" tunnel config_tunnel
  196. config_list_foreach "$1" transport config_transport
  197. ipsec_xappend ""
  198. }
  199. config_ipsec() {
  200. local debug
  201. local rtinstall_enabled
  202. local routing_tables_ignored
  203. local routing_table
  204. local routing_table_id
  205. local interface
  206. local device_list
  207. ipsec_reset
  208. secret_reset
  209. swan_reset
  210. ipsec_xappend "# generated by /etc/init.d/ipsec"
  211. ipsec_xappend "version 2"
  212. ipsec_xappend ""
  213. secret_xappend "# generated by /etc/init.d/ipsec"
  214. config_get debug "$1" debug 0
  215. config_get_bool rtinstall_enabled "$1" rtinstall_enabled 1
  216. [ $rtinstall_enabled -eq 1 ] && install_routes=yes || install_routes=no
  217. # prepare extra charon config option ignore_routing_tables
  218. for routing_table in $(config_get "$1" "ignore_routing_tables"); do
  219. if [ "$routing_table" -ge 0 ] 2>/dev/null; then
  220. routing_table_id=$routing_table
  221. else
  222. routing_table_id=$(sed -n '/[ \t]*[0-9]\+[ \t]\+'$routing_table'[ \t]*$/s/[ \t]*\([0-9]\+\).*/\1/p' /etc/iproute2/rt_tables)
  223. fi
  224. [ -n "$routing_table_id" ] && append routing_tables_ignored "$routing_table_id"
  225. done
  226. local interface_list=$(config_get "$1" "interface")
  227. if [ -z "$interface_list" ]; then
  228. WAIT_FOR_INTF=0
  229. else
  230. for interface in $interface_list; do
  231. network_get_device device $interface
  232. [ -n "$device" ] && append device_list "$device" ","
  233. done
  234. [ -n "$device_list" ] && WAIT_FOR_INTF=0 || WAIT_FOR_INTF=1
  235. fi
  236. swan_xappend "# generated by /etc/init.d/ipsec"
  237. swan_xappend "charon {"
  238. swan_xappend " load_modular = yes"
  239. swan_xappend " install_routes = $install_routes"
  240. [ -n "$routing_tables_ignored" ] && swan_xappend " ignore_routing_tables = $routing_tables_ignored"
  241. [ -n "$device_list" ] && swan_xappend " interfaces_use = $device_list"
  242. swan_xappend " plugins {"
  243. swan_xappend " include /etc/strongswan.d/charon/*.conf"
  244. swan_xappend " }"
  245. swan_xappend " syslog {"
  246. swan_xappend " identifier = ipsec"
  247. swan_xappend " daemon {"
  248. swan_xappend " default = $debug"
  249. swan_xappend " }"
  250. swan_xappend " auth {"
  251. swan_xappend " default = $debug"
  252. swan_xappend " }"
  253. swan_xappend " }"
  254. swan_xappend "}"
  255. }
  256. prepare_env() {
  257. mkdir -p /var/ipsec
  258. remove_includes
  259. config_load ipsec
  260. config_foreach config_ipsec ipsec
  261. config_foreach config_remote remote
  262. }
  263. service_running() {
  264. ipsec status > /dev/null 2>&1
  265. }
  266. reload_service() {
  267. running && {
  268. prepare_env
  269. [ $WAIT_FOR_INTF -eq 0 ] && {
  270. ipsec rereadall
  271. ipsec reload
  272. return
  273. }
  274. }
  275. start
  276. }
  277. check_ipsec_interface() {
  278. local intf
  279. for intf in $(config_get "$1" interface); do
  280. procd_add_interface_trigger "interface.*" "$intf" /etc/init.d/ipsec reload
  281. done
  282. }
  283. service_triggers() {
  284. procd_add_reload_trigger "ipsec"
  285. config load "ipsec"
  286. config_foreach check_ipsec_interface ipsec
  287. }
  288. start_service() {
  289. prepare_env
  290. [ $WAIT_FOR_INTF -eq 1 ] && return
  291. procd_open_instance
  292. procd_set_param command $PROG --daemon charon --nofork
  293. procd_set_param file $IPSEC_CONN_FILE
  294. procd_append_param file $IPSEC_SECRETS_FILE
  295. procd_append_param file $STRONGSWAN_CONF_FILE
  296. procd_append_param file /etc/strongswan.d/*.conf
  297. procd_append_param file /etc/strongswan.d/charon/*.conf
  298. procd_set_param respawn
  299. procd_close_instance
  300. }