Mein Datenhaufen zu IT und Elektronik Themen.

Schlagwort: Security (Seite 1 von 4)

FreeBSD SSH Server mit MFA 2FA

Dass man eigentlich keinen reinen Kennwort-Login für seine Anmeldung an einem SSH-Server haben möchte, ist sicherlich bei fast allen angekommen. Kennwörter lassen sich einfacher mittels eines Brute-Force-Angriffes herausfinden. Ebenso gehen diese auch mal verloren. SSH-Keys werden die meisten ebenfalls bereits aufseiten des Clients mit einem zweiten Faktor geschützt haben. Dies kann ein MFA-Token sein oder einfach eine Passphrase.

Hin und wieder lässt es sich aber nicht vermeiden, dass man seinen Login nur mit einer einfachen Kombination aus Benutzername und Kennwort sichert. Um dieses dennoch etwas aufzuwerten, lässt sich dieses ebenfalls mit MFA ausstatten. In diesem kurzen Beispiel geht es dabei um einen SSH-Server auf einem FreeBSD-System, welches nach der Authentifizierung mittels Benutzername/Kennwort noch nach einem Auth-Code vom Google Authenticator fragt.

Clientseitig ist eigentlich nichts weiter zu beachten. Auf Serverseite muss das Paket pam_google_authenticator installiert werden:

pkg install pam_google_authenticator

Ist die Installation abgeschlossen, müssen wir nun unsere PAM-Konfiguration für den SSHD-Password-Login erweitern. Oh, ja… Auf demselben Weg lässt sich dieses ebenfalls für den normalen Login an der Konsole, für su, ftp usw. einbinden. Selbstverständlich ebenfalls für den Login per SSH-Keys. Wir bleiben aber hier nun beim Login mit User/Pass. Meine /etc/pam.d/sshd sieht damit wie folgt aus:

#
#
# PAM configuration for the "sshd" service
#

# auth
#auth		sufficient	pam_krb5.so		no_warn try_first_pass
#auth		sufficient	pam_ssh.so		no_warn try_first_pass
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_krb5.so
account		required	pam_login_access.so
account		required	pam_unix.so

# session
#session	optional	pam_ssh.so		want_agent
session		required	pam_permit.so

# password
#password	sufficient	pam_krb5.so		no_warn try_first_pass
password	required	pam_unix.so		no_warn try_first_pass

Ebenfalls muss die folgende Option in der /etc/ssh/sshd_config aktiviert sein:

ChallengeResponseAuthentication yes

Das war es auch schon fast. Wenn man nun auf seinem Smartphone noch schnell den Google Authenticator installiert, können wir schon damit beginnen, den zweiten Faktor zu erstellen. Dafür einfach mit dem gewünschten Nutzer in dessen Home-Verzeichnis: „cd ~“ den google-authenticator aufrufen und den Anweisungen folgen:

Dieses nur noch mit der Authenticator-App am Smartphone scannen, den Code einmal eingeben und schon wird man bei jedem Kennwort-Login nach seinem aktuellen Code gefragt.

Oh, sehr ähnlich ist die Einrichtung unter Linux 🙂

Linux Mint / Ubuntu und DNSSEC

Heute habe ich versucht, mich von meiner neuen Linux Mint Installation aus mit einem meiner SSH-Server zu verbinden. Mein SSH-Client hat mich direkt mit der Frage begrüßt, ob ich dem neuen Hostkey vertrauen möchte oder nicht.

ssh username@hostname.kernel-error.org
The authenticity of host 'hostname.kernel-error.org (2a01:5a8:362:4416::32)' can't be established.
ED25519 key fingerprint is SHA256:kTRGVCMRLiHfvJunW2CbW5H3NZmn3Wkx2KnHJXl3iJu.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])?

Für viele mag diese Meldung bekannt und vollkommen normal erscheinen. In der Regel antwortet man initial mit „yes“ und sieht sie nie wieder. Aber diese Meldung hat ihren Grund. Beim initialen Aufbau einer Verbindung zu einem SSH-Server wird einem der Fingerprint des HostKeys angezeigt. So hat man die Möglichkeit, den Fingerprint mit dem erwarteten Fingerprint abzugleichen, um sicherzustellen, dass man sich wirklich mit dem gewünschten SSH-Server verbindet und nicht etwa ein Angreifer Zugangsdaten abfischt. Wenn man eh immer nur „JA“ sagt, könnte man diesen Check auch direkt in seiner ~/.ssh/config mit folgendem Eintrag deaktivieren:

Host *
    StrictHostKeyChecking no

