SSH, Proxy, Privatsphaere?

Autor: Raphael Eiselstein <rabe_at_uugrn.org>
Datum: Sun, 18 Oct 2015 19:43:30 +0200
Hallo zusammen,

immer mal wieder spiele ich den Erklärbär für Dinge, die man mit SSH
(OpenSSH) anstellen kann. Weil es so viele Möglichkeiten gibt Dinge 
damit anzustellen, will ich mal 2 verschiedene Hauptanwendungsfälle
skizzieren und einen Anwendungsfall basierend auf einer Kombination 
aus beiden:

Übersicht
0. Verwendete Werkzeuge
1. SSH als sicherer Tunnel
  1.1: einfaches tcp portforwarding
  1.2: dynamisches portforwarding

2. SSH unter erschwerten Bedingungen (Firewall, Proxyzwang) nutzen
  2.1: Firewall umgehen, SSH auf Port 443
  2.2: Proxypflicht: SSH via HTTP-Proxy auf Port 443

3. Kombinierte Anwendungsfälle
  3.1: Jabber auf xmpp.uugrn.org nutzen via shell.uugrn.org (Selbst-Registrierung)





0. Verwendete Werkzeuge
ssh:    OpenSSH: das zentrale Werkzeug, um das es hier geht  

nc:     netcat-openbsd (nicht netcat-traditional): Ein kleines aber 
        sehr mächtiges Hilfswerkzeug in Kombination mit OpenSSH

fuser:  Hilfsprogramm zum Anzeigen und Beenden ("-k") von Prozessen, 
        die eine bestimmte Ressource (zB Datei oder TCP Port ("-n tcp"))
        belegen.



1. SSH als sicherer Tunnel

1.1 Einfaches TCP-Portforwarding
Viele haben schon sicher gesehen, dass man mit einem gezielten
SSH-Tunnel den Zugriff auf einen bestimmten Dienst "absichern" kann.

Beispiel 1.1: Zugriff von PC auf mail.uugrn.org:25 via shell.uugrn.org

[PC] --(ssh)--> [shell.uugrn.org] --(smtp)--> [mail.uugrn.org]

Wichtig: Hier wird nur die Verbindung von meinem PC zu shell.uugrn.org
abgesichert (ssh), nicht jedoch die Verbindung zwischen shell.uugrn.org und
mail.uugrn.org (smtp).

-----------------------------------------------------------------------------
     1	user_at_pc:~$ ssh -L 30025:mail.uugrn.org:25 -f -N shell.uugrn.org
     2	user_at_pc:~$ nc 127.0.0.1 30025
     3	220 mail.uugrn.lan ESMTP Sendmail 8.14.5/8.14.5; Sun, 18 Oct 2015 13:08:36 +0200 (CEST)
     5	ehlo werbinich
     6	250-mail.uugrn.lan Hello unknown_at_shell.uugrn.org
     7	[IPv6:2a03:2500:1:6:16::], pleased to meet you
     8	250-ENHANCEDSTATUSCODES
     9	250-PIPELINING
    10	250-8BITMIME
    11	250-SIZE
    12	250-DSN
    13	250-DELIVERBY
    14	250 HELP
    15	quit
    16	221 2.0.0 mail.uugrn.lan closing connection
    17  user_at_pc:~$ fuser -k -n tcp 30025
    18  30025/tcp:            4912
-----------------------------------------------------------------------------
1: Aufbau eines SSH-Tunnels via shell.uugrn.org. Der einzige
Anwendungszweck ist der tcp-Forward mit -L, -f -N sorgen dafür, dass das 
lediglich der SSH-Tunnel aufgebaut wird, es wird kein weiteres
remote-command ausgeführt ("-N") und das ssh "forkt sich in den
Hintergrund", d.h. es läuft weiter, die Shell kommt allerdings zurück.

2: Zugriff mit "nc" auf 127.0.0.1 Port 30025: Nach einer kurzen Pause
antwortet der Mail-Server

