MySQL-Datenbank auf dedizierter Partition unter SELinux
Bei aktiviertem SELinux gestaltet sich die Auslagerung der Datenbank auf einer dedizierten Partition ein wenig kompizierter als bei deaktiviertem SELinux. Der Hintergrund ist, dass SELinux den Zugriff auf sämtliche Ressourcen stark reglementiert (das ist ja der Sinn hinter SELinux!). Durch Setzen von SELinux-Labels können die SELinux-unbekannten Verzeichnisse wieder die benötigten Rechte erhalten.
Rund um MySQL gibt es die folgenden Labels:
SELinux-Typ | Bedeutung |
mysqld_db_t | Dieses Flag kennzeichnet Dateien der MySQL-Datenbank. Diese Dateien liegen standardmäßig unter /var/lib/mysql. |
mysqld_etc_t | Label für die Hauptkonfigurationsdatei (/etc/my.cnf) oder zusätzliche Konfigurationsdateien der MySQL-Datenbank (i.d.R. unterhalb /etc/mysql). |
mysqld_exec_t | Flag für das Binärprogramm der MySQL-Datenbank - standardmäßig liegt es unter /usr/libexec/mysqld. Es gilt nicht für /usr/bin/mysqld_safe - hierfür gibt es ein eigenes Label |
mysqld_safe_exec_t | Label für das zu verwendende Binärprogramm zum Betreiben einer MySQL-Datenbank - standardmäßig liegt es unter /usr/bin/mysqld_safe. Eine MySQL-Datenbank wird in der Regel über dieses Programm und nicht direkt über /usr/lib/exec/mysqld gestartet - das o.g. Programm fügt Sicherheitsfunktionen und Logging-Mechanismen hinzu. |
mysqld_initrc_exec_t | Dieses Flag kennzeichnet das Init-Skript unterhalb /etc/rc.d/init.d - einige Distirbutionen, wie z. B. RHEL, verlinken /etc/rc.d/init.d und /etc/init.d, wodurch beide Skripte verlinkt sind und über die selben SELinux-Label verfügen. |
mysqld_log_t | Log-Dateien, in die MySQL schreiben darf, müssen mit diesem Label versehen werden. Standardmäßig gilt dieses Label für die Wildcard /var/log/mysql.*. |
mysqld_var_run_t | PID-Files und Sockets müssen mit diesem Flag versehen werden, damit MySQL startet. Das PID-File und evtl. Sockets liegen i.d.R. unter /var/run/mysqld/mysqld.pid und /var/lib/mysql/mysql.sock |
Im folgenden Beispiel sollen die Daten einer lokal installierten MySQL-Datenbank von /var/lib/mysql
nach /data/mysql
verschoben werden.
Zuerst wird die Datenbank gestoppt und die Konfigurationsdatei dahingehend angepasst, dass sie auf den neuen Pfad zeigt:
1# service mysqld stop
2# cp /etc/my.cnf /etc/my.cnf.initial
3# vi /etc/my.cnf
4...
5datadir=/data/mysql
6socket=/var/lib/mysql/mysql.sock
7...
8ZZ
Anschließend wird das neue Verzeichnis angelegt und erhält eine Kopie der vorherigen MySQL-Daten unter Berücksichtigung der Zugriffsrechte:
1# mkdir -p /data/mysql
2# cp --preserve=all -R /var/lib/mysql/* /data/mysql/
Das SELinux-Label "mysqld_db_t
" (siehe oben) wurden nicht übernommen, da sie nicht in den Inodes des Dateisystems gespeichert werden. Sie werden manuell vergeben:
1# semanage fcontext -a -t mysqld_db_t "/data/mysql(/.*)?"
2# restorecon -R -v /data/mysql
Versucht man jetzt, den MySQL-Dienst zu starten, schlägt das fehl. Es wird noch eine SELinux-Regel benötigt, die den Zugriff auf die dedizierte Partition erlaubt. In der SELinux-Logdatei (/var/log/audit/audit.log
) werden alle Regelverstöße vermerkt. Mithilfe von audit2allow
kann eine Ausnahmeregel, die später zu einem Modul gebündelt wird, erstellt werden. Nach der Installation des Moduls funktioniert der Zugriff.
Eine detailliertere Fehlermeldung des Regelverstoßes lässt sich mit audit2why anzeigen:
1# audit2why < /var/log/audit/audit.log
Es empfiehlt sich vorher das Audit-Log zu leeren, damit auch wirklich nur der MySQL-Regelverstoß erfasst und zu einem Modul konvertiert wird:
1# > /var/log/audit/audit.log
2# service mysqld start
3# audit2allow -m local < /var/log/audit/audit.log > local.te
Die generierte Datei local.te sollte eine solche Konfiguration enthalten:
1# cat local.te
2
3module local 1.0;
4
5require {
6 type file_t;
7 type mysqld_t;
8 class dir { getattr search };
9}
10
11#============= mysqld_t =============
12allow mysqld_t file_t:dir { getattr search };
Anschließend wird ein Modul generiert und installiert. Es empfiehlt sich, die Datei local.te
aufzubewahren, um eventuelle spätere Ausnahmeregeln darin zu dokumentieren.
1# checkmodule -M -m -o local.mod local.te
2checkmodule: loading policy configuration from local.te
3checkmodule: policy configuration loaded
4checkmodule: writing binary representation (version 10) to local.mod
5
6# semodule_package -o local.pp -m local.mod
7# semodule -i local.pp
Anschließend kann MySQL auch gestartet werden:
1# service mysqld start
2Starting mysqld: [ OK ]
🙂