Warum erzähle ich das alles? Nun, weil es für mich eigentlich nicht normal ist, diese Meldung zu sehen. Denn es gibt die Möglichkeit, die Fingerprints der erwarteten HostKeys in seiner DNS-Zone zu hinterlegen und seinen SSH-Client mit der folgenden Konfiguration in seiner ~/.ssh/config anzuweisen, dies einfach selbst zu überprüfen, sofern der SSH-Client eine vertrauenswürdige Antwort vom DNS-Server erhält.

Host *
   VerifyHostKeyDNS yes

Vertrauenswürdige Antwort vom DNS-Server… Hier sind wir schon bei DNSSEC angekommen. Meine DNS-Server, einschließlich des lokalen Resolvers auf meinem Router, unterstützen alle DNSSEC. Meine SSH-Client-Konfiguration ist korrekt und dennoch erscheint die Meldung…. Also habe ich den Verbindungsaufbau mit etwas mehr Debugging-Output gestartet, was bei ssh einfach die zusätzliche Option -vvv bedeutet:

ssh usermane@hostname.kernel-error.org -vvv
[...]
debug1: SSH2_MSG_KEX_ECDH_REPLY received
debug1: Server host key: ssh-ed25519 SHA256:kTRGVCMRLiHfvJunW2CbW5H3NZmn3Wkx2KnHJXl3iJu
debug3: verify_host_key_dns
debug1: found 2 insecure fingerprints in DNS
debug3: verify_host_key_dns: checking SSHFP type 4 fptype 1
debug1: verify_host_key_dns: matched SSHFP type 4 fptype 1
debug3: verify_host_key_dns: checking SSHFP type 4 fptype 2
debug1: verify_host_key_dns: matched SSHFP type 4 fptype 2
debug1: matching host key fingerprint found in DNS
[...]

Zu meiner Überraschung sehe ich:

debug1: found 2 insecure fingerprints in DNS

Hm… „insecure“… Er hat also die passenden Einträge in der DNS-Zone gefunden, kann diesen aber nicht vertrauen, weil… ja, warum? Die Antwort des DNS-Servers ist nicht vertrauenswürdig? OK, das lässt sich einfach mit dig und der Option +dnssec testen. Wir suchen einfach im Header nach „ad„:

dig +dnssec hostname.kernel-error.org @8.8.8.8

; <<>> DiG 9.18.18-0ubuntu0.22.04.2-Ubuntu <<>> +dnssec hostname.kernel-error.org
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48645
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
[...]

@8.8.8.8 gibt an, dass direkt der öffentliche DNS-Server von Google gefragt wird. Dieser wird natürlich meine Server fragen usw., einfach um sicherzugehen, dass meine eigentlichen DNS-Server, die für die Zone zuständig sind, sauber konfiguriert sind. Ich sehe ein „ad„, also ist dort schon mal alles gut. Im Anschluss habe ich den Test noch mit meinem lokalen DNS-Resolver auf dem Router durchgeführt. Also einfach @192.168.0.1 oder was auch immer euer lokaler Router ist. Gleiches Ergebnis…. Aber warum will dann mein Linux Mint nicht? Sollte Linux Mint etwa kein DNSSEC können?

dig +dnssec hostname.kernel-error.org

; <<>> DiG 9.18.18-0ubuntu0.22.04.2-Ubuntu <<>> +dnssec hostname.kernel-error.org
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 1789
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
[...]

Öhhh ähhh… Ja, öhm, geht nicht… Aber warum? Was steht denn in meiner /etc/resolv.conf? 127.0.0.53? Ohhhhhhhh, stimmt! systemd-resolv! OK, ok… Ich könnte also in meiner /etc/systemd/resolved.conf nun einfach DNSSEC=yes setzen und mit einem systemctl restart systemd-resolved sollte dann… Nope, leider nicht. Nun geht überhaupt keine DNS-Auflösung mehr. Es scheint am eingesetzten Stub-Resolver zu liegen, den man ebenfalls noch ändern kann usw… Nennt mich etwas oldschool, aber für meine Zwecke reicht der klassische Weg über die vom NetworkManager gepflegte resolv.conf. Um also systemd-resolved zu deaktivieren und auf den NetworkManager zu wechseln, sind die folgenden Schritte nötig:

sudo systemctl disable systemd-resolved
sudo systemctl stop systemd-resolved
sudo rm /etc/resolv.conf

Dann in die Konfigurationsdatei vom NetworkManager /etc/NetworkManager/NetworkManager.conf in der [main]-Sektion die folgende Option setzen:

dns=default

Nun nur noch den NetworkManager neu starten und schon sollte die /etc/resolv.conf mit den DNS-Informationen gefüttert werden:

sudo systemctl restart NetworkManager
cat /etc/resolv.conf
# Generated by NetworkManager
search kernel-error.local
nameserver 10.10.88.1
nameserver fd00:424e:6eff:f525:454e:6eff:f525:4241

