IT security, FreeBSD, Linux, mail server hardening, post-quantum crypto, DNS, retro computing & hands-on hardware hacks. Privater Tech-Blog seit 2003.

Kategorie: Self-Hosting & Infrastruktur (Seite 2 von 9)

Server selbst betreiben — Erfahrungen mit FreeBSD-Jails, Nginx, Postfix, Dovecot, Matrix und der eigenen Infrastruktur.

WordPress wp-cron.php: Ist die angebliche Sicherheitslücke real?

Picture of an hacker checken for wordpress vulnerability

In letzter Zeit begegnen mir immer wieder sogenannte „Vulnerability Report Scams“. Klar, mit Angst und Unwissenheit kann man Geld verdienen, also wird es auch jemand tun. Besonders fällt mir das im Zusammenhang mit der wp-cron.php auf.

Ich habe häufig Reports gesehen, die in etwa so aussehen:

Critical Vulnerability Report- {Critical BUG #P1} - https://www.example.com/ - vulnerable to attack via wp-cron.php

Hello  Security team,

I am a Security Engineer, Cyber Security Researcher, Bug Bounty Hunter  & Ethical Hacker. While testing your domain https://www.example.com/ I have found some important vulnerabilities in your site.

Vulnerability Name:   https://www.example.com/  -  vulnerable to DoS attack via wp-cron.php

Vulnerable Domain:  https://www.example.com/wp-cron.php

Description:

The WordPress application is vulnerable to a Denial of Service (DoS) attack via the wp-cron.php script. This script is used by WordPress to perform scheduled tasks, such as publishing scheduled posts, checking for updates, and running plugins.
An attacker can exploit this vulnerability by sending a large number of requests to the wp-cron.php script, causing it to consume excessive resources and overload the server. This can lead to the application becoming unresponsive or crashing, potentially causing data loss and downtime.

I found this vulnerability at https://www.example.com/wp-cron.php endpoint.

Steps to Reproduce: reference- https://hackerone.com/reports/1888723

navigate to: https://www.example.com/wp-cron.php
intercept the request through the burp suite
right click on the request and send it to the repeater
Now send a request, and you will see the response as  200 OK

---

this can be also done by the curl command given below

curl -I "https://www.example.com/wp-cron.php"

POC: Attached

Impact:

If successful, this misconfigured wp-cron.php file can cause lots of damage to the site, such as:

Potential Denial of Service (DoS) attacks, resulting in unavailability of the application.
Server overload and increased resource usage, leading to slow response times or application crashes.
Potential data loss and downtime of the site.
Hackers can exploit the misconfiguration to execute malicious tasks, leading to security breaches.

Exploitation:
Exploitation can be done through a GitHub tool called doser.go https://github.com/Quitten/doser.go
I did not do that as this can impact your website.
Get the doser.py script at https://github.com/Quitten/doser.py
Use this command to run the script: python3 doser.py -t 999 -g 'https://www.example.com/wp-cron.php'
Go after https://www.example.com/ 1000 requests of the doser.py script.
The site returns code 502.

Suggested Mitigation/Remediation Actions:

To mitigate this vulnerability, it is recommended to disable the default WordPress wp-cron.php script and set up a server-side cron job instead. Here are the steps to disable the default wp-cron.php script and set up a server-side cron job:
Access your website's root directory via FTP or cPanel File Manager.
Locate the wp-config.php file and open it for editing.
Add the following line of code to the file, just before the line that says "That's all, stop editing! Happy publishing.":

1define('DISABLE_WP_CRON', true);

Save the changes to the wp-config.php file.
Set up a server-side cron job to run the wp-cron.php script at the desired interval. This can be done using the server's control panel or by editing the server's crontab file.
References:

For more information about this vulnerability, please refer to the following resources:

https://hackerone.com/reports/1888723

https://medium.com/@mayank_prajapati/what-is-wp-cron-php-0dd4c31b0fee

Cron
Fix Them ----- I have protected your company and saved it from a big loss so give me some appreciation Bounty Reward. I am sharing my PayPal ID with you. Paypal ID: woop woop Current Market Value Minimum Bounty Reward for Critical BUG P1 Type. The bug I reported is part of type P1 Vulnerability severity Bug bounty reward amount (in USD) P1 (Critical) $2500 P2 (High) $1500 P3 (Medium) $1000 P4 (Low) $500 Please feel free to let me know if you have any other questions or need further information. I am happy to secure it. I hope this will be fixed soon. Feel free to let me know if you have any other questions. Thanks & Regards

Ist das nun ein echtes Problem oder nicht?

Ja und Nein. In der Nachricht wird korrekt beschrieben, was die wp-cron.php tut und warum sie wichtig ist. Auch die Tatsache, dass sie extern unendlich oft aufgerufen werden kann und dadurch potenziell eine Überlastung auslösen könnte, ist nicht falsch. Selbst der Tipp, auf eine lokale Crontab-Version umzusteigen, ist nicht verkehrt. Allerdings muss man das Ganze in den richtigen Kontext setzen: wp-cron.php ist standardmäßig in WordPress aktiviert und wird für geplante Aufgaben genutzt. Die geplanten Aufgaben werden in der Datenbank abgelegt. Gibt es etwas zu tun und die wp-cron.php wird aufgerufen, dann wird auch gearbeitet. Gibt es nichts zu tun, dann gibt es auch keine Arbeit. Die Empfehlung, sie zu deaktivieren und durch einen serverseitigen Cron-Job zu ersetzen, ist eher eine Performance-Optimierung als eine echte Sicherheitsmaßnahme.

Es handelt sich nicht um einen Zero-Day-Exploit und es gibt keine direkte Gefahr eines Datenabflusses. Falls es wirklich zu Performance-Problemen kommt, gibt es einfache Gegenmaßnahmen. Sollte tatsächlich jemand versuchen, die wp-cron.php gezielt anzugreifen, hilft ein simples Rate Limiting, entweder über die Firewall oder direkt mit mod_security (Apache) bzw. limit_req (nginx).

Rate Limiting mit nginx

limit_req_zone $binary_remote_addr zone=cronlimit:10m rate=1r/s;

server {
    location = /wp-cron.php {
        limit_req zone=cronlimit burst=3 nodelay;
        limit_req_status 429;
    }
}

Das begrenzt die Anfragen auf 1 pro Sekunde, mit maximal 3 Anfragen in kurzer Zeit.

Sollte man wp-cron.php deaktivieren?

Nicht unbedingt. Klar, im Fall eines Angriffs kann das als erste Maßnahme helfen. Besser ist es aber, wp-cron.php lokal auszuführen und den Zugriff darauf über den Webserver auf bestimmte IP-Adressen zu beschränken. Anschließend kann man einen Cronjob anlegen, der alle 15 Minuten ausgeführt wird:

*/15 * * * * wget -q -O - https://www.example.com/wp-cron.php?doing_wp_cron >/dev/null 2>&1

Zugriff per nginx einschränken:

location ~* ^/wp-cron.php$ {
    allow 1.2.3.4;  # Ersetze mit deiner IP
    deny all;
}

Fazit

Das ist ganz sicher kein P1-Bug. Und wenn der Report direkt eine Preistabelle mitliefert, ist das schon ein ziemlich eindeutiges Zeichen für einen Scam.

  • Ja, wp-cron.php könnte unter bestimmten Umständen zu Problemen führen.
  • Nein, es ist kein echter Sicherheits-Bug.
  • Wer weiß, was er tut, hat bereits die richtigen Maßnahmen getroffen.

Keine Panik. Stattdessen lieber kurz die eigene Konfiguration prüfen und gut ist. Wer auf das nginx Rate Limit setzt und dieses testen möchte, kann mein rate_limit_test.sh auf GitHub nutzen.

Siehe auch: Ist mein Netzwerk kompromittiert?

Fragen? Einfach melden.

FreeBSD SSH-Server absichern: MFA mit Google Authenticator einrichten​

SSH-Keys sind der Standard. Aber manchmal lässt es sich nicht vermeiden, dass ein Login nur mit Benutzername und Kennwort abgesichert ist. Um das aufzuwerten, lässt sich der SSH-Server mit einem zweiten Faktor ausstatten — hier mit dem Google Authenticator (TOTP) auf FreeBSD.

Installation

pkg install pam_google_authenticator

PAM-Konfiguration

In /etc/pam.d/sshd das Google Authenticator PAM-Modul als zweiten required-Eintrag nach pam_unix einfügen:

#
# PAM configuration for the "sshd" service
#

# auth
auth		required	pam_unix.so		no_warn try_first_pass
auth		required	/usr/local/lib/pam_google_authenticator.so

# account
account		required	pam_nologin.so
account		required	pam_login_access.so
account		required	pam_unix.so

# session
session		required	pam_permit.so

# password
password	required	pam_unix.so		no_warn try_first_pass

Die Reihenfolge ist wichtig: Erst das Kennwort (pam_unix), dann der TOTP-Code. Auf dem gleichen Weg lässt sich MFA auch für su, den Konsolen-Login oder SSH-Keys einrichten — einfach das entsprechende PAM-File anpassen.

sshd_config anpassen

In /etc/ssh/sshd_config muss Challenge-Response aktiviert sein:

# Seit OpenSSH 8.7 heißt die Option KbdInteractiveAuthentication
# ChallengeResponseAuthentication ist ein Alias und funktioniert weiterhin
KbdInteractiveAuthentication yes

Danach service sshd restart — aber vorher sicherstellen, dass man noch eine offene Session hat, falls etwas nicht stimmt.

Authenticator einrichten

Auf dem Smartphone den Google Authenticator installieren (oder eine andere TOTP-App wie Aegis, 2FAS oder den Microsoft Authenticator). Dann auf dem Server mit dem gewünschten Benutzer google-authenticator aufrufen:

cd ~
google-authenticator

Das Tool zeigt einen QR-Code im Terminal, den man mit der Authenticator-App scannt:

Danach den angezeigten Code einmal eingeben — fertig. Bei jedem Kennwort-Login wird jetzt zusätzlich der aktuelle TOTP-Code abgefragt.

Wichtig: Das Tool zeigt auch Backup-Codes an. Diese unbedingt sicher aufbewahren — wenn das Smartphone verloren geht, kommt man sonst nicht mehr rein. Die Konfiguration liegt in ~/.google_authenticator und kann dort auch nachträglich eingesehen werden.

Siehe auch: FreeBSD OpenSSH: OS-Banner sicher entfernen, SSH-Bruteforce, DigitalOcean und AbuseIPDB – warum Blocken das Problem nicht löst

Unter Linux ist die Einrichtung sehr ähnlich — das PAM-Modul heißt dort libpam-google-authenticator. Fragen? Einfach melden.

DNS over TLS mit BIND, Stunnel und Android 9: Eigener DoT-Server

Die Zeit ging weiter, die Entwicklung bei BIND und DNS ebenfalls. Daher gibt es nun einen neuen Beitrag, der das aktuelle Setup mit BIND 9.20 auf FreeBSD 15 beschreibt – inklusive sauberer Trennung von authoritative DNS (Port 53) und öffentlichem Resolver (DoT/DoH) sowie reproduzierbaren CLI-Tests für IPv4 und IPv6. Bitte dort weiterlesen.

Über die Techniken DoT (DNS over TLS) habe ich bereits im Zusammenhang mit Bind 9.16 geschrieben. Ebenfalls DoH (DNS over HTTPS) gibt es einen kleinen Beitrag.

Bilder der Bind 9 TLS Konfiguration

Zu diesem Zeitpunkt bracht BIND 9 die Unterstützung für DoH und DoT noch nicht selbst mit. Daher waren zu diesem Zeitpunkt noch Umwege über stunnel oder nginx zusammen mit doh-proxy nötig.

Zum Glück kommt die letzte stable Version 9.18.0 (26. Januar 2022) mit dem nötigen Support.

named now supports securing DNS traffic using Transport Layer Security (TLS). TLS is used by both DNS over TLS (DoT) and DNS over HTTPS (DoH).

Warum möchte man noch gleich DoH oder DoT benutzen? Ganz einfach… Über diese Techniken werden DNS Abfragen verschlüsselt übertragen. Dieses ist ein weiterer Schutz davor manipulierte Antworten zu bekommen und selbstverständlich, damit die eigenen DNS Abfragen erst überhaupt nicht mitgelesen werden. Denn wenn von einem Gerät im Netzwerk die DNS Abfrage zu z.B.: www.tagesschau.de kommt, könnte man davon bereits Dinge ableiten.

Wie die meisten Bind Konfigurationen ist dieses ebenfalls straightforward. Ab Version 9.18 bringt Bind alles Nötige mit. Da wir nun TLS mit dem Bind sprechen möchten, benötigen wir natürlich ein gültiges Zertifikat, wie z.B. beim nginx für seine Webseite.

Ebenfalls sollte man ein paar frische Diffie-Hellmann Parameter generieren:

openssl dhparam -out dhparam.pem 4096

Die eigentliche bind Konfiguration kann in der named.conf.options geschehen:

options {
        [...]
        listen-on port 853 tls local-tls { 37.120.183.220; };
        listen-on-v6 port 853 tls local-tls { 2a03:4000:38:20e::853; };
        listen-on port 443 tls local-tls http default { 37.120.183.220;  };
        listen-on-v6 port 443 tls local-tls http default { 2a03:4000:38:20e::853; };
        [...]
        allow-recursion-on { 127.0.0.0/8; ::1/128; 2a03:4000:38:20e::853; 37.120.183.220; };
        [...]
};

Da der bind auf weiteren Ports lauschen soll erweitert man diese für IPv4 und IPv6. Der Default Port für DoH ist dabei 443 und der default Port für DoT ist 853, beides TCP.

listen-on sowie listen-on-v6 sind wohl selbsterklärend.
port ist der TCP Port und erklärt sich ebenfalls.
tls sagt dem Bind das wir tls sprechen möchten.
local-tls verweißt auf den gleichnamigen tls Block über welchen man seine TLS Konfiguration vornimmt.
http ist für DoH.
default gibt den eigentlichen endpoint für die DoH Abfragen an, im default ist es /dns-query

Da der Server unsere DNS Abfragen erledigen soll, müssen wir ihm dieses noch per allow-recursion-on auf den jeweiligen Adressen erlauben.

Als nächstes wird die eigentliche TLS Terminierung konfiguriert (das lässt sich ebenfalls auslagern, wenn gewünscht). Dafür wird der folgende Block, außerhalb der Options Blocks, ergänzt:

tls local-tls {
    cert-file "/usr/local/etc/ssl/wild.kernel-error.de/2022/ecp/chain.crt";
    key-file "/usr/local/etc/ssl/wild.kernel-error.de/2022/ecp/http.key";
    dhparam-file "/usr/local/etc/ssl/dhparam.pem";
    protocols { TLSv1.2; TLSv1.3; };
    ciphers "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256";
    prefer-server-ciphers yes;
    session-tickets no;
};

local-tls ist dabei der name des Blocks. Auf diesen verweisen wir oben.
cert-file ist der Pfad zum Zertifikat. Ich habe dort nicht nur das Zertifikat, sondern die gesamte Chain, also mit Intermediate und Root.
key-file ist der Pfad zum Key des Zertifikates.
dhparam-file ist der Pfad zu den Diffie-Hellman Parametern.
protocols definiert die zu verwendenden TLS Protokolle. In diesem Beispiel TLS1.2 sowie TLS1.3.
ciphers definiert die zu verwendenden cipher. Es soll ja „sicher“ bleiben.
prefer-server-ciphers übermittelt dem Client die Information, in welcher Reihenfolge protokoll/cipher Kombinationen probiert werden sollen um einen Match zu finden. Erst das vermeintlich sicherste und dann immer „schlechter“.
session-tickets regelt ob eine Wiederaufnahme von TLS Sessions erlaubt ist oder nicht. Da ich forward secrecy nutzen möchte, ist es deaktiviert.

Damit ist die Konfiguration schon abgeschlossen (Firewall ggf. nicht vergessen!). Also testen….

Ein einfaches Tool dafür ist dog, oder natürlich dig aus den bind-tools aber Version 9.18. Für bind gibt es dann die Optionen +https oder auch +tls

dig +https @dns.kernel-error.de www.kernel-error.de A
dig +tls @dns.kernel-error.de www.kernel-error.de A

Der gleiche Test mit dog, sieht wie folgt aus:

dog www.kernel-error.de --tls "@dns.kernel-error.de"
A www.kernel-error.de. 6h00m00s   148.251.40.23
dog www.kernel-error.de --https "@https://dns.kernel-error.de/dns-query"
A www.kernel-error.de. 6h00m00s   148.251.40.23

Das war es auch schon! Viele Spaß mit einem „besseren“ DNS und wenn es noch Fragen gibt, einfach fragen.

Dead-Link-Checker für die Konsole: Effektive Tools im Überblick

Tote Links auf einer Webseite zu suchen, kann aufwendig sein. Es gibt viele Angebote im Internet, diese sind aber meist auf eine gewisse Anzahl Seiten beschränkt und ab dann kostenpflichtig.

Ich mag Tools, die einen Job gut können und dieses möglichst einfach erledigen. Daher habe ich für diesen Fall den LinkChecker für die CLI.

404 ERROR mit totem gehäkelten Link von Selder.

Das Tool ist schnell per pip installiert:

pip3 install linkchecker

Die Bedienung ist nicht viel komplizierter:

linkchecker https://www.kernel-error.de

Ohne weitere Angaben läuft das Tool mit 10 threads los, dieses lässt sich über die Option -t erweitern:

linkchecker -t 200 https://www.kernel-error.de

Nun läuft das Tool über die komplette Webseite und prüft alle Links, ist einer kaputt, meldet das Tool dieses. Dabei bekommt man direkt die Informationen, was verlinkt wurde, was der eigentliche Link ist und auf welcher seiner Seiten sich dieses befindet. So lässt sich ohne große Mühe und Arbeit nach toten Links suchen und diese im Anschluss beheben.

URL        `www.kernel-error.de'
Parent URL https://www.kernel-error.de/en/lala/seite, line 746, col 17
Real URL   https://www.kernel-error.de/en/lala/zeugen
Check time 67.089 seconds
Result     Error: 404 Not Found

Viel Spaß!

Link zur Dead Link Bild Quelle: https://www.deviantart.com/amiamalilium/art/It-looks-like-you-found-a-dead-link-365756737

Fragen? Einfach melden.

Jetzt mit HTTP/3 und QUIC: Schnelleres Surfen leicht gemacht

Von QUIC habt ihr sicher alle schon gehört, seit knapp Mitte 2021 ist dieser neue Standard fertig und in einem recht einfach zu merkendem RFC 9000 beschrieben.

Im Grunde geht es darum, HTTP-Verbindungen schneller zu machen und dabei sogar UDP zum Einsatz zu bringen. Nicht ganz korrekt ist es einfach eine Weiterentwicklung von SPDY.

Um zu testen, ob eine Webseite bereits HTTP/3 also QUIC unterstützt, kann ich euch http3check.net ans Herz legen. Diese gibt, wenn gewünscht, sogar noch ein paar Detailinformationen aus.

Wer sehen möchte, ob sein Browser QUIC „macht“, kann auch nginx.org nutzen. Steht oben „Congratulations! You’re connected over QUIC.“ Dann ist man ein Gewinner.

Die Konfiguration am Nginx ist wie immer sehr einfach und ein sehr gutes Beispiel findet sich direkt von nginx.

Mein Nginx spricht dieses nun ebenfalls, mal sehen ob es Probleme gibt.


Update März 2026: Drei Jahre HTTP/3 im Betrieb

Es sind jetzt gut drei Jahre vergangen und ich kann sagen: Es gab keine Probleme. Kein einziges. HTTP/3 läuft hier seit 2022 auf allen vHosts und ich habe nie einen Fehler gesehen, der auf QUIC zurückzuführen war. Auch in den Logfiles nichts Auffälliges.

Illustration zu HTTP/3 und QUIC: schneller Web-Transport über UDP mit moderner Verschlüsselung und Browser-Support

Was sich geändert hat: Damals war HTTP/3 in Nginx noch experimentell und brauchte einen separaten Build mit dem quiche-Patch oder BoringSSL. Seit Nginx 1.25.0 (Mai 2023) ist HTTP/3 offiziell im Mainline-Branch enthalten und wird mit dem normalen --with-http_v3_module Build-Flag aktiviert. Kein Patch mehr, kein BoringSSL mehr, einfach OpenSSL 3.x und fertig. Mein aktueller Stack: Nginx 1.29.4 mit OpenSSL 3.5.4 auf FreeBSD 15.

Was bringt HTTP/3 in der Praxis?

Der größte Vorteil von QUIC gegenüber TCP ist die Verbindungsaufbauzeit. Bei TCP+TLS braucht ihr mindestens zwei Roundtrips, bevor Daten fließen (TCP Handshake + TLS Handshake). QUIC macht das in einem einzigen Roundtrip. Bei einem Wiederverbindungsversuch sogar in null Roundtrips (0-RTT).

Auf einer Glasfaserleitung mit 5 ms Latenz merkt ihr das kaum. Aber auf einem Smartphone im Zug mit 80 ms Latenz und gelegentlichem Paketverlust macht das einen spürbaren Unterschied. Dazu kommt, dass QUIC auf UDP basiert und damit das Head-of-Line-Blocking Problem von TCP löst: Ein verlorenes Paket blockiert nicht mehr alle Streams, sondern nur den einen betroffenen.

Konfiguration 2026

Die Konfiguration hat sich seit 2022 etwas verändert. Hier mein aktuelles Setup für den Blog-vHost:

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

    http2 on;

    server_name  www.kernel-error.de;

    # TLS (wird per include eingebunden)
    include tls-default.conf;
    ssl_certificate      /path/to/fullchain.pem;
    ssl_certificate_key  /path/to/privkey.pem;

    # ...
}

Wichtig sind zwei Dinge. Erstens: Der quic Listener läuft auf demselben Port 443 wie der SSL-Listener, nur eben über UDP statt TCP. Zweitens: Die Clients müssen wissen, dass HTTP/3 verfügbar ist. Das passiert über den Alt-Svc Header:

add_header Alt-Svc 'h3=":443"; ma=86400' always;

Dieser Header sagt dem Browser: „Ich spreche auch h3 auf Port 443, merk dir das für 24 Stunden.“ Beim nächsten Besuch nutzt der Browser dann direkt QUIC. Ohne diesen Header bleibt alles bei HTTP/2 über TCP.

Optional könnt ihr auch einen HTTPS-DNS-Record (SVCB) setzen, damit der Browser schon beim DNS-Lookup weiß, dass HTTP/3 verfügbar ist:

$ dig +short HTTPS www.kernel-error.de
1 . alpn="h3,h2" ipv4hint=148.251.30.200 ipv6hint=2a01:4f8:262:4716::443

Mit alpn="h3,h2" im HTTPS-Record kann der Browser die QUIC-Verbindung schon beim allerersten Besuch aufbauen, ohne erst auf den Alt-Svc Header warten zu müssen.

Firewall nicht vergessen

Ein Klassiker, der mich 2022 kurz stolpern ließ: QUIC braucht UDP Port 443. Wenn eure Firewall nur TCP 443 durchlässt, sehen die Clients den Alt-Svc Header, versuchen QUIC und laufen ins Timeout. Auf FreeBSD mit pf:

pass in quick on $ext_if proto udp to $jail_nginx port 443

Post-Quantum-Kryptografie inklusive

QUIC verwendet intern TLS 1.3 für die Verschlüsselung. Das heißt: Wenn ihr in eurer Nginx-TLS-Konfiguration X25519MLKEM768 als Key-Exchange-Gruppe konfiguriert habt, gilt das automatisch auch für QUIC-Verbindungen. Kein extra Aufwand. Euer HTTP/3 Traffic ist dann ebenfalls mit hybridem Post-Quantum-Schlüsselaustausch abgesichert.

Browser-Support

2022 war HTTP/3 noch ein Feature für Early Adopter. 2026 ist es Standard. Chrome, Firefox, Safari und Edge unterstützen QUIC seit Jahren. Laut den Logfiles dieses Blogs nutzen inzwischen gut 40% der Besucher HTTP/3. Tendenz steigend, weil immer mehr Mobilgeräte von dem schnelleren Verbindungsaufbau profitieren.

Wer es noch nicht aktiviert hat: Der Aufwand ist minimal, die Vorteile real und das Risiko gleich null. Drei Jahre Betrieb ohne ein einziges Problem sprechen für sich.

Siehe auch: HTTPS RR und SVCB Records — per DNS-Record signalisieren, dass HTTP/3 verfügbar ist. Damit können Clients direkt mit QUIC starten, ohne vorher TCP zu probieren.

Wechsel zur WordPress

Ich nutze Joomla seit 2006, als es aus Mambo hervorging. Die Datenbank und einige Plugins/Teils sind inzwischen also sehr alt und machen bei Versionssprüngen immer mehr Probleme. Den Wechsel vom CMS habe ich dennoch immer von mir weggeschoben, denn es macht viel Arbeit und für eine solch kleine Spielerei lohnt der Aufwand kaum. Da ich es inzwischen eh nur noch für einfache Blogeinträge nutze… Nun ich werde wohl in der nächsten Zeit auf WordPress wechseln. Damit wird es ebenfalls einen neuen RSS Feed geben und sicher wird ebenfalls viel Content verschwinden.

Fragen? Einfach melden.

Windows Server RRAS: L2TP/IPsec-VPN mit sicheren Cipher Suites

RRAS Routing und RAS Icon.

Wenn ich schon bei Microsoft-Themen bin: Warum nicht gleich noch RRAS (Routing und RAS) mit einem L2TP/IPsec-VPN absichern? Im Standard verbinden sich die Clients nämlich mit SHA-1, 3DES und DH Group 2 (modp1024, also 1024 Bit). SHA-1 ist grenzwertig, 3DES muss nicht sein und modp1024 will man definitiv nicht mehr.

Hinweis: Ursprünglich für Windows Server 2012 R2 geschrieben (inzwischen End of Life). Die Konfiguration über die Windows-Firewall funktioniert auf neueren Versionen identisch.

Wo man die Einstellung findet (Spoiler: nicht bei RRAS)

Ich habe einige Zeit gesucht. Man würde erwarten, dass die IPsec-Cipher irgendwo in der Nähe von Routing und RAS konfiguriert werden. Falsch gedacht. Die Einstellung steckt in der Windows-Firewall mit erweiterter Sicherheit. Irgendeinen Grund wird es haben, das dort zu verstecken. Ich hätte dort nie gesucht.

Der Klickpfad: Windows Firewall → Rechtsklick auf „Windows-Firewall mit erweiterter Sicherheit“ → Eigenschaften → IPsec-Einstellungen → IPsec-Standardeinstellungen → „Anpassen“ → Schlüsselaustausch.

Screenshot der Windows-Firewall mit erweiterter Sicherheit und angezeichnetem Klickpfad um die Sicherheitsmethoden zu konfigurieren.

Hier kann man die Sicherheitsmethoden und Datenschutzeinstellungen anpassen. Windows Firewall als Ort für VPN-Cipher-Konfiguration. Kopfschütteln.

Screenshot der Windows-Firewall mit erweiterter Sicherheit und angezeichnetem Klickpfad um die Datenschutzeinstellungen zu konfigurieren.

UDP Encapsulation hinter NAT

Steht der RRAS hinter einem NAT, muss man noch UDP Encapsulation per Registry aktivieren. Dafür habe ich ein Registry-File:

Registry-File für IPsec UDP Encapsulation

Nach allen Änderungen den Server neu starten. Microsoft halt.

Prüfen ob es geklappt hat

Auf einem Windows-Client per PowerShell (mit erweiterten Rechten) prüfen, welche Cipher die VPN-Verbindung tatsächlich nutzt:

Get-NetIPsecMainModeSA | Select-Object -First 1
Screenshot des Kommandos Get-NetIPsecMainModeSA inkl Konsolenausgabe.

Relevant sind CipherAlgorithm, HashAlgorithm und GroupId. Im Standard steht da 3DES, SHA-1 und DH Group 2 (1024 Bit). Nach den Änderungen:

Encryption:                AES256
Authentication/Integrity:  SHA-1
Key Size:                  DH Group 20 (384-bit ECC)

Immer noch SHA-1 für die Integrity, aber AES-256 und ECC sind ein großer Sprung. Über Gruppenrichtlinien ließe sich das Ganze auch zentral ausrollen, aber das ist nochmal ein eigenes Thema. Vor allem die Reihenfolge korrekt vorzugeben ist dort unerwartet fummelig.

Wer auch die TLS-Cipher für Exchange/OWA härten will: SSL Labs A+ mit Exchange. Fragen? Einfach melden.

WSUS-Bereinigung: Timeouts beheben und Speicherplatz freigeben

WSUS Windows Server Update Service Icon

Pfffff… Einen dauerhaft richtig gut laufenden WSUS Server habe ich tatsächlich noch nie gesehen. Irgendwann werden die Dinger langsam, dann gibt es Timeouts, die Serverbereinigung läuft nicht mehr durch und die Platten laufen voll. WSUS ist kein Dienst, den man einmal konfiguriert und dann läuft er. WSUS möchte dauerhaft Aufmerksamkeit. Was mir dabei so aufgefallen ist, möchte ich hier teilen.

Keine Treiberupdates über WSUS

Screenshot der WSUS-Oberfläche: Produkte und Klassifizierungen konfigurieren.

Nie Treiberupdates über WSUS verteilen. Hier explodiert der Platzverbrauch. Falls aktiviert: Über Optionen → Produkte und Klassifizierungen → Klassifizierungen den Haken bei „Treiber“ entfernen. Dann unter Updates → Alle Updates die Dropdown-Menüs auf „Genehmigung: Genehmigt“ und „Status: Alle“ setzen, nach Klassifizierung sortieren und alle Treiberupdates ablehnen.

Abgelehnte Updates löschen

Abgelehnte Updates belegen weiterhin Plattenplatz, bis sie aktiv gelöscht werden. Dieses PowerShell-Script räumt sie weg — es läuft eine Weile, schafft aber viel Platz:

Screenshot der PowerShell ISE mit WSUS-Bereinigungsscript.
[reflection.assembly]::LoadWithPartialName("Microsoft.UpdateServices.Administration")
$wsus = [Microsoft.UpdateServices.Administration.AdminProxy]::GetUpdateServer();
$wsus.GetUpdates() | Where {$_.IsDeclined -eq $true} | ForEach-Object {
    $wsus.DeleteUpdate($_.Id.UpdateId.ToString())
    Write-Host $_.Title removed
}

Serverbereinigung automatisieren

Der „Assistent für die Serverbereinigung“ löscht überflüssige Updates — abgelehnte, ersetzte und nicht mehr benötigte. Man sollte ihn regelmäßig laufen lassen, aber er lässt sich nicht direkt automatisieren. Dafür braucht man ein PowerShell-Script, das man per Aufgabenplanung täglich ausführt:

# Variablen
$DateFormat = Get-Date -format yyyyMMdd-HH-mm
$Logfile = "H:\Logs\wsus-bereinigung-$DateFormat.log"

# WSUS Bereinigung durchführen
Invoke-WsusServerCleanup -CleanupObsoleteUpdates `
    -CleanupUnneededContentFiles -CompressUpdates `
    -DeclineExpiredUpdates -DeclineSupersededUpdates `
    | Out-File $Logfile

# Status-Mail versenden
$MailBody = Get-Content $Logfile | Out-String
Send-MailMessage -SmtpServer "smtp.example.de" `
    -From "wsus@example.de" -To "admin@example.de" `
    -Subject "${env:COMPUTERNAME} Bereinigung $DateFormat" `
    -Body $MailBody -Encoding Unicode

IIS-Einstellungen bei Timeouts

Wenn die WSUS-Konsole oder Bereinigung mit Timeouts abbricht, hilft es oft, dem WsusPool im IIS mehr Ressourcen zu geben:

IIS-Manager → Anwendungspools → WsusPool → Erweiterte Einstellungen

  • Limit für den privaten Speicher (KB): 6000000
  • Maximale Anzahl von Arbeitsprozessen: 0
  • Startmodus: AlwaysRunning

Danach den IIS neu starten — oder besser gleich den ganzen Server, es ist ja ein Windows.

SUSDB-Datenbank warten

Screenshot der Database Properties SUSDB: Compatibility Level auf SQL Server 2012 setzen.

Mit dem SQL Server Management Studio zur Windows Internal Database verbinden: \\.\pipe\MICROSOFT##WID\tsql\query

Compatibility Level anheben: Databases → SUSDB → Properties → Options → Compatibility level: SQL Server 2012 (110)

Screenshot SUSDB Shrink Database Dialog.

Datenbank verkleinern: Databases → SUSDB → Tasks → Shrink → Database

Synchronisierungshistorie aufräumen:

Screenshot SQL Server Management Studio mit Bereinigungsquery für WSUS-Synchronisierungen.
USE SUSDB
GO
DELETE FROM tbEventInstance
WHERE EventNamespaceID = '2'
  AND EVENTID IN ('381', '382', '384', '386', '387', '389')

Wenn die Bereinigung hängen bleibt

Manchmal bleibt die Serverbereinigung an einem bestimmten Update hängen. Dann hilft es, das erste Update in der „zu löschen“-Liste von Hand zu entfernen:

USE SUSDB
GO
-- Erste Update-ID ermitteln
exec spGetObsoleteUpdatesToCleanup
-- ID notieren und löschen
exec spDeleteUpdate @localUpdateID=HIER_UPDATE_ID

Wenn auch das nicht reicht, kann man alle obsoleten Updates in einer Schleife löschen — das läuft lange, räumt aber zuverlässig auf:

USE SUSDB
DECLARE @var1 INT, @curitem INT, @totaltodelete INT
CREATE TABLE #results (Col1 INT)
INSERT INTO #results(Col1) EXEC spGetObsoleteUpdatesToCleanup
SET @totaltodelete = (SELECT COUNT(*) FROM #results)
SELECT @curitem = 1

DECLARE WC Cursor FOR SELECT Col1 FROM #results
OPEN WC
FETCH NEXT FROM WC INTO @var1
WHILE (@@FETCH_STATUS > -1)
BEGIN
    RAISERROR('%d/%d: Deleting %d', 0, 1, @curitem, @totaltodelete, @var1) WITH NOWAIT
    EXEC spDeleteUpdate @localUpdateID=@var1
    SET @curitem = @curitem + 1
    FETCH NEXT FROM WC INTO @var1
END
CLOSE WC
DEALLOCATE WC
DROP TABLE #results

Abschließend die Indexe der SUSDB neu aufbauen — das beschleunigt danach alles spürbar. Microsoft hatte dafür ein Script in der TechNet Gallery veröffentlicht. Die Gallery ist inzwischen offline, aber das Script findet sich als WsusDBMaintenance.sql in diversen Microsoft-Docs-Artikeln. Im Kern macht es nichts anderes als fragmentierte Indexe zu erkennen und per ALTER INDEX REBUILD oder REORGANIZE zu reparieren, gefolgt von sp_updatestats.

Meist hilft eine Kombination aus mehreren dieser Maßnahmen. Bisher hat mir immer irgendetwas davon geholfen — auch wenn ich dafür einige Zeit in Suchmaschinen verschwenden musste. Fragen? Einfach melden.

Siehe auch: Windows Server Backup mit Nagios

Rspamd: Automatisches Spam/Ham-Lernen mit Dovecot und IMAPSieve

Rspamd hat ein Webinterface. Da kann man E-Mails reinkopieren und als Spam oder Ham markieren. Klingt erstmal praktisch. Ist es aber nicht. Niemand kopiert ernsthaft den Quellcode jeder fehlklassifizierten Mail in ein Webformular. Das macht man einmal zum Testen und dann nie wieder.

Automatisches Spam-Training mit Rspamd über Dovecot IMAPSieve – Mail wird zwischen Inbox und Junk verschoben

Was man eigentlich will: Wenn ein Benutzer eine Mail in den Junk-Ordner verschiebt, soll rspamd das automatisch als Spam lernen. Und wenn eine Mail aus dem Junk-Ordner rausgeholt wird, soll rspamd sie als Ham lernen. Kein Webinterface, kein manueller Eingriff. Der Benutzer sortiert einfach seine Mails — und rspamd lernt mit.

Genau das geht mit Dovecot und IMAPSieve. Hier beschreibe ich, wie ich das bei mir eingerichtet habe. Die Konfiguration läuft seit Mai 2020 unverändert — über sechs Jahre, ohne eine einzige Anpassung. Das darf man ruhig als stabil bezeichnen.

Was passiert da eigentlich

Der Datenfluss ist simpel:

  • Benutzer verschiebt eine Mail in den Ordner „Junk“
  • Dovecot erkennt die Verschiebung per IMAPSieve
  • IMAPSieve startet ein Sieve-Script
  • Das Sieve-Script ruft ein Shell-Script auf
  • Das Shell-Script übergibt die Mail per rspamc an rspamd
  • Rspamd lernt die Mail als Spam (Bayes-Klassifikator)

In die andere Richtung genauso: Mail raus aus Junk, Dovecot erkennt es, rspamd lernt Ham. Egal ob der Benutzer über Thunderbird, Roundcube, ein Smartphone oder was auch immer sortiert — solange es IMAP ist, greift das.

Voraussetzungen

  • Dovecot mit Sieve-Support (dovecot-pigeonhole unter FreeBSD, dovecot-sieve unter Debian/Ubuntu)
  • Rspamd mit laufendem Controller-Worker
  • rspamc CLI-Tool (kommt mit rspamd mit)

Mein Setup läuft auf FreeBSD. Die Pfade beginnen daher mit /usr/local/. Unter Linux ist es /etc/dovecot/ statt /usr/local/etc/dovecot/ und /usr/lib/dovecot/ statt /usr/local/libexec/dovecot/. Ansonsten ist alles identisch.

Mein rspamd läuft in einer eigenen Jail und lauscht auf 127.0.0.3:11334. Wer rspamd lokal auf dem gleichen System hat, nimmt stattdessen 127.0.0.1:11334 oder den Unix-Socket.

Dovecot konfigurieren

Zuerst muss das Sieve-Plugin für IMAP aktiviert werden.

20-imap.conf:

protocol imap {
  mail_plugins = $mail_plugins sieve
}

Dann die IMAPSieve-Konfiguration. Hier wird festgelegt, welche Ordner-Aktionen welches Sieve-Script auslösen.

90-plugin.conf:

plugin {
  sieve_plugins = sieve_imapsieve sieve_extprograms

  # Wenn eine Mail in den Junk-Ordner kopiert oder dort ein Flag geaendert wird
  imapsieve_mailbox1_name = Junk
  imapsieve_mailbox1_causes = COPY FLAG
  imapsieve_mailbox1_before = file:/usr/local/etc/dovecot/sieve/report-spam.sieve

  # Wenn eine Mail AUS dem Junk-Ordner woanders hin verschoben wird
  imapsieve_mailbox2_name = *
  imapsieve_mailbox2_from = Junk
  imapsieve_mailbox2_causes = COPY
  imapsieve_mailbox2_before = file:/usr/local/etc/dovecot/sieve/report-ham.sieve

  sieve_pipe_bin_dir = /usr/local/libexec/dovecot

  sieve_global_extensions = +vnd.dovecot.pipe
}

Zwei Trigger: Einer für „Mail landet im Junk“ (→ Spam lernen), einer für „Mail verlässt Junk“ (→ Ham lernen). COPY deckt Verschieben ab, FLAG fängt den Fall ab, dass ein Mail-Client den Junk-Status per Flag statt per Verschieben setzt.

Sieve-Scripts

Jetzt die beiden Sieve-Scripts, die von IMAPSieve aufgerufen werden.

report-spam.sieve — wird ausgelöst, wenn eine Mail im Junk-Ordner landet:

require ["vnd.dovecot.pipe", "copy", "imapsieve", "environment", "imap4flags"];

if environment :is "imap.cause" "COPY" {
    pipe :copy "sa-learn-spam.sh";
}

# Beantworteten oder weitergeleiteten Spam ebenfalls lernen
elsif anyof (allof (hasflag "\\Answered",
                    environment :contains "imap.changedflags" "\\Answered"),
             allof (hasflag "$Forwarded",
                    environment :contains "imap.changedflags" "$Forwarded")) {
    pipe :copy "sa-learn-spam.sh";
}

Der erste Block fängt das normale Verschieben ab. Der zweite Block ist für einen Sonderfall: Wenn jemand auf eine Mail im Junk-Ordner antwortet oder sie weiterleitet, ändert sich das Flag — und auch das sollte als Spam gelernt werden.

report-ham.sieve — wird ausgelöst, wenn eine Mail den Junk-Ordner verlässt:

require ["vnd.dovecot.pipe", "copy", "imapsieve", "environment", "variables"];

if environment :matches "imap.mailbox" "*" {
  set "mailbox" "${1}";
}

if string "${mailbox}" [ "Trash", "train_ham", "train_prob", "train_spam" ] {
  stop;
}

pipe :copy "sa-learn-ham.sh";

Hier passiert etwas Wichtiges: Bevor die Mail als Ham gelernt wird, prüfen wir wohin sie verschoben wurde. Wenn sie im Papierkorb landet, war das vermutlich kein „Das ist kein Spam“ sondern ein „Ich lösche den Spam“. Deshalb: stop; für Trash und die Trainingsordner. Nur wenn die Mail in einen echten Ordner verschoben wird, ist es ein Ham-Signal.

Beide Scripts müssen kompiliert werden:

sievec /usr/local/etc/dovecot/sieve/report-spam.sieve
sievec /usr/local/etc/dovecot/sieve/report-ham.sieve

Shell-Scripts für rspamc

Die Sieve-Scripts rufen Shell-Scripts auf, die die Mail per rspamc an rspamd übergeben. Simpel — jeweils ein Einzeiler.

/usr/local/libexec/dovecot/sa-learn-spam.sh:

#!/bin/sh
exec /usr/local/bin/rspamc -h 127.0.0.3:11334 learn_spam

/usr/local/libexec/dovecot/sa-learn-ham.sh:

#!/bin/sh
exec /usr/local/bin/rspamc -h 127.0.0.3:11334 learn_ham

Die Dateinamen sa-learn-* kommen historisch von SpamAssassin. Verwirrend, wenn man rspamd nutzt. Man könnte sie auch rspamd-learn-spam.sh nennen — funktional ist es egal. Ich habe sie so gelassen, weil man funktionierende Dinge nicht anfasst.

Beide ausführbar machen:

chmod +x /usr/local/libexec/dovecot/sa-learn-spam.sh /usr/local/libexec/dovecot/sa-learn-ham.sh

Wer rspamd lokal laufen hat, ersetzt 127.0.0.3 durch 127.0.0.1 oder nutzt den Unix-Socket (-h /var/run/rspamd/rspamd.sock). Unter Linux liegen die Scripts in /usr/lib/dovecot/ statt /usr/local/libexec/dovecot/. Der Pfad in sieve_pipe_bin_dir muss natürlich dazu passen.

Wichtig: Damit rspamc ohne Passwort trainieren darf, muss die IP im rspamd Controller-Worker als vertrauenswürdig eingetragen sein. In /usr/local/etc/rspamd/local.d/worker-controller.inc (FreeBSD) bzw. /etc/rspamd/local.d/worker-controller.inc (Linux):

secure_ip = "127.0.0.0/8";
secure_ip = "::1";

Ohne das schlägt rspamc learn_spam mit einem Authentifizierungsfehler fehl. Bei Jail-Setups wie meinem muss die Jail-IP (127.0.0.3) in der Liste stehen.

Testen

Dovecot neu laden:

service dovecot reload

Dann eine beliebige Mail in den Junk-Ordner verschieben und im rspamd-Log nachschauen:

rspamd_controller_learn_fin_task: <127.0.0.3> learned message as spam: MESSAGE-ID

Mail wieder raus aus Junk in den Posteingang:

rspamd_controller_learn_fin_task: <127.0.0.3> learned message as ham: MESSAGE-ID

Wenn das im Log steht, funktioniert alles. Kein Neustart nötig, kein Cache-Flush, kein Warten.

Wie viel Training braucht rspamd

Rspamd nutzt einen Bayes-Klassifikator. Der braucht eine Mindestmenge an gelernten Nachrichten, bevor er aktiv wird. Die Standardeinstellung ist 200 — also mindestens 200 Spam-Mails und 200 Ham-Mails. Vorher ignoriert rspamd die Bayes-Ergebnisse komplett.

Das klingt nach viel, geht aber schneller als man denkt. Wer ein paar Dutzend Benutzer auf dem Server hat, kommt da in wenigen Wochen hin. Und danach wird rspamd mit jeder sortierten Mail ein bisschen besser.

Den aktuellen Stand kann man jederzeit prüfen:

rspamc stat

Unter Statfile sieht man wie viele Nachrichten rspamd bereits gelernt hat.

Rspamd trainiert standardmäßig einen globalen Bayes-Klassifikator — alle Benutzer lernen in denselben Pool. Wer das pro Benutzer trennen will, setzt in der classifier-bayes.conf:

per_user = true;

Für die meisten Setups mit einer Handvoll Domains ist der globale Pool sinnvoller — mehr Trainingsdaten, schneller gute Ergebnisse.

Hinweise

Die Konfiguration ist stabil — Dovecot-Updates, rspamd-Updates, FreeBSD-Upgrades, alles durchgelaufen ohne Anpassung.

Wer rspamd danach noch eine Stufe weiter bringen will: Ich habe einen eigenen Beitrag geschrieben, wie man GPT-basierte Spam-Erkennung in rspamd integriert. Das läuft zusätzlich zum Bayes-Klassifikator und fängt die Mails ab, die durch das statistische Netz rutschen.

Siehe auch: Postfix und AMaViS: content_filter oder smtpd_proxy_filter?, DMARC-Prüfung in Postfix: OpenDMARC und rspamd im Vergleich

Fragen? Schreib mir über die Kontaktseite.

TLS-ECDHE mit AES-256-GCM-SHA384 einfach erklärt

Verschlüsselung-cipher

Wer sich mit TLS beschäftigt, stolpert früher oder später über Zeichenketten wie TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 oder TLS_AES_256_GCM_SHA384. Was da genau drinsteht, ist auf den ersten Blick nicht offensichtlich. Dabei folgt die Benennung einem klaren Schema.

Die Bestandteile einer Cipher Suite

Jede Cipher Suite beschreibt vier Dinge:

  • Key Exchange — wie sich Client und Server auf einen gemeinsamen Sitzungsschlüssel einigen.
  • Certificate Verification — wie das Serverzertifikat geprüft wird (Signaturverfahren).
  • Bulk Encryption — die symmetrische Verschlüsselung der eigentlichen Daten.
  • Hashing — die Prüfsummen, die Integrität und Authentizität sicherstellen.

TLS 1.2 vs. TLS 1.3

In TLS 1.2 stehen alle vier Bestandteile im Namen der Cipher Suite. Nehmen wir TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 auseinander:

  • TLS — das Protokoll (Transport Layer Security)
  • ECDHE — Key Exchange (Elliptic Curve Diffie-Hellman Ephemeral)
  • ECDSA — Certificate Verification (Elliptic Curve Digital Signature Algorithm)
  • AES_256_GCM — Bulk Encryption (AES mit 256 Bit im Galois/Counter Mode)
  • SHA384 — Hashing (SHA-2 mit 384 Bit)

TLS 1.3 hat das Namensschema verkürzt. Key Exchange und Certificate Verification sind nicht mehr Teil des Cipher-Suite-Namens, weil sie separat verhandelt werden. Darum sieht TLS_AES_256_GCM_SHA384 so kompakt aus: nur Protokoll, Verschlüsselung und Hash.

Key Exchange

Der Schlüsselaustausch legt fest, wie Client und Server einen temporären Sitzungsschlüssel aushandeln. Man will hier Ephemeral-Verfahren, also temporäre Schlüssel. Warum? Selbst wenn jemand den Traffic mitschneidet und später an den privaten Schlüssel des Servers kommt, kann er die aufgezeichneten Verbindungen nicht entschlüsseln. Der Sitzungsschlüssel existiert nur für die Dauer der Verbindung. Das nennt sich Perfect Forward Secrecy.

DHE (Diffie-Hellman Ephemeral) funktioniert, sollte aber mindestens 2048 Bit nutzen. Besser ist ECDHE (Elliptic Curve DHE), weil es bei gleicher Sicherheit deutlich kleiner und schneller ist. Idealerweise bietet der Server nur ECDHE an. Alles ohne das E am Ende (also statisches DH) hat kein Forward Secrecy und gehört abgeschaltet.

In Zukunft kommt hier noch Post-Quantum dazu. Mit X25519MLKEM768 lassen sich hybride Verfahren nutzen, die auch gegen Quantencomputer absichern. Wer das auf Nginx einrichten will, findet bei mir eine Anleitung: Post-Quantum TLS.

Certificate Verification

Verschlüsselung allein hilft nicht, wenn man mit dem falschen Server spricht. Das Serverzertifikat beweist die Identität. Es wird von einer CA signiert, kann per DANE/TLSA im DNSSEC-geschützten DNS verankert sein und sollte nicht trivial fälschbar sein.

RSA-Zertifikate sollten mindestens 2048 Bit haben, besser 4096 Bit. Allerdings werden RSA-Schlüssel mit steigender Sicherheit immer größer und langsamer. ECDSA-Zertifikate lösen das elegant: Ein ECDSA-Schlüssel mit 256 Bit bietet vergleichbare Sicherheit wie RSA mit 3072 Bit, ist aber deutlich kleiner und schneller zu verifizieren. Als Kurve sollte es mindestens secp256r1 (P-256) sein. secp384r1 geht auch, bringt aber aktuell keinen praktischen Vorteil.

Bulk Encryption

Das ist die eigentliche Datenverschlüsselung. Brauchbare Kombinationen sind:

  • AES-128-GCM oder AES-256-GCM — Standard, schnell, hardware-beschleunigt auf den meisten CPUs
  • ChaCha20-Poly1305 — gute Alternative, besonders auf Geräten ohne AES-NI

AES mit CBC ist noch akzeptabel, aber GCM ist vorzuziehen. Von 3DES sollte man die Finger lassen. Wenn irgendwo RC4 oder DES auftaucht: abschalten.

Hashing

Der Hash sichert die Integrität der übertragenen Daten. Minimum ist SHA-256, ein guter Mittelweg ist SHA-384. SHA-1 sollte man nicht mehr einsetzen. Taucht MD5 auf, stimmt etwas grundlegend nicht.

Fragen, Korrekturen oder Ergänzungen? Einfach melden.

« Ältere Beiträge Neuere Beiträge »

© 2026 -=Kernel-Error=-RSS

Theme von Anders NorénHoch ↑