Fernzugang zum MySQL-Daemon unterbinden in Ubuntu mit Plesk

Eine betrübliche Sicherheitslücke

Im Fehler-Log von mysqld (/var/log/mysql/error.log) fielen mir wiederholten Meldungen dieser Art auf:

[Warning] IP address ‚124.207.29.184‘ could not be resolved

Für die genannte IP-Adresse brachte mich eine Web-Suche sofort weiter: Die ist in Beijing, China registriert und für Mißbrauch bekannt. Mir war zwar schon bewusst, dass mein MySQL-Daemon öffentlich erreichbar war, denn es war für mich selbst sehr bequem, meine Server DB’s vom heimischen PC aus direkt erreichen zu können – doch diesen Preis hatte ich nicht bedacht!

Denn ich habe anschließend die Statistiken der Zugriffe auf meinen MySQL-Server geprüft – sie waren an dem Tag des versuchten Einbrechens absurd hoch, mit einem Durchschnitt von fast 1.000 Anfragen pro Sekunde. Da half nur:

Den Zugang zu MySQL-Daemon auf „localhost“ beschränken

Eher Sie handeln sollten Sie feststellen, dass keine berechtigten Zugriffe von „außerhalb“ stattfinden. Ich war selber zunächst unsicher, weil ich 4 zusätzliche IPs auf dem Server habe, so dass denkbar wäre dass ein lokaler Zugriff (unnötigerweise) über eine diese IPs stattfindet. Ich musste nachprüfen:

Plesk’s Version von phpMyAdmin am Server nutzen

Da die manuelle Verwaltung von DB’s nicht mehr aus der Ferne möglich sein wird, braucht es dafür einen Ersatz (meistens ein Ersatz für eine lokal-laufende Instanz von phpMyAdmin). Dies könnte eine Instanz von phpMyAdmin auf irgendeiner Subdomain auf dem Server sein – womit man die Angreifbarkeit aber nur verlagern würde. Zum Glück enthält Plesk 12 eine recht frische Version von phpMyAdmin, zugänglich nur wenn als „admin“ in Plesk eingeloggt, die er dafür mit vollen MySQL-Adminrechten aufruft:

  • Home | Tools & Settings | Database Servers + Klick auf „Local MySQL Server“
  • Dort auf Reiter „Databases“ im Bereich „Tools“ auf Icon WebAdmin klicken:
  • Plesk öffnet eine eigene Version von phpMyAdmin (rel. jung – 4.2.5) mit der SUPER-User von MySQL „admin“ – (nur) dieser hat z.B. genügend Rechte um globale Einstellungen vorzunehmen. Server: Localhost via UNIX socket (also ganz unabhängig von IP-Geschichten).

MySQL Logging während der Laufzeit einschalten

Seit MySQL 5.1 läßt sich das Logging per „SET global“ SQL-Befehlen ein- und ausschalten. Das ist sehr praktisch: Bei unerwarteten Lastspitzen das Logging (das sonst in Produktion zu viel Last / Daten erzeugt) „on the fly“ einschalten um sehen zu können, was diese Last erzeugt. In Plesk’s phpMyAdmin, im Reiter „SQL“, folgende Befehle eingeben:

SET global general_log_file = ‚/var/log/mysql/mysql.log‘;
[ Standardwert ist /var/lib/mysql/mail.log, was ich für suboptimal halte ]

SET global general_log = 1;
[ Zum Ausschalten: SET global general_log = 0; ]

Lassen Sie das 10 – 20 Minuten mitschneiden, dann können Sie mit
cd /var/log/mysql; grep “ Connect“ mysql.log
eine Liste aller Verbindungsversuche mit dem MySQL-Server ansehen. Hier fallen sowohl Angriffe als auch berechtigte Zugriffe auf, die nicht von „localhost“ aus kommen.

WordPress-Zugang zu per Plesk eingerichteten DBs