Perfekt! Also los, noch ein Versuch mit dem SSH-Client und… nichts… DNS-Auflösung funktioniert, aber es ist noch immer „insecure„. Stimmt! Es fehlt etwas in meiner resolv.conf. Wir brauchen bestimmt noch die folgende Option:

options edns0

Jetzt aber! HA, dig ist schon mal glücklich, ich sehe ein „ad“. Ähm, aber der SSH-Client noch immer nicht?! Was zum… OK, OK… Irgendwas um SSH muss ich vergessen haben. Aber was? Wie macht SSH das überhaupt? Vielleicht gibt mir das eine Idee. Also, mal kurz in den Code geschaut, C bekomme ich gerade noch hin:

        /* Check for authenticated data */
        if (ldns_pkt_ad(pkt)) {
                rrset->rri_flags |= RRSET_VALIDATED;
        } else { /* AD is not set, try autonomous validation */
                ldns_rr_list * trusted_keys = ldns_rr_list_new();

                debug2("ldns: trying to validate RRset");
                /* Get eventual sigs */
                rrsigs = ldns_pkt_rr_list_by_type(pkt, LDNS_RR_TYPE_RRSIG,
                    LDNS_SECTION_ANSWER);

                rrset->rri_nsigs = ldns_rr_list_rr_count(rrsigs);
                debug2("ldns: got %u signature(s) (RRTYPE %u) from DNS",
                       rrset->rri_nsigs, LDNS_RR_TYPE_RRSIG);

                if ((err = ldns_verify_trusted(ldns_res, rrdata, rrsigs,
                     trusted_keys)) == LDNS_STATUS_OK) {
                        rrset->rri_flags |= RRSET_VALIDATED;
                        debug2("ldns: RRset is signed with a valid key");
                } else {
                        debug2("ldns: RRset validation failed: %s",
                            ldns_get_errorstr_by_id(err));
                }

                ldns_rr_list_deep_free(trusted_keys);
        }

Aaaaaaaaaaaaaaaaaaaaaaa… ldns… woher bekommt er wohl die Trust Keys? Genau… woher? Da fehlt also NOCH etwas in meiner resolv.conf:

options edns0 trust-ad

Und? genau… geht 😀

ssh usermane@hostname.kernel-error.org -vvv
[...]
debug1: SSH2_MSG_KEX_ECDH_REPLY received
debug1: Server host key: ssh-ed25519 SHA256:kTRGVCMRLiHfvJunW2CbW5H3NZmn3Wkx2KnHJXl3iJu
debug3: verify_host_key_dns
debug1: found 2 secure fingerprints in DNS
debug3: verify_host_key_dns: checking SSHFP type 4 fptype 1
debug1: verify_host_key_dns: matched SSHFP type 4 fptype 1
debug3: verify_host_key_dns: checking SSHFP type 4 fptype 2
debug1: verify_host_key_dns: matched SSHFP type 4 fptype 2
debug1: matching host key fingerprint found in DNS
[...]

Pfff… nun habe ich natürlich die Optionen von Hand in meine resolv.conf eingetragen, der NetworkManager wird diese Option also spätestens beim nächsten Boot rauswerfen. Also muss ich noch meinem NetworkManager beibringen, dass er bitte diese Option ebenfalls in meine resolv.conf schreibt, wenn das jeweilige Netzwerkprofil aktiviert ist. Dazu gibt es aber leider keinen Menüpunkt in der GUI vom NetworkManager, also muss das per CLI gemacht werden. Dieses für IPv4 und IPv6 gleichermaßen, sonst greift es leider nicht!

nmcli conn modify DEINE-PROFIL-UUID ipv4.dns-options edns0,trust-ad
nmcli conn modify DEINE-PROFIL-UUID ipv6.dns-options edns0,trust-ad

Oh, ein nmcli conn show listet die bestehenden und vor allem das aktive Profil inkl. der UUID auf. Davon abgesehen, klappt es nun so und ist rebootfest.

So und nun ihr! Ich bin mit meinem FreeBSD-Wissen an das Thema herangegangen. Wie macht man das als Hardcore-Linux-User und mit systemd-resolved richtig und funktionierend?

Cloudflare deal for $10-11 YubiKeys

Es gibt aktuell einen EEEECCCHHHTTTT guten Deal um günstig an bis zu 10 YubiKeys 5 NFC und/oder 5C NFC zu kommen.

Man benötigt dafür einen Cloudflare Account, der ist ja schnell geklickt. Dann klickt man ein paar Links und wartet auf eine E-Mail mit seinem Discount Code.

Da die Keys in der Regel etwas um die 50€ Kosten, ist dieses schon eine extreme Ersparnis.

