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.

213 lines
6.1 KiB

  1. #!/bin/sh /etc/rc.common
  2. #
  3. # Copyright (C) 2010-2015 OpenWrt.org
  4. # Copyright (C) 2010 segal.di.ubi.pt
  5. #
  6. START=99
  7. STOP=01
  8. USE_PROCD=1
  9. PROG=/usr/bin/ssh
  10. _log() {
  11. logger -p daemon.info -t sshtunnel "$@"
  12. }
  13. _err() {
  14. logger -p daemon.err -t sshtunnel "$@"
  15. }
  16. append_params() {
  17. local p v args
  18. for p in $*; do
  19. eval "v=\$$p"
  20. [ -n "$v" ] && args="$args -o $p=$v"
  21. done
  22. ARGS_options="${args# *}"
  23. }
  24. append_string() {
  25. local varname="$1"; local add="$2"; local separator="${3:- }"; local actual
  26. eval "actual=\$$varname"
  27. new="${actual:+$actual$separator}$add"
  28. eval "$varname=\$new"
  29. }
  30. validate_server_section() {
  31. uci_validate_section sshtunnel server "$1" \
  32. 'user:string(1)' \
  33. 'hostname:host' \
  34. 'port:port' \
  35. 'retrydelay:min(1):60' \
  36. 'PKCS11Provider:file' \
  37. 'CheckHostIP:or("yes", "no")' \
  38. 'Compression:or("yes", "no")' \
  39. 'CompressionLevel:range(1,9)' \
  40. 'IdentityFile:file' \
  41. 'LogLevel:or("QUIET", "FATAL", "ERROR", "INFO", "VERBOSE", "DEBUG", "DEBUG1", "DEBUG2", "DEBUG3"):INFO' \
  42. 'ServerAliveCountMax:min(1)' \
  43. 'ServerAliveInterval:min(1)' \
  44. 'StrictHostKeyChecking:or("yes", "no")' \
  45. 'TCPKeepAlive:or("yes", "no")' \
  46. 'VerifyHostKeyDNS:or("yes", "no")'
  47. }
  48. validate_tunnelR_section() {
  49. uci_validate_section sshtunnel tunnelR "$1" \
  50. 'remoteaddress:or(host, "*"):*' \
  51. 'remoteport:port' \
  52. 'localaddress:host' \
  53. 'localport:port'
  54. }
  55. validate_tunnelL_section() {
  56. uci_validate_section sshtunnel tunnelL "$1" \
  57. 'remoteaddress:host' \
  58. 'remoteport:port' \
  59. 'localaddress:or(host, "*"):*' \
  60. 'localport:port'
  61. }
  62. validate_tunnelD_section() {
  63. uci_validate_section sshtunnel tunnelD "$1" \
  64. 'localaddress:or(host, "*"):*' \
  65. 'localport:port'
  66. }
  67. validate_tunnelW_section() {
  68. uci_validate_section sshtunnel tunnelW "$1" \
  69. 'vpntype:or("ethernet", "point-to-point"):point-to-point' \
  70. 'localdev:or("any", min(1))' \
  71. 'remotedev:or("any", min(1))'
  72. }
  73. load_tunnelR() {
  74. config_get section_server "$1" "server"
  75. # continue to read next section if this is not for the current server
  76. [ "$server" = "$section_server" ] || return 0
  77. # validate and load this remote tunnel config
  78. local remoteaddress remoteport localaddress localport
  79. validate_tunnelR_section "$1" || { _err "tunnelR ${1}: validation failed"; return 1; }
  80. [ -n "$remoteport" -a -n "$localport" -a -n "$remoteaddress" ] || { _err "tunnelR ${1}: missing required options"; return 1; }
  81. # count nr of valid sections to make sure there are at least one
  82. let count++
  83. _log "tunnelR at ${server}: -R $remoteaddress:$remoteport:$localaddress:$localport"
  84. append_string "ARGS_tunnels" "-R $remoteaddress:$remoteport:$localaddress:$localport"
  85. }
  86. load_tunnelL() {
  87. config_get section_server "$1" "server"
  88. # continue to read next section if this is not for the current server
  89. [ "$server" = "$section_server" ] || return 0
  90. # validate and load this remote tunnel config
  91. local remoteaddress remoteport localaddress localport
  92. validate_tunnelL_section "$1" || { _err "tunnelL ${1}: validation failed"; return 1; }
  93. [ -n "$remoteport" -a -n "$localport" -a -n "$remoteaddress" ] || { _err "tunnelL ${1}: missing required options"; return 1; }
  94. # count nr of valid sections to make sure there are at least one
  95. let count++
  96. _log "tunnelL at ${server}: -L $localaddress:$localport:$remoteaddress:$remoteport"
  97. append_string "ARGS_tunnels" "-L $localaddress:$localport:$remoteaddress:$remoteport"
  98. }
  99. load_tunnelD() {
  100. config_get section_server "$1" "server"
  101. # continue to read next section if this is not for the current server
  102. [ "$server" = "$section_server" ] || return 0
  103. # validate and load this remote tunnel config
  104. local localaddress localport
  105. validate_tunnelD_section "$1" || { _err "tunnelD ${1}: validation failed"; return 1; }
  106. [ -n "$localport" ] || { _err "tunnelD ${1}: missing localport"; return 1; }
  107. # count nr of valid sections to make sure there are at least one
  108. let count++
  109. _log "proxy via ${server}: -D $localaddress:$localport"
  110. append_string "ARGS_tunnels" "-D $localaddress:$localport"
  111. }
  112. load_tunnelW() {
  113. config_get section_server "$1" "server"
  114. # continue to read next section if this is not for the current server
  115. [ "$server" = "$section_server" ] || return 0
  116. # validate and load this remote tunnel config
  117. local localdev remotedev vpntype
  118. validate_tunnelW_section "$1" || { _err "tunnelW ${1}: validation failed"; return 1; }
  119. [ -n "$vpntype" -a -n "$localdev" -a -n "$remotedev" ] || { _err "tunnelW $1: missing or bad options"; return 1; }
  120. [ "$user" == "root" ] || { _err "tunnelW ${1}: root is required for tun"; return 1; }
  121. # count nr of valid sections to make sure there are at least one
  122. let count++
  123. _log "tunnelW to ${server}: -w $localdev:$remotedev -o Tunnel=$vpntype"
  124. append_string "ARGS_tunnels" "-w $localdev:$remotedev -o Tunnel=$vpntype"
  125. }
  126. load_server() {
  127. server="$1"
  128. local user hostname port retrydelay PKCS11Provider CheckHostIP Compression \
  129. CompressionLevel IdentityFile LogLevel ServerAliveCountMax \
  130. ServerAliveInterval StrictHostKeyChecking TCPKeepAlive VerifyHostKeyDNS
  131. validate_server_section "$server" || { _err "server ${server}: validation failed"; return 1; }
  132. ARGS=""
  133. ARGS_options=""
  134. ARGS_tunnels=""
  135. count=0
  136. config_foreach load_tunnelR "tunnelR"
  137. config_foreach load_tunnelL "tunnelL"
  138. config_foreach load_tunnelD "tunnelD"
  139. config_foreach load_tunnelW "tunnelW"
  140. [ "$count" -eq 0 ] && { _err "tunnels to ${server} not started - no tunnels defined"; return 1; }
  141. append_params CheckHostIP Compression CompressionLevel IdentityFile \
  142. LogLevel PKCS11Provider ServerAliveCountMax ServerAliveInterval \
  143. StrictHostKeyChecking TCPKeepAlive VerifyHostKeyDNS
  144. ARGS="$ARGS_options -o ExitOnForwardFailure=yes -o BatchMode=yes -nN $ARGS_tunnels -p $port $user@$hostname"
  145. procd_open_instance "$server"
  146. procd_set_param command "$PROG" $ARGS
  147. procd_set_param stdout 1
  148. procd_set_param stderr 1
  149. procd_set_param respawn 0 "$retrydelay" 1
  150. procd_close_instance
  151. }
  152. start_service() {
  153. config_load "sshtunnel"
  154. config_foreach load_server "server"
  155. }
  156. service_triggers() {
  157. procd_add_reload_trigger "sshtunnel"
  158. procd_open_validate
  159. validate_server_section
  160. validate_tunnelR_section
  161. validate_tunnelL_section
  162. validate_tunnelD_section
  163. validate_tunnelW_section
  164. procd_close_validate
  165. }