Re: rsync/ssh über firewall
- From: Ansgar -59cobalt- Wiechers <usenet-2008@xxxxxxxxxxxxxxxx>
- Date: Fri, 14 Nov 2008 16:01:34 +0100 (CET)
Steven Varco <ng.10.partyjunkie@xxxxxxxxxxxxxxx> wrote:
Ansgar -59cobalt- Wiechers schrieb:
Im logfile erhalte ich dann (mehrfach):
---
[IPTABLES DROP] : IN= OUT=eth0 SRC=webserver-ip
DST=z-z-z-z.my.provider.ip LEN=1500 TOS=0x08 PREC=0x00 TTL=64 ID=42012
DF PROTO=TCP SPT=22 DPT=3597 WINDOW=2003 RES=0x00 ACK PSH URGP=0 OPT
(0101080A0181498B39B878C3)
---
Das sieht mir eher nicht danach aus, als wäre der Paketfilter dein
Problem. Kann es evtl. sein, dass dein Provider zwischendurch die
Verbindung beendet? Oder die Datenrate so weit drosselt, dass die
Verbindung in einen Timeout läuft? Das würde AFAICS dieses Verhalten
verursachen. Initial kann die Verbindung ja offensichtlich aufgebaut
werden, und es werden auch Daten übertragen, aber irgendwann später
reißt dann die Verbindung ab.
Nein, beides ist so viel ich weiss nicht der Fall bei meinem provider.
Zudem, wenn ich die firewall ganz abschalte (iptables -F -X), dann gehts
reibungslos.
Und sollange im iptables-log steht: "paket VON webserver NACH
backup-host VOM S-PORT 22 NACH D-PORT XXXX wurde gedropt" schliesse ch
doch eher darauf, dass es am paketfilter liegt, oder?
Nicht notwendigerweise. Es muss einen Grund geben, warum der Paketfilter
während der Übertragung anfängt, Pakete zu verwerfen, denn zu Beginn der
Übertragung lässt er sie ja offensichtlich durch.
Vereinfache mal deinen Regelsatz, und baue ein paar zusätzliche Logging-
Regeln ein, damit du siehst, was mit den Paketen passiert. Und poste
dann mal die Ausgabe von "iptables -nvL".
Eine detailierte Kritik deines bisherigen Regelwerks findest du weiter
unten. Für den Moment versuch's mal mit folgenden vereinfachten Regeln,
in denen ich Backup-Server und vertrauenswürdige IP-Adressen sowie ein
paar der speziellen Regeln mal außen vor gelassen habe:
----8<----
#!/bin/sh
ipt=/sbin/iptables
TCP_PORTS="21,25,53,80,110,143,443,783,993,995"
$ipt -P INPUT DROP
$ipt -P OUTPUT DROP
$ipt -P FORWARD DROP
$ipt -X
$ipt -F
$ipt -N LOG_DROP
$ipt -A LOG_DROP -j LOG --log-prefix "[IPTABLES DROP] : " \
--log-tcp-options --log-ip-options
$ipt -A LOG_DROP -j DROP
$ipt -N icmp_packets
$ipt -A icmp_packets -p icmp --icmp-type echo-request \
-m limit --limit 10/s --limit-burst 50 -j ACCEPT
$ipt -A icmp_packets -p icmp --icmp-type echo-reply \
-m state --state RELATED -j ACCEPT
$ipt -A icmp_packets -p icmp --icmp-type destination-unreachable \
-m state --state RELATED -j ACCEPT
$ipt -A icmp_packets -p icmp --icmp-type source-quench \
-m state --state RELATED -j ACCEPT
$ipt -A icmp_packets -p icmp --icmp-type time-exceeded \
-m state --state RELATED -j ACCEPT
$ipt -A icmp_packets -j DROP
$ipt -A INPUT -i lo -j ACCEPT
$ipt -A INPUT -p icmp -j icmp_packets
$ipt -A INPUT -p tcp --dport 22 -j LOG --log-prefix "INPUT: SSH (all): "
$ipt -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
$ipt -A INPUT -p tcp --dport 22 -j LOG \
--log-prefix "INPUT: SSH (NEW or INVALID): "
$ipt -A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT
$ipt -A INPUT -p tcp --dport 22 -j LOG --log-prefix "INPUT: SSH (INVALID): "
$ipt -A INPUT -p tcp -m multiport --dports $TCP_PORTS \
-m state --state NEW -j ACCEPT
$ipt -A INPUT -p udp --dport 53 -m state --state NEW -j ACCEPT
$ipt -A INPUT -p udp -s v.v.v.v --dport 123 -m state --state NEW -j ACCEPT
$ipt -A INPUT -j LOG_DROP
$ipt -A OUTPUT -o lo -j ACCEPT
$ipt -A OUTPUT -p icmp -j icmp_packets
$ipt -A OUTPUT -p tcp --sport 22 -j LOG --log-prefix "OUTPUT: SSH (all): "
$ipt -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
$ipt -A OUTPUT -p tcp --sport 22 -j LOG \
--log-prefix "OUTPUT: SSH (NEW or INVALID): "
$ipt -A OUTPUT -p tcp -m multiport --dports $TCP_PORTS \
-m state --state NEW -j ACCEPT
$ipt -A OUTPUT -p udp --dport 53 -m state --state NEW -j ACCEPT
$ipt -A OUTPUT -j LOG_DROP
---->8----
Jetzt im Detail zu deinem bestehenden Regelsatz:
######################################################################
# NAT
######################################################################
# The NAT portion of the ruleset. Used for Network Address Transalation.
# Usually not needed on a typical web server, but it's there if you need
# it.
*nat
:PREROUTING ACCEPT [127173:7033011]
:POSTROUTING ACCEPT [31583:2332178]
:OUTPUT ACCEPT [32021:2375633]
COMMIT
Wenn du kein NAT machst, kannst du dir die nat-Table komplett schenken,
d.h. du solltest das Modul gar nicht erst laden bzw. einen Kernel ohne
diese Table bauen. Weniger Code == weniger Angriffsfläche für Exploits.
######################################################################
# Mangle
######################################################################
# The Mangle portion of the ruleset. Here is where unwanted packet types
# get dropped.
# This helps in making port scans against the server a bit more time
# consuming and difficult, but not impossible.
*mangle
:PREROUTING ACCEPT [444:43563]
:INPUT ACCEPT [444:43563]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [402:144198]
:POSTROUTING ACCEPT [402:144198]
-A PREROUTING -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,PSH,URG \
-j DROP
-A PREROUTING -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
-A PREROUTING -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -j DROP
-A PREROUTING -p tcp -m tcp --tcp-flags FIN,SYN FIN,SYN -j DROP
-A PREROUTING -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,PSH,URG \
-j DROP
-A PREROUTING -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
-A PREROUTING -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -j DROP
-A PREROUTING -p tcp -m tcp --tcp-flags FIN,SYN FIN,SYN -j DROP
-A PREROUTING -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,PSH,URG \
-j DROP
-A PREROUTING -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
-A PREROUTING -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -j DROP
-A PREROUTING -p tcp -m tcp --tcp-flags FIN,SYN FIN,SYN -j DROP
-A PREROUTING -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,PSH,URG \
-j DROP
-A PREROUTING -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
-A PREROUTING -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -j DROP
-A PREROUTING -p tcp -m tcp --tcp-flags FIN,SYN FIN,SYN -j DROP
COMMIT
Filter-Regeln gehören in die filter-Table, nicht in die mangle-Table. Mach
daraus eine eigene Chein in der filter-Table, in die du dann aus den
Default-Chains verzweigst:
$ipt -N invalid_flags
$ipt -A invalid_flags -p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,PSH,URG \
-j DROP
$ipt -A invalid_flags -p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
$ipt -A invalid_flags -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
$ipt -A invalid_flags -p tcp --tcp-flags FIN,SYN FIN,SYN -j DROP
$ipt -A invalid_flags -p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,PSH,URG \
-j DROP
$ipt -A invalid_flags -p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
$ipt -A invalid_flags -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
$ipt -A invalid_flags -p tcp --tcp-flags FIN,SYN FIN,SYN -j DROP
$ipt -A invalid_flags -p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,PSH,URG \
-j DROP
$ipt -A invalid_flags -p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
$ipt -A invalid_flags -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
$ipt -A invalid_flags -p tcp --tcp-flags FIN,SYN FIN,SYN -j DROP
$ipt -A invalid_flags -p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,PSH,URG \
-j DROP
$ipt -A invalid_flags -p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
$ipt -A invalid_flags -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
$ipt -A invalid_flags -p tcp --tcp-flags FIN,SYN FIN,SYN -j DROP
$ipt -A INPUT -p tcp -j invalid_flags
Ansonsten gilt für die mangle-Table dasselbe wie für die nat-Table: wenn
du sie nicht nutzt -> weg damit.
[...]
######################################################################
# Filter: Special Rules
######################################################################
# Handle special requirements, like special access for various clients
# Open SSH Ports; port 22 only for authorized IPs, Port 922 for everyone
# Work
-A INPUT -p tcp -m tcp --dport 22 -s x.x.x.x -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 22 -s x.x.x.x -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -s y.y.y.y -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 22 -s y.y.y.y -j ACCEPT
# Home
-A INPUT -p tcp -m tcp --dport 22 -s z.z.z.z -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 22 -s z.z.z.z -j ACCEPT
# ALL
-A INPUT -p tcp -m tcp --dport 922 -j LOG_ACCEPT
-A OUTPUT -p tcp -m tcp --dport 922 -j ACCEPT
Das ist paranoider Unfug. Erlaube SSH und konfiguriere deinen SSH-Server
geeignet (Login nur per Public Key und nur für definierte Benutzer bzw.
Gruppen erlaubt). Wenn dich die Wörterbuchangriffe in den Logs stören:
verwende fail2ban oder vergleichbares.
# Special rules with connection tracking for rsync
-A INPUT -p tcp -m state --state ESTABLISHED,RELATED -s z.z.z.z -j ACCEPT
-A OUTPUT -p tcp -m state --state ESTABLISHED,RELATED -s z.z.z.z -j ACCEPT
-A OUTPUT -p tcp --dport 22 -m state --state NEW -s z.z.z.z -j ACCEPT
-A INPUT -p tcp -m state --state ESTABLISHED,RELATED -s z.z.z.z -j ACCEPT
-A INPUT -p tcp --dport 22 -m state --state NEW -s z.z.z.z -j ACCEPT
-A OUTPUT -p tcp -m state --state ESTABLISHED,RELATED -s z.z.z.z -j ACCEPT
Rsync verwendet per Default SSH, d.h. du brauchst dafür genau gar keine
separaten Regeln. Für ESTABLISHED,RELATED reicht eine einzige Regel
am Anfang des Regelsatzes.
$ipt -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
$ipt -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
Darüber hinaus ist z.z.z.z AFAICS nicht die IP-Adresse deines Servers,
d.h. in den OUTPUT-Regeln hat "-s z.z.z.z" nichts zu suchen. Ich
wiederhole nochmals: mach deine Regeln so generisch wie möglich und nur
so speziell wie nötig. Zu spezielle Regeln erschweren die Wartung und
fallen dir früher oder später auf den Fuß.
Für inbound SSH (und damit auch rsync, sofern dein Rechner daheim die
Daten vom Server zieht) sind folgende Regeln vollständig ausreichend:
$ipt -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
$ipt -A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT
$ipt -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Nagios NRPE; only for Nagios Host
-A INPUT -p tcp -m tcp --dport 5666 -s z.z.z.z -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 5666 -s z.z.z.z -j ACCEPT
Ist z.z.z.z die IP-Adresse deines Servers? Oder die IP-Adresse des
Nagios-Hosts? Beides geht nicht. Von wo nach wo soll die Verbindung
erfolgen? Vom Nagios-Host zum Server? Dann genügt folgende Regel:
$ipt -A INPUT -p tcp --dport 5666 -s z.z.z.z -m state --state NEW -j ACCEPT
Alles weitere wird von der bereits existierenden ESTABLISHED,RELATED-
Regel erledigt.
# Ganglia
-A INPUT -p tcp -m tcp -m state --state NEW -s z.z.z.z --dport 8649 -j ACCEPT
-A INPUT -p udp -m udp -d 239.2.11.71 --dport 8649 -j ACCEPT
-A OUTPUT -p udp -m udp -d 239.2.11.71 --dport 8649 -j ACCEPT
-A INPUT -p udp -m udp -d z.z.z.z --dport 8650 -j ACCEPT
-A OUTPUT -p udp -m udp -d z.z.z.z --dport 8650 -j ACCEPT
Wie oben. Von wo nach wo soll die Verbindung aufgebaut werden? Dieselbe
IP-Adresse als Destination in INPUT- und OUTPUT-Chain ergibt nur dann
Sinn, wenn es die Adresse des Servers selbst ist. Wenn die Verbindung
von z.z.z.z zu 239.2.11.71 aufgebaut werden soll, und sowohl TCP als
auch UDP benötigt werden, dann genügen folgende zwei Regeln:
$ipt -A INPUT -p tcp --dport 8649 -s z.z.z.z -m state --state NEW -j ACCEPT
$ipt -A INPUT -p udp --dport 8649 -s z.z.z.z -m state --state NEW -j ACCEPT
Alles weitere wird von der bereits existierenden ESTABLISHED,RELATED-
Regel erledigt.
# Allow Access to Backupserver
-A INPUT -s w.w.w.w -j ACCEPT
-A OUTPUT -d w.w.w.w -j ACCEPT
Wie oben. Von wo nach wo soll die Verbindung aufgebaut werden? Für
inbound genügt diese Regel:
$ipt -A INPUT -s w.w.w.w -m state --state NEW -j ACCEPT
Für outbound genügt diese Regel:
$ipt -A OUTPUT -s w.w.w.w -m state --state NEW -j ACCEPT
Nur wenn der Verbindungsaufbau in beide Richtungen erfolgen soll,
braucht man beide Regeln.
# Timesync with Server
-A INPUT -p udp -m udp --dport 123 -s v.v.v.v -j ACCEPT
-A OUTPUT -p udp -m udp --dport 123 -d v.v.v.v -j ACCEPT
Sollen sich Clients mit dem Zeitserver auf deinem Server synchronisie-
ren? Dann brauchst du diese Regel:
$ipt -A INPUT -p udp --dport 123 -s v.v.v.v -m state --state NEW -j ACCEPT
Oder soll dein Server seine Zeit mit einem anderen Server synchronisie-
ren? Dann brauchst du diese Regel:
$ipt -A OUTPUT -p udp --dport 123 -d v.v.v.v -m state --state NEW -j ACCEPT
######################################################################
# Filter: Rest
######################################################################
# First, we cover the INPUT rules, or the rules for incoming requests.
# Note how at the end we log any incoming packets that are not accepted.
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 20 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 21 -j ACCEPT
Benutze FTP-Connection-Tracking, dann brauchst du nur Port 21/tcp
inbound zu erlauben:
$ipt -A INPUT -p tcp --dport 21 -m state --state NEW -j ACCEPT
Alles weitere wird von der bereits existierenden ESTABLISHED,RELATED-
Regel erledigt.
# Port 22 is handled unter "Filter: Special"
#-A INPUT -p tcp -m tcp --dport 22 -j LOG_ACCEPT
-A INPUT -p tcp -m tcp --dport 25 -j ACCEPT
-A INPUT -p udp -m udp --dport 53 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 53 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 110 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 143 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 993 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 995 -j ACCEPT
Mittels des multiport-Moduls kannst du mehrere Ports in einer Regel
angeben. Das macht den Regelsatz übersichtlicher.
$ipt -A INPUT -p tcp -m multiport --dports 25,53,80,110,143,443,993,995 \
-m state --state NEW -j ACCEPT
$ipt -A INPUT -p udp --dport 53 -m state --state NEW -j ACCEPT
-A INPUT -p tcp -m tcp --dport 43 -j ACCEPT
Betreibst du einen whois-Server? Falls nicht, brauchst du Port 43/tcp
inbound nicht zu erlauben.
-A INPUT -p tcp -m tcp --dport 783 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 3306 -j ACCEPT
Bist du sicher, dass du Zugriff von außen auf deinen Spamassassin und
MySQL-Server erlauben willst?
-A INPUT -s 127.0.0.1 -j ACCEPT
Besser:
$ipt -A INPUT -i lo -j ACCEPT
-A INPUT -p icmp -j icmp_packets
ICMP-Pakete würde ich ganz am Anfang behandeln, damit sie nicht die
ganze Chain durchlaufen müssen.
[...]
# Next, we cover the OUTPUT rules, or the rules for all outgoing
# traffic.
# Note how at the end we log any outbound packets that are not accepted.
-A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
Eine einzige ESTABLISHED,RELATED-Regel pro Chain genügt.
-A OUTPUT -p tcp -m tcp --dport 20 -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 21 -j ACCEPT
Wie oben. Erlaube Port 21/tcp, wenn du vom Server aus ausgehend FTP-
Verbindungen aufbauen willst. Den Rest erledigt Connection-Tracking in
Kombination mit dem FTP-Helper für dich.
# Port 22 is handled unter "Filter: Special"
#-A OUTPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 23 -j ACCEPT
Willst du Telnet ausgehend nutzen? Warum?
-A OUTPUT -p tcp -m tcp --dport 25 -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 43 -j ACCEPT
-A OUTPUT -p udp -m udp --dport 53 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 53 -j ACCEPT
Da muss OUTPUT stehen, nicht INPUT.
-A OUTPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 110 -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 143 -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 443 -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 993 -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 995 -j ACCEPT
Wie oben. Das Multiport-Modul hilft, den Regelsatz zu vereinfachen.
-A OUTPUT -p tcp -m tcp --dport 783 -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 3306 -j ACCEPT
Willst du outbound auf irgendeine Spamassassin- oder MySQL-Installation
zugreifen? Wenn nicht, sind diese Regeln sinnlos.
-A OUTPUT -d 127.0.0.1 -j ACCEPT
Besser:
$ipt -A OUTPUT -o lo -j ACCEPT
-A OUTPUT -p icmp -j icmp_packets
Siehe oben.
Noch eine ganz elementare Bemerkung zum Schluss. Überlege dir gut, ob du
überhaupt einen Paketfilter auf deinem Server brauchst. Auch ein Paket-
filter kann exploitbare Bugs enthalten, über die ein Angreifer die Kiste
aufmachen könnte.
Sinnvollerweise verwendet man Paketfilter eher um dahinter liegende
Netzwerke zu schützen, weniger für einzelne Server. Bei einzelnen
Servern ist es weitaus sinnvoller, am externen Interface nur die Dienste
zu haben, die man auch tatsächlich nach außen anbieten will. Alles
andere konfiguriert man so, dass es entweder gar nicht gestartet wird,
oder aber nur an localhost lauscht.
HTH
cu
59cobalt
--
"The Mac OS X kernel should never panic because, when it does, it
seriously inconveniences the user."
--http://developer.apple.com/technotes/tn2004/tn2118.html
.
- Follow-Ups:
- Re: rsync/ssh über firewall
- From: Steven Varco
- Re: rsync/ssh über firewall
- References:
- rsync/ssh über firewall
- From: Steven Varco
- Re: rsync/ssh über firewall
- From: Heiko Schlenker
- Re: rsync/ssh über firewall
- From: Ansgar -59cobalt- Wiechers
- Re: rsync/ssh über firewall
- From: Steven Varco
- Re: rsync/ssh über firewall
- From: Steven Varco
- Re: rsync/ssh über firewall
- From: Ansgar -59cobalt- Wiechers
- Re: rsync/ssh über firewall
- From: Steven Varco
- rsync/ssh über firewall
- Prev by Date: Re: Sicherheit bei sofort-überweisung.de
- Next by Date: Re: rsync/ssh über firewall
- Previous by thread: Re: rsync/ssh über firewall
- Next by thread: Re: rsync/ssh über firewall
- Index(es):
Relevant Pages
|
Loading