So richten Sie eine Iptables-Firewall zum Schutz des Datenverkehrs zwischen Ihren Servern ein

Einführung

Das Bereitstellen diskreter Komponenten in der Anwendungskonfiguration auf verschiedenen Knoten ist eine gängige Methode, um die Last zu verringern und mit der horizontalen Skalierung zu beginnen. Ein typisches Beispiel ist die Konfiguration einer Datenbank auf einem von Ihrer Anwendung getrennten Server. Obwohl dieses Setup eine Reihe von Vorteilen bietet, wirft das Herstellen einer Verbindung über ein Netzwerk neue Sicherheitsbedenken auf.

In diesem Handbuch wird gezeigt, wie Sie eine einfache Firewall auf jedem Ihrer Server in einem verteilten Setup einrichten. Wir werden unsere Richtlinie so konfigurieren, dass legitimer Verkehr zwischen unseren Komponenten zugelassen wird, während anderer Verkehr abgelehnt wird.

Für die Demonstration in diesem Handbuch werden zwei Ubuntu 14.04-Server verwendet. Eine WordPress-Instanz wird mit Nginx bereitgestellt und die andere hostet die MySQL-Datenbank für die Anwendung. Obwohl wir dieses Setup als Beispiel verwenden, sollten Sie in der Lage sein, die beteiligten Techniken zu extrapolieren, um Ihren eigenen Serveranforderungen zu entsprechen.

Voraussetzungen

Um loszulegen, müssen Sie zwei neue Ubuntu 14.04-Server haben. Fügen Sie ein reguläres Benutzerkonto mit jeweilssudoBerechtigungen hinzu. Um zu lernen, wie man das richtig macht, folgen Sie unserenUbuntu 14.04 initial server setup guide.

Das Anwendungssetup, das wir sichern werden, basiert aufthis guide. Wenn Sie mitmachen möchten, richten Sie Ihre Anwendungs- und Datenbankserver wie in diesem Lernprogramm angegeben ein.

Einrichten einer Basisfirewall

Wir beginnen mit der Implementierung einer Firewall-Basiskonfiguration für jeden unserer Server. Die Richtlinie, die wir implementieren, verfolgt einen Ansatz, bei dem Sicherheit an erster Stelle steht. Wir werden fast alles außer SSH-Verkehr sperren und dann Löcher in die Firewall für unsere spezifische Anwendung stechen.

Die Firewall inthis guide bietet die Grundkonfiguration, die wir benötigen. Installieren Sie das Paketiptables-persistent und fügen Sie die Grundregeln in die Datei/etc/iptables/rules.v4ein:

sudo apt-get update
sudo apt-get install iptables-persistent
sudo nano /etc/iptables/rules.v4

/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

# 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]
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

Wenn Sie dies in einer Live-Umgebung implementierendo not reload your firewall rules yet. Durch das Laden des hier beschriebenen Grundregelsatzes wird die Verbindung zwischen Ihrer Anwendung und dem Datenbankserver sofort getrennt. Wir müssen die Regeln anpassen, um sie unseren betrieblichen Erfordernissen anzupassen, bevor wir sie erneut laden.

Entdecken Sie die Ports, die von Ihren Diensten verwendet werden

Um Ausnahmen hinzuzufügen, um die Kommunikation zwischen unseren Komponenten zu ermöglichen, müssen wir die verwendeten Netzwerkports kennen. Wir konnten die richtigen Netzwerkports anhand unserer Konfigurationsdateien ermitteln. Eine anwendungsunabhängige Methode zum Ermitteln der richtigen Ports besteht jedoch darin, nur zu überprüfen, welche Dienste auf den einzelnen Computern auf Verbindungen warten.

Wir können das Toolnetstatverwenden, um dies herauszufinden. Da unsere Anwendung nur über IPv4 kommuniziert, fügen wir das Argument-4hinzu. Sie können dies jedoch entfernen, wenn Sie auch IPv6 verwenden. Die anderen Argumente, die wir benötigen, um unsere laufenden Dienste zu finden, sind-plunt.

Auf Ihrem Webserver sehen wir ungefähr Folgendes:

sudo netstat -4plunt
OutputActive Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1058/sshd
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      4187/nginx

Die erste hervorgehobene Spalte zeigt die IP-Adresse und den Port an, die der Dienst am Ende der Leitung abhört. Die spezielle0.0.0.0-Adresse bedeutet, dass der betreffende Dienst alle verfügbaren Adressen abhört.

Auf unserem Datenbankserver würden wir so etwas sehen:

sudo netstat -4plunt
OutputActive Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1097/sshd
tcp        0      0 192.0.2.30:3306     0.0.0.0:*               LISTEN      3112/mysqld

Sie können diese Spalten genauso lesen. Im obigen Beispiel repräsentiert die Adresse von192.0.2.30die private IP-Adresse des Datenbankservers. Im Setup der Anwendung haben wir MySQL aus Sicherheitsgründen auf die private Oberfläche beschränkt.

Notieren Sie sich die Werte, die Sie in diesem Schritt finden. Dies sind die Netzwerkdetails, die wir benötigen, um unsere Firewall-Konfiguration anzupassen.

