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.

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