Socket Server über SSH

  • Leider wird dieses Thema wohl nicht besonders viele interessieren. Doch statt ich mich die ganze Zeit aufrege, dass hier aus technischer Sicht tote Hose ist, versuche ich etwas Input zu liefern. Natürlich mit der Hoffnung, dass andere welche zur Zeit mehr nur passiv unterwegs sind über die Feiertage auch etwas Zeit finden und es mir nachtun.

    SSH ist ein verschlüsseltes Protokoll um per Remote eine Netzwerkverbindung herzustellen. ssh um eine Remoteshell zu erhalten und scp um Dateien zu kopieren sind für Linux und Unix Admins wohl etwa die meistgebrauchten Tools. Natürlich gibt es auch Tools für Windows: z.B. Putty und winscp.

    Wenn ich nun einen ssh Server habe, kann ich relativ einfach einen Socket zu diesem einrichten, welchen ich für eine gesicherte Verbindung gebrauchen kann:

    ssh -D $port -N -f $user@$host

    Als $port ist nicht der Remoteport sondern ein lokaler Port gemeint, welcher noch frei ist, dies kann Beispielsweise 4444 sein. Paramet -N steht dafür, dass auf der Gegenstelle nichts ausgeführt wird, -f damit das ganze im Background verläuft. $user und $host dürfte klar sein.

    Mit ps -ef | grep ssh sehen wir nun, dass eine Verbindung besteht:
    tux@main:~$ ps -ef | grep ssh
    root 6409 1 0 12:20 ? 00:00:01 ssh -D 666 tux@lap -N -f
    tux 6593 6576 0 13:39 pts/1 00:00:00 grep ssh

    Nun kann man im Browser localhost auf dem eingestellten Port als Proxy verwenden. Der macht dann jegliche Verbindungen über diesen Server.

    Stellt man im Firefox in about:config network.proxy.socks_remote_dns auf true um, geschiet auch die Namensauflösung über den Proxy.

    Selbstverständlich funktioniert das ganze auch mit Windows (Putty): YouTube - SSH Tunneling

    Das bringt es:
    Man hat eine abhörsichere Verbindung.
    Es ist schneller eingerichtet als ein üblicher Proxy, VPN oder ein forwarding mittels einer Firewall.
    Man ruft eine Webseite vom Server her aus an. (Steht mein ssh-Server in Russland, habe ich eine russische IP-Adresse).

    Einsatzzweck:
    Wenn man zum Bleistift ans 25C3 geht und man annehmen muss, dass alle unverschlüsselten Passwörter welche man auf irgendwelchen Webforen oder sonstigem eingibt mitgeschnitten werden.
    Wenn man einen Hardwaredefekt hat und der lokale Computer über das Wlan des Laptops ins Internet muss.
    Wenn man einer Webseite vorgaukeln möchte, dass man aus dem Land des ssh-Servers kommt.
    Wenn man aus anderen Gründen (wie eine ausgereifte Paranoia) eine gesichterte Verbindung haben möchte.

    Leider habe ich noch nicht herausgefunden, wie man Systemweit den Socket benutzen kann. Evtl geht das mit iptables, da bin ich aber noch am suchen.

  • Zitat von chessboi


    Leider habe ich noch nicht herausgefunden, wie man Systemweit den Socket benutzen kann. Evtl geht das mit iptables, da bin ich aber noch am suchen.


    Unter Linux gibt es dafür tsocks.
    Einfach installieren, in die /etc/tsocks.conf schreiben:

    Code
    server = 127.0.0.1
    server_port = 4444

    Dann vor jeden Befehl der den SSH Tunnel nutzen soll, tsocks schreiben, also zb "tsocks firefox".
    Wenn man für alle Programme den Tunnel nutzen will, einfach "tsocks bash" starten, dann nutzen alle Programme, die aus der bash gestartet werden, den Tunnel ;)

  • Wenn man zum Bleistift ans 25C3 geht und man annehmen muss, dass alle unverschlüsselten Passwörter welche man auf irgendwelchen Webforen oder sonstigem eingibt mitgeschnitten werden.

    hum ich dachte die sind selber gegen vorratsspeicherung und mitschnüffeln?

  • Zitat von bobe

    Wenn man für alle Programme den Tunnel nutzen will, einfach "tsocks bash" starten, dann nutzen alle Programme, die aus der bash gestartet werden, den Tunnel ;)


    Hm.. interessant. Danke für den Tipp

    Ich hab mich jetzt kurz über tsocks schlau gemacht. Der Befehl tsocks ist nichts weiter als ein Shellscript, was die Umgebungsvariable LD_PRELOAD setzt.

    Das heisst, man kann via tsocks on|off das ganze für die aktuelle Shell aktivieren bzw. deaktiveren.

    Will man das ganze systemweit, muss man nur die Variable LD_PRELOAD in die /etc/profile (oder die distributionsabhängige Variante) schreiben. tsocks muss natürlich installiert sein.

    Code
    export LD_PRELOAD="/usr/lib/libtsocks.so $LD_PRELOAD"

    Mit "tsocks off" kann man es dann für ein bestimmtes Terminal wieder deaktivieren.

    Wenn man ssh als SOCKS-Server verwendet, lohnt es sich in der /etc/tsocks.conf noch die Option server_type = 5 zu setzen, damit SOCKS5 verwendet und auch UDP und IPv6 weitergeleitet wird.

    chiaki: Da wird auch nichts mitgeschnitten von den Betreibern.
    Wohl aber kann ein gelangweiltes Scriptkiddie dort ein bisschen mitschneiden.

  • tsocks ist zwar interessant, aber so ganz funktionieren tut es bei mir nicht:

    Die Tools wie ping, nslookup usw gehen nicht über den Socket.
    Die Namensauflösung funktioniert ebenfalls nicht mit dem Socket.

  • Nunja, tiefer als mit tsocks kannst du SOCKS kaum verankern. Dann muss schon OpenVPN ran :fresse:

    die libtsocks.so überschreibt die üblichen C-Funktionen zum erstellen einer TCP oder UDP Verbindung, ist ein Binary statisch gelinkt oder verwendet weder TCP oder UDP (ping bentuzt ja IMCP und nslookup DNS), dann geht das nunmal nicht.

    Zwar soll tsocks DNS über TCP umleiten können, aber so ganz funktionieren tut das nicht. Das SOCKS Protokoll sieht das auch nicht vor.

    Von daher, selbst wenn es möglich wäre, SOCKS als virtuelles Interface (tun0 oder so) anzubieten, müsste ein Hack für IMCP und DNS her, und dafür hat man dann ja VPN. Und das wiederum haben wir ja nicht hingekriegt.

    Nachtrag: Die einige Möglichkeit, DNS-Requests zu verschlüsseln, ist via SOCKS5. Der Firefox kann das über die oben genannte Option - dann wird der Hostname dem SOCKS-Proxy übergeben und dieser löst ihn dann auf.
    Mit tsocks geht das nicht, weil dieses wie gesagt die C-Funktionen überschreibt und dort gibt es getrennte Funktionen für das auflösen Hosts und das öffnen einer TCP-Verbindung.

    Nachtrag 16.07.09: Natürlich ist DNS keine eigene Transportschicht, das war Unsinn. Das Problem ist, dass SOCKS nur Sockets umleitet, und tsocks sich vor die Socket-Funktionen des Betriebsystems stellt und so die Sockets umleitet. Die DNS-Auflösung verwendet offenbar andere Funktionen und lässt sich damit nicht umleiten.

    Einmal editiert, zuletzt von gandro (16. Juli 2009 um 15:42)

  • Woohoo, habs rausgekriegt wie man DNS doch umleitet.

    Nach mehreren gescheiterten Versuchen, DNS Requests abzufangen und irgendwie erst ab den SSH-Server abzusenden, habe ich eine Lösung gefunden:

    ttdnsd : The TOR TCP DNS Daemon

    Ein Daemon, der eigentlich für TOR konzipiert ist - doch weil TOR ebenfalls auf SOCKS und tsocks zurückgreift macht es keinen Unterschied. Das Programm macht eigentlich nichts, als auf localhost nach DNS-Anfragen zu warten und diese an echte DNS-Server weiterzuleiten.

    Alles was man tun muss, ist 127.0.0.1 als Nameserver einzutragen und ttdnsd via tsocks starten. Der voreingestellte OpenDNS-Nameserver tut bei mir seinen Dienst, die meines ISP leider nicht (ich habe das Gefühl, die kommen mit TCP nicht so ganz zurecht)

    Nachtrag: ttdnsd benötigt ohne TOR den Parameter -c. Warum auch immer.

    Einmal editiert, zuletzt von gandro (23. Dezember 2008 um 21:17)

  • Hab das ganze nochmal angeschaut und herausgefunden wie einfach sich doch ein VPN mit ssh einrichten lässt:

    Eine einfache Socketverbindung kann mit ssh -D 5000 -N -f $user@$host eingerichtet werden. Auf Server sowie Client reicht dazu ein normales Benuzterkonto ohne spezielle Rechte aus. Die meisten Programme welche auf das Internet zugreifen lassen sich über diesen Socket tunneln, wie etwa Firefox und Pidgin. Für die anderen gibt es das Programm tsocks welches die TCP-Verbindungen umleiten kann. Das funktioniert allerdings nicht mit allen Programmen (etwa wget weigert sich da mitzumachen) und ist zudem nicht besonders Komfortabel.

    Hat man nun ein Root-Login auf Server sowie Client bietet ssh die Möglichkeit ein richtiges VPN einzurichten. Bedingung ist, dass man sich am Server mit root über ssh einloggen kann. Da manche Distributionen (wie etwa Ubuntu) ziemlich restriktive Berechtigungen haben muss in der /etc/ssh/sshd_config PermitRootLogin auf yes gesetzt sein. In der /etc/security/access.conf muss das Rootlogin auch erlaubt sein (Beispielzeile "+ : root : ALL" - dies kann allerdings auch auf gewisse Hosts eingeschränkt werden), dazu noch die Zeile "account required pam_access.so" in /etc/pam.d/sshd. Setzt man nun das root-Passwort neu (damit die Einstellungen übernommen werden) sollte das Login mit root per ssh funktionieren und wir können loslegen:

    --- Einrichten eines VPN mittels SSH ---
    ssh -NTCf -w 0:0 root@server
    Nach dem Ausführen dieses Befehls sollte man auf dem Client sowie auf dem Server ein Netzwerkinterface mit dem Namen tun0 haben. Nun muss dies noch konfiguriert werden:
    ifconfig tun0 192.168.2.90 pointopoint 192.168.2.80
    Respektive auf dem Server:
    ifconfig tun0 192.168.2.80 pointopoint 192.168.2.90
    (IP-Adressen sind frei wählbar)
    Auf dem Client noch die Defaultroute anpassen:
    route add default gw 192.168.2.80 netmask 0.0.0.0
    Nun kann der Client über den Server ins Netzwerk / Internet zugreiffen. Allerdings weiss der Server noch nichts mit den Paketen anzufangen. Einerseits muss TCP-Forwarding eingeschaltet sein:
    echo "1" /proc/sys/net/ipv4/ip_forward
    Nun noch ein NAT einrichten, damit die Pakete auch den Rückweg wiederfinden:
    iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
    (wlan0 ist Interface vom Netzwerk auf dem man sich den Zugriff wünscht)


    Informationsquelle:
    http://www.cyberciti.biz/tips/openssh-ro…-revisited.html
    https://help.ubuntu.com/community/SSH_VPN
    ip forward - Ubuntu Forums

    Und schon steht das VPN!
    Script welcher das ganze automatisiert folgt ...

  • Naja, ein übliches VPN hat dann schon noch ein paar Vorteile gegenüber dem SSH-Tunneling:

    - Man will nicht gerade dem VPN-Client root-Rechte am Server geben
    - VPN wie IPSec kennen noch andere Authentifizierungsmethoden als nur gerade Preshared-Keys oder User-Passwort
    - VPN wie IPsec können zwischen verschiedenen Verschlüsselungsalgorithmen gewählt werden, und es lässt sich fein einstellen was Verschlüsselt werden soll (z.B. nur die Nutzlast)

    Dafür ist SSH relativ einfach und für die Standardbedürfnisse wohl bei weitem sicher genug.

  • Zitat von oreissig

    kann man darüber auch dhcp fahren um die routen und IPs einzustellen?

    Naja ... dann müsste der SSH-Server ja auch der DHCP-Server sein, da dieser sonst ausserhalb der Broadcastdomäne ist (ausser du richtest dir einen Releay-Agent ein), zudem weiss ich nicht ob man mit DHCP ein Interface auch auf eine Point-to-Point Verbindung einrichten lässt (wie es hier gemacht wird, falls dies denn überhaut zwanghaft so notwendig ist) - das mal grundsätzlich zu DHCP.

    Allerdings seh ich nicht genau ein, für was du DHCP nutzen willst. Um die SSH Verbindung herstellen zu können, musst du bereits in einem Netz sein (lokles Netz, oder gar Internet) - diese Verbindung kannst du selbstverständlich mit DHCP einrichten lassen. Die Verbindung des virtuellen Interfaces tun0, welches du mit dem SSH-Tunnel einrichtest, kann ein autonomes Netz sein. (z.B. auch ein Klasse A Netz, wenn du dich sonst in einem C Netz befindest.) Wenn du nun den SSH-Server nicht als Default-Route verwenden willst, kannst du allenfalls noch per Script beim Server die Routingtabelle auslesen und die Netze bei dir einrichten, mit dem Server als Ziel.

  • Hi, sehr nettes Howto.
    Was noch schön wäre, wäre eine Erklärung der einzelnen Befehle und Parameter und warum man sie benutzt.
    Das sorgt dafür, dass man im Anwendungsfall nicht nur copierpaste aus dem Forum macht, sondern auch noch nebenbei das ganze anzuwenden lernt ;)
    Vor allem fühlt man sich gleich sicherer, etwas einzutippen, von dem man auch schon vorher die Auswirkungen kennt...


    Was macht son Socket technisch? Alles was ich da rein schmeiße kommt an der Gegenseite wieder 1:1 heraus? (Wikipedia ist leider gerade down)

  • Welchen Beitrag meinst du jetzt?

    Im Eröffnungsbeitrag steht ja alles erklärt, zum neuen Beitrag unten schau dir mal folgende Links an:

    Die SSH-Zeile:
    https://help.ubuntu.com/community/SSH_…20SSH%20command

    NAT:
    NAT mit Linux und iptables - Tutorial (Einführung)

    Einzig die Sache mit dem pointopoint habe ich noch nicht ganz verstanden, die Manpage von ifconfig sagt da leider auch nicht gewaltig viel mehr.

    Ein Socket ist abstrakt gesprochen, ein Paar aus IP-Adresse und Port, welches du als Programm deinem Betriebsystem übergibst: Dieses leitet dann alle einzelnen Pakete von diesem Socket zu dir und jedes Paket zu diesem Socket an die entsprechende IP-Adresse mit dessen Port.

    Bei einem SOCKS-Server redest du dabei mit nicht deinem Betriebsystem, sondern mit dem SOCKS-Server, dieser leitet dann die Pakete weiter (in diesem Falle über eine verschlüsselte SSH-Verbindung) und übergibt erst am anderen (sicheren Ende) des Tunnels das Socket einem Betriebsystem.

    Der Nachteil ist, dass Programme SOCKS unterstützten müssen, sonst reden sie weiter mit dem Betriebsystem. Man kann dies bei dynamisch gelinkten Programmen z.T. mit umleiten der entsprechenden Funktionen lösen, geht aber nicht überall und mit allem, daher empfiehlt sich eine VPN-artige Lösung, wo man nicht Sockets, sondern einzelne Pakete tunnelt.

  • Grob hab ich es ja schon eklärt, detailierter ist es in den Links, aber ich kann es auch hier etwas genauer erklären, mit meinen eigenen Worten:

    SSH ist ein Protokoll zum Remotelogin an einem anderen Rechner, vergleichbar mit RemoteShell (RSH) oder Telnet, allerdings mit einer Verschlüsselung der übertragenen Daten. Allerdings kann man über dieses Protokoll auch einfach einen Befehl ausführen am anderen Rechner oder Daten kopieren (mit SCP) oder was für uns interessanter ist einen Socket oder einen Tunnel aufbauen.
    ssh -NTCf -w 0:0 root@server
    Zu den Parametern: N sagt das ich am gegenüber keinen Befehl ausführen will, also auch keine Shell gestartet werden soll, T sagt dass ich auch kein virtuelles tty haben will C komprimiert die übertragenen Daten und f schickt das ganze in den Hintergrund. -w ist der eigentliche Paramter für einen Tunnel, gefolgt von lokalemInterface:serverInterface. 0:0 erstellt mir somit auf beiden seiten ein tun0 Device. Dafür muss im übrigen das Kernelmodul tun geladen sein. (modprobe tun)

    Das Netzwerkinterface tun0, welches wir mit der SSH-Verbindung erhalten ist ein logisches Interface, welches wir benutzen können um in die am Server angeschlossene Netzwerke zu benutzen. Sprich wir haben ein VPN - Virtual Private Network - ich kann von meinem Rechner (oder meinem Netzwerk) eine Verschlüsselte Verbindung in ein anderes Netzwerk (über den SSH-Server) aufbauen, ohne dass jemand im (unsicheren) Netzwerk (Internet) dazwischen die Verbindung abhören könnte. Dieses Netzwerkinterface muss aber noch konfiguriert werden, dass macht man mit ifconfig. (Vergleichbar mit dem Befehl ipconfig unter Windows, allerdings kann man damit die Werte nicht nur auslesen, sondern auch setzen.)
    ifconfig tun0 192.168.2.90 pointopoint 192.168.2.80
    Setzt die ip-Adresse des tun0 auf 192.168.2.90. Als Adressraum nimmt man am besten etwas völlig anderes als bei den übrigen Interfaces (an denen man am unsicheren Netzwerk angeschlossen ist) um verwechslungen zu vermeiden.
    Auf dem Server das Selbe:
    ifconfig tun0 192.168.2.80 pointopoint 192.168.2.90
    Pointopoint heisst im übrigen, dass wir hier eine direkte Verbindung zwischen den beiden Interfaces haben. Damit gibt es auch keine Unterstützung für Broadcasts oder ARP, da dies einfach nur unnützer Overhead wäre. Natürlich funktioniert das ganze auch wenn man das Interface wie gewohnt mit mit ifconfig tun0 192.168.2.80 netmask 255.255.255.0 konfigurieren würde - es wäre aber einfach Blödsinn.

    Nun steht zwar die Verbindung, und Server sowie Client können sich gegenseitig anpingen, doch weiss ich noch nichts über die Netwerke welche sich hinter dem Server verbergen. Daher adde ich den Server einfach als Standardgateway.
    route add default gw 192.168.2.80 netmask 0.0.0.0
    Natürlich könnte man mit dem route Befehl auch einfach nur bestimmte Netzwerke oder einzelne Hosts auf den Server umleiten. Wenn man den Server als Standardgateway definiert wird einfach der gesammte Netzwerkverkehr (wie etwa der Zugriff auf das Internet) über den Server umgeleitet. Ausser die Routen welche sonst definiert sind (und wenn man keine manuell definiert hat, sind das nur jene welche direkt mit dem Client verbunden sind).

    Nun leite ich also den ganzen Netzwerkverkehr auf den Server um. Doch dieser verwirft die Pakete welche er erhält einfach! Denn er weiss nicht was er mit ihnen anfangen soll. Nun gibt es unter Linux eine Datei welche aussagt ob ein Host Traffic weiterleiten darf oder nicht. Damit der Server den Traffic weiterleitet muss in dieser Datei eine 1 ("Eins" für true) stehen:
    echo "1" > /proc/sys/net/ipv4/ip_forward

    Wenn ich nun etwa den Browser öffne und auf Google zugreiffe, wird die HTTP-Anfrage über den Server umgeleitet (verschlüsselt durch den Tunnel) und der schickt sie weiter an Google. Doch bei Google steht in der Absenderadresse der IP-Datagramme die Adresse des SSH-Servers. Der Google Webserver schickt mir also alles an den SSH-Server zurück, und der verwirft die Pakete, da er ja nie einen HTTP-Request gemacht hat.
    Damit nun die Pakete auch wieder den korrekten Weg zurück finden, muss ein sogenantes Source-NAT gemacht werden. Die Pakete von meinem Client bekommen dann offiziell als Absenderadresse die des Servers über. Die Sequenznummer des IP-Datagramms wird auf dem SSH-Server (der nun auch als NAT-Server fungiert) in einer Tabelle eingetragen. Dank dieser weiss er, wenn Pakete retour kommen, von welchem Client sie stammen (evtl brauchen ja auch mehrere Clients den Server als Gateway).
    Dieses NAT lässt sich ganz einfach mit einer Firewall-Regel über iptabels einrichten. (iptables ist eine extrem schnelle im Linux-Kernel integrierte Firewall).
    iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
    Alle Pakete welche durch das Interface wlan0 heraugeroutet werden werden somit nach dem Routen entsprechend maskiert und in die NAT-Tabelle eingetragen.

    Wer sich noch etwas genauer dafür interessiert wie das denn genau mit den Paketen abläuft, soll sich doch das ganze mal aufbauen und den Netzwerkverkehr sniffen (etwa mit Wireshark).

  • Zitat von ggeretsae

    gibts dafür eigentlich auch ne methode mit putty für windows, oder kann man das über cygwin erreichen?

    Einen Socket kriegst du mit Putty hin, gibt auch gute Anleitungen im Internet. (Unter anderem auf Youtube.) Einen Tunnel mit einem nutzbaren Interface bezweifle ich, da dass ganze recht betriebssystemnah ist. (Unter Linux brauchst du ein entsprechendes Kernelmodul.)

  • Zitat von ggeretsae

    gibts dafür eigentlich auch ne methode mit putty für windows, oder kann man das über cygwin erreichen?

    Ich hab das ganze hier nur überflogen... aber ist das hier nicht im Prinzip nen SOCKS5 Proxy via SSH? Das kann man ja mit Putty machen...

    Mark IV Style Motherfucker!

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!