5+6: mit "ehlo werbinich" begrüße ich den Mailserver mit meinem eigenen
Namen ("werbinich") und der Mailserver Grüßt mich zurück als 
"unknown_at_shell.uugrn.org":  --> der Mailserver sieht, dass mein Zugriff
von shell.uugrn.org aus kommt. q.e.d.

15: quit -> smtp-Dialog beenden

17+18: mit "fuser -k" kann man Prozesse killen bzw. anzeigen, die eine
bestimmte Ressource (hier: "-n tcp 30025") belegen. In diesem Fall also
den ssh-Client, der am Anfang (1) gestartet wurde. Den Tunnel muss man
allerdings nicht beenden wenn man ihn verwendet hat, für mehrere
Trial-and-Error Runden empfiehlt es sich allerdings.


1.2 Dynamisches TCP Portforwarding / SOCKS5 Proxy
Statt nur einer einzelnen TCP Weiterleitung kann man auch etwas bauen,
mit dem man recht flexibel mehrere verschiedene Anwendungsfälle durch
den gleichen SSH-Tunnel schleusen kann, etwa wenn man per SSH-Tunnel im
WorldWideWeb surfen möchte wäre es sehr anstrengend und teilweise sehr
kompliziert für alle möglichen Server jeweils die passenden Tunnel
anzulgen. Viele Anwendungsprogramme (Browser, Mailprogramme,
Chat-Programme, netcat, etc) unterstützen generell die Nutzung eines Proxy
Servers, insbesondere SOCKS5-Proxies. 

Beispiel 1.2: Zugriff von PC auf beliebige Dienste via shell.uugrn.org

[PC] --(ssh)--> [shell.uugrn.org] --(protokoll)--> [zielserver:port]

Wichtig: Hier wird nur die Verbindung von meinem PC zu shell.uugrn.org
abgesichert (ssh), nicht jedoch die Verbindung zwischen shell.uugrn.org und
dem jeweiligen Zielserver.

In diesem Beispiel verwenden wir den Service "shell.uugrn.org" auf Port
"8888", welcher nur mit der IP-Adresse des Clients antwortet. Der
gleiche Service ist auch auf "sigsys.de:8888" verfügbar.

Meine IP-Adresse ist in diesem Fall die IPv6-Adresse
2003:5f:ed1c:9100:b8b4:bc4:ea07:1bde, das funktioniert allerdings
gleichermaßen auch mit IPv4.

-----------------------------------------------------------------------------
     1	user_at_pc:~$ fuser -k -n tcp 1080
     2	1080/tcp:             3793  5376
     3	user_at_pc:~$ ssh -D 1080 -f -N shell.uugrn.org 
     4	user_at_pc:~$ nc shell.uugrn.org 8888
     5	2003:5f:ed1c:9100:b8b4:bc4:ea07:1bde
     6	user_at_pc:~$ nc sigsys.de 8888
     7	2003:5f:ed1c:9100:b8b4:bc4:ea07:1bde
     8	user_at_pc:~$ nc -X 5 -x 127.0.0.1:1080 shell.uugrn.org 8888
     9	2a03:2500:1:6:16::
    10	user_at_pc:~$ nc -X 5 -x 127.0.0.1:1080 sigsys.de 8888
    11	2a03:2500:1:6:16::
    12	user_at_pc:~$ host 2a03:2500:1:6:16::
    13	0.0.0.0.0.0.0.0.0.0.0.0.6.1.0.0.6.0.0.0.1.0.0.0.0.0.5.2.3.0.a.2.ip6.arpa domain name pointer shell.uugrn.org.
-----------------------------------------------------------------------------

1+2:    Prozesse killen, die Port 1080 belegen (fuser -k)

3:      SSH-Tunnel mit "Dynamic Portforwarding" aufbauen, es handelt
        sich anwendungsseitig um einen SOCKS5-Proxy.

4..7:   Einfacher Zugriff auf shell.uugrn.org:8888 und sigsys.de:8888
        ohne SSH-Tunnel und ohne Proxy. 
        Der Service antwortet jeweils mit meiner eigenen IP-Adresse.

