Cisco-ASA Layer-7-Inspection/Benutzerlogins per FTP verbieten
Die Cisco ASA hat so einige Features, u. A. eine Layer-7-Inspection. Sie kann in Pakete eines Streams schauen und die Verbindung basierend auf den gefundenen Werten unterbrechen.
Im folgenden Beispiel werden relevante Konfigurationsfragmente aufgezeigt, welche einen FTP-Server schützen sollen:
- Generell soll nur ein Gastlogin möglich sein,
- Von bestimmten Adressen aus soll auch ein normaler Login möglich sein.
Es ist leider nicht möglich, Pakete innerhalb einer vereinfachten Regelbasis auf Layer-¾ und Layer-7 (Deep-Packet-Inspection) zu klassifizieren. Dies muss getrennt geschehen.
Diese Konfiguration wurde auf einer ASA mit Firmware Version 9.2 getestet.
Festlegen der Layer-¾-Übereinstimmungen
Hierzu ist die Definition zweier Access-Listen notwendig: Eine als Standard, um interessanten FTP-Traffic zu einem bestimmten Host zu filtern[1]…
access-list ftp_default extended permit tcp any host 198.51.100.20 eq ftp
… und eine, welche Ausnahmen zu dieser ACL zulässt, in diesem Falle also der Quelladresse(n):
access-list ftp_auth_allow extended permit tcp object-group ftp-auth-allowed-networks host 198.51.100.20 eq ftp
Die Objektgruppe ftp-auth-allowed-networks ist in diesem Fall ein ASA group-object network
.
Diese Access-Listen werden nun von Class-Maps referenziert:
class-map ftp-traffic-auth-allowed match access-list ftp_auth_allow ! class-map ftp-traffic-default match access-list ftp_default !
Policies (also Regelwerke) arbeiten immer mit Class-Maps. Daher ist diese zusätzliche Verknotung leider notwendig.
Festlegen der Layer-7-Übereinstimmungen
Anhand einer Regex wird festgelegt, welche Loginnamen erlaubt sind:
regex ftp_anonymous "[^A-Z,a-z,0-9]+(ftp|anonymous)[^A-Z,a-z,0-9]+"
Leider unterstützt die Cisco ASA nicht alle Regex-Möglichkeiten. Regex-Ende ($
) ist grundsätzlich nicht möglich. Regex-Beginn (^
) erzielt in der Praxis hier auch keine Übereinstimmung. Somit würden ohne weitere Einschränkungen Logins wie blanonymousfoo oder anftpuser ebenfalls als gültig markiert. Hier sind Zeichenklassen-Auslassungen wie z. B. [^a-z,A-Z,0-9]
eine ersatzweise Möglichkeit, Anfang und ende der gewünschten Zeichenkette eindeutig zu identifizieren.
Zunächst wird eine PMap definiert für "allen anderen" FTP-Traffic, bei dem der Paketinhalt also "egal" ist. Bei Bedarf können hier z. B. noch Parameter für Maskierungen bestimmter FTP-Antworten angeknipst werden.
policy-map type inspect ftp standard_ftp-map parameters
Nun wird die PMap erstellt, in welcher der alle Logins, die nicht auf o. G. Regex passen, mit einen Verbindungsrücksetzung (TCP RST) quittiert werden. Zusätzlich soll ein Logeintrag erzeugt werden.
policy-map type inspect ftp auth-reset_ftp-map parameters match not username regex ftp_anonymous reset log
Zusammenfügen zum Großen Ganzen
Nun können in einer generischen (non-Inspect) PMap die Klassen und die Inspection-Policies miteinander verknüpft werden:
policy-map outside-in_policy class ftp-traffic-auth-allowed inspect ftp strict standard_ftp-map class ftp-traffic-default inspect ftp strict auth-reset_ftp-map set connection per-client-max 2
Heisst:
- Pakete, die auf oben beschriebene Ausnahmen-ACL passen, werden durch die normale Inspection-Regel standard_ftp-map geführt, welche Auth zulässt,
- Pakete, die auf die Default-ACL passen (also alle anderen an Port tcp/21), werden durch die auth-reset_ftp-map geführt und daher geprüft, wie sich die Gegenseite authentisiert.
Diese "Verdrehung" ist nicht so ganz einfach zu durchschauen, weil standardmäßig nur Gastlogins möglich sein sollen. Ausnahmen sollen mit richtigen Benutzern authentisieren dürfen.[2]
Im obigen Beispiel werden die gleichzeitig pro IP erlaubten Verbindungen in der non-anon-Klasse auf zwei restriktiert, damit ein Script, welches verschiedene Logins parallel durchprobieren würde, noch etwas mehr ausgebremst wird.
Damit Pakete wie gewünscht inspiziert werden, muss diese PMap an eine Netzwerkschnittstelle gebunden werden:
service-policy outside-in_policy interface outside fail-close
Natürlich können die beiden Regelwerke auch in der globalen PMap untergebracht werden. Dies habe ich hier absichtlich nicht getan, damit FTP-Sitzungen vom LAN in die DMZ grundlegend einschränkungsfrei möglich sind.
Dies hätte ich auch durch eine entsprechende Erweiterung der Access-Liste für Netzausnahmen erreichen können, die gezeigte Möglichkeit sehe ich aber als sauberer an.
Log
Im Logging der ASA tauchen bei Fehlversuchen diese Meldungen auf:
%ASA-5-303005: Strict FTP inspection matched username regex ftp_anonymous in policy-map ftp_out_in_map, Reset connection from outside:203.0.113.10/53112 to dmz:198.51.100.20/21 %ASA-4-507003: tcp flow from outside:203.0.113.10/53112 to dmz:198.51.100.20/21 terminated by inspection engine, reason - inspector reset unconditionally.