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.

206 lines
5.8 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 new
  26. eval "actual=\$$varname"
  27. new="${actual:+$actual$separator}$add"
  28. eval "$varname=\$new"
  29. }
  30. validate_server_section() {
  31. uci_load_validate sshtunnel server "$1" "$2" \
  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(0)' \
  44. 'StrictHostKeyChecking:or("yes", "no", "accept-new")' \
  45. 'TCPKeepAlive:or("yes", "no")' \
  46. 'VerifyHostKeyDNS:or("yes", "no")'
  47. }
  48. validate_tunnelR_section() {
  49. uci_load_validate sshtunnel tunnelR "$1" "$2" \
  50. 'remoteaddress:or(host, "*"):*' \
  51. 'remoteport:port' \
  52. 'localaddress:host' \
  53. 'localport:port'
  54. }
  55. validate_tunnelL_section() {
  56. uci_load_validate sshtunnel tunnelL "$1" "$2" \
  57. 'remoteaddress:host' \
  58. 'remoteport:port' \
  59. 'localaddress:or(host, "*"):*' \
  60. 'localport:port'
  61. }
  62. validate_tunnelD_section() {
  63. uci_load_validate sshtunnel tunnelD "$1" "$2" \
  64. 'localaddress:or(host, "*"):*' \
  65. 'localport:port'
  66. }
  67. validate_tunnelW_section() {
  68. uci_load_validate sshtunnel tunnelW "$1" "$2" \
  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. [ "$2" = 0 ] || { _err "tunnelR $1: validation failed"; return 1; }
  79. [ -n "$remoteport" -a -n "$localport" -a -n "$remoteaddress" ] || { _err "tunnelR $1: missing required options"; return 1; }
  80. # count nr of valid sections to make sure there are at least one
  81. let count++
  82. _log "tunnelR at $server: -R $remoteaddress:$remoteport:$localaddress:$localport"
  83. append_string "ARGS_tunnels" "-R $remoteaddress:$remoteport:$localaddress:$localport"
  84. }
  85. load_tunnelL() {
  86. config_get section_server "$1" "server"
  87. # continue to read next section if this is not for the current server
  88. [ "$server" = "$section_server" ] || return 0
  89. # validate and load this remote tunnel config
  90. [ "$2" = 0 ] || { _err "tunnelL $1: validation failed"; return 1; }
  91. [ -n "$remoteport" -a -n "$localport" -a -n "$remoteaddress" ] || { _err "tunnelL $1: missing required options"; return 1; }
  92. # count nr of valid sections to make sure there are at least one
  93. let count++
  94. _log "tunnelL at $server: -L $localaddress:$localport:$remoteaddress:$remoteport"
  95. append_string "ARGS_tunnels" "-L $localaddress:$localport:$remoteaddress:$remoteport"
  96. }
  97. load_tunnelD() {
  98. config_get section_server "$1" "server"
  99. # continue to read next section if this is not for the current server
  100. [ "$server" = "$section_server" ] || return 0
  101. # validate and load this remote tunnel config
  102. [ "$2" = 0 ] || { _err "tunnelD $1: validation failed"; return 1; }
  103. [ -n "$localport" ] || { _err "tunnelD $1: missing localport"; return 1; }
  104. # count nr of valid sections to make sure there are at least one
  105. let count++
  106. _log "proxy via $server: -D $localaddress:$localport"
  107. append_string "ARGS_tunnels" "-D $localaddress:$localport"
  108. }
  109. load_tunnelW() {
  110. config_get section_server "$1" "server"
  111. # continue to read next section if this is not for the current server
  112. [ "$server" = "$section_server" ] || return 0
  113. # validate and load this remote tunnel config
  114. [ "$2" = 0 ] || { _err "tunnelW $1: validation failed"; return 1; }
  115. [ -n "$vpntype" -a -n "$localdev" -a -n "$remotedev" ] || { _err "tunnelW $1: missing or bad options"; return 1; }
  116. [ "$user" = "root" ] || { _err "tunnelW $1: root is required for tun"; return 1; }
  117. # count nr of valid sections to make sure there are at least one
  118. let count++
  119. _log "tunnelW to $server: -w $localdev:$remotedev -o Tunnel=$vpntype"
  120. append_string "ARGS_tunnels" "-w $localdev:$remotedev -o Tunnel=$vpntype"
  121. }
  122. load_server() {
  123. local server="$1"
  124. [ "$2" = 0 ] || { _err "server $server: validation failed"; return 1; }
  125. local ARGS=""
  126. local ARGS_options=""
  127. local ARGS_tunnels=""
  128. local count=0
  129. config_foreach validate_tunnelR_section "tunnelR" load_tunnelR
  130. config_foreach validate_tunnelL_section "tunnelL" load_tunnelL
  131. config_foreach validate_tunnelD_section "tunnelD" load_tunnelD
  132. config_foreach validate_tunnelW_section "tunnelW" load_tunnelW
  133. [ "$count" -eq 0 ] && { _err "tunnels to $server not started - no tunnels defined"; return 1; }
  134. append_params CheckHostIP Compression CompressionLevel IdentityFile \
  135. LogLevel PKCS11Provider ServerAliveCountMax ServerAliveInterval \
  136. StrictHostKeyChecking TCPKeepAlive VerifyHostKeyDNS
  137. ARGS="$ARGS_options -o ExitOnForwardFailure=yes -o BatchMode=yes -nN $ARGS_tunnels -p $port $user@$hostname"
  138. procd_open_instance "$server"
  139. procd_set_param command "$PROG" $ARGS
  140. procd_set_param stdout 1
  141. procd_set_param stderr 1
  142. procd_set_param respawn 0 "$retrydelay" 1
  143. procd_close_instance
  144. }
  145. start_service() {
  146. config_load "sshtunnel"
  147. config_foreach validate_server_section "server" load_server
  148. }
  149. service_triggers() {
  150. procd_add_reload_trigger "sshtunnel"
  151. procd_open_validate
  152. validate_server_section
  153. validate_tunnelR_section
  154. validate_tunnelL_section
  155. validate_tunnelD_section
  156. validate_tunnelW_section
  157. procd_close_validate
  158. }