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).