8..11:  Der gleiche Zugriff auf shell.uugrn.org:8888 und sigsys.de:8888
        allerdings unter Verwndung eins SOCKS5-Proxies ("-X 5") unter
        der Adresse 127.0.0.1:1080 ("-x").
        Der Service antwortet in diesem Fall jeweils mit der IP-Adresse
        des SSH-Tunnelendpunktes, hier shell.uugrn.org.

Statt mit netcat ("nc") wie in diesem Beispiel könnte man nun für
beliebige Clients (zB Thunderbird, psi-plus, Firefox, ...) einen
SOCKS5-Proxy konfigurieren und dann für die jeweils zugegriffenen
Ziel-Dienste nutzen, etwa mail.uugrn.org:25:

-----------------------------------------------------------------------------
     1	user_at_pc:~$ nc -X 5 -x 127.0.0.1:1080 mail.uugrn.org 25
     2	220 mail.uugrn.lan ESMTP Sendmail 8.14.5/8.14.5; Sun, 18 Oct 2015 13:55:53 +0200 (CEST)
     3	ehlo werbinich
     4	250-mail.uugrn.lan Hello unknown_at_shell.uugrn.org [IPv6:2a03:2500:1:6:16::], pleased to meet you
     [...]
-----------------------------------------------------------------------------

1: Zugriff per netcat via SOCKS-Proxy auf mail.uugrn.org:25
3+4: Begrüßung in SMTP

Genug der Beispiele, wie man SSH-Tunnel *anwenden* kann.



2. SSH unter erschwerten Bedingungen

In manchen Netzen, zum Beispiel öffentliche WLANs in Hotels und
Gastronomie ist der Zugriff auf das Internet beschränkt auf die Nutzung
von einigen wenigen Diensten, zum Beispiel E-Mail und Web-Surfen. Unser
aller Liebling-Service SSH ist meistens nicht erlaubt und somit häufig
geblockt.

Besonders gesicherte Netzwerke verbieten den direkten Zugriff auf das
Internet und erzwingen die Nutzung eines Proxy Servers, meistens ein
einfache Web-Proxy.

2.1 Einfache Firewall "umgehen"

Billige "Gäste-WLAN" Lösungen erlauben/verbieten den Zugriff auf Dienste
durch eine Firewall, die basierend auf TCP-Ports Zugriffe ermöglicht
oder eben sperrt.

Die Lösung ist hier recht einfach, man benötigt allerdings (irgendeinen)
SSH-Server, der auf Port 443 lauscht, dem Port der normalerweise für
"https" reserviert und somit auch häufig freigegeben ist.

Beispiel 2.1
-----------------------------------------------------------------------------
     1	user_at_pc:~$ ssh -p 443 user_at_shell.uugrn.org
     2	[...]
     3	[user_at_shell ~]$ echo $SSH_CLIENT
     4	2003:5f:ed1c:9100:b8b4:bc4:ea07:1bde 33369 443
     5	[user_at_shell ~]$ logout
     6	Connection to shell.uugrn.org closed.
-----------------------------------------------------------------------------

1: Normale SSH-Verbindung auf Port 443 an shell.uugrn.org
3+4: Anzeige der Verbindungsparameter dieser SSH-Session

2.2: SSH durch Zwangsproxy

In diesem Fall gibt es gar keine direkte Verbindung zum Internet und man
muss einen Zwangsproxy benutzen. Zwangsproxies ermöglichen normalerweise
nur den Zugriff auf bestimmte freigegebene Ports, zum Beispiel 443
(https), nicht aber auf 8888 (zB unser MyIP-Service).

Beispiel 2.2: Zugriff mit netcat via HTTP-Proxy auf 192.168.5.20:3128 mit der
"CONNECT"-Methode:
-----------------------------------------------------------------------------
     1	user_at_pc:~$ nc -X connect -x 192.168.5.20:3128 shell.uugrn.org 8888
     2	nc: Proxy error: "HTTP/1.0 403 Forbidden"
     3	user_at_pc:~$ nc -X connect -x 192.168.5.20:3128 shell.uugrn.org 22
     4	nc: Proxy error: "HTTP/1.0 403 Forbidden"
     5	user_at_pc:~$ nc -X connect -x 192.168.5.20:3128 shell.uugrn.org 443
     6	SSH-2.0-OpenSSH_5.8p2_hpn13v11 FreeBSD-20110503
     7	^C
