123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- #!/bin/sh /etc/rc.common
- #
- # Copyright (C) 2010-2015 OpenWrt.org
- # Copyright (C) 2010 segal.di.ubi.pt
- #
- START=99
- STOP=01
- USE_PROCD=1
- PROG=/usr/bin/ssh
- _log() {
- logger -p daemon.info -t sshtunnel "$@"
- }
- _err() {
- logger -p daemon.err -t sshtunnel "$@"
- }
- append_params() {
- local p v args
- for p in $*; do
- eval "v=\$$p"
- [ -n "$v" ] && args="$args -o $p=$v"
- done
- ARGS_options="${args# *}"
- }
- append_string() {
- local varname="$1"; local add="$2"; local separator="${3:- }"; local actual
- eval "actual=\$$varname"
- new="${actual:+$actual$separator}$add"
- eval "$varname=\$new"
- }
- validate_server_section() {
- uci_validate_section sshtunnel server "$1" \
- 'user:string(1)' \
- 'hostname:host' \
- 'port:port' \
- 'retrydelay:min(1):60' \
- 'PKCS11Provider:file' \
- 'CheckHostIP:or("yes", "no")' \
- 'Compression:or("yes", "no")' \
- 'CompressionLevel:range(1,9)' \
- 'IdentityFile:file' \
- 'LogLevel:or("QUIET", "FATAL", "ERROR", "INFO", "VERBOSE", "DEBUG", "DEBUG1", "DEBUG2", "DEBUG3"):INFO' \
- 'ServerAliveCountMax:min(1)' \
- 'ServerAliveInterval:min(1)' \
- 'StrictHostKeyChecking:or("yes", "no")' \
- 'TCPKeepAlive:or("yes", "no")' \
- 'VerifyHostKeyDNS:or("yes", "no")'
- }
- validate_tunnelR_section() {
- uci_validate_section sshtunnel tunnelR "$1" \
- 'remoteaddress:or(host, "*"):*' \
- 'remoteport:port' \
- 'localaddress:host' \
- 'localport:port'
- }
- validate_tunnelL_section() {
- uci_validate_section sshtunnel tunnelL "$1" \
- 'remoteaddress:host' \
- 'remoteport:port' \
- 'localaddress:or(host, "*"):*' \
- 'localport:port'
- }
- validate_tunnelD_section() {
- uci_validate_section sshtunnel tunnelD "$1" \
- 'localaddress:or(host, "*"):*' \
- 'localport:port'
- }
- validate_tunnelW_section() {
- uci_validate_section sshtunnel tunnelW "$1" \
- 'vpntype:or("ethernet", "point-to-point"):point-to-point' \
- 'localdev:or("any", min(1))' \
- 'remotedev:or("any", min(1))'
- }
- load_tunnelR() {
- config_get section_server "$1" "server"
- # continue to read next section if this is not for the current server
- [ "$server" = "$section_server" ] || return 0
- # validate and load this remote tunnel config
- local remoteaddress remoteport localaddress localport
- validate_tunnelR_section "$1" || { _err "tunnelR ${1}: validation failed"; return 1; }
- [ -n "$remoteport" -a -n "$localport" -a -n "$remoteaddress" ] || { _err "tunnelR ${1}: missing required options"; return 1; }
- # count nr of valid sections to make sure there are at least one
- let count++
- _log "tunnelR at ${server}: -R $remoteaddress:$remoteport:$localaddress:$localport"
- append_string "ARGS_tunnels" "-R $remoteaddress:$remoteport:$localaddress:$localport"
- }
- load_tunnelL() {
- config_get section_server "$1" "server"
- # continue to read next section if this is not for the current server
- [ "$server" = "$section_server" ] || return 0
- # validate and load this remote tunnel config
- local remoteaddress remoteport localaddress localport
- validate_tunnelL_section "$1" || { _err "tunnelL ${1}: validation failed"; return 1; }
- [ -n "$remoteport" -a -n "$localport" -a -n "$remoteaddress" ] || { _err "tunnelL ${1}: missing required options"; return 1; }
- # count nr of valid sections to make sure there are at least one
- let count++
- _log "tunnelL at ${server}: -L $localaddress:$localport:$remoteaddress:$remoteport"
- append_string "ARGS_tunnels" "-L $localaddress:$localport:$remoteaddress:$remoteport"
- }
- load_tunnelD() {
- config_get section_server "$1" "server"
- # continue to read next section if this is not for the current server
- [ "$server" = "$section_server" ] || return 0
- # validate and load this remote tunnel config
- local localaddress localport
- validate_tunnelD_section "$1" || { _err "tunnelD ${1}: validation failed"; return 1; }
- [ -n "$localport" ] || { _err "tunnelD ${1}: missing localport"; return 1; }
- # count nr of valid sections to make sure there are at least one
- let count++
- _log "proxy via ${server}: -D $localaddress:$localport"
- append_string "ARGS_tunnels" "-D $localaddress:$localport"
- }
- load_tunnelW() {
- config_get section_server "$1" "server"
- # continue to read next section if this is not for the current server
- [ "$server" = "$section_server" ] || return 0
- # validate and load this remote tunnel config
- local localdev remotedev vpntype
- validate_tunnelW_section "$1" || { _err "tunnelW ${1}: validation failed"; return 1; }
- [ -n "$vpntype" -a -n "$localdev" -a -n "$remotedev" ] || { _err "tunnelW $1: missing or bad options"; return 1; }
- [ "$user" == "root" ] || { _err "tunnelW ${1}: root is required for tun"; return 1; }
- # count nr of valid sections to make sure there are at least one
- let count++
- _log "tunnelW to ${server}: -w $localdev:$remotedev -o Tunnel=$vpntype"
- append_string "ARGS_tunnels" "-w $localdev:$remotedev -o Tunnel=$vpntype"
- }
- load_server() {
- server="$1"
- local user hostname port retrydelay PKCS11Provider CheckHostIP Compression \
- CompressionLevel IdentityFile LogLevel ServerAliveCountMax \
- ServerAliveInterval StrictHostKeyChecking TCPKeepAlive VerifyHostKeyDNS
- validate_server_section "$server" || { _err "server ${server}: validation failed"; return 1; }
- ARGS=""
- ARGS_options=""
- ARGS_tunnels=""
- count=0
- config_foreach load_tunnelR "tunnelR"
- config_foreach load_tunnelL "tunnelL"
- config_foreach load_tunnelD "tunnelD"
- config_foreach load_tunnelW "tunnelW"
- [ "$count" -eq 0 ] && { _err "tunnels to ${server} not started - no tunnels defined"; return 1; }
- append_params CheckHostIP Compression CompressionLevel IdentityFile \
- LogLevel PKCS11Provider ServerAliveCountMax ServerAliveInterval \
- StrictHostKeyChecking TCPKeepAlive VerifyHostKeyDNS
- ARGS="$ARGS_options -o ExitOnForwardFailure=yes -o BatchMode=yes -nN $ARGS_tunnels -p $port $user@$hostname"
- procd_open_instance "$server"
- procd_set_param command "$PROG" $ARGS
- procd_set_param stdout 1
- procd_set_param stderr 1
- procd_set_param respawn 0 "$retrydelay" 1
- procd_close_instance
- }
- start_service() {
- config_load "sshtunnel"
- config_foreach load_server "server"
- }
- service_triggers() {
- procd_add_reload_trigger "sshtunnel"
- procd_open_validate
- validate_server_section
- validate_tunnelR_section
- validate_tunnelL_section
- validate_tunnelD_section
- validate_tunnelW_section
- procd_close_validate
- }
|