So leiten Sie Ports über ein Linux-Gateway mit Iptables weiter

Einführung

  • NAT * (Network Address Translation) ist ein allgemeiner Begriff für das Verwirren von Paketen, um sie an eine alternative Adresse umzuleiten. In der Regel wird dies verwendet, um den Datenverkehr über Netzwerkgrenzen hinweg zuzulassen. Ein Host, der NAT implementiert, hat normalerweise Zugriff auf zwei oder mehr Netzwerke und ist so konfiguriert, dass der Datenverkehr zwischen ihnen weitergeleitet wird.

  • Portweiterleitung * ist das Weiterleiten von Anforderungen für einen bestimmten Port an einen anderen Host, ein anderes Netzwerk oder einen anderen Port. Da dieser Prozess das Ziel des Pakets während des Flugs ändert, wird er als eine Art NAT-Operation betrachtet.

In diesem Handbuch wird gezeigt, wie mit "+ iptables +" Ports mithilfe von NAT-Techniken an Hosts hinter einer Firewall weitergeleitet werden. Dies ist nützlich, wenn Sie ein privates Netzwerk konfiguriert haben, aber dennoch bestimmten Datenverkehr über einen bestimmten Gateway-Computer zulassen möchten. Wir werden zwei Ubuntu 14.04-Hosts verwenden, um dies zu demonstrieren.

Voraussetzungen und Ziele

Um diesem Handbuch folgen zu können, benötigen Sie zwei Ubuntu 14.04-Hosts im selben Rechenzentrum mit aktiviertem privaten Netzwerk. Auf jedem dieser Computer müssen Sie ein Nicht-Root-Benutzerkonto mit den Rechten "+ sudo " einrichten. Sie erfahren, wie Sie einen Benutzer mit den Rechten " sudo +" erstellen, indem Sie unserer Ubuntu 14.04 anfänglichen Server-Setup folgen leiten.

Der erste Host fungiert als Firewall und Router für das private Netzwerk. Zu Demonstrationszwecken wird der zweite Host mit einem Webserver konfiguriert, auf den nur über seine private Schnittstelle zugegriffen werden kann. Wir werden den Firewall-Computer so konfigurieren, dass auf seiner öffentlichen Schnittstelle empfangene Anforderungen an den Webserver weitergeleitet werden, den er auf seiner privaten Schnittstelle erreicht.

Host-Details

Bevor Sie beginnen, müssen wir wissen, welche Schnittstellen und Adressen von unseren beiden Servern verwendet werden.

Finden Ihrer Netzwerkdetails

Um die Details Ihrer eigenen Systeme zu erhalten, suchen Sie zunächst Ihre Netzwerkschnittstellen. Sie finden die Schnittstellen auf Ihren Maschinen und die damit verbundenen Adressen, indem Sie Folgendes eingeben:

ip -4 addr show scope global
Sample Output2: : <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
   inet /18 brd 45.55.191.255 scope global eth0
      valid_lft forever preferred_lft forever
3: : <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
   inet /16 brd 10.132.255.255 scope global eth1
      valid_lft forever preferred_lft forever

Die oben hervorgehobene Ausgabe zeigt zwei Schnittstellen ("+ eth0 " und " eth1 ") und die jeweils zugewiesenen Adressen (" 192.51.100.45 " und " 192.168.1.5 +"). Um herauszufinden, welche dieser Schnittstellen Ihre öffentliche Schnittstelle ist, geben Sie Folgendes ein:

ip route show | grep default
Outputdefault via 111.111.111.111

Die gezeigte Schnittstelle (+ eth0 + in diesem Beispiel) ist die Schnittstelle, die mit Ihrem Standard-Gateway verbunden ist. Dies ist mit ziemlicher Sicherheit Ihre öffentliche Schnittstelle.

Suchen Sie diese Werte auf jeder Ihrer Maschinen und verwenden Sie sie, um diese Anleitung korrekt zu befolgen.