-----------------------------------------------------------------------------
       
1+2:    Zugriff auf shell.uugrn.org:8888      
                --> gesperrt, 8888 ist kein erlaubter Port

3+4:    Zugriff auf shell.uugrn.org:22 (ssh)  
                --> gesperrt, 22 ist kein erlaubter Port

5+6:    Zugriff auf shell.uugrn.org:443 (https, hier ssh)
                --> klappt, SSH-Server shell.uugrn.org:443 antwortet

Beispiel 2.3: OpenSSH via HTTP-Proxy mithilfe von netcat

-----------------------------------------------------------------------------
     1	$ ssh -p 443 -o "ProxyCommand = nc -X connect -x 192.168.5.20:3128 %h %p" shell.uugrn.org 
     2	[user_at_shell ~]$ echo $SSH_CLIENT
     3	2003:5f:ed1c:9100:b699:baff:feb5:3635 44953 443
     4	[user_at_shell ~]$ logout
     5	Connection to shell.uugrn.org closed.
-----------------------------------------------------------------------------
1:      Über die Option "ProxyCommand" kann man den ssh-Client anweisen ein
        tool oder script auszuführen *anstelle* der TCP-Verbindung, die
        ssh normalerweise eigenständig ausmachen würde. Wichtig ist,
        dass alles hinter -o "..." zu ProxyCommand gehört.
        %h wird dabei durch den hostnamen und %p durch den Port ersetzt.

3:      $SSH_CLIENT enthält nun die IPv6-Adresse meines Proxy-Servers,
        den ich intern unter 192.168.5.20 angesprochen habe.
        Proxy:  2003:5f:ed1c:9100:b699:baff:feb5:3635
        PC:     2003:5f:ed1c:9100:b8b4:bc4:ea07:1bde

Das Szenario mit dem Firewall oder dem Zwangsproxy hat natürlich auch
andere Anwendungsfälle, zum Beispiel wenn man Netzwerke nutzen muss bei
denen die Privatsphäre nicht sicher gestellt sein kann. SSH-Tunnel kann
man außerdem Nutzen um die eigene IP-Adresse gegenüber dem
Dienstanbieter zu verschleiern, wenn man der "freiwilligen" 
Vorratsdatenspeicherung des Serviceanbieters nicht vertraut
("Logfiles").


Aber Achtung: bei der Nutzung von Zwangsproxies gelten idR auch andere
Vorschriften *und* der Admin verfügt über ein Logfile des Proxy Servers,
bei dem dann Logzeilen enthalten sind, etwa bei squid3:

-----------------------------------------------------------------------------
     1	1445170658.507      0 192.168.5.135 TCP_DENIED/403 3389 CONNECT shell.uugrn.org:8888 - NONE/- text/html
     2	1445170668.899      0 192.168.5.135 TCP_DENIED/403 3385 CONNECT shell.uugrn.org:22 - NONE/- text/html
     3	1445170674.473    815 192.168.5.135 TCP_MISS/200 49 CONNECT shell.uugrn.org:443 - DIRECT/2a03:2500:1:6:16:: -
     4	1445170971.123   7677 192.168.5.135 TCP_MISS/200 4065 CONNECT shell.uugrn.org:443 - DIRECT/2a03:2500:1:6:16:: -
-----------------------------------------------------------------------------

Die Zeilen 1-3 entsprechen dabei den Versuchen aus Beispiel 2.2 (oben).

Übrigens: ssh mit Hilfe von ProxyCommand über eine bestehende
SOCKS5-Verbindung geht hier natürlich auch (ProxyCommand = nc -X 5 -x ...)
Die Kombinationen aus ssh-erzeugt-Proxy und ssh-nutzt-Proxy sind 
unbegrenzt.


3. Kombinierte Anwendungsfälle zum Ausprobieren
3.1: Nutzung von UUGRN Jabber mit Selbstregistrierung für Mitglieder 

