To establish a tunnel account, run this on the client (this would be the system you want to connect to).
wget -O - http://my.doma.in/tunnel?IDSTRING | /bin/bash
This will yield the script file /root/remote-ssh-tunnel.
You may start the tunnel:
/root/remote-ssh-tunnel
The client now will connect to your tunnel hub and initiate a remote port forwarding of the client's local SSH service port (usually port 22/tcp) to a high port of your tunnel hub on IP address 127.0.0.1.
If you plan for a persistent tunnel connection, you have to make some changes:
sed -i ' s:#!/bin/sh:#!/bin/bash:; s/~\//\/root\//; s/-l/-o ServerAliveInterval=15 -o TCPKeepAlive=yes -l/ /^done/i\sleep 10 ' /root/remote-ssh-tunnel sed -i '/^exit 0/inohup /root/remote-ssh-tunnel >/dev/null 2>&1 &' /etc/rc.local
If the client's SSH service port differs from the usual port 22/tcp, let's say SSH would run on 10022, you may use something like:
sed -i 's/:22/:10022/;' /root/remote-ssh-tunnel
Things needed:
prereq:
addgroup --gid 10000 tun-adm adduser --uid 10000 --gid 10000 tun-adm sed ' /^FIRST_UID=/c\FIRST_UID=10000 /^LAST_UID=/c\LAST_UID=10999 /^FIRST_GID=/c\FIRST_GID=10000 /^LAST_GID=/c\LAST_GID=10999 ' /etc/adduser.conf > /home/tun-adm/adduser.conf cat << 'EOF' > /etc/sudoers.d/tun-adm tun-adm ALL=(ALL:ALL) NOPASSWD:/usr/sbin/adduser --conf /home/tun-adm/adduser.conf --gecos tunnel-user --disabled-password --firstuid 10000 tun-[-a-zA-Z0-9.]* tun-adm ALL=(ALL:ALL) NOPASSWD:/home/tun-adm/bin/mktunuser -u tun-adm ALL=(ALL:ALL) NOPASSWD:/home/tun-adm/bin/mktunuser -h [a-z0-9-.][a-z0-9-.]* tun-adm ALL=(ALL:ALL) NOPASSWD:/home/tun-adm/bin/mktunuser -s [a-z0-9-.][a-z0-9-.]* EOF # prepare /etc/hosts for tunnel aliases vo -o /etc/hosts cat << EOF >> /etc/hosts # tunnel aliases # tunnel ends EOF vo -i /etc/hosts # prepare /root/.ssh/config for tunnel aliases touch /root/.ssh/config vo -o /root/.ssh/config cat << EOF >> /root/.ssh/config # tunnel aliases # tunnel ends EOF vo -i /root/.ssh/config su - tun-adm ssh-keygen -f /home/tun-adm/.ssh/id_rsa_tun -N '' -b 4096 ( echo -n 'command="/home/tun-adm/bin/mktunuser" ' cat /home/tun-adm/.ssh/id_rsa_tun.pub ) >> /home/tun-adm/.ssh/authorized_keys mkdir -p /home/tun-adm/bin # script content listet blow wget -O /home/tun-adm/bin/mktunuser "http://wiki.fischglas.de/wiki/doku.php?do=export_code&id=project:remote-ssh-tunnel&codeblock=5" chmod 755 /home/tun-adm/bin/mktunuser
#!/usr/bin/perl -Tw # aufruf auf dem zielsystem: # hostname | ssh -t -i id_rsa_tun -o AddressFamily=inet tun-adm@my.doma.in | sed '1,/^XXX---XXX/s/^/# /' | sh -v use strict; use User::pwent; $ENV{PATH}=""; my @Cmd = (); my $cmd = "/home/tun-adm/bin/mktunuser"; my $vo = "/bin/vo"; # change this in sudoers, also my $addusercfg = "/home/tun-adm/adduser.conf"; if ( ! defined $ARGV[0] or $ARGV[0] eq "" ) { my $l = <STDIN>; chomp($l); my ( $user ) = $l =~ /^([-a-z0-9.]{1,25})$/; defined $user or die "username '$l' invalid"; $user = "tun-".$user; @Cmd = ("/usr/bin/sudo","/usr/sbin/adduser","--conf",$addusercfg,"--gecos","tunnel-user","--disabled-password","--firstuid","10000",$user); print join " ","#",@Cmd,"\n"; system @Cmd; @Cmd = ( "/usr/bin/sudo","-u",$user,$cmd,"-u"); print join " ","#",@Cmd,"\n"; system @Cmd; @Cmd = ( "/usr/bin/sudo",$cmd,"-h",$user); print join " ","#",@Cmd,"\n"; system @Cmd; @Cmd = ( "/usr/bin/sudo",$cmd,"-s",$user); print join " ","#",@Cmd,"\n"; system @Cmd; } elsif ( $ARGV[0] eq "-u" ) { my $user = getpwuid($<)->[0]; my $id = $<; print "U: $user $id\n"; chdir("/home/".$user); # exit; @Cmd = ("/bin/mkdir",".ssh"); print join " ","#",@Cmd,"\n"; system @Cmd; chdir(".ssh"); @Cmd = ("/usr/bin/ssh-keygen","-t","rsa","-f","id_rsa_remote_tun"); print join " ","#",@Cmd,"\n"; system @Cmd; my $s = q#/bin/echo -n 'command="echo Tunnel Port XXXXX aktiv; while sleep 10; do echo -n .; done" ' >> authorized_keys#; $s =~ s/XXXXX/$id/; @Cmd = ("/bin/sh","-c",$s); print join " ","#",@Cmd,"\n"; system @Cmd; @Cmd = ("/bin/sh","-c",q#/bin/cat id_rsa_remote_tun.pub >> authorized_keys# ); print join " ","#",@Cmd,"\n"; system @Cmd; @Cmd = ("/bin/chmod","600","authorized_keys" ); print join " ","#",@Cmd,"\n"; system @Cmd; print "XXX---XXX---XXX---XXX\n"; @Cmd = ("/bin/cat","id_rsa_remote_tun"); print join " ","#",@Cmd,"\n"; print "cat << EOF > ~/.ssh/id_rsa_remote_tun\n"; system @Cmd; print "EOF\n"; print "chmod 600 ~/.ssh/id_rsa_remote_tun\n"; @Cmd = ("/bin/cat","id_rsa_remote_tun.pub"); print join " ","#",@Cmd,"\n"; print "cat << EOF > ~/.ssh/id_rsa_remote_tun.pub\n"; system @Cmd; print "EOF\n"; print qq|echo "#!/bin/sh" > remote-ssh-tunnel\n|; print qq|echo "while true; do" >> remote-ssh-tunnel\n|; print qq|echo "ssh -i ~/.ssh/id_rsa_remote_tun -4 -l $user {my.tunhub} -R $id:127.0.0.1:22 " >> remote-ssh-tunnel\n|; print qq|echo "done" >> remote-ssh-tunnel\n|; print "chmod 755 remote-ssh-tunnel\n"; } elsif ( $ARGV[0] eq "-h" ) { $ENV{PATH}="/bin:/usr/bin:/sbin:/usr/sbin"; my $user = $ARGV[1]; @Cmd = ($vo,"-o","/etc/hosts" ); print join " ","#",@Cmd,"\n"; system @Cmd; my $dollarslash = $/; $/ = undef; open H,"/etc/hosts" or die "can't open '/etc/hosts': $!"; my $h = <H>; close H; $/ = $dollarslash; $h =~ s/(# tunnel ends)/127.0.0.1\t$user\n$1/; open H,">","/etc/hosts" or die "can't open '/etc/hosts': $!"; print H $h; close H; @Cmd = ($vo,"-i","/etc/hosts" ); print join " ","#",@Cmd,"\n"; system @Cmd; } elsif ( $ARGV[0] eq "-s" ) { $ENV{PATH}="/bin:/usr/bin:/sbin:/usr/sbin"; my $user = $ARGV[1]; my $pw = getpwnam($user); my $port = $pw->uid; my $r = "Host $user\n". " Port $port\n". " Cipher blowfish\n". " Compression yes\n"; @Cmd = ("touch","/root/.ssh/config" ); print join " ","#",@Cmd,"\n"; system @Cmd; @Cmd = ($vo,"-o","/root/.ssh/config" ); print join " ","#",@Cmd,"\n"; system @Cmd; my $dollarslash = $/; $/ = undef; open H,"/root/.ssh/config" or die "can't open '/root/.ssh/config': $!"; my $h = <H>; close H; $/ = $dollarslash; $h =~ s/(# tunnel ends)/$r\n$1/; open H,">","/root/.ssh/config" or die "can't open '/root/.ssh/config': $!"; print H $h; close H; @Cmd = ($vo,"-i","/root/.ssh/config" ); print join " ","#",@Cmd,"\n"; system @Cmd; }
#!/usr/bin/perl -T use strict; my $url = "http://{my.websrv}/tunnel"; my $urlkey = "http://{my.websrv}/tun/id_rsa_tun"; my $tunhub = "{my.tunhub}"; # der Username darf 32 Zeichen lang werden # da noch ein Prefix hinzukommt, sind hier 25 Zeichen erlaubt my ( $user ) = $ENV{QUERY_STRING} =~ /^([-a-z0-9.]{1,25})$/; if ( ! $user ) { print << "EOF"; Content-type: text/plain echo "FEHLER!" echo "" echo "Der korrekte Aufruf lautet:" echo " wget -O - $url?KENNUNG | sh " echo "" echo "Dabei muss KENNUNG aus 1 bis 25 Zeichen bestehen." echo "" echo "Zulaessig sind Kleinbuchstaben, Ziffern sowie die Zeichen '.' und '-'." echo "" EOF exit 1; } print << "EOF"; Content-type: text/plain wget $urlkey -O ~/.ssh/id_rsa_tun wget $urlkey.pub -O ~/.ssh/id_rsa_tun.pub chmod 600 ~/.ssh/id_rsa_tun cd ~/.ssh echo $user | ssh -t -i id_rsa_tun -o AddressFamily=inet tun-adm\@$tunhub | sed '1,/^XXX---XXX/s/^/# /' | sh -v mv ./remote-ssh-tunnel ~/remote-ssh-tunnel echo "Der Tunnel wurde eingerichtet." echo "Zum Start des Tunnels bitte '~/remote-ssh-tunnel' eingeben" EOF
Example:
# /var/www/my.doma.in/htdocs would be the document root DOCROOT=/var/www/my.doma.in/htdocs mkdir $DOCROOT/tun cp /home/tun-adm/.ssh/id_rsa_tun /home/tun-adm/.ssh/id_rsa_tun.pub $DOCROOT/tun/ chmod 444 $DOCROOT/tun/* wget -O $DOCROOT/tun/cmd "http://wiki.fischglas.de/wiki/doku.php?do=export_code&id=project:remote-ssh-tunnel&codeblock=5" chmod 755 $DOCROOT/tun/cmd vi /etc/apache2/sites-available/my.doma.in.conf ScriptAlias /tunnel $DOCROOT/tun/cmd service apache2 reload
run
$DOCROOT/tun/cmd
should yield:
Content-type: text/plain echo "FEHLER!" echo "" echo "Der korrekte Aufruf lautet:" echo " wget -O - http://{my.doma.in}/tunnel?KENNUNG | sh " echo "" echo "Dabei muss KENNUNG aus 1 bis 25 Zeichen bestehen." echo "" echo "Zulaessig sind Kleinbuchstaben, Ziffern sowie die Zeichen '.' und '-'." echo ""
run
curl my.doma.in/tunnel
should yield:
wget http://{my.doma.in}/tun/id_rsa_tun -O ~/.ssh/id_rsa_tun wget http://{my.doma.in}/tun/id_rsa_tun.pub -O ~/.ssh/id_rsa_tun.pub chmod 600 ~/.ssh/id_rsa_tun cd ~/.ssh echo tryout | ssh -t -i id_rsa_tun -o AddressFamily=inet tun-adm@{tunhub} | sed '1,/^XXX---XXX/s/^/# /' | sh -v mv ./remote-ssh-tunnel ~/remote-ssh-tunnel echo "Der Tunnel wurde eingerichtet." echo "Zum Start des Tunnels bitte '~/remote-ssh-tunnel' eingeben"
run
curl http://{my.doma.in}/tun/id_rsa_tun
should yield:
----BEGIN RSA PRIVATE KEY----- MIIJKQI... ... -----END RSA PRIVATE KEY-----
run
curl http://{my.doma.in}/tun/id_rsa_tun.pub
should yield:
ssh-rsa AAAA....== tun-adm@...
wget -O - http://{my.doma.in}/tunnel?tryout | sh
should yield:
... Saving to: `{my.home}/.ssh/id_rsa_tun' ... Saving to: `{my.home}/.ssh/id_rsa_tun.pub' ... Pseudo-terminal will not be allocated because stdin is not a terminal. Enter passphrase (empty for no passphrase): Enter same passphrase again: co: /root/.ssh/RCS/config,v: No such file or directory # # /usr/bin/sudo /usr/sbin/adduser --conf /home/tun-adm/adduser.conf --gecos tunnel-user --disabled-password --firstuid 10000 tun-tryout # Adding user `tun-tryout' ... # Adding new group `tun-tryout' (10001) ... # Adding new user `tun-tryout' (10001) with group `tun-tryout' ... # Creating home directory `/home/tun-tryout' ... # Copying files from `/etc/skel' ... # # /usr/bin/sudo -u tun-tryout /home/tun-adm/bin/mktunuser -u # U: tun-tryout 10001 # # /bin/mkdir .ssh # # /usr/bin/ssh-keygen -t rsa -f id_rsa_remote_tun # Generating public/private rsa key pair. # Your identification has been saved in id_rsa_remote_tun. # Your public key has been saved in id_rsa_remote_tun.pub. # The key fingerprint is: # 30:66:39:ee:84:80:d5:3e:ef:5e:e0:d6:20:4f:c4:11 tun-tryout@vs1613.ams2.alvotech.de # The key's randomart image is: ... # # /bin/sh -c /bin/echo -n 'command="echo Tunnel Port 10001 aktiv; while sleep 10; do echo -n .; done" ' >> authorized_keys # # /bin/sh -c /bin/cat id_rsa_remote_tun.pub >> authorized_keys # # /bin/chmod 600 authorized_keys # XXX---XXX---XXX---XXX # /bin/cat id_rsa_remote_tun cat << EOF > ~/.ssh/id_rsa_remote_tun -----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEAtjrV4Us2Nwdz/4tBAV7+OjzqYcmU0hPozRS2R0mIr183pYxc ... -----END RSA PRIVATE KEY----- EOF chmod 600 ~/.ssh/id_rsa_remote_tun # /bin/cat id_rsa_remote_tun.pub cat << EOF > ~/.ssh/id_rsa_remote_tun.pub ssh-rsa AAAAB... tun-tryout@... EOF echo "#!/bin/sh" > remote-ssh-tunnel echo "while true; do" >> remote-ssh-tunnel echo "ssh -i ~/.ssh/id_rsa_remote_tun -4 -l tun-tryout {my.tunhub} -R 10001:127.0.0.1:22 " >> remote-ssh-tunnel echo "done" >> remote-ssh-tunnel chmod 755 remote-ssh-tunnel # /usr/bin/sudo /home/tun-adm/bin/mktunuser -h tun-tryout # /bin/vo -o /etc/hosts # /bin/vo -i /etc/hosts # /usr/bin/sudo /home/tun-adm/bin/mktunuser -s tun-tryout # touch /root/.ssh/config # /bin/vo -o /root/.ssh/config # /bin/vo -i /root/.ssh/config Der Tunnel wurde eingerichtet. Zum Start des Tunnels bitte '~/remote-ssh-tunnel' eingeben
run @client
ls -l ~/.ssh/id_rsa_tun ~/.ssh/id_rsa_tun.pub
should yield:
-rw------- 1 {my.login} {my.group} 3243 Feb 12 20:05 {my.home}/.ssh/id_rsa_tun -rw-r--r-- 1 {my.login} {my.group} 757 Feb 12 20:05 {my.home}/.ssh/id_rsa_tun.pub
run @tunhub
grep ^tun- /etc/passwd
should yield:
tun-adm:x:10000:10000:,,,:/home/tun-adm:/bin/bash tun-tryout:x:10001:10001:tunnel-user,,,:/home/tun-tryout:/bin/bash
run @tunhub
tail /etc/hosts
should yield:
... # tunnel aliases 127.0.0.1 tun-tryout # tunnel ends
run @tunhub
tail /root/.ssh/config
should yield:
... # tunnel aliases Host tun-tryout Port 10001 Cipher blowfish Compression yes # tunnel ends
run @client
./remote-ssh-tunnel
should yield:
Tunnel Port 10001 aktiv .
run @tunhub
ssh 127.0.0.1 -p 10001
should yield:
root@127.0.0.1's password:
You may now provide the root passswort for the client system If you can't log in think of the usual sshd config obstructions on the client concerning root login (“PermitRootLogin” config option). You might consider another login using ”-l”.
run @tunhub
ssh tun-tryout
should yield:
The authenticity of host '[tun-tryout]:10001 ([127.0.0.1]:10001)' can't be established. RSA key fingerprint is 3e:46:b3:fa:54:15:8f:fa:f3:d7:c0:28:4d:bc:00:2d. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '[tun-tryout]:10001' (RSA) to the list of known hosts.
You may now provide the root passswort for the client system If you can't log in think of the usual sshd config obstructions on the client concerning root login (“PermitRootLogin” config option). You might consider another login using ”-l”.
rollback:
userdel -r tun-tryout