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

Kategorie: IT-Security (Seite 14 von 15)

Notizen & Praxis zur IT-Sicherheit – von Responsible Disclosure bis Härtung.

StartSSL Identiy Validation Class 2

Veraltet: StartSSL wurde 2017 von allen Browsern als nicht vertrauenswürdig eingestuft und eingestellt. Kostenlose Zertifikate gibt es bei Let’s Encrypt.

Na wunderbar, mein Class 2 x.509 S/MIME Zertifikat läuft in kürze aus. Die Class 2 Validation ist auch ausgelaufen, also muss ich wohl was tun, hm?


Schnell alles bei StartSSL angeschoben und auf den bekannten Anruf irgendwo aus Israel warten… Es klingelte auch aber aus 001 213-341. Die Landesvorwahl ist USA und mein Android meint der Rest wäre etwas aus Los Angeles, CA! Das hat mich etwas überrascht; whatever. Wie gewohnt war das Gespräch schnell erledigt. Wobei die Dame am anderen Ende der Leitung extrem schlecht zu verstehen war. Nun warte ich also auf die Bestätigung meiner Class 2 Zertifizierung.

 


 

*UPDATE*

Na wunderbar:

### Schnipp ###
To Sebastian Van De Meer,

This electronic mail message was created by StartCom’s Administration Personnel:

Congratulations! Your Class 2 Identity Validation has been confirmed and approved. You are eligible for certificates at Class 2 level until 2014-05-01.
Additionally you have been awarded with StartSSL™ Web-of-Trust Notary status due to your fulfilling of all requirements. Well done!

Best Regards
### Schnapp ###

Dann kann ich ja gleich mal von diesem Zertifikat:

Seriennummer: 13:27
SHA1-Fingerprint: 28:AE:4C:96:51:75:EB:18:03:F9:9E:E3:7A:ED:C7:EA:13:8B:44:99

Zu diesem Zertifikat wechseln:

Seriennummer: 33:97
SHA1-Fingerprint: 7F:8B:92:19:FF:07:BF:EB:8E:E0:18:D4:98:B8:48:DF:E3:0E:4A:85

 

 

Unix / Linux Openssl Zertifikat pem konvertieren zu Microsoft Windows pfx

Man man man… Da bittet ein Kollege um ein Zertifikat, ich schraube das schnell zusammen und schiebe es im als .PEM – Base64-kodiertes Zertifikat, umschlossen von „—–BEGIN CERTIFICATE—–“ und „—–END CERTIFICATE—–“ zu.

