WordPress CLI installieren und nutzen

Für das Content-Management-System WordPress existiert neben dem eigentlichen System auch eine separate Kommandozeile. Die hört auf den Namen WP-CLI und muss im ersten Schritt installiert werden:

curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
chmod +x wp-cli.phar
mv wp-cli.phar /usr/local/bin/wp

Damit ist die WP-CLI installiert und kann über das Kommando:

wp --info

getestet werden. Um WP-CLI aktuell zu halten, kann das Kommando:

wp cli update

genutzt werden.

Grundsätzlich sollten die Befehle der WP-CLI im Kontext des Webserver-Nutzers ausgeführt werden. In den meisten Fällen ist dies www-data. Eine Ausnahme bilden die Befehle zur Installation und zur Aktualisierung. Wird versucht ein WP-CLI-Befehl unter dem root-Nutzer auszuführen, so erhält der Nutzer folgende Meldung:

Error: YIKES! It looks like you’re running this as root. You probably meant to run this as the user that your WordPress installation exists under.

If you REALLY mean to run this as root, we won’t stop you, but just bear in mind that any code on this site will then have full control of your server, making it quite DANGEROUS.

If you’d like to continue as root, please run this again, adding this flag: –allow-root

If you’d like to run it as the user that this site is under, you can run the following to become the respective user:

sudo -u USER -i — wp

Per sudo mit dem korrekten Nutzer ausgeführt funktioniert das Ganze:

sudo -u www-data wp transient delete --all
Success: 163 transients deleted from the database.

Mittels der WP-CLI lassen sich eine Reihe von Aufgaben bewerkstelligen. So verfügt die CLI über Methoden, um Kommentare zu erzeugen und zu verwalten. Mit dem Befehl:

wp comment delete $(wp comment list --status=spam --format=ids)

können z.B. alle Spam-Kommentare gelöscht werden. Über den core-Namespace können unter anderem WordPress-Updates vorgenommen werden:

wp core update

Vor allem im Zusammenhang mit einer Automation spielt WP-CLI seine Stärken aus. So können neue WordPress-Installationen angelegt werden und entsprechende Plugins automatisch installiert werden. In der Entwickler-Dokumentation von WordPress findet sich eine Referenz der Befehle der WP-CLI.

Entwickelt wird WP-CLI auf Github. Lizenziert ist das CLI unter der MIT-Lizenz und damit freie Software. Die offizielle Seite des Projektes ist unter wp-cli.org zu finden.

RAID-Synchronisation unter Ubuntu beschleunigen

Wenn ein Ubuntu-Server mit einem Software-RAID betrieben wird, so kann der Status des RAIDs über den Befehl:

cat /proc/mdstat

eingesehen werden. Eine entsprechende Ausgabe könnte dann wie folgt aussehen:

Personalities : [raid1] [linear] [multipath] [raid0] [raid6] [raid5] [raid4] [raid10] 
md1 : active raid1 sda2[0] sdb2[1]
      11714556864 blocks super 1.2 [2/2] [UU]
      bitmap: 6/88 pages [24KB], 65536KB chunk

md0 : active raid1 sda1[0] sdb1[1]
      4189184 blocks super 1.2 [2/2] [UU]
      
unused devices: <none>

Wird ein RAID neu aufgebaut bzw. synchronisiert sieht die Ausgabe etwas ausführlicher aus:

Personalities : [raid1] [linear] [multipath] [raid0] [raid6] [raid5] [raid4] [raid10] 
md1 : active raid1 sda2[0] sdb2[1]
      11714556864 blocks super 1.2 [2/2] [UU]
      [==================>..]  resync = 94.6% (11088768000/11714556864) finish=153.3min speed=67991K/sec
      bitmap: 12/88 pages [48KB], 65536KB chunk

md0 : active raid1 sda1[0] sdb1[1]
      4189184 blocks super 1.2 [2/2] [UU]
      
unused devices: <none>

Die Synchronisation kann unter anderem über die Variable speed_limit_max gesteuert werden. Der Standardwert für dieses Limit liegt bei 200000. Wird dieser Wert höher gesetzt:

echo 1250000 > /proc/sys/dev/raid/speed_limit_max

kann die Synchronisation mehr Ressourcen nutzen und läuft somit schneller. Das bedeutet natürlich auch, dass das System im Allgemeinen stärker ausgelastet wird. Nach einem Neustart wird der geänderte Wert wieder auf seinen ursprünglichen Wert gesetzt.

