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

#!/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
}