Nun versucht dieser das Zertifikat auf seinem Windows Server zu importieren. Klappt aber so einfach nicht. Microsoft hätte nämlich gerne das Zertifikat als .PFX (.P12 – PKCS#12, kann öffentliche Zertifikate und private Schlüssel (Kennwort-geschützt) enthalten.) Macht ja auch Sinn wenn es eh in einer Zertifikatsverwaltung liegt und dass ganze Kennwortgeschützt ist. So ist es etwas sicherer, wenn die Datei mal jemanden in die Hände fällt, der es nicht haben soll!

Wie also nun aus PEM ein PFX machen? Openssl hilft:

# openssl pkcs12 -export -out telefon.de.pfx -inkey telefon.de.key -in telefon.de.crt -certfile CACert.crt

telefon.de.key sowie telefon.de.crt sollten wir beim einfachen erstellen des Zertifikates per Openssl ja bereits haben. CACert.crt ist einfach der Zertifikat der CA, mit welchem unsere CSR unterschrieben wurde. Noch Fragen?

Siehe auch: Elliptic Curve Zertifikate mit OpenSSL

Fragen? Einfach melden.

GPG-Schlüssel per PKA im DNS veröffentlichen

Hinweis: PKA (Public Key Association) wird von GnuPG seit Version 2.1 (2014) nicht mehr unterstützt. Der Nachfolger ist der OPENPGPKEY Resource Record, der den kompletten Schlüssel direkt im DNS speichert. Dieser Beitrag beschreibt das ältere PKA-Verfahren — historisch interessant, aber für neue Setups nicht mehr empfehlenswert.


Die Idee hinter PKA

GnuPG konnte über DNS nach GPG-Schlüsseln fragen. Der Vorteil: Ich muss meinen öffentlichen Schlüssel nicht auf Keyservern verteilen, sondern veröffentliche ihn über meinen eigenen DNS-Server. Ist die Zone per DNSSEC geschützt, kann der Schlüssel nicht gefälscht werden — deutlich vertrauenswürdiger als Keyserver, auf denen jeder beliebige Schlüssel hochladen kann.

PKA funktioniert mit einem TXT-Record, der den Fingerprint des Schlüssels und eine URL zum Download enthält. GnuPG prüft den Fingerprint gegen den heruntergeladenen Schlüssel — stimmt beides überein, wird der Schlüssel importiert.

Schlüssel exportieren

Zuerst den öffentlichen Schlüssel exportieren und auf dem Webserver ablegen:

gpg --list-keys --fingerprint kernel-error@kernel-error.com
gpg --export --armor 0F9874D8 > kernel-error.asc

Die exportierte Datei muss per HTTP erreichbar sein — HTTPS ist nicht zwingend nötig, da der Schlüssel am Ende gegen den Fingerprint aus dem DNS geprüft wird.

PKA-Record erstellen

Der PKA-Record ist ein TXT-Record unter localpart._pka.domain. Er enthält den Fingerprint und die URL zum Schlüssel:

kernel-error._pka.kernel-error.com. IN TXT "v=pka1;fpr=80CF90446B5867DA3A55854AF01C3E040F9874D8;uri=http://www.kernel-error.de/kernel-error.pubkey.txt"

Aufbau: Das @ in der E-Mail-Adresse wird durch ._pka. ersetzt. Der Record enthält die PKA-Version (v=pka1), den vollständigen Fingerprint (fpr=...) und die Download-URL (uri=...). Für jede E-Mail-Adresse, unter der man erreichbar ist, braucht man einen eigenen Record — auch über verschiedene Zonen hinweg.

Prüfen

Mit dig testen, ob der Record im DNS angekommen ist:

dig +short kernel-error._pka.kernel-error.com TXT
"v=pka1;fpr=80CF90446B5867DA3A55854AF01C3E040F9874D8;uri=http://www.kernel-error.de/kernel-error.pubkey.txt"

GnuPG (bis Version 2.0) konnte den Schlüssel dann automatisch finden und importieren:

echo "test" | gpg --auto-key-locate pka --keyring /tmp/test.gpg \
  --encrypt --armor -r kernel-error@kernel-error.com

GnuPG fragt den PKA-Record ab, lädt den Schlüssel von der angegebenen URL herunter, prüft den Fingerprint und importiert den Schlüssel in den Keyring.

Warum OPENPGPKEY besser ist

PKA hatte zwei Schwächen: Der Schlüssel lag nicht im DNS selbst, sondern musste per HTTP heruntergeladen werden — ein zusätzlicher Angriffsvektor. Und der TXT-Record war auf 255 Bytes pro String begrenzt, was bei langen URLs und Fingerprints knapp wurde.

Der OPENPGPKEY Resource Record (RFC 7929) löst beides: Der komplette Schlüssel steckt direkt im DNS, kein HTTP-Download nötig. Mit DNSSEC ist die gesamte Kette vom DNS-Lookup bis zum Schlüssel kryptographisch abgesichert.

Siehe auch: OPENPGPKEY im DNS, GPG: E-Mails signieren und verschlüsseln mit GnuPG, Der sichere GPG-Schlüssel

Fragen? Einfach melden.

SSH Host Keys per SSHFP im DNS veröffentlichen

SSH-Host-Key-Prüfung per SSHFP im DNS mit DNSSEC-validiertem Fingerprint, OpenSSH-Client, Server-Host-Key und Schutz vor Man-in-the-Middle-Angriffen.

OpenSSH kann die Fingerprints seiner Host Keys als SSHFP-Records im DNS veröffentlichen. Beim Verbindungsaufbau prüft der Client dann automatisch, ob der Fingerprint des Servers mit dem DNS-Eintrag übereinstimmt, ein wirksamer Schutz gegen Man-in-the-Middle-Angriffe. Ist die Zone zusätzlich per DNSSEC gesichert, kann der DNS-Record selbst nicht gefälscht werden. Die Spezifikation steht in RFC 4255.

Client konfigurieren

Damit OpenSSH beim Verbindungsaufbau SSHFP-Records prüft, muss VerifyHostKeyDNS aktiviert werden. Global für alle Benutzer in /etc/ssh/ssh_config:

VerifyHostKeyDNS yes

Oder nur für die aktuelle Sitzung:

ssh -o "VerifyHostKeyDNS=yes" server.example.de

SSHFP-Records erzeugen

Am einfachsten direkt auf dem Server mit ssh-keygen, das erzeugt die fertigen DNS-Records für alle vorhandenen Host Keys:

ssh-keygen -r server.example.de.

Ausgabe (Beispiel mit RSA, ECDSA und Ed25519):

server.example.de. IN SSHFP 1 1 47890eecc9a2893061734b07b8f60caa1a856148
server.example.de. IN SSHFP 1 2 b2518ad49cc2adf517d3f6a9faaf4017abc2c3e3...
server.example.de. IN SSHFP 3 1 3dd9de0dcf1523341b45a53f1d57043609e26c62
server.example.de. IN SSHFP 3 2 e1c76bd66b5a0641789b0b37be5b80ae3f6395c1...
server.example.de. IN SSHFP 4 1 a1b2c3d4e5f6...
server.example.de. IN SSHFP 4 2 d4e5f6a7b8c9...

Aufbau des SSHFP-Records

Ein SSHFP-Record besteht aus zwei Zahlen und dem Fingerprint:

hostname IN SSHFP [Algorithmus] [Hash-Typ] [Fingerprint]

Algorithmus:

  • 1, RSA
  • 3, ECDSA
  • 4, Ed25519 (empfohlen, ab OpenSSH 6.7)

DSS (2) ist seit OpenSSH 7.0 standardmäßig deaktiviert und sollte nicht mehr verwendet werden.

Hash-Typ: 1 = SHA-1, 2 = SHA-256. Beide sollten veröffentlicht werden, ältere Clients verstehen nur SHA-1, neuere bevorzugen SHA-256.

Prüfen

Mit dig lässt sich prüfen, ob die Records im DNS angekommen sind:

dig +short server.example.de SSHFP
1 1 47890EECC9A2893061734B07B8F60CAA1A856148
1 2 B2518AD49CC2ADF517D3F6A9FAAF4017ABC2C3E3...
3 1 3DD9DE0DCF1523341B45A53F1D57043609E26C62
4 2 D4E5F6A7B8C9...

Wichtig: Bei der DNSSEC-validierten Abfrage muss das ad-Flag (Authenticated Data) gesetzt sein, sonst ist die Antwort nicht vertrauenswürdig:

dig +dnssec server.example.de SSHFP | grep flags
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 6, AUTHORITY: 0, ADDITIONAL: 1

Verbindungsaufbau mit SSHFP

Ohne SSHFP-Records im DNS meldet OpenSSH:

DNS lookup error: data does not exist
No matching host key fingerprint found in DNS.
Are you sure you want to continue connecting (yes/no)?

Mit SSHFP-Records und DNSSEC:

debug1: found 4 secure fingerprints in DNS
debug1: matching host key fingerprint found in DNS

secure bedeutet: Die DNS-Antwort wurde per DNSSEC validiert. Ohne DNSSEC steht dort insecure, der Fingerprint wurde zwar gefunden, aber der DNS-Antwort selbst kann nicht vertraut werden. Für echte Sicherheit braucht man beides: SSHFP-Records und DNSSEC.

Strenge Prüfung erzwingen

Optional: OpenSSH anweisen, die Verbindung nur aufzubauen, wenn der Host Key erfolgreich validiert wurde:

Host *
    VerifyHostKeyDNS yes
    StrictHostKeyChecking yes

Damit wird die Verbindung abgelehnt, wenn kein passender SSHFP-Record gefunden wird oder die DNSSEC-Validierung fehlschlägt. Das ist die sicherste Einstellung, setzt aber voraus, dass alle Zielserver SSHFP-Records haben.

Kleiner Aufwand, viel mehr Sicherheit. Fragen? Einfach melden.

Evolution merkt sich die Einstellungen der Zertifizierungsstellen nicht

Ich nutze Evolution als E-Mail Client. In den Zertifikatseinstellungen habe ich unter Zertifizierungsstellen auch eine ganze Latte von CAs. Ich kann auch welche hinzufügen und entfernen alles kein Problem.

Will ich aber deren Einstellung bearbeiten, sprich für welche Dinge ich dieser CA vertrauen möchte bleiben diese Einstellungen nur immer für die aktuelle Sitzung gespeichert. Schließe und Starte ich Evolution wieder sind die Einstellungen alles wieder weg 🙁 Das ist doof!

Wer sucht, der findet einen Workaround……..

Das Problem ist wohl dass Evolution aus irgendwelchen Gründen die cert9.db / key4.db unter ~/.pki/nssdb nicht updatet.

So kann ich mir anschauen was bei mir eingetragen ist:

$ certutil -L -d sql:/home/kernel/.pki/nssdb/

Certificate Nickname                                         Trust Attributes
                                                             SSL,S/MIME,JAR/XPI

StartCom Ltd. ID von Sebastian Van De Meer                   u,u,u
StartCom Class 2 Primary Intermediate Client CA - StartCom Ltd. ,,   
CA Cert Signing Authority - Root CA                          ,,   
CAcert Class 3 Root - Root CA                                ,,   
StartCom Class 1 Primary Intermediate Client CA - StartCom Ltd. ,,   
StartCom Certification Authority - StartCom Ltd.             ,,   
StartCom Ltd.                                                ,,   
StartCom Certification Authority                             ,,   
......

Und so verpasse ich den einzelnen Zertifikaten die passenden „Verwendungsmöglichkeiten“:

$ certutil -M  -n "CA Cert Signing Authority - Root CA"  -t "TCu,Cu,TCuw" -d sql:/home/kernel/.pki/nssdb/

Am Ende schaut es nun so aus (ich mache mir dann noch mal nen Kopf ob es so auch sinnig ist):

$ certutil -L -d sql:/home/kernel/.pki/nssdb/

Certificate Nickname                                         Trust Attributes
                                                             SSL,S/MIME,JAR/XPI

StartCom Ltd. ID von Sebastian Van De Meer                   u,u,u
StartCom Class 2 Primary Intermediate Client CA - StartCom Ltd. CT,C,C
CA Cert Signing Authority - Root CA                          CT,C,C
CAcert Class 3 Root - Root CA                                CT,C,C
StartCom Class 1 Primary Intermediate Client CA - StartCom Ltd. CT,C,C
StartCom Certification Authority - StartCom Ltd.             C,C,C
StartCom Ltd.                                                C,C, 
StartCom Certification Authority                             C,C,C
......

Auf meine Openindiana Kiste musste ich dafür noch folgendes Paket installieren:

system/mozilla-nss

Und wegen des Bugs #1739 certutil with incomplete runpath musste ich noch folgenden Workaround dafür einwerfen:

$ elfedit -e 'dyn:runpath $ORIGIN/../lib:/usr/lib/mps' /usr/sfw/bin/certutil

Jetzt macht zwar Evolution nicht die Arbeit aber mein Wunsch ist erfüllt. Ob ich da mal nen Bug bei den Jungs aufmache?

So long…

Siehe auch: S/MIME per DNS mit SMIMEA

Fragen? Einfach melden.

StartSSL

Veraltet: StartSSL/StartCom wurde 2017 von allen Browsern als nicht mehr vertrauenswürdig eingestuft und hat den Betrieb eingestellt. Für kostenlose Zertifikate nimmt man heute Let’s Encrypt.

StartCom ist ein Unternehmen, das Software herstellt und als Zertifizierungsstelle digitale Zertifikate ausstellt. Seit Februar 2005 ist das Unternehmen als Zertifizierungsstelle tätig. Das bekannteste Produkt ist das kostenlose Class 1 X.509 SSL-Zertifikat „StartSSL Free“, das sowohl für Webserver (SSL/TLS) als auch für die E-Mail-Verschlüsselung (S/MIME) eingesetzt werden kann. Außerdem werden Class 2 Zertifikate und Extended-Validation-SSL-Zertifikate ausgestellt, für die eine kostenpflichtige Validierung Voraussetzung ist. StartCom-Zertifikate werden von allen modernen Browsern akzeptiert: Mozilla Firefox unterstützt sie schon ab Version 2.0, Opera seit Juli 2010, Apple Mac OS X ab Version 10.5 (Leopard) und Microsoft Windows seit September 2009; Apple Safari, Internet Explorer und Google Chrome greifen auf den Zertifikatspeicher des Betriebssystems zurück.

Das kostenlose Class1 Zertifikat stellt nur sicher das der angegebene Domainname existiert und anscheinend dem Halter des StartCom Accounts gehört. Aus diesem Grund findet sich natürlich auch nur der Domainname im Zertifikat. Wer seinen Namen auch noch im Zertifikat hinterlegen möchte kann dieses denn noch auf einem kostenlosen Weg schaffen. Ähnlich CAcert setzt StartCom auf das Prinzip des Web of Trust (wot). Es gibt bei StartCom ehrenamtliche Notare. Jeder Inhaber eines StartCom Accounts kann sich von diesen verifizieren lassen. Dazu findet sich im Webinterface des eigenen Accounts auf der Seite unter StartSSL WoT ==> WoT Netzwerk der Punkt Notarsucher. Hier findet sich über die Eingabe des eigenen Wohnortes oder halt der nächsten größeren Stadt schnell ein solcher Notar.

Wurde man von mindestens zwei dieser Notare bestätigt, kann man seinen Namen mit ins Zertifikat aufnehmen.

Eine solche Bestätigung findet immer über ein persönliches Treffen mit dem Notar statt. Bei diesem Treffen prüft der Notar anhand von zwei amtlichen Lichtbildausweisen ob der Name im Account mit dem auf den Ausweisen identisch ist.

Da die Root-Zertifikate dieser Zertifizierungsstelle bereits in den meisten großen Browsern und Betriebssystemen enthalten sind, kommt es bei diesen Zertifikaten (anders als bei z.B. CAcert.org) nicht zu „Fehlermeldunge“ bzw. Warnmeldungen im Zusammenhang mit den Zertifikaten. Vor allem dieser Umstand und natürlich da es kostenneutral ist, würde ich StartCom x.509 Zertifikate als einen optimalen Einstieg in diesen Themenbereich nennen können. Wer am Ende mehr will, wie eine Class 2 Zertifizierung oder bis hin zum Class 3 Zertifikat für Unternehmen, kann dieses schnell und günstig weiterführen. Wem das Class 1 Zertifikat ausreicht, dem stehen direkt nach der erfolgreichen Anmeldung schon fast alle Möglichkeiten der E-Mail Signatur / Verschlüsselung sowie SSL/TLS Verschlüsselte Serververbindungen offen.

Ich selbst bin bei StartSSL Notar und wie bei GPG / PGP oder CAcert.org bestätige ich auch hier gerne Identitäten auf Anfrage.

DNSSEC einrichten: Zonen signieren mit BIND

DNSSEC (Domain Name System Security Extensions) schützt DNS-Antworten vor Fälschung. Ein anfragender Resolver kann damit prüfen, ob die gelieferten Zonendaten tatsächlich vom autorisierten Nameserver stammen und unterwegs nicht verändert wurden. DNSSEC wurde als Mittel gegen Cache Poisoning entwickelt — Serverauthentifizierung findet nicht statt.

Die Vertrauenskette

Was mich beim ersten Lesen zu DNSSEC durcheinandergebracht hat, war das Umherwerfen mit Begriffen: KSK, ZSK, DNSKEY, RRSIG, DS. Im Grunde ist es einfach:

Der KSK (Key Signing Key) hat eine Aufgabe: den ZSK unterschreiben. Der KSK wird als DS-Record in der übergeordneten Zone hinterlegt. Der ZSK (Zone Signing Key) hat auch nur eine Aufgabe: die eigentlichen Zonendaten unterschreiben.

Es beginnt bei der Root-Zone. Die Root-Server wissen, welche Nameserver für die TLDs zuständig sind. Die TLD-Server wissen, welche Nameserver für die einzelnen Domains zuständig sind. Jede Ebene signiert ihre Zone und veröffentlicht den DS-Record der Ebene darunter. So entsteht eine durchgehende Kette vom Root-KSK bis zu meiner Zone.

Will ein Angreifer dafür sorgen, dass www.kernel-error.org auf seinen Server zeigt, hat er zwei Möglichkeiten:

  1. Er antwortet auf die Delegation-Anfrage mit seinem eigenen Nameserver.
  2. Er antwortet mit gefälschter Absenderadresse schneller als der echte Server.

Mit DNSSEC kann der Resolver beide Angriffe erkennen — die gefälschte Antwort hat keine gültige Signatur.

Schematische Darstellung der DNSSEC-Vertrauenskette: Root-KSK signiert TLD, TLD signiert Domain.

DNSSEC in BIND aktivieren

Auf dem autoritativen Nameserver muss DNSSEC-Validierung aktiv sein. In modernen BIND-Versionen (ab 9.16) reicht im options-Block:

options {
    dnssec-validation auto;
};

auto bedeutet, dass BIND den eingebauten Root-Trust-Anchor nutzt und diesen bei KSK-Rollovers automatisch aktualisiert (RFC 5011). Der alte dnssec-enable yes wurde in BIND 9.18 entfernt — DNSSEC ist seitdem immer aktiv.

Zone signieren — der moderne Weg

Seit BIND 9.16 gibt es dnssec-policy. Damit übernimmt BIND die Schlüsselerzeugung, das Signieren und den Key-Rollover vollautomatisch:

zone "kernel-error.org" {
    type primary;
    file "kernel-error.org";
    dnssec-policy default;
    inline-signing yes;
};

Die default-Policy verwendet ECDSAP256SHA256 (Algorithmus 13) — schneller und sicherer als das früher übliche NSEC3RSASHA1 mit 4096-Bit-Schlüsseln. inline-signing yes bedeutet: BIND signiert die Zone im Speicher, die Zonendatei auf der Platte bleibt unsigniert und lässt sich wie gewohnt bearbeiten.

Zone manuell signieren

Wer mehr Kontrolle will oder eine ältere BIND-Version hat, kann die Schlüssel von Hand erzeugen. KSK erstellen:

$ dnssec-keygen -a ECDSAP256SHA256 -f KSK -n ZONE kernel-error.org
Kkernel-error.org.+013+12345

ZSK erstellen:

$ dnssec-keygen -a ECDSAP256SHA256 -n ZONE kernel-error.org
Kkernel-error.org.+013+67890

Die öffentlichen Teile (*.key) in die Zonendatei einbinden und signieren:

$ cat Kkernel-error.org.+013+*.key >> kernel-error.org

$ dnssec-signzone -S -K /pfad/zu/keys -o kernel-error.org kernel-error.org
Verifying the zone using the following algorithms: ECDSAP256SHA256.
Zone signing complete:
Algorithm: ECDSAP256SHA256: ZSKs: 1, KSKs: 1 active, 0 stand-by
kernel-error.org.signed

Dann BIND anweisen, die signierte Zonendatei zu laden. Nach jeder Änderung an der Zone muss neu signiert werden — oder man nutzt inline-signing, dann entfällt das.

DS-Record beim Registrar einreichen

Der öffentliche KSK muss als DS-Record in der übergeordneten Zone landen. Bei der DENIC (.de) und den meisten TLD-Registries gibt es dafür ein Webinterface beim Registrar. Man schickt den öffentlichen KSK hin, der Registrar erstellt daraus einen DS-Record und veröffentlicht ihn neben den NS-Records.

Ob der DS-Record gesetzt ist, lässt sich prüfen, indem man die TLD-Nameserver direkt fragt:

$ dig +short kernel-error.org DS @a0.org.afilias-nst.info
12345 13 2 A1B2C3D4...

Prüfen ob alles funktioniert

Mit dig +dnssec eine signierte Domain abfragen. Das ad-Flag (Authenticated Data) in der Antwort zeigt, dass die DNSSEC-Validierung erfolgreich war:

$ dig +dnssec kernel-error.org @8.8.8.8
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

Grafisch lässt sich die gesamte Vertrauenskette mit DNSviz darstellen — einfach die eigene Domain einsetzen:

Stolpersteine

DNSSEC-Signaturen machen DNS-Antworten deutlich größer als die 512 Bytes, die klassisches DNS über UDP erlaubt. EDNS (RFC 6891) hebt dieses Limit auf. Das ist seit 1999 spezifiziert, aber manche Firewalls und Billig-Router haben damit immer noch Probleme — sie filtern große UDP-Pakete oder EDNS-Optionen.

Wichtig: Gehen die Schlüssel verloren oder die signierte Zonendatei brennt ab, hat man ein Problem. Vor jeder großen Änderung (Key-Rollover, Algorithmus-Wechsel) immer die längste TTL der Zone abwarten. Sonst sind gecachte Antworten mit der alten Signatur noch gültig, während die neue Signatur schon aktiv ist — die Zone wird temporär nicht validierbar.

Meinen „analogen“ DNSSEC-Masterplan dazu habe ich mir damals aufgezeichnet:

Handgezeichneter DNSSEC-Masterplan: Reihenfolge fuer Key-Rollover und Zonenuebergaenge mit TTL-Wartezeiten.

Was man auf DNSSEC aufbauen kann

Wenn die Zone signiert ist, lassen sich darüber weitere Sicherheitsmechanismen verteilen:

Wer einen DNSSEC-validierenden Resolver sucht — dns.kernel-error.de bietet DNS over TLS und DNS over HTTPS mit DNSSEC-Validierung., DNSSEC: KSK auf 4096 Bit aktualisieren und SHA-512 vorbereiten, OPENPGPKEY: GPG-Schlüssel direkt im DNS veröffentlichen


Chronik

Dieser Beitrag wurde 2010 veröffentlicht und dokumentiert meine DNSSEC-Einführung über mehrere Jahre:

  • November 2010 — Erste Signierung von kernel-error.org (NSEC3RSASHA1, 4096 Bit).
  • Februar 2011 — DS-Record für kernel-error.org endlich in der .org-Zone veröffentlicht. DENIC kündigt Signierung der .de-TLD an.
  • Februar 2011 — kernel-error.de signiert, über DENIC-Testbed validierbar.
  • Juni 2011 — DENIC signiert .de offiziell, DS-Records in der Root-Zone.
  • Februar 2012 — kernel-error.com ebenfalls signiert. Alle drei Domains komplett.
  • Mai 2012 — GPG-Keys und SSHFP-Records im DNS hinterlegt.
  • August 2013 — DANE/TLSA-Records für alle TLS-Dienste eingerichtet.
  • 2024 — Algorithmus-Wechsel auf ECDSAP256SHA256 (Algorithmus 13). Anleitung oben entsprechend aktualisiert.

Siehe auch: DNSSEC und DANE

Fragen? Einfach melden.

DKIM einrichten: E-Mails signieren und verifizieren mit rspamd und Postfix

DKIM (DomainKeys Identified Mail, RFC 6376) signiert ausgehende E-Mails kryptografisch. Der empfangende Mailserver prüft die Signatur über einen DNS-Record. Stimmt sie nicht, ist die Mail manipuliert oder stammt nicht vom angegebenen Absender. DKIM ist neben SPF und DMARC einer der drei Bausteine moderner E-Mail-Authentifizierung.

Wie DKIM funktioniert

Der sendende Mailserver berechnet einen Hash über definierte Header-Felder und den Body der E-Mail, verschlüsselt diesen Hash mit seinem privaten Schlüssel und hängt das Ergebnis als DKIM-Signature-Header an die Mail. Der empfangende Server holt den öffentlichen Schlüssel per DNS-Abfrage (selektor._domainkey.domain.de), entschlüsselt die Signatur und vergleicht den Hash. Stimmt er überein, ist die Mail authentisch und unverändert.

DKIM-Schlüssel erstellen

RSA mit 2048 Bit ist der Standard. 1024 Bit gilt seit Jahren als zu schwach, nicht mehr verwenden. Ed25519-Schlüssel sind kompakter und schneller, werden aber noch nicht von allen Empfängern unterstützt. Wer auf Nummer sicher gehen will, signiert mit beiden (Dual Signing).

# RSA 2048 Bit (Standard, universell unterstützt)
openssl genrsa -out /var/db/rspamd/dkim/2026.key 2048
chmod 640 /var/db/rspamd/dkim/2026.key
chown _rspamd:_rspamd /var/db/rspamd/dkim/2026.key

# Öffentlichen Schlüssel extrahieren (für den DNS-Record)
openssl rsa -in /var/db/rspamd/dkim/2026.key -pubout -out /var/db/rspamd/dkim/2026.pub

Der Selektor (hier 2026) ist frei wählbar. Gängige Konvention: Jahr oder Monat als Selektor, das erleichtert die Key-Rotation.

DNS-Record veröffentlichen

Der öffentliche Schlüssel wird als TXT-Record im DNS veröffentlicht. Der Recordname folgt dem Schema selektor._domainkey.domain.de:

2026._domainkey.kernel-error.de. 3600 IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkq...langer-Base64-String...IDAQAB"

Den Base64-String aus der .pub-Datei nehmen, ohne Header/Footer-Zeilen und Zeilenumbrüche, alles in eine Zeile. Bei BIND-Zonefiles auf die 255-Zeichen-Grenze pro TXT-String achten. Längere Schlüssel müssen in mehrere Strings aufgeteilt werden (BIND macht das automatisch, wenn man den Record in Anführungszeichen setzt).

rspamd als DKIM-Signer konfigurieren

rspamd bringt DKIM-Signing und -Verification von Haus aus mit, kein zusätzliches Paket nötig. Die DKIM-Signing-Dokumentation beschreibt alle Optionen. Für eine einfache Konfiguration mit einem Schlüssel pro Domain:

# /usr/local/etc/rspamd/local.d/dkim_signing.conf

allow_username_mismatch = true;

domain {
    kernel-error.de {
        path = "/var/db/rspamd/dkim/2026.key";
        selector = "2026";
    }
}

# Nur lokal eingelieferte Mails signieren (SASL-authentifiziert)
sign_authenticated = true;
sign_local = true;

Nach einem service rspamd reload signiert rspamd alle ausgehenden Mails. Die Verification eingehender Mails ist standardmäßig aktiv. Das DKIM-Modul läuft automatisch und fließt in den rspamd-Score ein. Wer rspamd auch für automatisches Spam/Ham-Lernen nutzt, hat damit eine Lösung für beides.

Alternative: opendkim

Wer kein rspamd einsetzt, kann opendkim als Milter in Postfix einbinden. Die Konfiguration ist etwas aufwändiger (eigener Daemon, Socket, Milter-Einbindung in main.cf), funktioniert aber zuverlässig. Die Schlüsselerstellung und DNS-Konfiguration sind identisch.

DKIM testen

Ob der DNS-Record korrekt veröffentlicht ist:

# DNS-Record abfragen
dig TXT 2026._domainkey.kernel-error.de +short

# Mit rspamd testen (wenn lokal installiert)
rspamadm dkim_keygen -d kernel-error.de -s 2026 -k /var/db/rspamd/dkim/2026.key --check

Den einfachsten Funktionstest macht man, indem man eine Mail an eine Adresse bei Gmail oder Outlook schickt und dort die Header prüft. Im Header der empfangenen Mail steht dann:

Authentication-Results: mx.google.com;
    dkim=pass header.d=kernel-error.de header.s=2026

dkim=pass bedeutet: Signatur gültig, Schlüssel im DNS gefunden, Hash stimmt überein.

Key-Rotation

DKIM-Schlüssel sollten regelmäßig getauscht werden. Einmal pro Jahr ist ein guter Rhythmus. Der Ablauf:

  • Neuen Schlüssel mit neuem Selektor erstellen (z.B. 2027)
  • Neuen DNS-Record veröffentlichen
  • rspamd auf den neuen Selektor umstellen
  • Alten DNS-Record noch 30 Tage stehen lassen (für Mails die noch in Queues liegen)
  • Alten Record löschen

Durch die Selektoren können alter und neuer Schlüssel parallel im DNS existieren. Empfänger prüfen immer den Selektor aus dem DKIM-Signature-Header, es gibt keine Unterbrechung.

DKIM allein reicht nicht

DKIM beweist nur, dass eine Mail von einem bestimmten Schlüssel signiert wurde, nicht dass der Absender im From:-Header berechtigt ist, diese Domain zu nutzen. Dafür braucht es die anderen Bausteine:

  • SPF — definiert per DNS, welche IP-Adressen für eine Domain Mails versenden dürfen
  • DMARC — verknüpft SPF und DKIM mit einer Policy: Was soll der Empfänger tun, wenn beides fehlschlägt?
  • DANE/TLSA — sichert den Transportweg per DNSSEC ab

Siehe auch: internet.nl: Mailserver-Sicherheit testen mit dem niederländischen Standard

Erst alle drei zusammen (SPF, DKIM und DMARC) ergeben eine vollständige E-Mail-Authentifizierung. Fragen? Einfach melden.

Linux-Firewall mit iptables und Traffic Shaping: Aufbau und Konzepte

Hinweis: Dieses Script stammt aus 2009 und nutzt iptables auf einem Debian mit Kernel 2.4. Die Konzepte sind zeitlos, aber die Umsetzung ist veraltet. Heute nimmt man nftables statt iptables. Trotzdem: Wer versteht was hier passiert, versteht auch nftables.

Das Setup

Dedizierte Firewall-Maschine mit drei Netzwerkkarten. Ein Interface zum Internet (PPPoE), zwei für interne Netze mit unterschiedlichen Berechtigungen. Default-Policy auf allen Chains: DROP. Alles was nicht explizit erlaubt ist, wird verworfen.

Grundstruktur

#!/bin/bash

# Module laden
modprobe ip_tables
modprobe ip_conntrack
modprobe ip_conntrack_ftp
modprobe ip_nat_ftp

# Tabellen leeren
iptables -F
iptables -t nat -F
iptables -t mangle -F
iptables -X
iptables -t nat -X
iptables -t mangle -X

# Default: Alles verwerfen
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP

Custom Chains für Logging

Eigene Chains für sauberes Logging. Jedes verworfene Paket wird mit Prefix geloggt bevor es gedroppt wird:

# MY_REJECT: Protokollieren und zurückweisen
iptables -N MY_REJECT
iptables -A MY_REJECT -p tcp -m limit --limit 7200/h -j LOG --log-prefix "REJECT TCP "
iptables -A MY_REJECT -p tcp -j REJECT --reject-with tcp-reset
iptables -A MY_REJECT -p udp -m limit --limit 7200/h -j LOG --log-prefix "REJECT UDP "
iptables -A MY_REJECT -p udp -j REJECT --reject-with icmp-port-unreachable

# MY_DROP: Portscans stillschweigend verwerfen
iptables -N MY_DROP
iptables -A MY_DROP -m limit --limit 7200/h -j LOG --log-prefix "PORTSCAN DROP "
iptables -A MY_DROP -j DROP

Stealth Scan Detection

Ungültige TCP-Flag-Kombinationen erkennen und verwerfen. Kein normaler Client setzt SYN+FIN gleichzeitig oder schickt ein Paket ohne Flags:

# Keine Flags gesetzt
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j MY_DROP
# SYN und FIN gleichzeitig
iptables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j MY_DROP
# SYN und RST gleichzeitig
iptables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j MY_DROP
# FIN ohne ACK
iptables -A INPUT -p tcp --tcp-flags ACK,FIN FIN -j MY_DROP

Connection Tracking und NAT

Stateful Firewall: Bestehende und zugehörige Verbindungen durchlassen, neue nur aus dem internen Netz erlauben. NAT per MASQUERADE für den Internetzugang:

# Loopback erlauben
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

# Ausgehend: Alles erlauben
iptables -A OUTPUT -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT

# Forwarding: Neue Verbindungen nur von innen
iptables -A FORWARD -i ! ppp0 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# NAT für interne Netze
iptables -t nat -A POSTROUTING -o ppp0 -s 192.168.0.0/24 -j MASQUERADE

Traffic Shaping mit tc

Mit tc (traffic control) und iptables -t mangle lässt sich die Bandbreite pro Client oder Netz begrenzen. iptables markiert die Pakete, tc ordnet sie in Queues ein:

# HTB Queueing Discipline auf dem internen Interface
tc qdisc add dev eth2 root handle 1:0 htb default 10
tc class add dev eth2 parent 1:0 classid 1:1 htb rate 150kbit ceil 250kbit
tc filter add dev eth2 parent 1: prio 0 protocol ip handle 1 fw flowid 1:1

# Pakete per iptables markieren
iptables -t mangle -A FORWARD -s 192.168.100.0/24 -j MARK --set-mark 1

Kernel-Hardening

Am Ende des Scripts werden Kernel-Parameter gesetzt die über die Firewall hinausgehen:

# SYN-Cookies gegen SYN-Flood
echo 1 > /proc/sys/net/ipv4/tcp_syncookies

# Source-Routing deaktivieren
for i in /proc/sys/net/ipv4/conf/*; do echo 0 > $i/accept_source_route; done

# Redirects ignorieren
for i in /proc/sys/net/ipv4/conf/*; do echo 0 > $i/accept_redirects; done

# Martian-Pakete loggen
for i in /proc/sys/net/ipv4/conf/*; do echo 1 > $i/log_martians; done

# ICMP-Ping ignorieren
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all

# TCP-FIN-Timeout gegen DoS
echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout

Die Konzepte aus diesem Script gelten unverändert: Default DROP, Stateful Tracking, Custom Chains für Logging, Stealth Scan Detection, Kernel-Hardening. Nur die Syntax hat sich geändert. Wer heute eine Linux-Firewall baut, nimmt nft statt iptables und erspart sich die Modprobe-Zeilen. Für IPv6 braucht man eine eigene Regelkette, damals mit ip6tables, heute in nftables integriert.

Fragen? Einfach melden.

« Ältere Beiträge Neuere Beiträge »

© 2026 -=Kernel-Error=-RSS

Theme von Anders NorénHoch ↑