--- /dev/null
+#
+# Copyright (C) 2010 segal.di.ubi.pt
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=sshtunnel
+PKG_VERSION:=1
+PKG_RELEASE:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/sshtunnel
+ SECTION:=net
+ CATEGORY:=Network
+ TITLE:=Manages Local and Remote openssh ssh(1) tunnels
+ MAINTAINER:=Nuno Goncalves <nunojpg@gmail.com>
+ DEPENDS:=+openssh-client
+endef
+
+define Package/sshtunnel/description
+Creates openssh ssh(1) Local and Remote tunnels configured in UCI file. Can be user to allow remote connections, possibly over NATed connections or without public IP/DNS
+endef
+
+define Package/sshtunnel/conffiles
+/etc/config/sshtunnel
+endef
+
+define Build/Compile
+endef
+
+define Package/sshtunnel/install
+ $(CP) ./files/* $(1)
+endef
+
+$(eval $(call BuildPackage,sshtunnel))
--- /dev/null
+#
+# only authentication supported is public key with indentity file specified
+# pkcs11 support soon
+#
+
+# tunnelR(emote) - when the connection will be initiated to the R(emote) endpoint at
+# remoteaddress:remoteport and then forward to localaddress:localport
+#
+config tunnelR http
+ option user mourinho
+ option hostname server.disney.com
+ option identity /root/.ssh/id_rsa
+ option remoteaddress *
+ option remoteport 9009
+ option localaddress 192.168.1.13
+ option localport 80
+ option options '-o ServerAliveCountMax=3 -o ServerAliveInterval=20 -o StrictHostKeyChecking=false'
+
+# tunnelL(ocal) - when the connection will be initiated to the L(ocal) endpoint at
+# localaddress:localport and then forward to remoteaddress:remoteport
+#
+config tunnelL test
+ option user mourinho
+ option hostname server.disney.com
+ option identity /root/.ssh/id_rsa
+ option localaddress *
+ option localport 1022
+ option remoteaddress secretserver.disney.com
+ option remoteport 22
+ option options '-o ServerAliveCountMax=3 -o ServerAliveInterval=20 -o StrictHostKeyChecking=false'
--- /dev/null
+#!/bin/sh /etc/rc.common
+
+START=99
+STOP=01
+
+PIDFILE="/tmp/run/sshtunnel"
+
+load_tunnel() {
+ config_get user $1 user
+ config_get hostname $1 hostname
+ config_get identity $1 identity
+ config_get remoteport $1 remoteport
+ config_get localport $1 localport
+ config_get options $1 options '-o ServerAliveCountMax=3 -o ServerAliveInterval=20 -o StrictHostKeyChecking=false'
+ config_get retrydelay $1 retrydelay "10"
+ [ "$cfgtype" = "tunnelL" ] && {
+ config_get localaddress $1 localaddress "127.0.0.1"
+ config_get remoteaddress $1 remoteaddress "*"
+ }
+ [ "$cfgtype" = "tunnelR" ] && {
+ config_get localaddress $1 localaddress "*"
+ config_get remoteaddress $1 remoteaddress "127.0.0.1"
+ }
+
+ local error
+ [ -f "$identity" ] || error="Identity file $identity not accessible"
+ [ -n "$user" ] || error="please set user option"
+ [ -n "$hostname" ] || error="please set hostname option"
+ [ "$remoteport" -gt 0 -a "$localport" -gt 0 -a "$retrydelay" -ge 0 ] || error="invalid configuration"
+ [ -n "$error" ] && { logger -p user.err -t "sshtunnel" "$cfgtype $1 not started - $error"; return; }
+
+ [ "$cfgtype" = "tunnelL" ] && {
+ args="-N -i $identity -o PasswordAuthentication=no -o ExitOnForwardFailure=yes $options -L $localaddress:$localport:$remoteaddress:$remoteport $user@$hostname"
+ }
+ [ "$cfgtype" = "tunnelR" ] && {
+ args="-N -i $identity -o PasswordAuthentication=no -o ExitOnForwardFailure=yes $options -R $remoteaddress:$remoteport:$localaddress:$localport $user@$hostname"
+ }
+
+ /usr/bin/sshtunnel.sh "$args" "$retrydelay" &
+ echo $! >> "$PIDFILE".pids
+ logger -p user.info -t "sshtunnel" "started new $cfgtype $1 (pid=$!;retrydelay=$retrydelay)"
+}
+
+stop() {
+ if [ -f "$PIDFILE".pids ]
+ then
+ logger -p user.info -t "sshtunnel" "stopping all tunnels"
+
+ while read pid
+ do
+ start-stop-daemon -K -p "$PIDFILE"_"$pid".pid
+ kill $pid
+ logger -p daemon.info -t "sshtunnel[$pid]" "tunnel stopped"
+ done < "$PIDFILE".pids
+
+ rm "$PIDFILE".pids
+
+ logger -p user.info -t "sshtunnel" "all tunnels stopped"
+ else
+ logger -p user.info -t "sshtunnel" "no tunnels running"
+ fi
+}
+
+start() {
+ [ -f "$PIDFILE".pids ] && stop
+
+ logger -p user.info -t "sshtunnel" "starting all tunnels"
+
+ config_load sshtunnel
+ config_foreach load_tunnel tunnelR
+ config_foreach load_tunnel tunnelL
+
+ logger -p user.info -t "sshtunnel" "all tunnels started"
+}
--- /dev/null
+#!/bin/sh
+
+PIDFILE="/tmp/run/sshtunnel"
+
+args=$1
+retrydelay=$2
+
+while true
+do
+ logger -p daemon.info -t "sshtunnel[$$]" "connecting: ssh $args"
+
+ start-stop-daemon -S -p "$PIDFILE"_"$$".pid -mx ssh -- $args &>/tmp/log/sshtunnel_$$
+ logger -p daemon.err -t "sshtunnel[$$]" < /tmp/log/sshtunnel_$$
+ rm /tmp/log/sshtunnel_$$
+
+ logger -p daemon.info -t "sshtunnel[$$]" "ssh exited with code $?, retrying in $retrydelay seconds"
+
+ sleep "$retrydelay" & wait
+done