Oh der Link: https://www.reddit.com/r/yubikey/comments/xrcly7/cloudflare_deal_for_1011_keys/

Bind 9.18 mit DoH und DoT

Ü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.

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 🙂

Windows Server 2012 R2 RRAS Routing- und RAS sichere Konfiguration

Wenn ich schon bei den ganzen Microsoft Themen bin, warum nicht gleich noch „sicheres“ RRAS Routing- und RAS  mit einem Windows Server 2012 R2?! Im speziellen Beispiel an einem L2TP IPsec VPN für Clientsysteme.

Hat mein alles im Routing und RAS konfiguriert verbinden sich die Clients im Standard mit etwas wie: SHA-1 3DES und der DH Group 2 was ein modp1024 (1024-bit) ist. Pfffffff SHA-1 ja, ok… 3DES muss nicht unbedingt und modp1024 möchte man auch nicht oder?

Wie konfiguriert man dieses nun also „weg“? Ich muss zugeben dafür einige Zeit gelesen zu haben. Dann ich hätte erwartet dieses irgendwo in der Nähe vom Routing und RAS konfigurieren zu müssen. Dem ist aber nicht so. Die Konfiguration dieser Parameter findet man über die Windows-Firewall mit erweiterter Sicherheit auf dem Windows Server. Irgendeinen Grund wird es schon haben es dort zu ~verstecken~ und sicher ist dieser absolut einleuchtend, wenn man sich näher damit auskennt. Ich hätte dort von alleine sicher niemals gesucht. Man findet es also über: Windows Firewall ==> recht Maus: Windows-Firewall mit erweiterter Sicherheit ==> Eigenschaften ==> IPsec-Einstellungen ==> IPsec-Standardeinstellungen Button „Anpassen“ ==> Schlüsselaustausch.

Hier kann man nun die Einstellungen konfigurieren… *kopfschüttel* Windows Firewall…. Hat jemand eine Idee warum es ausgerechnet da ist? Wie auch immer…

Steht der Windows RRAS hinter einem NAT sollte man ebenfalls noch UDP Encapsulation aktivieren. Dafür habe ich folgendes Registry File für euch:

Nach diesen Änderungen sollte man natürlich ganz Windowslike den Server einmal durchstarten. Baut man nun von einem Windows Client eine neue VPN Verbindung auf kann man auf diesem natürlich per PowerShell (bitte mit erweiterten Rechten) prüfen ob seine Änderungen gegriffen haben:

Get-NetIPsecMainModeSA | Select-Object -First 1

Wichtig sind dann:

CipherAlgorithm
HashAlgorithm
GroupId

Im Standard wäre es:

Encryption: 3DES
Authentication/Integrity: SHA-1
Key Size: DH Group 2 (1024 bit)

Nach unseren Änderungen:

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

Windows Firewall…. Pfff… Ja natürlich lässt sich das Thema mit Gruppenrichtlinien erschlagen, nur ist dieses noch einmal ein Thema für sich, hm? Vor allem habe ich mich sehr schwer damit getan hier die Reihenfolge korrekt vorzugeben.

Fragen? Dann wie immer fragen 🙂

Windows Server 2012 R2 mit Exchange 2016 und dann Qualys SSL Labs A+, geht das?

Ich habe hier einen Windows Server 2012 R2 mit einem Exchange 2016. Out of the Box spricht das Ding TLS 1.0, SSLv3 und RC4. Da gehen einem schnell die Haare hoch, oder?

Kann man so ein System auf ein A+ im Qualys Rating bekommen und es arbeitet dann noch? Kleiner Spoiler, ja geht!

Ich muss zugeben, Microsoft Produkte strengen mich in dieser Hinsicht immer sehr an. Auch wenn sie ganz sicher ihre Daseinsberechtigung haben.