Fehlende Nextcloud-Indicies erzeugen

Unter Umständen kann es bei einer Nextcloud-Installation dazu kommen, das nach einem Update folgende Meldung im Backend angezeigt wird:

In der Datenbank fehlen einige Indizes. Auf Grund der Tatsache, dass das Hinzufügen von Indizes in großen Tabellen einige Zeit in Anspruch nehmen kann, wurden diese nicht automatisch erzeugt. Durch das Ausführen von „occ db:add-missing-indices“ können die fehlenden Indizes manuell hinzugefügt werden, während die Instanz weiter läuft. Nachdem die Indizes hinzugefügt wurden, sind Anfragen auf die Tabellen normalerweise schneller.

Fehlender Index „direct_edit_timestamp“ in der Tabelle „oc_direct_edit“.

Fehlende Indices können unter anderem zu Performanceeinbußen führen, sodass die Indices erstellt werden sollten. Möglich ist dies mit dem Tool occ, welches in der Nextcloud-Installation vorhanden ist. Dieses sollte im Ordner der Nextcloud-Installation ausgeführt werden:

sudo -u www-data php occ db:add-missing-indices

Anschließend findet eine Überprüfung der Indices statt:

Check indices of the share table.
Check indices of the filecache table.
Check indices of the twofactor_providers table.
Check indices of the login_flow_v2 table.
Check indices of the whats_new table.
Check indices of the cards table.
Check indices of the cards_properties table.
Check indices of the calendarobjects_props table.
Check indices of the schedulingobjects table.
Check indices of the oc_properties table.
Check indices of the oc_jobs table.
Check indices of the oc_direct_edit table.
Adding direct_edit_timestamp index to the oc_direct_edit table, this can take some time...
oc_direct_edit table updated successfully.

Fehlende Indices werden hierbei automatisch angelegt und damit eventuellen Performanceeinbußen vorgebeugt.

Fail2ban für WordPress einrichten

Beim Betrieb eines Servers wird der Nutzer schnell feststellen, dass er nicht der einzige ist, der gerne Zugriff auf den Ser­ver hätte. Um zu häu­fige Log­in­ver­su­che abzu­blo­cken, gibt es Fail2ban. Die­ses Pro­gramm­pa­ket durch­sucht die ent­spre­chen­den Logs und blockiert bös­wil­lige Ver­su­che, in das Sys­tem ein­zu­bre­chen. Damit gehört Fail2ban zu den Intru­sion Preven­tion-Sys­te­men. Damit kann es auch zur Auswertung von Login-Versuchen auf die eigenen WordPress-Installationen genutzt werden. Wer in die Logs schaut, wird dort ähnliche Zeilen finden:

18.217.216.181 – – [23/Nov/2021:19:32:40 +0100] „POST /wp-login.php HTTP/1.1“ 200 8408 „https://seeseekey.net/wp-login.php“ „Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:94.0) Gecko/20100101 Firefox/94.0“

Um WordPress mit Fail2ban zu verheiraten muss ein einsprechender Jail und ein Filter angelegt werden. Was mich im Vorfeld in Bezug auf WordPress irritierte war der Statuscode 200, wenn ein Login in WordPress fehlschlägt. Hintergrund ist hier das WordPress bei einem erfolgreichen Login stattdessen den Statuscode 302 (Found) nutzt. Damit kann im ersten Schritt der Jail für Fail2ban erstellt werden:

nano /etc/fail2ban/jail.d/wordpress.conf

Diese Datei wird nun wie folgt befüllt:

[wordpress]
enabled = true
port = http,https
filter = wordpress
logpath = /var/log/nginx/access.log
maxretry = 3

Anschließend muss der genutzte Filter ebenfalls angelegt werden:

nano /etc/fail2ban/filter.d/wordpress.conf

Der entsprechende Filter sieht wie folgt aus:

# Filter for WordPress login

[INCLUDES]

before = common.conf
 
[Definition]

failregex = <HOST>.*POST.*(wp-login\.php|xmlrpc\.php).* 200

datepattern = %%d/%%b/%%Y:%%H:%%M:%%S %%z

Nach einem Neustart von Fail2ban mittels:

service fail2ban restart

ist der neue Jail aktiv. Über das Log kann die Arbeit desselben betrachtet werden:

tail -f /var/log/fail2ban.log

Damit sind die WordPress-Installationen gegen den Versuch unbefugter Logins besser abgesichert. Nach drei Fehlversuchen, wird die entsprechende IP-Adresse gesperrt, sodass weitere Verbindungsversuche von dieser IP-Adresse vom Server nicht mehr beantwortet werden.

Etherpad unter Ubuntu installieren

Bei Etherpad handelt es sich um einen Editor für kollaboratives Schreiben, welcher selbst gehostet werden kann. Soll Etherpad unter Ubuntu gehostet werden, muss im ersten Schritt Node.js installiert werden:

apt install -y libssl-dev
curl -sL https://deb.nodesource.com/setup_14.x | bash -
apt install -y nodejs

Anschließend wird ein Nutzer für Etherpad angelegt und in diesen gewechselt werden und dort der Quellcode für Etherpad heruntergeladen und initial einmal gestartet und dann mittels Strg + C wieder beendet:

adduser --disabled-login --gecos "" etherpad
su - etherpad
git clone --branch master https://github.com/ether/etherpad-lite.git
cd etherpad-lite
npm install sqlite3
src/bin/run.sh

Nun werden einige Konfigurationen vorgenommen. Im Groben werden die Datenbank, die Authentifikation, Vorbereitungen für den Reverse Proxy, die Nutzer und die maximale Länge von einzufügendem Inhalt und das Log konfiguriert:

nano etherpad-lite/settings.json

Die Änderungen sind in ihrer Reihenfolge in der Konfigurationsdatei angegeben:

...

"dbType": "sqlite",
"dbSettings": {
  "filename": "var/sqlite.db"
},

...

"requireAuthentication": true,

...

"trustProxy": true,

...

"users": {
"admin": {
  // 1) "password" can be replaced with "hash" if you install ep_hash_auth
  // 2) please note that if password is null, the user will not be created
  "password": "example",
  "is_admin": true
},
"user": {
  // 1) "password" can be replaced with "hash" if you install ep_hash_auth
  // 2) please note that if password is null, the user will not be created
  "password": "example",
  "is_admin": false
}
},

...

"socketIo": {
/*
 * Maximum permitted client message size (in bytes). All messages from
 * clients that are larger than this will be rejected. Large values make it
 * possible to paste large amounts of text, and plugins may require a larger
 * value to work properly, but increasing the value increases susceptibility
 * to denial of service attacks (malicious clients can exhaust memory).
 */
"maxHttpBufferSize": 1048576
},

...

"logconfig" :
{ "appenders": [
    { "type": "console"
    //, "category": "access"// only logs pad access
    }

  , { "type": "file"
  , "filename": "etherpad.log"
  , "maxLogSize": 1024000
  , "backups": 3 // how many log files there're gonna be at max
    }

...

Anschließend wird der Kontext des Nutzers etherpad verlassen und eine neue Service-Unit für systemd angelegt:

exit
nano /etc/systemd/system/etherpad.service

Diese wird mit folgendem Inhalt befüllt:

[Unit]
Description=Etherpad
After=syslog.target
After=network.target

[Service]
Type=simple
User=etherpad
Group=etherpad
Environment="NODE_ENV=production"
ExecStart=/home/etherpad/etherpad-lite/src/bin/run.sh
Restart=always

[Install]
WantedBy=multi-user.target

Nachdem die Datei angelegt wurde, kann der Service aktiviert und gestartet werden:

systemctl enable etherpad
systemctl start etherpad

Lokal ist der Service nun per HTTP unter dem Port 9001 erreichbar. Damit der Service auch von außen erreichbar ist, kann Nginx als Reverse Proxy konfiguriert werden. Dazu muss die entsprechende Konfiguration hinterlegt werden:

server {
    listen 443 ssl;
    listen [::]:443 ssl;

    ssl_certificate        /etc/letsencrypt/live/example.org/fullchain.pem;
    ssl_certificate_key    /etc/letsencrypt/live/example.org/privkey.pem;

    server_name example.org;

    client_max_body_size 512m;

    location / {

        # Set proxy headers
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # These are important to support WebSockets
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";

        # Make sure to set your Etherpad port number
        proxy_pass http://localhost:9001;
    }
}

Damit steht Etherpad auch von außen unter der entsprechenden Domain zur Verfügung und kann benutzt werden.