Bei der Einrichtung von WordPress (sprich: erzeugen der wp-config.php) schlägt dieser (buchstäblich) „localhost“ für den DB-Zugang vor, was bei VPS’en immer stimmt und daher nicht überschrieben wird. Wenn Sie die DB dafür wie üblich in Plesk eingerichtet haben, hat Plesk einen neuen DB-Nutzer extra für die DB angelegt (wohl wegen Abschottung) mit folgenden Eigenschaften:

  • Ganz ohne globalen Privilegien;
  • Mit „ALL PRIVILEGES“ (bis auf GRANT) für „ihre“ DB, Anmeldung wird von „Jeder Host“ akzeptiert (schließt localhost ein).

In solchen Konstellationen spricht nichts dagegen, den MySQL-Zugriff per TCP/IP auf „localhost“ zu beschränken.

Zugang in der MySQL-Config einschränken

Wie immer bei Plesk sollte man Standard-Dateien / erzeugte Dateien möglichst nicht anfassen sondern die dafür vorgesehenen Ergänzungsdateien bemühen. Wie ich in meinem Artikel zu MySQL-Tuning erläutere, habe ich die /etc/mysql/my.cnf nicht angerührt, sondern eine eigene Datei /etc/mysql/conf.d/tuning.cnf angelegt. Fügen Sie einer solchen Datei in der Section [mysqld] folgende Anweisung zu:

bind-address = 127.0.0.1

und verpassen Sie danach MySQL einen Restart: service mysql restart
Das reicht schon um den Fernzugang zu unterbinden – mysqld horcht dann nur noch auf diese IP-Adresse (= localhost) und ignoriert alle anderen.

Optional: Den Firewall anpassen

Anhänger von „Doppelt hält besser“ können auch den Zugang zum MySQL-Port 3306 in der Firewall auf localhost beschränken. In meinem Artikel über Server-Sicherheit habe ich die Aktivierung einer Firewall erst unter Optionen aufgeführt – mit der Begründung: Wozu ein Port blockieren, hinter dem gar keine Software etwas entgegennimmt? Nach obigem Eingriff stimmt diese Aussage nun auch bei MySQL, aber wer will:

Manuell (untested)

## Block all connections to 3306 except from localhost ##
/sbin/iptables -A INPUT -p tcp -s localhost --dport 3306 -j ACCEPT
/sbin/iptables -A OUTPUT -p tcp -d localhost --sport 3306 ! --syn -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 3306 -j DROP
service iptables save

echo -e „target     prot opt source               destination\n$(iptables -L INPUT -n | grep 3306)“

Via Plesk „Firewall“

„Firewall“ in Anführungszeichen weil es sich um eine GUI plus Plesk-eigene DB-Einträge zum Standard-Programm /sbin/iptables handelt.

  • Tools & Settings | Security | Firewall
  • Falls nicht dort, nachladen:
    Tools & Settings | Plesk | Updates and Upgrades | Add/remove components
    [ Im neuen Tab ] Additional Plesk extensions | Plesk Firewall extension
  • Enable Firewall Rules Management (erzeugten Script akzeptieren)
  • Modify Plesk Firewall Rules | MySQL Server | Allow from selected sources, deny from others | Source = 127.0.0.1

Versuchen Sie es ruhig mit Plesk, bei mir hat’s auf Anhieb geklappt. Wenn es Probleme geben sollte, kann man es einfach wieder abschalten: Disable Firewall Rules Management.

UND: System policy for incoming traffic: Allow all other incoming traffic
Dies könnte evtl. auf „Deny“ stehen, womit passives FTP nicht mehr funktioniert, da Server und Client ein zufällig ausgewähltes Port zur Datenübertragung nutzen – also „Allow“ muss sein.

Zur abschließenden Kontrolle per SSH, welche Prozesse nun insgesamt auf welche Ports horchen:
netstat -pltn

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.