Webserver vor Einbrüchen schützen mit Mod-Selinux 2 Webwehr Web Application Firewalls wehren bekannte Angriffe ab, bieten jedoch keinen Schutz vor den immer neuen Tricks der Cracker. Mod-Selinux schiebt ihnen den endgültigen Riegel vor. Thorsten Scherf Jaroslaw Grudzinski, 123RF Web-basierte Applikationen entwickeln sich immer mehr zu einem beliebten Angriffspunkt für Einbruchsversuche in Computersysteme. Vor modernen Angriffsmethoden wie SQL Injection und Cross Site Scripting bieten klassische Firewall-Systeme keinen Schutz, somit kann ein Fehler in einer Webapplikation fatale Folgen haben. Erstens sind Webapplikationen extrem dynamisch und komplex, zweitens kann der Entwickler einer Webanwendung nicht in die Zukunft blicken und alle möglichen Gefahren bereits im Vorfeld erkennen und eliminieren. Eine Barriere bilden so genannte Web Application Firewalls (WAF), die mit Wissen über die beschriebenen Angriffe ausgestattet sind. Zusätzlich hat sich im Open-Source-Umfeld in den letzten Jahren Mod-Security [1] verbreitet. Hierbei handelt es sich um ein Apache-Modul, anhand von Regelsätzen den eingehenden Datenstrom auf verdächtige Inhalte überwacht. Mod-Security arbeitet ähnlich wie ein Intrusion-Detection-System, das anhand einer Pattern-Datenbank unerwünschte Datenpakete verwirft. Hiermit lässt sich bereits ein großer Anteil gefährlicher Pakete vor der Übergabe an die Web-Applikation abfangen. Aber was passiert mit Paketen, die trotzdem durchrutschen? Systemen, die auf Basis von Pattern-Matching arbeiten, erkennen ja immer nur bekannte Muster wieder und versagen somit bei bisher unbekannten Angriffsmethoden. Dann würde das eigentlich unerwünschte Paket problemfrei durchgereicht und könnte innerhalb der Web-Applikation Schaden anrichten. SE Linux für die Datenbank Auf Betriebssystem-Ebene löst der Administrator solche Probleme mit Hilfe von Mandatory Access Control (MAC). In diesem Bereich hat sich in letzten Jahren SE Linux als Standard etabliert. Das Problem ist aber, dass SE Linux nur den Zugriff auf System-Ressourcen einschränkt. Nun stehen jedoch beim Einsatz von Webapplikationen primär Web- beziehungsweise Applikationsserver und Datenbanken im Vordergrund und benötigen besonderen Schutz. Mit Hilfe von Security Enhanced PostgreSQL (SE-PostgreSQL) [2] und Mod-Selinux [3] lassen sich nun auch Webapplikationen und deren Zugriff auf einzelne Datenbank-Objekte unter das Schutzschild von SE Linux stellen. Dass dies zwingend notwendig ist zeigt eine Studie der Little earth Corporation (LAC) vom März 2009 (Abbildung 1). Hiernach zeigt sich eine deutliche Zunahme der Angriffe auf webbasierte Applikationen von 53 Prozent im Jahr 2006 auf über 90 Prozent im Jahre 20. Eigener Security-Context Bei klassischen PostgreSQL-Installationen meldet sich ein Benutzer mit seinem Benutzernamen an und authentifiziert sich mit seinem Passwort. Der Benutzer erhält dann Zugriff auf alle Objekte die für dieses Benutzerkonto zugänglich sind, wobei das Benutzerkonto hierbei unabhängig vom eigentlichen Systemkonto ist. Im Fall von SE-PostgreSQL teilt die Funktion»getpeercon()«den Security- Context des zugreifenden Client-Sockets mit: entweder den Security-Context eines zugreifenden Benutzers oder den eines Prozesses. Somit bekommt jede Verbindung zur Datenbank einen individuellen Security-Context zugewiesen. Da der Administrator bei SE-PostgreSQL auch jede Tabelle und jedes darin enthaltene Objekt mit einem Security-Label versehen darf, kann er über das zentrale SE-Linux-Regelwerk genau festlegen, welcher Benutzer beziehungsweise
Prozess auf welches Datenbank-Objekt zugreifen darf oder eben nicht. Das heißt, wie bei SE Linux üblich, dass zwei Zugriffsprüfungen erfolgreich zu passieren sind, bevor das angeforderte Objekt ausgeliefert wird. Zuerst muss der Zugriff auf Basis der datenbankbasierten Authentifizierung gestattet sein, im zweiten Schritt überprüft das System dann, ob das Security-Label des zugreifenden Sockets die nötigen Rechte für das angefragte Objekt hat. Nur wenn beide Tests erfolgreich abgelaufen sind, liefert die Datenbank das gewünschte Objekt aus, sonst kommt es zu einer Fehlermeldung und einem Eintrag im Log. Selbst der Datenbank- Administrator hat nur dann Zugriff auf ein bestimmtes Objekt, wenn der zuständige Security-Administrator diesen Zugriff explizit über eine entsprechende SE-Linux-Regel erlaubt hat. Somit lässt sich das Vier-Augen-Prinzip von MAC- Regeln umsetzen. Security-Context in der Tabelle Anders als bei den klassischen System- Objekten, beispielsweise Dateien oder Verzeichnissen eines Dateisystems, bei denen der Security-Context in den erweiterten Attributen gespeichert sind, hält SE-PostgreSQL den Security-Context für ein Datenbank-Objekt in einem besonderen Systemkatalog vor. In solchen Systemkatalogen befinden sich bei relationalen Datenbanksystemen üblicherweise ihre Schemadaten und andere Metainformationen. SE-PostgreSQL führt einen zusätzlichen Katalog mit dem Namen»sg_security«ein. In diesem Katalog führt SE-PostgreSQL ein Mapping zwischen dem eigentlichen Security-Context eines Objektes und einem Object-Identifier (OID) durch. Legt man ein neues Datenbank-Objekt an, so bekommt es eine numerische OID zugwiesen. Um die Auflösung in die klassische String-Darstellung für einen Security-Context kümmert sich die Datenbank selbst. SE Linux als Apache-Modul Ähnlich verhält es sich mit dem Apache-Modul Mod-Selinux. Hiermit ist es möglich, unterschiedliche Webserver-Instanzen mit einem individuellen Security- Context zu starten anstatt für jeden Prozess immer wieder den gleichen Kontext zu verwenden. Welcher Security-Context für eine Webserver-Instanz zum Einsatz kommt, hängt nun vom zugreifenden Benutzer ab. Die Vorgehensweise ähnelt der eines klassischen Shell-Logins. Nach erfolgreicher Authentifizierung mittels»login«oder»ssh«bekommt die Shell des Benutzers einen Security-Kontext zugewiesen. Der Anwender kann nun, gemäß der in diesem Kontext gestatteten Rechte, auf dem System arbeiten. Führt er eine Aktion aus, die für seinen Kontext nicht gestattet ist, dann verhindert SE Linux sie. Im Fall von Mod-Selinux ist es der Webserver Apache, der als Agent/ Proxy für einen zugreifenden Benutzers agiert. Meldet er sich mit seinem Benutzerkonto an, verwendet der Webserver-Prozess den Kontext des Benutzers. Über eine Abfrage des Security-Servers im Kernel, wird erkennbar welche Rechte dieser Prozess hat und auf welche Objekte der Benutzer über den Webserver als Agent/ Proxy nun Zugriff erhält und auf welche nicht. Wer SE-PostgreSQL als Backend für die Webapplikation verwendet, weitet die Zugriffskontrolle sogar auf einzelne Objekte innerhalb der Datenbank aus. Bevor es an die Konfiguration geht, ist erst einmal das Paket Mod-Selinux zu installieren. Es ist in den Software-Repositories der großen Linux-Distribution standardmäßig enthalten, alternativ finden sich auf der Projektseite [2] die Quellen zur Installation. Nach erfolgreicher Installation liegt auf einem Fedora-11-System die Datei»mod_selinux.conf«im Verzeichnis»/etc/httpd/conf.d«. Die Frage ist nun, wie bekommt der Benutzer einer Webapplikation seinen Security-Context? Mod-Selinux bietet hierfür mehrere Möglichkeiten an, die in der Konfigurationsdatei von Mod-Selinux beschrieben sind. Listing 1:»/etc/httpd/conf.d/mod_ selinux.conf«01 <Directory "/var/www/html"> 02 ### HTTP Basic Authentication 03 AuthType Basic 04 AuthName "Secret Zone" AuthUserFile /var/www/htpasswd 06 Require valid user 07 </Directory> Listing 2:»/etc/httpd/conf.d/mod_ selinux.conf«01 ### mod_selinux.conf kann auf eine lokale Datei zurückgreifen, um 02 ### Benutzer mit einem Security Context zu verknüpfen 03 04 selinuxdomainmap /var/www/mod_selinux.map selinuxdomainval anon_webapp_t:s0 06 selinuxdomainenv SELINUX_DOMAIN Listing 3:»/var/www/mod_selinux. map«01 foo *:s0:c0 02 bar *:s0:c1 03 anonymous anon_webapp_t:s0 04 * user_webapp_t:s0 Mod-Selinux Linux-Magazin 10/09 Sysadmin 3 Listing 4:»chcat«Abbildung 1: Die Angriffe auf Webapplikationen haben in den letzten Jahren enorm zugenommen. Quelle: Little Earth Corporation. 01 # chcat L 02 s0 03 s0 s0:c0.c255 SystemLow SystemHigh 04 s0:c0.c255 SystemHigh s0:c1 Marketing 06 s0:c2 Payroll 07 s0:c3 IT 09 chcat +IT /var/www/virtual/www1/index.html 10 ls lz /var/www/virtual/www1/index.html 11 rw rw r root apache root:object_r:httpd_sys_ content_t:it /var/www/virtual/www1/index.html
4 01 # su sepgsql 02 # createdb web 03 # psql web 04... Zuerst muss der Administrator Apache natürlich mitteilen, für welches Verzeichnis oder welche Location eine Authentifizierung erfolgen soll. Listing 1 zeigt ein Beispiel zur Authentifizierung der Benutzer mittels einer lokalen Datei, die Benutzernamen und die MD5-Passworthashes der Benutzer enthält.mit dem folgenden Kommando nimmt der Administrator einen Benutzer in die Passwort-Datei auf: htpasswd m /var/www/htpasswd foo 06 web=# CREATE TABLE uaccount ( 07 web(# uname TEXT PRIMARY KEY, web(# upass TEXT, 09 web(# udomain TEXT 10 web(# ); 11 Listing 5:»sesearch«zeigt Regeln 01 # sesearch allow s user_webapp_t 02 Found 120 semantic av rules: 03 allow user_webapp_t public_content_t : file { ioctl read getattr lock open} ; 04 allow user_webapp_t public_content_t : dir { ioctl read getattr lock search open } ; allow user_webapp_t public_content_t : lnk_file { read getattr } ; 06 allow user_webapp_t sysctl_kernel_t : file { ioctl read getattr lock open } ; 07 allow user_webapp_t sysctl_kernel_t : dir { ioctl read getattr lock search open } ;... Listing 6: Tabelle»uaccount«12 web=# INSERT INTO uaccount VALUES ('foo', 'pass', 'user_webapp_t:s0:c0'); 13 web=# INSERT INTO uaccount VALUES ('bar', 'pass', 'user_webapp_t:s0:c1'); 01 LoadModule dbd_module modules/mod_dbd.so 02 LoadModule authn_dbd_module modules/mod_authn_ dbd.so 03 04 # Parameter für die Datenbank Verbindung 06 DBDriver pgsql 07 DBDParams "dbname=web user=apache" 09 # Digest Authentifizierung 10 11 <Directory "/var/www/html"> 12 AuthType Digest 13 AuthName "Secret Zone" Listing 2 zeigt die weiteren Einstellungen. Die Anweisung»selinuxDomain- Map«bestimmt eine lokale Datei, die jedem Benutzer einen Security-Context zuweist, alternativ lässt sich mittels»selinuxdomainval«ein Default-Context setzen. Eine solche Map-Datei kann wie in Listing 3 aussehen. Nach einer erfolgreichen Authentifizierung laufen die Webserver-Prozesse der beiden Benutzeranfragen jeweils in der SE-Linux- Domäne»user_webapp_t«mit einem MLS-Sensitiviätslevel von»s0«und einer MCS-Kategorie von»c0«(foo) und»c1«(bar). Somit ist ein Zugriff nur auf Objekte möglich, die ebenfalls diesen Kategorien angehören und auf die Domäne»user_webapp_t«zugreifen dürfen. MCS-Kategorien an Dateiobjekten setzt das Tool»chcat«(Listing 4). Policy Suche Listing 7:»/etc/httpd/conf.d/mod_selinux.conf«Ist ein Benutzer in dieser Map-Datei nicht explizit aufgeführt, findet der Zugriff lediglich über die Domäne»user_ webapp_t«, ohne gesetzter MCS-Kategorie, statt. Das Tool»sesearch«verrät, auf welche Objekte ein Zugriff aus der Domäne»user_webapp_t«gestattet ist (Listing 5). Diese neuen Regeln für die SE-Linux-Policy stammen aus dem Policy- Paket»mod_selinux.pp«. Das Paket wird nach der Installation von Mod-Selinux automatisch geladen, wie ein Aufruf von»semodule«bestätigt: # semodule l grep mod_selinux mod_selinux 2.2 Natürlich kann der Administrator der Policy eigene Regeln hinzufügen. Hierfür muss er dann aber ein eigenes Policy- 14 AuthDigestProvider dbd 15 AuthDBDUserRealmQuery \ 16 "SELECT md5(uname ':' $2 ':' upass), udomain, \ 17 %s=%s as dummy FROM uaccount WHERE uname = $1" 18 19 # SE Linux context mapping 20 21 selinuxdomainenv AUTHENTICATE_UDOMAIN 22 selinuxdomainval anon_webapp_t:s0 23 24 </Directory> Paket entwickeln. Wie das geht, verrät ein anderer Artikels des Autors [4]. Alle nicht authentifizierten Zugriffe auf den Webserver laufen, wie in der Map-Datei festgelegt, in der SE-Linux-Domäne»anon_webapp_t«. Nur mit PostgreSQL Für größere Umgebungen wird man die Benutzer jedoch in einer Datenbank ablegen wollen und die Authentifizierung hierüber abwickeln, zumal beim Einsatz einer Webapplikation bereits ein Datenbank-System vorhanden ist. Im folgenden Beispiel kommt als Datenbank das bereits angesprochene SE-PostgreSQL zum Einsatz. Das hat den Vorteil, dass der Administrator alle Objekte der Datenbank mit einem Security-Context verknüpfen kann, was bei anderen RDBMS-Systemen nicht möglich ist. Die Installation gelingt bei den meisten Linux-Distributionen wieder aus dem Standard-Software-Repository heraus. Alternativ finden sich auf der Webseite des Projektes [2] die Sourcen. Auf einem Fedora-11-System installiert der folgende Yum-Aufruf die Datenbank: yum install sepostgresql Im Anschluss ist die Datenbank zu initialisieren und zu starten, dies übernehmen die folgenden Befehle: /etc/init.d/sepostgresql initdb /etc/init.d/sepostgresql start Für den administrativen Zugriff auf die Datenbank existiert ein Standardbenutzer»sepgsql«. Darüber kann der Administrator die erste Datenbank erzeugen und dann Benutzer-Objekte darin anlegen (Listing 6). Anmeldung am Web In der Konfigurationsdatei von»mod_selinux.conf«kann man nun zur Authentifizierung der Benutzern einer Webapplikation auf diese Objekte zurückgreifen. Der passende Security-Context ist zu jedem Benutzer-Objekt bereits in der Datenbank hinterlegt, somit ist kein Mapping mehr durchzuführen. Die notwendigen Direktiven zur Konfiguration von»mod_selinux«zeigt Listing 7. Hier sind zuerst die passenden Apache-
Module zum Zugriff auf die Datenbank zu laden. Die nächsten beiden Parameter legen den gewünschten Treibernamen und die Anmeldeparameter für den Zugriff auf PostgreSQL fest. Im Anschluss erfolgt die Authentifizierung der Benutzer. Diese wandern dann über die Variable»AUTHENTICATE_UDOMAIN«an Mod-Selinux. Klappt die Anmeldung eines Benutzers nicht, so dient als Fallback-Lösung wieder der Security-Context»anon_webapp_t«. Dank Mod-Selinux ist es nun also möglich, einzelne Webserver-Prozesse (genauer: Webserver-Threads) mit einem jeweils individuellen Security-Context zu starten. Über SE-Linux-Regeln definiert der Administrator dann, welche Objekte Mod-Selinux Listing 8: Security-Context auf Datenbank-Zeilen 01 # su sepgsql 02 # createdb footballdb 03 # psql footballdb 04 Welcome to psql 8.3.7, the PostgreSQL interactive terminal. 06 Type: \copyright for distribution terms 07 \h for help with SQL commands \? for help with psql commands 09 \g or terminate with semicolon to execute query 10 \q to quit 11 12 footballdb=# CREATE TABLE clubs ( 13 footballdb(# id integer primary key, 14 footballdb(# name varchar(32), 15 footballdb(# platz integer, 16 footballdb(# punkte integer 17 footballdb(# ); 18 19 footballdb=# INSERT INTO clubs (id, name, platz, punkte) 20 footballdb # VALUES (1, 'Schalke', 1, 72); 21 22 footballdb=# SELECT security_context, * FROM clubs; 23 24 security_context id name platz punkte 25. + + + + 26 unconfined_u:object_r:sepgsql_table_t:s0 1 Schalke 1 72 27 (1 row) 28 29 footballdb=# UPDATE clubs SET security_context = 'system_u:object_r:public_content_t:s0' WHERE name='schalke'; 30 31 footballdb=# SELECT security_context, * FROM clubs; 32 33 security_context id name platz punkte 34 + + + + 35 system_u:object_r:public_content_t:s0 1 Schalke 1 72 36 (1 row) Linux-Magazin 10/09 5 1/2 quer A 210 x 148 mm zzgl. Beschnitt???
6 auf diese einzelnen Threads zugreifen dürfen. Wer sich die Dokumentation etwas genauer anschaut stellt schnell fest, dass das Einsatzgebiet bei den hier vorgeführten Beispielen nicht aufhört. So kann der Administrator mittels Mod-Selinux beispielsweise auch einzelne virtuelle Apache-Hosts mit einem jeweils eigenen Security-Context starten oder in Abhängigkeit der IP-Adresse eines zugreifenden Hosts den Context setzen. SE-PostgreSQL mit MAC- Schutz Die folgenden Abschnitte führen die SE- Linux-Konfiguration eines relationalen Datenbankverwaltungssystem am Beispiel von SE-PostgreSQL vor. Dabei handelt es sich um eine Erweiterung des bekannten PostgreSQL-Datenbanksystems. Die Erweiterung ermöglicht, einzelne Objekte mit einem SE-Linux Security- Context zu versehen und beim Zugriff auf diese Objekte eine Abfrage an den Security-Server im Kernel zu stellen, welche Rechte der Kontext des zugreifenden Sockets in Bezug auf das angefragte Objekt besitzt. Listing 8 zeigt den schematischen Ablauf. Zuerst meldet der Administrator sich erneut mit einem administrativen Konto am RDBMS an und erzeugt eine neue Datenbank, in diesem Fall»footballdb«. Anschließend verbindet er sich über die Psql-Clientanwendung mit der Datenbank und erzeugt eine neue Tabelle, hier»clubs«. Diese bekommt einen einzelnen Datensatz zugewiesen. Das erste Select- Statement gibt den Datensatz aus. Hierbei zeigt sich, dass dieser bereits über einen Security-Context verfügt. Der Type für diesen Default-Security-Context lautet für Zugriffe aus der»unconfined_t«-domäne 01 foo=# CREATE TABLE mitarbeiter ( 02 foo(# mid integer primary key, 03 foo(# mname varchar(32), Listing 9: Security-Context auf Spalten 04 foo(# mgehalt varchar(32) CONTEXT = 'system_u:object_r:sepgsql_secret_table_t:s0' foo(# ); 06 07 foo=# GRANT ALL ON mitarbeiter TO PUBLIC; 09 foo=# SELECT sepgsql_getcon(); 10 sepgsql_getcon jeweils»sepgsql_table_t«. Möchte man den Context ändern, so gelingt dies mit einem einfachen Update-Statement. Der letzte Select-Aufruf verifiziert, dass der Datensatz nun über einen neuen Typ im Security-Context verfügt. Natürlich lässt sich ein Context nicht nur auf eine Datenbank-Zeile anwenden, sondern auch auf einzelne Spalten. Listing 9 zeigt ein Beispiel. Hierbei handelt es sich um eine Tabelle die Mitarbeiter-Daten enthält. Für diese Spalte soll dersecurity- Context»sepgsql_secret_table_t«zum Zuge kommen. Auf diesen Typen darf eine reguläre SE-Linux User-Domäne nicht zugreifen. Dies bestätigten die letzten beiden Select-Statements. Der Befehl»SELECT sepgsql_getcon();«zeigt den Security-Context des zugreifenden Sockets an, in diesem Fall handelt es sich um die User-Domäne»user_t«. Das abschließende Select versucht nun auf alle Spalten der Mitarbeiter-Tabelle zuzugreifen. Dies endet in einer SE-Linux- Fehlermeldung, da der Zugriff aus der Domäne»user_t«auf ein Datenbank-Objekt mit dem Typen»sepgsql_secret_table_t«nicht gestattet ist. Die hierfür notwendigen Regeln hat das Policy-Paket»sepostgresql devel.pp«dem systemweiten SE-Linux-Regelwerk bei der Installation von SE-PostgreSQL hinzugefügt. Es lässt sich, genau wie auch bei Mod-Selinux, natürlich durch eigene Regelsätze erweitern. Die Manpage von»sepostgresql«listet alle möglichen SE-Linux-Typen und deren Berechtigungen auf. Wie bereits im letzten Abschnitt erwähnt, verwendet SE-PostgreSQL immer den SE- Linux-Context des zugreifenden Client- Sockets, um eine Zugriffsentscheidung auf ein Objekt innerhalb der Datenbank zu treffen. Hierbei handelt es sich entweder um den Security-Context eines 11 12 user_u:user_r:user_t:s0 13 (1 row) 14 15 foo=# SELECT * FROM mitarbeiter; 16 ERROR: SELinux: denied { select } \ 17 scontext=user_u:user_r:user_t:s0 \ 18 tcontext=system_u:object_r:sepgsql_ secret_table_t:s0 \ 19 tclass=db_column name=mitarbeiter. mgehalt zugreifenden Prozesses (beispielsweise»httpd_t«) oder den Context der Shell des Benutzers (beispielsweise»user_t«). Den Context des zugreifenden Sockets zeigt»psql«über ein»select sepgsql_getcon();«statement an. Findet der Zugriff nicht von der lokalen Maschine, sondern von einem Apache einer anderen Maschine statt, sieht SE-PostgreSQL nur den Kontext des zugreifenden Netzwerk-Sockets. Hierfür existiert mit Labeled Networking eine elegante Lösung. Damit lassen sich beliebige IPSec- Tunnel zwischen verschiedenen Systemen aufbauen, die den Security-Context eines Prozesses über Netzwerkgrenzen hinweg übertragen [5]. Fazit Mod-Selinux bietet einen wesentlich fein granulierteren Zugriff auf SE-Linux-Objekte als es bisher der Fall war. App Armor bietet zwar mit Apache-Heads eine ähnliche Lösung, sie erfordert aber den Einsatz eines speziellen Apache-Servers, was hier nicht der Fall ist. Kommt SE- PostgreSQL als Backend der Webapplikation zum Einsatz, lässt sich da Einsatzgebiet der Mandatory Access Control auch auf Datenbank-Objekte ausweiten. Gerade eine Kombination aus beiden Systemen verspricht beim Einsatz von Webapplikationen einen großen Gewinn an Sicherheit. (ofr) n Infos [1] Tim Schürmann, Web Application Firewall mit Mod-Security und Apache, Linux-Magazin Sonderheft 02/ 20, S. 114 [2] SE-PostgreSQL, Security Enhanced PostgreSQL: [http:// wiki. postgresql. org/ wiki/ SEPostgreSQL] [3] Mod-Selinux: [http:// code. google. com/ p/ sepgsql/] [4] Thorsten Scherf, Grafisches Frontend für SE Linux, Linux-Magazin-Sonderheft 01/ 2009, S. 102 [5] Thorsten Scherf, SE Linux kontrolliert Netzwerk-Traffic, Linux-Magazin-Sonderheft 01/ 2009, S. 19 Der Autor Thorsten Scherf arbeitet für die Firma Red Hat, wo er unter anderem Trainings sowie Projekte im Bereich Netzwerksicherheit durchführt.