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.

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