Beispieldaten für dieses Handbuch

Um das Verfolgen zu vereinfachen, verwenden wir in diesem Lernprogramm die folgenden Dummy-Adress- und Schnittstellenzuweisungen. Bitte ersetzen Sie die unten angezeigten Werte durch Ihre eigenen:

Details zum Webserver-Netzwerk:

  • Öffentliche IP-Adresse: ++

  • Private IP-Adresse: ++

  • Öffentliche Schnittstelle: ++

  • Private Schnittstelle: ++

Firewall-Netzwerkdetails:

  • Öffentliche IP-Adresse: ++

  • Private IP-Adresse: ++

  • Öffentliche Schnittstelle: ++

  • Private Schnittstelle: ++

Einrichten des Webservers

Wir beginnen mit unserem Webserver-Host. Melden Sie sich mit Ihrem Benutzer "+ sudo +" an, um zu beginnen.

Installieren Sie Nginx

Der erste Vorgang, den wir abschließen werden, besteht darin, "+ Nginx +" auf unserem Webserver-Host zu installieren und zu sperren, so dass nur die private Schnittstelle abgehört wird. Dadurch wird sichergestellt, dass unser Webserver nur verfügbar ist, wenn wir die Portweiterleitung korrekt eingerichtet haben.

Aktualisieren Sie zunächst den lokalen Paket-Cache und laden Sie die Software mit + apt + herunter und installieren Sie sie:

sudo apt-get update
sudo apt-get install nginx

Beschränken Sie Nginx auf das private Netzwerk

Nach der Installation von Nginx öffnen wir die Standard-Serverblock-Konfigurationsdatei, um sicherzustellen, dass nur die private Schnittstelle abgehört wird. Öffne die Datei jetzt:

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

Im Inneren finden Sie die Anweisung "+ listen +". Sie sollten es zweimal hintereinander oben in der Konfiguration finden:

/ etc / nginx / sites-enabled / default

server {
   listen 80 default_server;
   listen [::]:80 default_server ipv6only=on;

   . . .
}

Fügen Sie bei der ersten Anweisung "+ listen " die private IP-Adresse Ihres Web-Servers und einen Doppelpunkt vor " 80 +" ein, um Nginx anzuweisen, nur die private Schnittstelle abzuhören. In diesem Handbuch wird nur die IPv4-Weiterleitung demonstriert, sodass wir die zweite Abhöranweisung entfernen können, die für IPv6 konfiguriert ist.

In unserem Beispiel würden wir die Listen-Direktiven folgendermaßen ändern:

/ etc / nginx / sites-enabled / default

server {
   listen :80 default_server;

   . . .
}

Speichern und schließen Sie die Datei, wenn Sie fertig sind. Testen Sie die Datei auf Syntaxfehler, indem Sie Folgendes eingeben:

sudo nginx -t

Wenn keine Fehler angezeigt werden, starten Sie Nginx neu, um die neue Konfiguration zu aktivieren:

sudo service nginx restart

Überprüfen Sie die Netzwerkeinschränkung

An dieser Stelle ist es hilfreich, den Grad des Zugriffs auf unseren Webserver zu überprüfen.

Wenn wir von unserem * Firewall * -Server aus versuchen, über die private Schnittstelle auf unseren Webserver zuzugreifen, sollte dies funktionieren:

curl --connect-timeout 5
Output<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
   body {
       width: 35em;
       margin: 0 auto;
       font-family: Tahoma, Verdana, Arial, sans-serif;
   }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
. . .

Wenn wir versuchen, die öffentliche Schnittstelle zu verwenden, werden wir feststellen, dass wir keine Verbindung herstellen können:

curl --connect-timeout 5
curl: (7) Failed to connect to 203.0.113.2 port 80: Connection refused

Genau das erwarten wir.

Konfigurieren der Firewall zum Weiterleiten von Port 80

