Linux Port-Forwarding mit Iptables

In diesem Beitrag werden wir zwei Ubuntu Systeme verwenden, um über Iptables Ports mit Hilfe der NAT-Technik an Computer hinter einer Firewall zu leiten.

Begriffe

Bevor wir den Beitrag beginnen, möchten wir noch zwei Begriffe erklären, die zum Verständnis des Beitrags wichtig sind:

Port forwarding (Portweiterleitung)

Eine Portweiterleitung ist eine Möglichkeit, einen Computer im Heim- oder Firmennetzwerk für fremde Systeme im Internet zugänglich zu machen, auch wenn sie sich hinter einem Router befinden. Es wird häufig für Spiele, Sicherheitskameras, Internet-Telefonanlagen (VoIP) und das Herunterladen von Dateien verwendet.

Network Address Translation (NAT)

Network Address Translation, kurz auch “NAT”, ist der Prozess, bei dem ein Netzwerkgerät, einem Computer innerhalb eines privaten Netzwerks eine öffentliche Adresse zuweist. Die Hauptanwendung von NAT besteht darin, die Anzahl der öffentlichen IP-Adressen zu begrenzen, die eine Organisation oder ein Unternehmen verwenden muss, sowohl aus Gründen der Wirtschaftlichkeit als auch der Sicherheit. Ein System, welches NAT implementiert, hat in der Regel Zugang zu zwei oder mehr Netzwerken und ist so konfiguriert, dass er den Datenverkehr zwischen ihnen leitet.


Vorbereitungsmaßnahmen

Um dieser Anleitung zu folgen, benötigst du zwei Ubuntu Rechner im selben Rechenzentrum oder Computernetzwerk mit aktiviertem privaten Netzwerk. Auf jedem dieser Rechner musst ein Nicht-Root-Benutzer mit “sudo”-Rechten eingerichtet sein.

Der erste Host wird als Firewall und für das private Netzwerk genutzt. Zur besseren Veranschaulichung, wird der zweite Host mit einem Nginx Webserver konfiguriert. Wir werden die Firewall bzw. den ersten Host so konfigurieren, dass diese die Anfragen aus dem öffentlichen Netz annimmt und an den Webserver weiterleitet, welcher normalerweise nur aus dem privaten Netz erreichbar ist.

Adressen

Damit wir die Firewall und das Netz vollständig einrichten können, ist es notwendig, dass du sowohl die öffentlichen, als auch privaten Netzwerkadressen und Interfaces von deinen Hostsystemen kennst.
Wir verwenden in diesem Beitrag nur Beispiel-Adressen. Tausche diese bitte in deiner Einrichtung, mit deinen echten Daten aus!

WebServer

Öffentliche IP-Adresse203.0.113.18
Private IP-Adresse192.168.14.2
Öffentliches Netzwerk-Interfaceeth0
Private Netzwerk-Interfaceeth1

Firewall

Öffentliche IP-Adresse203.0.113.55
Private IP-Adresse192.168.14.99
Öffentliches Netzwerk-Interfaceeth0
Private Netzwerk-Interfaceeth1

Webserver

Wir beginnen mit der Einrichtung des WebServers. Wir installieren dazu Nginx auf diesem Server. Dazu meldest du dich auf den Server an und gibst folgende Befehle ein:

sudo apt-get update
sudo apt-get install nginx

Danach prüfen wir, ob der Webserver nur auf sein lokales Netz hört und das öffentliche Netz ignoriert, da wir dieses nur über unsere Firwall betreten lassen wollen.

sudo nano /etc/nginx/sites-enabled/default

Hier findest du die Nginx Konfiguration, in welchem alle “listen” tags entfernt werden müssen und nur noch die IP Adresse als hörende Adresse angegeben werden muss. Dies sollte wie folgt aussehen:

server {
    listen 192.168.14.2:80 default_server;
...

Speichere das File ab und kontrolliere die Nginx Konfiguration mit sudo nginx -t

Sollte es zu keinen Fehlern kommen, kann der Nginx Webserver mit sudo service nginx restart neugestartet werden.

Netzwerkbeschränkung testen

An diesem Punkt ist es sinnvoll, die Zugriffsrechte auf unseren Webserver zu überprüfen.

Wenn wir von unserem Firewall-Server aus versuchen, über das private Interface auf unseren Webserver zuzugreifen, sollte es funktionieren. Teste dies nun als über folgende Befehle auf dem Firewall Server aus:

curl --connect-timeout 5 192.168.14.2

Es erscheint der HTML Code der Nginx Demoseite:

Beim versuch auf die öffentliche IP-Adresse zuzugreifen, kommt der Fehler “Connection refused”.

Also genau das, was passieren sollte.

Firewall konfigurieren

Jetzt können wir mit der eigentlichen Funktion der Firewall beginnen und die Portweiterleitung auf die interne Server IP von unserem Webserver starten. Dazu muss du zuerst auf dem Linux Kernel das Forwarding aktivieren. Damit dies permanent geschieht, muss die sysctl Konfiguration bearbeiten werden.

sudo nano /etc/sysctl.conf

Dort suchst du die Zeile “net.ipv4.ip_forward=1” und entfernst die Raute ( # ) davor. Speichere und verlasse danach die Konfiguration und wende die neue Konfiguration auf das System an:

sudo sysctl -p
sudo sysctl --system

Hinzufügen der Weiterleitungsregeln

Wir wollen unsere Firewall so konfigurieren, dass der Datenverkehr, der an unserem öffentlichen Interface (eth0) auf Port 80 ankommt, an unser privates Interface (eth1) weitergeleitet wird.

Unsere Basis-Firewall hat eine FORWARD-Chain, die standardmäßig auf DROP eingestellt ist, also alle Pakete verwirft. Wir müssen Regeln hinzufügen, die es uns erlauben, Verbindungen zu unserem Webserver weiterzuleiten. Aus Sicherheitsgründen werden wir die Regeln ziemlich eng fassen, so dass nur die Verbindungen erlaubt sind, die wir weiterleiten wollen.

In der FORWARD-Chain werden wir neue Verbindungen akzeptieren, die für Port 80 bestimmt sind und von unserem öffentlichen Interface zu unserem privaten Interface gehen. Neue Verbindungen werden durch die conntrack-Erweiterung identifiziert und speziell durch ein TCP SYN-Paket repräsentiert:

sudo iptables -A FORWARD -i eth0 -o eth1 -p tcp --syn --dport 80 -m conntrack --ctstate NEW -j ACCEPT

Dadurch wird das erste Paket, das eine Verbindung aufbauen soll, durch die Firewall gelassen. Wir müssen auch jeden nachfolgenden Verkehr in beide Richtungen erlauben, der aus dieser Verbindung resultiert. Um ESTABLISHED und RLEATED Verkehr zwischen unseren öffentlichen und privaten Interfaces zu erlauben, gebe folgende Befehle ein:

iptables -A FORWARD -i eth0 -o eth1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i eth1 -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

NAT-Regeln

Als Nächstes fügen wir die NAT-Regeln hinzu, die dem iptable sagen, wie es unseren Datenverkehr weiterleiten soll. Wir müssen zwei separate Operationen durchführen, damit iptables die Pakete korrekt umleiten kann, damit die Clients mit dem Webserver kommunizieren können.

Die erste Operation nennt sich DNAT. DNAT ist eine Operation, die die Zieladresse eines Pakets verändert, damit es auf dem Weg zwischen den Netzwerken korrekt geroutet werden kann. Die Clients im öffentlichen Netzwerk verbinden sich mit unserem Firewall-Server und haben keine Kenntnis über die Topologie unseres privaten Netzwerks. Wir müssen die Zieladresse jedes Pakets ändern, damit es, wenn es in unser privates Netzwerk gesendet wird, unseren Webserver korrekt erreichen kann.

Wir werden nun die Pakete, die auf Port 80 gerichtet sind, der privaten IP-Adresse unseres Webservers zuordnen:

sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 192.168.14.2

Das Paket sollte korrekt an unseren Webserver weitergeleitet werden. Allerdings wird das Paket jetzt immer noch die ursprüngliche Adresse des Clients als Quelladresse haben. Der Server wird versuchen, die Antwort direkt an diese Adresse zu senden, was es unmöglich macht, eine legitime TCP-Verbindung aufzubauen, da er diese über den Firewall-Server zurücksenden muss.

Um das richtige Routing zu konfigurieren, müssen wir auch die Quelladresse des Pakets ändern, wenn es die Firewall auf dem Weg zum Webserver verlässt. Wir müssen die Quelladresse auf die private IP-Adresse unseres Firewall-Servers ändern. Die Antwort wird dann zurück an die Firewall gesendet, die sie dann wie erwartet an den Client weiterleiten kann.

Um diese Funktionalität zu aktivieren, fügen wir eine Regel zur POSTROUTING-Chain der NAT-Tabelle hinzu, die abgefragt wird, bevor die Pakete auf das Netzwerk gesendet werden. Wir werden die Pakete, die für unseren Webserver bestimmt sind, nach IP-Adresse und Port abgleichen:

sudo iptables -t nat -A POSTROUTING -o eth1 -p tcp --dport 80 -d 192.168.14.2 -j SNAT --to-source 192.168.14.99

Wenn wir nun den Quellcode erneut abfragen ( curl 203.0.113.55 ), erhalten wir den Quellcode der Nginx Demoseite, zu erkennen an dem Titel “Welcome to nginx!”

Speichern der Regeln

Damit die Firewall Regeln auch nach einem Reboot noch in Kraft treten, müssen diese permanent gespeichert werden. Wie dies funktioniert, haben wir in diesem Wissensdatenbank-Artikel bereits erklärt: https://devstorage.eu/wissensdatenbank/iptables-firewall-regeln-permanent-speichern/

Quellen


https://www.nginx.com/
https://wiki.ubuntuusers.de/Portweiterleitung/

administrator
X