Nun gut… Für ein A+ benötigen wir neben brauchbaren ciphern, sauberen Protokollen usw. noch HTTP Strict Transport Security (https://de.wikipedia.org/wiki/HTTP_Strict_Transport_Security). Dieses ist im Grunde nur ein http response header und dieses konfigurieren wir im IIS Manager. Das besagte Testsystem kümmert sich nur um den Exchangeserver, daher konfiguriere ich es ganz oben (so wird es überall hin vererbt).

IIS-Manager ==> HTTP-Antwortheader ==> Hinzufügen

Name: strict-transport-security
Wert: max-age=31536000; includeSubdomains

Wie auch im Bild zu sehen.

Jetzt der spannende Teil. Man muss einige Änderungen in der Registrierung vornehmen um MD5, RC4 usw. zu deaktivieren. Ich habe da etwas vorbereitet um dieses zu tun. Ebenfalls wird SSLv3, TLS 1.0, TLS 1.1 deaktiviert. TLS 1.2 und TLS 1.3  wird aktiviert (TLS 1.3 dabei nur für die Zukunft). Ebenfalls werden super schwache Cipher deaktiviert. Die bestmöglichen dafür aktiviert und es wird auch eine Cipherorder vorgegeben. Das File einfach herunterladen, ausführen und im Anschluss den Server durchstarten (Microsoft halt…).

Aber dann sollte man sein A+ haben. Auch wenn ich gerne noch schönere Cipher hätte :-/ aber mehr ging nicht, bzw. habe ich nicht hin bekommen!

Oh natürlich… Das Registry Snippet zum Download:

Fragen? Dann fragen…

TLS_ECDHE_ECDHE_WITH_AES_256_GCM_SHA384 was bedeutet das eigentlich? TLS cipher einfach erklärt..

TLS_AES_256_CGM_SHA384 oder TLS_ECDHE_ECDHE_WITH_AES_256_GCM_SHA384 liest man immer mal wieder, wenn man sich etwas mit Transportverschlüsselung beschäftigt. Was genau dieses bedeutet ist nicht immer ganz klar. Daher möchte ich einmal probieren es etwas aufzuschlüsseln.

Um dieses nachvollziehen zu können, müssen vorher noch die folgenden Begriffe geklärt werden:

  • Key exchange
    Damit ist der Schlüsselaustausch gemeint.
  • Certificate verification
    Hier geht es um das eigentliche Zertifikat vom Server.
  • Bulk encryption
    Die eigentliche Verschlüsselung welche am Ende genutzt wird um die Daten auf ihrem Weg zu verschlüsseln.
  • Hashing
    Die eingesetzten Prüfsummen um sicherstellen zu können, das alles „richtig“ ist.
Verschlüsselung-cipher

Ebenfalls muss man wissen, dass es seit TLSv1.3 einen Unterschied in der Schreibweise der cipher suite gibt. Bei <= TLSv1.2 tauchen in der cipher suite als erstes das Protokoll auf, dann der Algorithmus für den Schlüsselaustausch, nun die digitalen Signaturen des Serverzertifikates gefolgt vom „Rest“. Die Menge möglicher Kombinationen ist jetzt schon sehr hoch. Damit diese „Liste“ nicht in ihrer Länge explodiert hat man bei TLSv1.3 die beiden Punkte Key exchange und Certificate verification aus der Schreibweise entfernt.

Mit diesem Wissen kann man nun anfangen die beiden Zeichenkennten zu „zerlegen“.

TLS_ECDHE_ECDHE_WITH_AES_256_GCM_SHA384

  • TLS
    Nicht schwer, das eingesetzte Protokoll TLS (Transport Layer Security)
  • ECDHE
    Key exchange in diesem Fall ECDHE
  • ECDHE
    Certificate verification bei mir inzwischen ECDHE, sehr oft aber RSA
  • WITH_AES_256_GCM
    Bulk encryption also die eigentliche Verschlüsselung der Daten. In diesem Fall AES (Advanced Encryption Standard) mit der maximalen Länger von 256bit und GCM (Galois/Counter Mode).
  • SHA384
    Das eingesetzte Hashing SHA (Secure Hash Algorithm) in Version 2 mit einer Länge von 384bit.

TLS_AES_256_CGM_SHA384 schafft nun jeder allein, oder?

Sprechen wir noch kurz über den Key exchange. In diesem ist spezifiziert, wie sich Client und Server auf einen eigenen Schlüssel für ihre verschlüsselte Kommunikation einigen. Brauchbar sind dabei Kombinationen aus DHE (wenn sie >= 2048bit sind) und besser noch ECDHE, dabei stehe EC für elliptische Kurven DHE ist Diffie-Hellman. Diffie-Hellmann hat nämlich eine Möglichkeit aufgeführt, wie man für die Verschlüsselung einer Verbindung temporäre Schlüssel einsetzten kann. Denn es lassen sich auch verschlüsselte Verbindungen aufzeichnen. Natürlich kann man so noch immer nicht den Inhalt sehen.. Kommt man an den eingesetzten Schlüssel für die Kommunikation kann man diese damit entschlüsseln. Setzte man also auf einen temporären Schlüssel, gibt es diesen nur für eine gewisse Zeit und dann verschwindet er. Die Zeit, um an diesen Schlüssel zu kommen, ist daher extrem begrenzt und sorgt für eine zusätzliche Sicherheit. „Früher“ hat es gereicht sich einfach irgendwann/irgendwie den Schlüssel vom Server zu besorgen und man konnte mit diesem die Aufgezeichneten Verbindungen entschlüsseln. Bugs wie Heartbleed haben dieses noch vereinfacht. DHE minimiert also etwas das Risiko von Bugs und ergaunerten privat Keys vom Server. Man möchte für seine Verbindungen also nur DHE, besser noch ECDHE! Am besten bietet der Server nichts anders an, da sonst ggf. ein Angreifer versuchen könnte die Verbindung auf etwas „schlechteres“ herunter zu stufen, um so doch am Ende wieder an etwas kommen zu können.

Wenn wir dabei sind… Certificate verification. Nur eine verschlüsselte Verbindung alleine hilft ja nicht, wenn man sich mit dem falschen Server unterhält. Ich meine damit, dass ein Angreifer einfach dafür sorgt, dass wir nicht mit dem gewünschten Server sprechen, sondern mit seinem und dieser vielleicht einfach nur alle Daten durchreicht. Um dieses möglichst zu erschweren gibt es eine ganze Reihe verschiedener Möglichkeiten. Eine davon ist die Certificate verification. Der Server hat also ein Zertifikat, welches vielleicht noch von einer CA signiert wurde, dessen Prüfsumme im DNSsec geschützten DNS liegt, zu dem es HPKP (http Public Key Pinning) gibt oder oder… Dieses Zertifikat sollte daher ebenfalls so gebaut sein, dass man es nicht einfach „nachmachen“ kann. Daher sollte es >=2048bit RSA (asymmetrisches kryptographisches Verfahen) sein, besser noch 4096bit RSA. Hier sieht man schon ein „Problem“. Die Systeme „rechnen“ schneller und damit wird die Bitzahl erhört und die zu übertragenden Daten und das errechnen der Clients usw.. Insg. keine sehr schöne Lösung. ECDHE Zertifikate sind deutlich kleiner, damit schneller zu übertragen und zudem noch für den Client schneller zu prüfen.

Als Beispiel:
Ein Zertifikat mit elliptischen Kurven und einer Länge von 256bit ist grob vergleichbar mit einem RSA Zertifikat mit 3072bit. Wenn jemand daher auf elliptische Kurven setzt, sollten diese nicht kleiner als <=secp256r1 sein. secp224r1 liegt schon zu nahe an 1024bit RSA und fliegt bald weg. secp384r1 ist ganz vorne mit dabei, hat aktuell keinen besonderen Vorteil.

Bulk encryption, tjo die eingesetzte Verschlüsselung. Hier gibt es verschiedene Kombinationen, welche als „sicher“ gelten. Alle zu erklären sprengt sicher den Rahmen. April 2020 kann man sicher merken:

Kombinationen aus AES >=128bit mit GCM oder ChaCha20 mit Poly1305 sind ganz gut. OK ist im Moment noch AES >=128bit mit CBC. 3DES sollte man in keiner Kombination mehr nutzen, das fliegt bald aus der „Sicher“ Liste raus, so wie <= TLSv1.2. Von allen anderen Kombinationen sollte man tunlichst die Finger lassen!

Das Hashing bei der Bulk encryption (das Hashing für Key exchange und Certificate verification hängt am Serverzertifikat, unterliegt den gleichen Merkpunkten) sollte etwas um >= 256bit SHA 2 sein. Ein ganz guter Mittelweg ist hier SHA-384. SHA1 „geht“ wohl dabei ebenfalls noch. Ich würde davon und von allem anderen dennoch die Finger lassen. Wenn ihr irgendwo MD5 RC4 oder ähnliches seht, rennt weg!

Habe ich etwas vergesse, ist etwas falsch oder es gibt Fragen? Dann einfach E-Mail bitte!

SSH bruteforce mit „alter“ Implementierung?!?

Wenn man mit einem System im Internet steht fummelt immer irgendein script kiddie oder bot an den Diensten herum. Oft ist hier eine IP Adresse aus China dabei. Dann probieren sie ein paar default logins und wandern weiter zur nächsten IP Adresse. Die Bots geben dem Ganzen in der Regel schon nicht mehr als drei Versuche, weil sie dann eh von irgendeinem Sicherheitssystem geblockt werden. Da es noch viele andere bots hinter anderen IP Adressen gibt, übermittelt der bot nur seinen Stand der Versuche an das Hirn des Botnetzes und der nächste, nicht geblockte bot, kommt und probiert es weiter…

Alles „kalter Kaffee“… In den letzten Wochen fallen mir zwei kleine Veränderungen auf.

old SSH Bot

Einmal kommen diese IP Adressen noch immer stark aus China… ABER sehr oft ebenfalls von DigitalOcean (USA). Zudem fallen mir die anderen Cloudprovider auf (Google, Microsoft, AWS…). Das verschiebt sich aktuell wohl etwas. Normalerweise kommt ganz viel aus China, dann ganz viel von verschiedenen dynamischen Endkundenanschlüssen auf der Erde. Jetzt kommt ganz viel aus China, dann unglaublich nahe daran Digitalocean, direkt gefolgt von der google-cloud und microsoft-cloud. Erst jetzt kommen die Endkundenanschlüsse und mischen sich mit Adressen aus der AWS-Cloud. Scheinbar haben die Amazonjungs irgendetwas „besser“ gemacht, um ihre Kunden davor zu schützen sich etwas „einzufangen“?!?

Zweitens scheint da ein Botnetz mit recht alter ssh Implementierung unterwegs zu sein. Oder es sucht halt speziell alte SSH-Server? Auf IoT Geräte mit alter Firmware tippe ich weniger, denn von diesen kommt ebenfalls etwas von Cloudanbietern. Bei denen unterstelle ich einfach mal, keine alten IoT Geräte im Einsatz zu haben, die infiziert sind. Naja… Oder es wird halt nach genau solchen Geräten gesucht. Warum alt? Weil ich so etwas in den Logs finde:

Apr  8 10:35:58 YOURMOM sshd[43201]: reverse mapping checking getaddrinfo for 4.3.2.1.serverdedicati.mum.your [1.2.3.4] failed.
Apr  8 10:35:58 YOURMOM sshd[43201]: Did not receive identification string from 1.2.3.4 port 34244
Apr  8 10:36:22 YOURMOM sshd[43202]: reverse mapping checking getaddrinfo for 4.3.2.1.serverdedicati.mum.your [1.2.3.4] failed.
Apr  8 10:36:22 YOURMOM sshd[43202]: Unable to negotiate with 1.2.3.4 port 36160: no matching key exchange method found. Their offer: diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1 [preauth]
Apr  8 10:36:42 YOURMOM sshd[43204]: reverse mapping checking getaddrinfo for 4.3.2.1.serverdedicati.mum.your [1.2.3.4] failed.
Apr  8 10:36:42 YOURMOM sshd[43204]: Unable to negotiate with 1.2.3.4 port 39556: no matching key exchange method found. Their offer: diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1 [preauth]

Wie ist das bei euch?

Keine RSA Zertifikate mehr o/ ….

….. naja, fast :-/

Wir sind alle in 2020 angekommen und so laaaannngggsssaaammmm könnte man von 4096 bit RSA Zertifikaten mal auf >= 256 bit EC Zertifikate wechseln, oder? Bringt mehr Sicherheit, die Schlüssel sind kleiner und so schneller gerechnet und alle gängigen Browser machen es ebenfalls schon ein paar Jahre.

Vor knapp 6 Monaten habe ich daher einen Satz neuer Schlüssel erstellt und diese schon mal in mein HPKP Header eingebunden, damit der Key-Rollover gut funktioniert. Heute habe ich zu den Schlüsseln Zertifikate gebaut, diese von einer CA signieren lassen und alles eingebunden.

Bei meinem nginx vollkommen schmerzfrei. Einfach die neuen Schlüssel hinterlegt und die Cipherliste von allem RSA-Zeug befreit:

ssl_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;

Restart vom nginx und zack, schon läuft alles!

Bei den Webseiten also überhaupt kein Problem. Etwas anders ist es bei E-Mail! Postfix macht es natürlich schon, ach LANGE.. Aber ein Microsoft Exchange 2016 in der (weiter weiter fertigstellen) Installation natürlich nicht. Wenn ich also von so einem System weiterhin E-Mails erhalten möchte (ja will ich und per RSA kann so ein System es auch in ~sicher~), muss ich weiterhin etwas auf RSA Basis anbieten.

Jetzt haben sich die Entwickler(innen) bei Postfix schon so etwas gedacht und bieten dieses in der Konfiguration an. Also RSA Keys/Zertifikate? Richtig… OK, das ist nichts besonders aber das es in Kombination mit ECD Keys/Zertifikaten möglich ist. Ach schaut einfach mal die Konfiguration:

smtpd_tls_eckey_file = /usr/local/etc/postfix/ec-postfix.key
smtpd_tls_eccert_file = /usr/local/etc/postfix/ec-postfix.pem
smtpd_tls_key_file = /usr/local/etc/postfix/postfix.key
smtpd_tls_cert_file = /usr/local/etc/postfix/postfix.pem

Ha, ist das nicht schön? smtpd_tls_eckey_ und smtpd_tls_key_?!? Der Server wirft jedem Client nun also zwei Serverzertifikate entgegen. Einmal EC und einmal RSA (ok man braucht also nun ebenfalls zwei Zertifikate).

Schaut mal:

➜  ~ testssl.sh -t smtp smtp.kernel-error.de:25
[....]
  Server Certificate #1
   Signature Algorithm          SHA256 with RSA
   Server key size              RSA 4096 bits
   Server key usage             Digital Signature, Key Encipherment
   Server extended key usage    TLS Web Server Authentication, TLS Web Client Authentication
   Serial / Fingerprints        4F7A9159AEED9414B7D542ED / SHA1 908FD237EF13A6048077082023C4CDE092F55F33
                                SHA256 74E3984BD5F9FAC26375DAEA6F0326229A0F42AC2EE53088A73DFD5F65107FA9
   Common Name (CN)             *.kernel-error.de 
   subjectAltName (SAN)         *.kernel-error.de kernel-error.de 
   Issuer                       AlphaSSL CA - SHA256 - G2 (GlobalSign nv-sa from BE)
   Trust (hostname)             Ok via SAN wildcard (same w/o SNI)
   Chain of trust               Ok   
   EV cert (experimental)       no 
   ETS/"eTLS", visibility info  not present
   Certificate Validity (UTC)   403 >= 60 days (2020-02-26 14:19 --> 2021-04-05 13:58)
   # of certificates provided   2
   Certificate Revocation List  http://crl2.alphassl.com/gs/gsalphasha2g2.crl
   OCSP URI                     http://ocsp2.globalsign.com/gsalphasha2g2
   OCSP stapling                not offered
   OCSP must staple extension   --
   DNS CAA RR (experimental)    available - please check for match with "Issuer" above
                                iodef=mailto:kernel-erro@kernel-error.de, issue=comodoca.com, issue=geotrust.com, issue=globalsign.com, issue=letsencrypt.org, issue=thawte.com
   Certificate Transparency     yes (certificate extension)

  Server Certificate #2
   Signature Algorithm          SHA256 with RSA
   Server key size              EC 256 bits
   Server key usage             Digital Signature, Key Agreement
   Server extended key usage    TLS Web Server Authentication, TLS Web Client Authentication
   Serial / Fingerprints        24E25E2F3D57B41671392F25 / SHA1 763EE6D52D3CF0237D9858F27EDF42EF4696B1E2
                                SHA256 9C4C0FCE32BA7E8AEAF17210B509D871D6B2EF237E0E887D7190F28F28011143
   Common Name (CN)             *.kernel-error.de 
   subjectAltName (SAN)         *.kernel-error.de kernel-error.de 
   Issuer                       AlphaSSL CA - SHA256 - G2 (GlobalSign nv-sa from BE)
   Trust (hostname)             Ok via SAN wildcard (same w/o SNI)
   Chain of trust               Ok   
   EV cert (experimental)       no 
   ETS/"eTLS", visibility info  not present
   Certificate Validity (UTC)   365 >= 60 days (2020-02-26 13:37 --> 2021-02-26 13:37)
   # of certificates provided   2
   Certificate Revocation List  http://crl2.alphassl.com/gs/gsalphasha2g2.crl
   OCSP URI                     http://ocsp2.globalsign.com/gsalphasha2g2
   OCSP stapling                not offered
   OCSP must staple extension   --
   DNS CAA RR (experimental)    available - please check for match with "Issuer" above
                                iodef=mailto:kernel-erro@kernel-error.de, issue=comodoca.com, issue=geotrust.com, issue=globalsign.com, issue=letsencrypt.org, issue=thawte.com
   Certificate Transparency     yes (certificate extension)
[....]

Jetzt kann noch ein 2016 Microsoft Exchangeserver einliefern und auch die „coolen Kinder“. Was mache ich wohl 2021? Exchange 2016 ignorieren?!?!


Kleines Update, da es Fragen gab..

Natürlich sollte man seine ciphers in einer sinnigen Reihenfolge für seinen Postifx konfigurieren. Kommen sie in der Reihe erst nach den RSA ciphern wird es natürlich fast nie benutzt *kopfschüttel*. Leute bitte kein copy & paste, mitdenken!

Ein Beispiel für die cipherliste wäre:

tls_high_cipherlist = TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256

TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256 sind dabei für TLS1.3

ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256 sind für den gewünschten ECD-Key

ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256 sind dann für TLS 1.2 RSA Verbindungen.

Kommt nun ein Client/einliefernder Mailserver, dann wird dieser dank:

tls_preempt_cipherlist = yes

Die vom Server übermittelte cipherliste durchgehen und die erste für beide funktionierende Kombination benutzen.

RSA Verbindungen sehen dann so aus:

Mar  3 08:24:13 smtp postfix/smtpd[49650]: Anonymous TLS connection established from RSA-mailserver[1.2.3.4]: TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)

ECD Verbindungen so:

Mar  3 08:23:53 smtp postfix/smtpd[49650]: Anonymous TLS connection established from EDC-mailserver[5.6.7.8]: TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)

Einfach, oder?

« Ältere Beiträge

© 2024 -=Kernel-Error=-

Theme von Anders NorénHoch ↑