Jetzt können wir die Portweiterleitung auf unserer Firewall-Maschine implementieren.

Weiterleitung im Kernel aktivieren

Als erstes müssen wir die Weiterleitung des Datenverkehrs auf Kernel-Ebene aktivieren. Standardmäßig ist die Weiterleitung auf den meisten Systemen deaktiviert.

Geben Sie Folgendes ein, um die Portweiterleitung nur für diese Sitzung zu aktivieren:

echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward

Um die Portweiterleitung dauerhaft zu aktivieren, müssen Sie die Datei "+ / etc / sysctl.conf " bearbeiten. Öffnen Sie die Datei mit den Privilegien " sudo +", indem Sie Folgendes eingeben:

sudo nano /etc/sysctl.conf

Suchen Sie die Zeile, die folgendermaßen aussieht, und kommentieren Sie sie aus:

/etc/sysctl.conf

net.ipv4.ip_forward=1

Speichern und schließen Sie die Datei, wenn Sie fertig sind. Sie wenden die Einstellungen in dieser Datei an, indem Sie Folgendes eingeben:

sudo sysctl -p
sudo sysctl --system

Einrichten der Basisfirewall

Wir werden die Firewall in this guide als verwenden das Grundgerüst für die Regeln in diesem Tutorial. Führen Sie die Anleitung jetzt auf Ihrem Firewall-Computer durch, um die Einrichtung zu starten. Am Ende haben Sie:

  • Installiertes + iptables-persistent +

  • Der Standardregelsatz wurde in "+ / etc / iptables / rules.v4 +" gespeichert

  • Erfahren Sie, wie Sie Regeln hinzufügen oder anpassen, indem Sie die Regeldatei bearbeiten oder den Befehl + iptables + verwenden

Wenn Sie die grundlegende Firewall eingerichtet haben, fahren Sie unten fort, damit wir sie für die Portweiterleitung anpassen können.

Hinzufügen der Weiterleitungsregeln

Wir möchten unsere Firewall so konfigurieren, dass der Datenverkehr, der über Port 80 in unsere öffentliche Schnittstelle ("+ eth0 ") fließt, an unsere private Schnittstelle (" eth1 +") weitergeleitet wird.

In unserer Basis-Firewall ist die Kette "+ FORWARD " standardmäßig auf " DROP +" eingestellt. Wir müssen Regeln hinzufügen, die es uns ermöglichen, Verbindungen zu unserem Webserver weiterzuleiten. Aus Sicherheitsgründen sperren wir dies ziemlich genau, sodass nur die Verbindungen zugelassen werden, die wir weiterleiten möchten.

In der "+ FORWARD " - Kette akzeptieren wir neue Verbindungen für Port 80, die von unserer öffentlichen Schnittstelle zu unserer privaten Schnittstelle gelangen. Neue Verbindungen sind durch die Erweiterung " conntrack +" gekennzeichnet und werden speziell durch ein TCP-SYN-Paket dargestellt:

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

Dadurch wird das erste Paket, das eine Verbindung herstellen soll, durch die Firewall geleitet. Wir müssen auch jeden nachfolgenden Verkehr in beide Richtungen zulassen, der sich aus dieser Verbindung ergibt. Geben Sie Folgendes ein, um Datenverkehr zwischen unseren öffentlichen und privaten Schnittstellen zuzulassen:

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

Wir können überprüfen, ob unsere Richtlinie für die Kette "+ FORWARD " auf " DROP" gesetzt ist, indem wir Folgendes eingeben:

sudo iptables -P FORWARD DROP

Zu diesem Zeitpunkt haben wir bestimmten Datenverkehr zwischen unseren öffentlichen und privaten Schnittstellen über unsere Firewall zugelassen. Wir haben jedoch noch keine Regeln konfiguriert, die angeben, wie der Datenverkehr übersetzt und geleitet werden soll.