In unserem Beispielszenario können wir feststellen, dass wir auf unserem Webserver sicherstellen müssen, dass auf die folgenden Ports zugegriffen werden kann:

  • Port 80 auf allen Adressen

  • Port 22 auf allen Adressen (bereits in Firewall-Regeln berücksichtigt)

Unser Datenbankserver müsste sicherstellen, dass die folgenden Ports verfügbar sind:

  • Port 3306 an der Adresse192.0.2.30 (oder der damit verbundenen Schnittstelle)

  • Port 22 auf allen Adressen (bereits in Firewall-Regeln berücksichtigt)

Passen Sie die Firewall-Regeln des Webservers an

Nachdem wir die benötigten Portinformationen haben, werden wir den Firewall-Regelsatz unseres Webservers anpassen. Öffnen Sie die Regeldatei in Ihrem Editor mit den Berechtigungen vonsudo:

sudo nano /etc/iptables/rules.v4

Auf dem Webserver müssen wir Port 80 zu unserer Liste der zulässigen Zugriffe hinzufügen. Da der Server alle verfügbaren Adressen überwacht, wird die Regel nicht durch die Schnittstellen- oder Zieladresse eingeschränkt.

Unsere Webbesucher verwenden das TCP-Protokoll, um eine Verbindung herzustellen. Unser Basisframework verfügt bereits über eine benutzerdefinierte Kette namensTCP für TCP-Anwendungsausnahmen. Wir können dieser Kette Port 80 hinzufügen, direkt unterhalb der Ausnahme für unseren SSH-Port:

/etc/iptables/rules.v4

*filter
. . .

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

. . .

Unser Webserver wird die Verbindung zu unserem Datenbankserver herstellen. Unser ausgehender Datenverkehr ist in unserer Firewall nicht eingeschränkt und eingehender Datenverkehr im Zusammenhang mit bestehenden Verbindungen ist zulässig. Daher müssen wir keine zusätzlichen Ports auf diesem Server öffnen, um diese Verbindung zuzulassen.

Speichern und schließen Sie die Datei, wenn Sie fertig sind. Unser Webserver verfügt jetzt über eine Firewall-Richtlinie, die allen legitimen Datenverkehr zulässt und alles andere blockiert.

Testen Sie Ihre Regeldatei auf Syntaxfehler:

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

Wenn keine Syntaxfehler angezeigt werden, laden Sie die Firewall neu, um den neuen Regelsatz zu implementieren:

sudo service iptables-persistent reload

Passen Sie die Firewall-Regeln des Datenbankservers an

Auf unserem Datenbankserver müssen wir den Zugriff auf Port3306 über die private IP-Adresse unseres Servers zulassen. In unserem Fall war diese Adresse192.0.2.30. Wir können den für diese Adresse bestimmten Zugriff einschränken, oder wir können den Zugriff einschränken, indem wir eine Übereinstimmung mit der dieser Adresse zugewiesenen Schnittstelle herstellen.

Geben Sie Folgendes ein, um die dieser Adresse zugeordnete Netzwerkschnittstelle zu suchen:

ip -4 addr show scope global
Output2: eth0:  mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet 203.0.113.5/24 brd 104.236.113.255 scope global eth0
       valid_lft forever preferred_lft forever
3: eth1:  mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet 192.0.2.30/24 brd 192.0.2.255 scope global eth1
       valid_lft forever preferred_lft forever

Die hervorgehobenen Bereiche zeigen, dass dieeth1-Schnittstelle dieser Adresse zugeordnet ist.

Als nächstes werden wir die Firewall-Regeln auf dem Datenbankserver anpassen. Öffnen Sie die Regeldatei mit den Berechtigungen vonsudoauf Ihrem Datenbankserver:

sudo nano /etc/iptables/rules.v4

Wieder werden wir unsererTCP-Kette eine Regel hinzufügen, um eine Ausnahme für die Verbindung zwischen unserem Web und den Datenbankservern zu bilden.

Wenn Sie den Zugriff basierend auf der tatsächlichen Adresse einschränken möchten, fügen Sie die Regel wie folgt hinzu:

/etc/iptables/rules.v4

*filter
. . .

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

. . .

Wenn Sie die Ausnahme lieber basierend auf der Schnittstelle zulassen möchten, die diese Adresse enthält, können Sie stattdessen eine Regel hinzufügen, die der folgenden ähnelt:

/etc/iptables/rules.v4

*filter
. . .

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

. . .

Speichern und schließen Sie die Datei, wenn Sie fertig sind.

Suchen Sie mit diesem Befehl nach Syntaxfehlern:

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

Wenn Sie fertig sind, laden Sie die Firewall-Regeln neu:

sudo service iptables-persistent reload

Ihre beiden Server sollten jetzt geschützt sein, ohne den erforderlichen Datenfluss zwischen ihnen einzuschränken.

Fazit

Die Implementierung einer ordnungsgemäßen Firewall sollte beim Einrichten einer Anwendung immer Teil Ihres Bereitstellungsplans sein. Obwohl wir diese Konfiguration mit den beiden Servern demonstriert haben, auf denen Nginx und MySQL ausgeführt werden, um eine WordPress-Instanz bereitzustellen, sind die oben gezeigten Techniken unabhängig von Ihren spezifischen Technologiewahlen anwendbar.

Weitere Informationen zu Firewalls undiptablesfinden Sie in den folgenden Handbüchern: