view · edit · print · history

OpenSSH: SSH Tunnel on Demand (DE)

 HOWTO - SSH-Tunnel on demand
 ============================

 !! Achtung !!
 Der Autor übernimmt keine Haftung für Schäden, die durch dieses HOWTO
 direkt oder indirekt verursacht wurden. Nutzung der Informationen
 geschieht auf eigene Gefahr. Vielen Dank für ihre Aufmerksamkeit.


   0. Inhalt
   ---------
   1. Worum geht's?
   2. Vor-/Nachteile?
   3. Namen, Konventionen
   4. Was brauche ich?
   5. SSH Pubkey Authentifizierung
   6. SSH Pubkey testen
   7. Zugriff einschränken
   8. xinetd/inetd konfigurieren
     8.1 xinetd
     8.2 inetd
     8.3 Test + Fehlersuche
   9. Autor, Kontakt



   1. Worum geht's?
   ----------------

 Um durch eine Firewall hindurchzukommen braucht man immer mal wieder
 einen SSH-Tunnel. SSH bietet nämlich ein Feature das sich
 Portforwarding schimpft. Das blöde an der Geschichte ist, dass man
 den Tunnel immer erst aufbauen muss (= ssh von Hand starten), bevor
 man ihn benutzen kann.

 Dieses HOWTO zeigt, wie man mit Hilfe von SSH und (x)inetd dafür
 sorgen kann, dass der Tunnel bei Bedarf aufgebaut wird, ohne weiteres
 zutun.

 Das HOWTO ist relativ lang für das bischen Konfiguration aber Profis
 können den grössten Teil überspringen und nicht-Profis sind
 wahrscheinlich froh darum :)



   2. Vor-/Nachteile?
   -----------------

 Vorteil:
  - man muss nix mehr tippen
  - man muss nicht mal mehr dran denken, erst einen Tunnel aufzubauen
  - funktioniert in allen Fällen, in denen auch ein SSH-Tunnel
    funktioniert

 Nachteil:
  - inetd bzw. xinetd muss laufen
  - Verbindungsaufbau dauert länger, also nur bedingt geeignet, um
    viele einzelne HTTP-Requests zu tunneln *gähn*. Für NNTP, POP3?, IMAP,
    SMTP, IRC usw. ist es aber wunderbar.



   3. Namen, Konventionen
   ----------------------

 An manchen Stellen muss ein Benutzer- oder Servername angegeben
 werden. In den Beispielen wird davon ausgegangen, dass der SSH-Server
 (das ist der, auf dem man sich mit ssh einloggt)
 "ssh-host.example.org" heisst und der Account auf dem Server den
 Namen "ssh-user" trägt. Der Newsserver, zu dem man connecten will
 heisst "news-server.example.org".

 Die Namen sind wenig kreativ aber leicht merkbar :)



   4. Was brauche ich?
   -------------------

 Einen SSH-Account auf dem Server, zu dem getunnelt werden soll. Das
 muss übrigens nicht der gleiche Rechner sein wie der, zu dem ich
 eigentlich eine Verbindung aufbauen will; er muss sich lediglich auf
 der selben Seite der Firewall befinden wie der Zielrechner.

   [lokal]           |        [ssh-host]     [news-server]
      H              |          H    |             |
      +==============|==========+    +-------------+
                     |
                  Firewall

   ===  SSH-Tunnel (verschlüsselte Verbindung)
   ---  normale Verbindung (unverschlüsselt)


 Auf dem Server muss das Programm netcat installiert sein (in manchen
 Distributionen heisst es netcat (z.B. SuSE?), in anderen nc (RedHat?,
 Debian)).

 Auf der lokalen Seite braucht man den xinetd (bevorzugt) oder inetd
 (zweite Wahl). Die meisten Distributionen haben einen der beiden
 schon installiert. SuSE? Linux (zumindest bis SuSE? 7.x) verwendet
 standardmässig inetd, RedHat? Linux arbeitet mit xinetd.

 Die Beschreibung geht davon aus, dass auf'm Client und Server jeweils
 OpenSSH zum Einsatz kommt. Bei anderen Clients und Servern können
 sich die Konfigurationen und Kommandozeilenparameter unterscheiden,
 das Prinzip bleibt aber gleich.



   5. SSH Pubkey Authentifizierung
   -------------------------------

 Das ist der aufwändigste Teil und deshalb ein bischen ausführlicher.
 Wer schon weiss, wie man sich mit SSH auf einem Rechner einloggt,
 ohne ein Passwort tippen zu müssen, der kann diesen Teil hier
 überspringen.

 Wer's noch nicht weiss: SSH bietet nicht nur die Möglichkeit, sich
 über ein Passwort am Server anzumelden sondern auch
 mittels eines Schlüssels. Genauer gesagt: mit einem Schlüsselpaar
 bestehend aus privatem (private key) und öffentlichen Schlüssel
 (public key). Gleiches Prinzip wie's auch für SSL, PGP und GPG
 benutzt wird.

 Wem bei den Begriffen public und private key noch kein Licht aufgeht
 sollte erstmal eine Suchmaschine bemühen und sich über die
 Funktionsweise informieren, bevor er weiterliest.

 Dreh- und Angelpunkt der tunnel-on-demand-Geschichte ist die
 Authentifizierung ohne Passwort (dafür mit Pubkey ohne Passphrase).
 Das ist notwendig, weil ssh später nicht-interaktiv als Daemonprozess
 läuft und daher kein Passwort abfragen kann. Ein paar SSH-Clients
 kriegen's trotzdem hin, ein Fenster in X aufzumachen und nach dem
 Passwort zu fragen aber das klappt nicht immer und überall :(

 Also gut, machen wir uns dran, das zu konfigurieren...
 Zunächst mal meldet man sich am System als der User an, unter dessen
 UID der (x)inetd läuft. Meist ist das root.

 Dann generiert man ein Schlüsselpaar. Mit

   ssh-keygen -t dsa -f tunnel -N ""

 erzeugt man zwei Dateien, tunnel und tunnel.pub. Das sind der Private
 Key und der Public Key. Den Private Key (tunnel) kopiert man sich an
 eine sichere Stelle, z.B. ins Verzeichnis .ssh/ im Homeverzeichnis
 des aktuellen Benutzers. Unbedingt drauf achten, dass der Private Key
 nur vom Benutzer selbst lesbar ist und von sonst niemanden!

 Den Pubkey kopiert man auf den SSH-Server. Praktischerweise bietet
 SSH das Programm scp (secure copy) an.

   scp tunnel.pub ssh-user@ssh-host.example.org:

 Als nächstes muss ein bischen was auf dem SSH-Server konfiguriert werden.
 Und zwar erstellt man dort den Ordner .ssh/ im Homeverzeichnis, falls
 er nicht schon existiert und kopiert die Datei tunnel.pub hinein.

   mkdir -m 0700 .ssh/
   mv tunnel.pub .ssh/

 Im Ordner .ssh/ erstellt man nun die Datei authorized_keys, falls sie
 noch nicht existiert und kopiert den Inhalt von tunnel.pub hinein
 bzw. hängt ihn an, wenn authorized_keys schon existiert. Folgendes
 Kommando macht das in einem Rutsch:

   cd .ssh
   cat tunnel.pub >>authorized_keys

 Sodali, ab hier sollte einloggen ohne Passwort möglich sein. Testen
 wir's, indem wir uns mit dem Private Key auf dem Server einloggen
 (siehe nächster Abschnitt).


   6. SSH Pubkey testen
   --------------------

 Sagen wir, der im vorangegangenen Abschnitt erzeugte Private Key
 liegt in /root/.ssh/tunnel und die Konfiguration ist fehlerfrei
 verlaufen, dann müsste

   ssh ssh-user@ssh-host.example.org -i /root/.ssh/tunnel

 einen Shellaccount auf dem Server öffnen, ohne vorher nach einem
 Passwort zu fragen. Wenn's die erste Verbindung ist, kommt erst noch
 eine Meldung, ob man den Key vom Server in die Datei known_hosts
 aufnehmen will.

 Wichtig: Das Kommando muss unter der User-ID (UID) laufen, unter der
 es auch später im (x)inetd aufgerufen wird. Wie gesagt, in den
 meisten Fällen läuft's als User root.

 Wenn's nicht funktioniert fragt man am besten jemand, der sich damit
 auskennt, denn es gibt verschiedene Ursachen, woran es liegen kann.
 Z.B. kann es sein, dass die Datei für den Public Key nicht authorized_keys
 sondern authorized_keys2 heisst. Oder man hat sie in den falschen
 Ordner kopiert (richtig: .ssh/ im Homeverzeichnis auf dem Server).
 Oder Pubkey-Authentifizierung wurde vom Serveradministrator verboten.
 Oder auf'm Server läuft kein OpenSSH.



   7. Zugriff einschränken
   -----------------------

 Die Pubkey Authentifizierung ist ziemlich mächtig. Etwas zu mächtig
 für unsere Bedürfnisse. Allein der Besitz des Private Keys ermöglicht
 vollen Zugriff auf den Shellaccount auf dem SSH-Server. Das ist nicht
 sooo sicher und überhaupt nicht nötig. Deshalb zeigt der Abschnitt,
 wie man Möglichkeiten auf ein Minimum einschränkt.

 Auf dem Server muss wie bereits erwähnt das Programm netcat vorhanden
 sein. Unter RedHat? und Debian heisst es nc. SuSE? hat es netcat
 getauft, wahrscheinlich, um's vom Northern Commander zu
 unterscheiden, der ebenfalls nc abgekürzt wird.

 Einfach mal nc -h bzw. netcat -h tippen. Wenn eine Liste mit Optionen
 auftaucht, wie man sich mit einem anderen Rechner verbindet war's
 wahrscheinlich richtig :)

 Jetzt brauchen wir den absoluten Pfad von nc:

     which nc    bzw. which netcat

 Meist isses /usr/bin/nc oder /usr/bin/netcat.
 Wenn man den Pfad weiss, kann man in authorized_keys auf'm Server
 folgendes vor den Pubkey in die gleiche Zeile schreiben:

     command="/usr/bin/nc news-server.example.org nntp",no-port-forwarding

 Durch ein Leerzeichen getrennt sollte dann ssh-dss, gefolgt von einer
 langen Reihe wilder Buchstaben und Zahlen kommen. Wie gesagt, alles
 in eine Zeile (zumindest bei OpenSSH, bei anderen Servern weiss ich
 nicht, wie das aussehen muss).

 Der zweite Parameter von nc (hier: nntp) ist übrigens der Port, auf
 den connected werden soll. Für POP3? gibt man pop3, für IMAP imap und
 für SMTP smtp an :)  Oder wenn man die Portnummer weiss geht auch
 die.

 Jetzt kann man nochmal den Abschnitt 6 erklärten Test durchführen.
 Nur diesmal geht keine Shell auf und stattdessen meldet sich
 hoffentlich der Newsserver.

 Kommt doch eine Shell, hat man das Kommando vielleicht vor den
 falschen Schlüssel geschrieben. Passiert überhaupt nichts bzw. geht
 die Verbindung gleich wieder zu, dann hat man dem nc vielleicht 'nen
 falschen Parameter gegeben. Zum Überprüfen auf dem Server das in
 Anführungszeichen angegebene Kommando ausführen und schauen, ob sich
 da mehr tut.



   8. xinetd/inetd konfigurieren
   -----------------------------

 Wer's bis hierhin geschafft hat, sollte sich mal auf die Schulter
 klopfen, denn dann kriegt man das bischen jetzt auch noch geregelt :)

 Zunächst geben wir dem Tunnel eine Portnummer und einen Namen. Sagen
 wir mal Port 61023 und als Name nntp-tunnel. Das tragen wir dann auch
 gleich in /etc/services ein. Eine Zeile der Form

     nntp-tunnel     61023/tcp   # Tunnel zum Newsserver

 irgendwo zwischenreinschieben. Cool gemacht.


 An dieser Stelle trennt sich der Weg für diejenigen, die xinetd
 benutzen von vom Weg für die inetd-Nutzer.



     8.1 xinetd
     ---------- 

 Fehlt nur noch der xinetd. Der hat gleich ein ganzes
 Konfigurationsverzeichnis: /etc/xinetd.d/. Darin erzeugt man eine
 neue Datei mit dem Namen unseres Tunnels (hier: nntp-tunnel) mit
 folgendem Inhalt:

     # default: on
     # description: SSH on demand tunnel zum Newsserver
     service nntp-tunnel
     {
         socket_type             = stream
         wait                    = no
         user                    = root
         server                  = /usr/bin/ssh
         server_args             = -T ssh-user@ssh-host.example.org -i /root/.ssh/tunnel
         log_on_success          += USERID
         log_on_failure          += USERID
         disable                 = no
         only_from               = localhost
     }

 Schnell noch lässig dem xinetd Bescheid geben, dass sich die
 Konfiguration geändert hat und dann war's das auch schon.
 Naja, fast. Eine kleine Schwierigkeit gibt's noch: Das Kommando zum
 neuladen ist von Distribution zu Distribution unterschiedlich :(
 Probier' mal die hier aus, eines wird schon passen...

     service xinetd reload
     /etc/init.d/xinetd reload
     rcxinetd reload
     service xinetd restart
     /etc/init.d/xinetd restart
     rcxinetd restart
     killall -HUP xinetd



     8.2 inetd
     ---------

 Der inetd wird über die Datei /etc/inetd.conf gesteuert. In die trägt man
 irgendwo (z.B. am Schluss) folgende Zeile ein:

     nntp-tunnel stream tcp nowait root /usr/sbin/tcpd /usr/bin/ssh -T ssh-user@ssh-host.example.org -i /root/.ssh/tunnel

 Ist das geschehen, muss man noch den inetd neu starten. Wie im
 vorangegangenen Abschnitt zu xinetd gibt's auch hier mehrere Möglichkeiten,
 von denen eine schon stimmen wird :)

     service inetd reload
     /etc/init.d/inetd reload
     rcinetd reload
     killall -HUP inetd


     8.3 Test + Fehlersuche
     ----------------------

 Obercool.
 Ab jetzt kann man eine Verbindung zu localhost Port 61023 aufmachen und
 wird *zauber-zauber, magie, hex-hex* zum Newsserver durchgereicht.

 Ok, was tun, wenn doch nicht? In die Logfiles schauen (z.B.
 /var/log/messages). Immer noch kein Hinweis? Dann jemanden fragen,
 der sich auskennt, denn auch hier gibt's wieder viele seltsame
 Fehler, die sich nicht schnell im Howto klären lassen.

 Ein Fehler könnte sein, dass der Tunnel zum allerersten Mal mit dieser UID
 aufgemacht wird. Probier's nochmal von Hand unter der UID des Users, mit dem
 die SSH im (x)inetd gestartet wird.

 Bei mir hat es sich mal als vorteilhaft erwiesen, den Aufruf von SSH um den
 Parameter -T zu ergaenzen, also

     [...] ssh-user@ssh-host.example.org -T -i /root/.ssh/tunnel

 Wenn das aber auch nichts bringt ist doch Rat von Freunden gefragt.



   9. Autor/Kontakt
   ----------------

 Zu erreichen bin ich unter
 E-Mail: Achim Settelmeier <sshtunnelhowto@sirlab.de>.
    WWW: http://www.sirlab.de/linux/
    IRC: Settel, #gnuher.de (auf deutschen Servern)

 Ich bin ganz besonders gut zu erreichen für Leute, die trotz oder
 wegen dem Howto immer noch Probleme haben aber auch für die, die
 Fehler finden oder Verbesserungsvorschläge anbringen wollen.
Nixes changes · ALL changes
Page last modified on January 31, 2005, at 04:09 PM