Richtiges Hinzufügen der NAT-Regeln zu Direct Packets

Als nächstes werden wir die Regeln hinzufügen, die "+ iptables" mitteilen, wie unser Verkehr weitergeleitet werden soll. Wir müssen zwei separate Operationen ausführen, damit "+ iptables +" die Pakete korrekt ändert, damit Clients mit dem Webserver kommunizieren können.

Die erste Operation mit dem Namen "+ DNAT" findet in der "+ PREROUTING" -Kette der "+ nat " -Tabelle statt. ` DNAT +` ist eine Operation, mit der die Zieladresse eines Pakets geändert wird, damit es bei der Übertragung zwischen Netzwerken korrekt weitergeleitet werden kann. Die Clients im öffentlichen Netzwerk stellen eine Verbindung zu unserem Firewall-Server her und haben keine Kenntnis von unserer privaten Netzwerktopologie. Wir müssen die Zieladresse jedes Pakets so ändern, dass es, wenn es in unserem privaten Netzwerk versendet wird, weiß, wie es unseren Webserver korrekt erreicht.

Da wir nur die Portweiterleitung konfigurieren und nicht NAT für jedes Paket ausführen, das auf unsere Firewall trifft, möchten wir Port 80 in unserer Regel zuordnen. Wir werden Pakete, die auf Port 80 abzielen, mit der privaten IP-Adresse unseres Webservers abgleichen (+ 192.0.2.2 + in unserem Beispiel):

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

Das macht die Hälfte des Bildes aus. Das Paket sollte korrekt an unseren Webserver weitergeleitet werden. Derzeit hat das Paket jedoch immer noch die ursprüngliche Adresse des Clients als Quelladresse. Der Server versucht, die Antwort direkt an diese Adresse zu senden, wodurch es unmöglich wird, eine legitime TCP-Verbindung herzustellen.

Note

Um das richtige Routing zu konfigurieren, müssen wir auch die Quelladresse des Pakets ändern, da es die Firewall auf dem Weg zum Webserver verlässt. Wir müssen die Quelladresse an die private IP-Adresse unseres Firewall-Servers anpassen (+ 192.0.2.15 + in unserem Beispiel). Die Antwort wird dann an die Firewall zurückgesendet, die sie erwartungsgemäß an den Client weiterleiten kann.

Um diese Funktionalität zu aktivieren, fügen wir der "+ POSTROUTING " - Kette der " nat +" - Tabelle eine Regel hinzu, die ausgewertet wird, bevor Pakete im Netzwerk gesendet werden. Wir stimmen die für unseren Webserver bestimmten Pakete nach IP-Adresse und Port ab:

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

Sobald diese Regel eingeführt ist, sollte unser Webserver erreichbar sein, indem Sie unseren Webbrowser auf die öffentliche Adresse unseres Firewall-Computers richten:

curl
Output<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
   body {
       width: 35em;
       margin: 0 auto;
       font-family: Tahoma, Verdana, Arial, sans-serif;
   }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
. . .

Die Einrichtung der Portweiterleitung ist abgeschlossen.

Anpassen des permanenten Regelsatzes

Nachdem wir die Portweiterleitung eingerichtet haben, können wir diese in unserem permanenten Regelsatz speichern.

Wenn Sie die Kommentare in Ihrem aktuellen Regelsatz nicht verlieren möchten, speichern Sie Ihre Regeln mit dem Dienst "+ iptables-persistent":

sudo service iptables-persistent save

Wenn Sie die Kommentare in Ihrer Datei behalten möchten, öffnen Sie sie und bearbeiten Sie sie manuell:

sudo nano /etc/iptables/rules.v4

Sie müssen die Konfiguration in der Tabelle "+ filter " für die hinzugefügten " FORWARD " - Kettenregeln anpassen. Sie müssen auch den Abschnitt anpassen, der die " nat " - Tabelle konfiguriert, damit Sie Ihre " PREROUTING " - und " POSTROUTING +" - Regeln hinzufügen können. In unserem Beispiel würde es ungefähr so ​​aussehen:

/etc/iptables/rules.v4

*filter
# Allow all outgoing, but drop incoming and forwarding packets by default
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]

# Custom per-protocol chains
:UDP - [0:0]
:TCP - [0:0]
:ICMP - [0:0]

# Acceptable UDP traffic

# Acceptable TCP traffic
-A TCP -p tcp --dport 22 -j ACCEPT

# Acceptable ICMP traffic

# Boilerplate acceptance policy
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
-A INPUT -i lo -j ACCEPT

# Drop invalid packets
-A INPUT -m conntrack --ctstate INVALID -j DROP

# Pass traffic to protocol-specific chains
## Only allow new connections (established and related should already be handled)
## For TCP, additionally only allow new SYN packets since that is the only valid
## method for establishing a new TCP connection
-A INPUT -p udp -m conntrack --ctstate NEW -j UDP
-A INPUT -p tcp --syn -m conntrack --ctstate NEW -j TCP
-A INPUT -p icmp -m conntrack --ctstate NEW -j ICMP

# Reject anything that's fallen through to this point
## Try to be protocol-specific w/ rejection message
-A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
-A INPUT -p tcp -j REJECT --reject-with tcp-reset
-A INPUT -j REJECT --reject-with icmp-proto-unreachable



# Web server network details:

# * Public IP Address:
# * Private IP Address:
# * Public Interface:
# * Private Interface:
#
# Firewall network details:
#
# * Public IP Address:
# * Private IP Address:
# * Public Interface:
# * Private Interface:
-A FORWARD -i eth0 -o eth1 -p tcp --syn --dport 80 -m conntrack --ctstate NEW -j ACCEPT
-A FORWARD -i eth0 -o eth1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
-A FORWARD -i eth1 -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT


# Commit the changes

COMMIT

*raw
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT

*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]





# Web server network details:

# * Public IP Address:
# * Private IP Address:
# * Public Interface:
# * Private Interface:
#
# Firewall network details:
#
# * Public IP Address:
# * Private IP Address:
# * Public Interface:
# * Private Interface:
-A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination
-A POSTROUTING -d  -o eth1 -p tcp --dport 80 -j SNAT --to-source

COMMIT

*security
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT

*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
COMMIT

Speichern und schließen Sie die Datei, nachdem Sie die obigen Angaben hinzugefügt und die Werte an Ihre eigene Netzwerkumgebung angepasst haben.

Testen Sie die Syntax Ihrer Regeldatei, indem Sie Folgendes eingeben:

sudo iptables-restore -t < /etc/iptables/rules.v4

Wenn keine Fehler festgestellt werden, laden Sie den Regelsatz:

sudo service iptables-persistent reload

Testen Sie, ob auf Ihren Webserver über die öffentliche IP-Adresse Ihrer Firewall weiterhin zugegriffen werden kann:

curl

Dies sollte genauso funktionieren wie zuvor.

Fazit

Inzwischen sollten Sie mit dem Weiterleiten von Ports auf einem Linux-Server mit "+ iptables " vertraut sein. Der Prozess umfasst das Zulassen der Weiterleitung auf Kernelebene, das Einrichten des Zugriffs zum Weiterleiten des Datenverkehrs eines bestimmten Ports zwischen zwei Schnittstellen des Firewall-Systems und das Konfigurieren der NAT-Regeln, damit die Pakete korrekt weitergeleitet werden können. Dies scheint ein unhandlicher Prozess zu sein, zeigt aber auch die Flexibilität des " netfilter " - Paketfilter-Frameworks und der " iptables +" - Firewall. Dies kann verwendet werden, um die Topologie Ihres privaten Netzwerks zu verschleiern, während der Dienstverkehr ungehindert durch Ihren Gateway-Firewall-Computer fließen kann.