Ich habe eine ziemlich einfache iptables-Firewall auf einem Server, der MySQL-Dienste bereitstellt, aber iptables scheint mir sehr inkonsistente Ergebnisse zu liefern.
Die Standardrichtlinie für das Skript lautet wie folgt:
iptables -P INPUT DROP
Ich kann MySQL dann mit der folgenden Regel öffentlich machen:
iptables -A INPUT -p tcp --dport 3306 -j ACCEPT
Mit dieser Regel kann ich problemlos von jeder Quell-IP zu jeder Ziel-IP auf dem Server eine Verbindung zu MySQL herstellen. Wenn ich jedoch versuche, den Zugriff auf nur drei IPs zu beschränken, indem ich die obige Zeile durch die folgende ersetze, stoße ich auf Probleme (xxx = maskierter Oktekt):
iptables -A INPUT -p tcp --dport 3306 -m state --state NEW -s 208.XXX.XXX.184 -j ACCEPT
iptables -A INPUT -p tcp --dport 3306 -m state --state NEW -s 208.XXX.XXX.196 -j ACCEPT
iptables -A INPUT -p tcp --dport 3306 -m state --state NEW -s 208.XXX.XXX.251 -j ACCEPT
Sobald die oben genannten Regeln vorhanden sind, geschieht Folgendes:
Ich kann von den Hosts .184, .196 und .251 aus eine Verbindung zum MySQL-Server herstellen, sofern ich eine Verbindung zum MySQL-Server mit seiner Standard-IP-Adresse oder einem IP-Alias im selben Subnetz wie die Standard-IP-Adresse herstelle.
Ich kann keine Verbindung zu MySQL über IP-Aliase herstellen, die dem Server aus einem anderen Subnetz als der Standard-IP des Servers zugewiesen sind, wenn ich von den Hosts .184 oder .196 komme, aber .251 funktioniert einwandfrei. Von den .184- oder .196-Hosts hängt nur ein Telnet-Versuch ...
# telnet 209.xxx.xxx.22 3306 Trying 209.xxx.xxx.22...
Wenn ich die .251-Zeile entferne (wobei .196 die letzte hinzugefügte Regel ist), kann der .196-Host immer noch keine Verbindung zu MySQL über IP-Aliase herstellen (es ist also nicht die Reihenfolge der Regeln, die das inkonsistente Verhalten verursacht). Ich weiß, dieser spezielle Test war albern, da es keine Rolle spielen sollte, in welcher Reihenfolge diese drei Regeln hinzugefügt werden, aber ich dachte, jemand könnte fragen.
Wenn ich wieder zur "öffentlichen" Regel wechsle, können alle Hosts eine Verbindung zum MySQL-Server herstellen, indem sie entweder die Standard- oder die Alias-IPs (in beiden Subnetzen) verwenden:
iptables -A INPUT -p tcp --dport 3306 -j ACCEPT
Der Server wird in einem CentOS 5.4 OpenVZ / Proxmox-Container (2.6.32-4-pve) ausgeführt.
Und für den Fall, dass Sie die Problemregeln lieber im Kontext des iptables-Skripts sehen möchten, finden Sie sie hier (xxx = maskierter Oktekt):
# Flush old rules, old custom tables
/sbin/iptables --flush
/sbin/iptables --delete-chain
# Set default policies for all three default chains
/sbin/iptables -P INPUT DROP
/sbin/iptables -P FORWARD DROP
/sbin/iptables -P OUTPUT ACCEPT
# Enable free use of loopback interfaces
/sbin/iptables -A INPUT -i lo -j ACCEPT
/sbin/iptables -A OUTPUT -o lo -j ACCEPT
# All TCP sessions should begin with SYN
/sbin/iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
# Accept inbound TCP packets (Do this *before* adding the 'blocked' chain)
/sbin/iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Allow the server's own IP to connect to itself
/sbin/iptables -A INPUT -i eth0 -s 208.xxx.xxx.178 -j ACCEPT
# Add the 'blocked' chain *after* we've accepted established/related connections
# so we remain efficient and only evaluate new/inbound connections
/sbin/iptables -N BLOCKED
/sbin/iptables -A INPUT -j BLOCKED
# Accept inbound ICMP messages
/sbin/iptables -A INPUT -p ICMP --icmp-type 8 -j ACCEPT
/sbin/iptables -A INPUT -p ICMP --icmp-type 11 -j ACCEPT
# ssh (private)
/sbin/iptables -A INPUT -p tcp --dport 22 -m state --state NEW -s xxx.xxx.xxx.xxx -j ACCEPT
# ftp (private)
/sbin/iptables -A INPUT -p tcp --dport 21 -m state --state NEW -s xxx.xxx.xxx.xxx -j ACCEPT
# www (public)
/sbin/iptables -A INPUT -p tcp --dport 80 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# smtp (public)
/sbin/iptables -A INPUT -p tcp --dport 25 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 2525 -j ACCEPT
# pop (public)
/sbin/iptables -A INPUT -p tcp --dport 110 -j ACCEPT
# mysql (private)
/sbin/iptables -A INPUT -p tcp --dport 3306 -m state --state NEW -s 208.xxx.xxx.184 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 3306 -m state --state NEW -s 208.xxx.xxx.196 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 3306 -m state --state NEW -s 208.xxx.xxx.251 -j ACCEPT
Irgendwelche Ideen? Danke im Voraus. :-)
.184 or .196 hosts
Client-Hosts auch zusätzliche IP-Adressen in Ihrem anderen Subnetz?tcpdump -qn port 3306
Was sehen Sie, wenn Sie versuchen, eine Verbindung von einem dieser Systeme herzustellen? Sehen Sie die erwartete Quelladresse?