Ich war etwas überrascht, als FreeBSD meine Netzwerkkarte von Mellanox nicht erkannt hat. Die Mellanox ConnectX-2 ist vielleicht eine der verbreitetsten 10GbE-Netzwerkkarten.
FreeBSD unterstützt die natürlich auch, allerdings muss man da wieder manuell eingreifen. Es fehlt nur eine Zeile in der Datei /boot/loader.conf.
mlx4en_load="YES"
Nach einem Reboot wird der Treiber für die Netzwerkkarte geladen. Danach kann man sein Netzwerkinterface konfigurieren. In meinem Fall wollte ich DHCP und dafür waren folgende zusätzlichen Zeilen in /etc/rc.conf nötig:
ifconfig_mlxen0="DHCP"
ifconfig_mlxen0_ipv6="inet 6 accept_rtadv"
Danach noch folgenden Befehl ausführen:
service dhclient start mlxen0
Und das Netzwerk dürfte funktionieren.
Vor langer Zeit wurde es gefordert und hier ist es: eine Anleitung inklusive Erklärung wie man mit netcat einen Proxy für eine TCP-Verbindung baut, der bei Bedarf auch den Traffic anzeigt oder speichert.
Zunächst einmal benötigt man einen Server zu dem der Client sich normalerweise direkt verbinden würde. Wer live mittesten will, kann sich mit netcat einen basteln:
nc -l -p 1220
Nun wollen wir aber einen Proxy. Hierfür lauschen wir mit einem weiteren netcat-Prozess auf einem anderen Port. Der Client soll sich dann mit dem Proxy verbinden, und der Proxy soll den Traffic an den Server (Port 1220) senden. Bevor wir zur kompletten Lösung für bidirektionale Traffic-Weiterleitung kommen, hier erstmal der einfache Fall nur für eine Richtung.
nc -l -o 1221 | nc localhost 1220
Mit einer einfachen Pipe wird die Ausgabe des Proxies, also die Daten, die der Client sendet, zu dem Server gesendet. Alles was der Server sendet, wird jedoch vom netcat-Prozess, der den Proxy mit dem Server verbindet (nc localhost 1220
), auf stdout ausgegeben. Was also fehlt ist, dass die Ausgabe dieses Prozesses als Eingabe für den Proxy dient. Und dafür benutzen wir eine Named Pipe (FIFO).
Eine normale Pipe besteht nur aus zwei Filedeskriptoren und kann daher nur an Kindprozesse weitergegeben werden. Eine FIFO hingegen wird im Dateisystem abgebildet und jeder Prozess kann auf diese zugreifen. Erstellen können wir eine FIFO mit dem Befehl mkfifo
.
mkfifo fifo
Dann erweitern wir den Befehl für den Proxy noch so, dass der Proxy-Prozess seine Eingabe aus der FIFO bezieht und der zweite netcat-Prozess seine Ausgabe in die FIFO schreibt.
nc -l -o 1221 < fifo | nc localhost 1220 > fifo
Jetzt wird der ganze Traffic in beide Richtungen weitergereicht, wir wollen ihn jedoch noch im Terminal anzeigen lassen oder loggen. Hierfür verwenden wir das Tool tee
, welches seine Eingabe auf stdout ausgibt und sie zusätzlich noch in eine Datei schreibt. Damit können wir jetzt z.B. den Traffic in zwei separaten Dateien loggen:
nc -l -p 1221 < fifo | tee client.log | nc localhost 1220 | tee server.log > fifo
Den Traffic im Terminal anzeigen kann man, in dem man /dev/tty
zur Hilfe nimmt. Dieses ist ein spezielles Device, was für das Terminal des aktuellen Prozesses steht. Daten, die wir in /dev/tty
reinschreiben, werden im Terminal ausgegeben.
nc -l -p 1221 < fifo | tee /dev/tty | nc localhost 1220 | tee fifo
Eine weitere Möglichkeit ist, den Traffic in eine weitere FIFO zu schreiben. Aus dieser kann man in einem anderen Terminal dann mit cat
oder einem anderen Programm den Traffic live mitlesen.
mkfifo traffic
nc -l -p 1221 < fifo | tee traffic | nc localhost 1220 | tee traffic > fifo
Beachten muss man dabei jedoch, dass man erst aus der traffic-FIFO liest, bevor Daten übertragen werden, da das Öffnen einer FIFO blockiert, bis das andere Ende geöffnet wird. Solange also die traffic-FIFO nicht geöffnet wird, blockieren die tee
-Prozesse, was das ganze Konstrukt aufhält.
Mit iperf kann man sehr einfach sein Netzwerk benchmarken. Dazu startet man auf einem Computer einen iperf-Server:
$ iperf -s
------------------------------------------------------------
Server listening on TCP port 5001
TCP window size: 85.3 KByte (default)
------------------------------------------------------------
Und auf einem anderen Computer startet man den iperf-Client und gibt den Server an (in diesem Fall rpi):
$ iperf -c rpi
------------------------------------------------------------
Client connecting to rpi, TCP port 5001
TCP window size: 85.0 KByte (default)
------------------------------------------------------------
[ 3] local 192.168.178.170 port 39890 connected with 192.168.178.28 port 5001
[ ID] Interval Transfer Bandwidth
[ 3] 0.0-10.0 sec 114 MBytes 95.5 Mbits/sec
Man sieht, ein Raspberry Pi 1 kann sein 100 Mbit/s LAN gut auslasten. Allerdings hat das bei mir auch zu 75% CPU-Last geführt.
Gigabit-Ethernet gibt es jetzt schon lange (der Standard für 1000BASE-T ist von 1999) und lange Zeit war es ausreichend, zumindestens im Consumerbereich. Mit einzelnen Festplatten hat man selbst bei sequenziellen Schreib- und Leseoperationen weniger als 100 Mb/s geschafft. Seit ein paar Jahren sieht das jedoch schon anders aus. SSDs sind weit verbreitet und selbst gammelige Festplatten lasten GbE voll aus. Da bald selbst WLAN schneller als 1 Gbit/s ist, wäre es eigentlich an der Zeit, dass sich 10 GbE auch im Consumerbereich durchsetzt.
Aber nein, das passiert wohl nicht. Stattdessen kommt Ethernet mit 2,5 und 5 Gbit/s. Wie heise berichtet gibt es sogar schon ein Switch dafür (allerdings auch nicht Consumertauglich). Der Standard für diese Ethernet-Varianten soll Mitte 2016 fertig sein. Wann es dann noch mehr Hardware gibt, vor allem passende NICs, PCs, Notebooks und Mainboards mit 5 GbE, wird natürlich spannend. Ich vermute erst dann, wenn jeder PCIe-basierte SSDs hat, die locker 1 Gb/s schreiben können und damit schon langsam 10 GbE auslasten.
Aber ich gebe zu, es ist zumindestens ein wenig Fortschritt. Lieber das, als 10 weitere Jahre mit 1 GbE.
Es kommt des Öfteren vor, dass man einen Netzwerk-Service testen, oder allgemein mit einer Anwendung über Sockets kommunizieren möchte. Viele verwenden dafür telnet, jedoch ist das eine Zweckentfremdung des Programms. Telnet ist eigentlich ein Fernwartungstool, das heute nur noch selten eingesetzt wird, weil es unsicher ist. Der Telnet-Client kann aber für die meisten textbasierten Protokolle verwendet werden. Z.B. wird telnet manchmal verwendet, um manuell einen HTTP-Request auszuführen. Es gibt jedoch ein Tool, was genau für solche Zwecke gedacht ist, nämlich netcat, das oft als "TCP/IP swiss army knife" bezeichnet wird. Netcat kann natürlich mehr als nur die Standardeingabe zum Server zu schicken und die Antworten auszugeben. Es unterstützt unter anderem auch UDP, es kann als Server verwendet werden und im Gegensatz zu telnet kann netcat mit Pipes und Redirections umgehen.
Ein typischer Anwendungsfall ist, dass mit netcat eine Verbindung zu einem Server aufgebaut wird, die Standardeingabe von Netcat an den Server geschickt wird und die Antwort vom Server ausgegeben wird. Im folgendem Beispiel wird eine Verbindung zu einem Webserver hergestellt und ein HTTP-Request abgeschickt.
$ nc unixwork.de 80
GET / HTTP/1.1
Host: unixwork.de
HTTP/1.1 307 Temporary Redirect
Server: Apache-Coyote/1.1
Location: /blog/
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 0
Date: Wed, 05 Nov 2014 20:14:29 GMT
...
Ein weiteres und komplexeres Beispiel sei der Wikipedia entlehnt:
{ echo -ne "HTTP/1.0 200 OK\r\n\
Content-Length: $(wc -c < some.file)\r\n\r\n";\
cat some.file; } | nc -l 8080
Fertig ist ein kleiner Webserver, der eine Datei überträgt.
Es gibt mitlerweile viele Varianten von netcat, unter anderem auch welche, die SSL unterstützen. Für Windows ist netcat ebenfalls erhältlich.