Der UUGRN Jabber Server steht aktuell nur für Mitglieder offen.

Einmal registrierte Accounts können den Jabber-Server von überall her
nutzen, allerdings ist die Selbst-Registrierung des Servers limitiert
auf die IP-Adressen des UUGRN-Vereinsservers, mithin können also nur
rechtmäßige Nutzer des Servers (=Mitglieder) eine entsprechende
Verbindung öffnen.

Grob gesagt funktioniert es so: Zuächst wird ein SSH-Tunnel als
SOCKS5 Proxy gestartet. Über diesen SOCKS5 proxy kann man dann zB mit
"psi plus" (Jabber Client) eine Verbindung zum Server hin aufmachen. Aus
Sicht des Servers kommt der Zugriff dann von shell.uugrn.org, was in
diesem Falle die Selbstregistrierung ermöglicht ("Whitelist").

Zunächst benötigen wir einen SOCKS5-Proxy auf 127.0.0.1:1080 der auf
shell.uugrn.org terminiert:

---------------------------------------------------------------
     1	user_at_pc:~$ ssh -D 1080 -f -N shell.uugrn.org 
---------------------------------------------------------------

Beispiel für psi-plus:

Allgemein -> Benutzerkonten -> Hinzufügen 
Name: uugrn  [x] Neues Benutzerkonto registrieren -> Hinzufügen

Name des Servers: uugrn.org
[x] Server-Namen und -Port manuell (Auflösung über SRV-records klappt
                                scheinbar nicht via SOCKS5-Proxy)

Server: xmpp.uugrn.org  Port: 5222
Verschlüsselung: Immer
Proxy: (Auswahl) --> Bearbeiten

[Neu] -> "ssh tunnel" 
        Typ: SOCKS Version 5 
        Server: 127.0.0.1   Port 1080
        [Speichern]


Zurück in der Konto-Registrierung: 
Proxy: "ssh-tunnel" (Auswahl)
[Weiter]

SSL-Zertifikat vertrauen oder "Trotzdem"

Username: Wunschname
Password: geheimgeheim123!

Fertig, Speichern.

Nach der Registrierung am Server kann man in Psi-plus im Account unter
den Verbindungseinstellungen die Nutzung des SOCKS-Proxys wieder
deaktivieren und auch die Verbindungsparameter auf "automatisch"
stellen.
 

Danach kann der SOCKS-Proxy auch wieder weg

---------------------------------------------------------------
     1	user_at_pc:~$ fuser -k -n tcp 1080
     2	1080/tcp:             5448
---------------------------------------------------------------


Abschließend möchte ich auf die Vorzüge von ~/.ssh/config verweisen, wo
man viele der Parameter je nach Ziel-Host oder auch Global hinterlegen
kann, etwa die Angabe von ProxyCommand.

Alle Beispiele von ssh+netcat kann man sinngemäß auch mit PuTTY unter
Windows nachbauen, wobei PuTTY nicht auf ein exteres Hilfstool wie
netcat angewiesen ist sondern eigenständig SOCKS5-Clientfunktionen oder
CONNECT-Proxyclient ("https") implementiert.

Für viele Anwendungsprogramme gibt es (meistens irgendwo versteckt)
SOCKS5-Proxy Unterstützung, mindestens bei Firefox, thunderbird,
psi-plus.

Have fun!

Raphael
-- 
SMTP+XMPP:	rabe_at_uugrn.org oder rabe_at_sigsys.de 
OTR:		33790A42 C28ED889 2ABEA87C 4E829C29 C76E2F24	
PGP:		4E63 5307 6F6A 036D 518D  3C4F 75EE EA14 F625 DB4E
.........|.........|.........|.........|.........|.........|.........|..


-- 
UUGRN e.V. http://www.uugrn.org/
http://mailman.uugrn.org/mailman/listinfo/uugrn
Wiki: https://wiki.uugrn.org/UUGRN:Mailingliste
Archiv: http://lists.uugrn.org/

Empfangen am 18.10.2015

Dieses Archiv wurde generiert von hypermail 2.2.0 : 18.10.2015 CEST