Verschlüsselung, Secure Shell ############################# .. highlight:: bash .. shell-session Grundlagen ********** Siehe dazu auch https://www.cryptool.org/de/ Verschlüsselungsarten ===================== Symmetrische Verschlüsselung ---------------------------- - Auf beiden Seiten ist der eine, selbe Schlüssel hinterlegt - Einsatz bei *Pre Shared Key* ⇒ WLAN - Schwierige Schlüsselverwaltung - Wichtige Verschlüsselungsverfahren: AES (WPA2 bei WLAN), Blowfish, 3DES Asymmetrische Verschlüsselung ----------------------------- - Laut Kerkhoff: Selbst wenn der Algorithmus in die Hände des Feindes fällt, dürfen keine Rückschlüsse auf den Schlüssel gezogen werden können - Das Schlüsselpaar besteht aus dem privaten Schlüssel, der NIEMALS das System verlassen darf, der öffentliche Schlüssel wird weitergegeben - Ablauf einer Verschlüsselung: - Der Sender verschlüsselt die Nachricht mit dem Public-Key der Empfängers - Der Empfänger entschlüsselt sie mit seinem eigenen Private-Key - Wichtige Verschlüsselungsverfahren: RSA, DH (IKE-Handshake), ECDSA (Unter Mitwirkung der NSA entstanden!), DSA - Risiken: Zu geringe Schlüssellänge (inbesondere bei RSA wichtig), oft kein Schutz gegen Man-In-The-Middle (MITM) Angriffe ⇒ **Fingerabruck prüfen!** - Anwendungen, die u.a. RSA verwenden: Secure Shell, Pretty Good Privacy (GnuPG) Die Secure Shell **************** - ssh (ersetzt ``rlogin`` und ``rsh``) ⇒ Fernadministration (remote control) - scp (ersetzt ``rcp``) ⇒ remote copy - sftp (ersetzt mit reduziertem Befehlssatz einen klassische ``ftpd``) Aufbau einer Vertrauensbasis ============================ 1. Zuerst einmal wird auf dem **Server** der eigene krytografische Fingerabdruck vom eigenen Schlüsselpaar extrahiert, damit Clients später die Identität des Servers überprüfen können. Je nach Distribution werden unterschiedlich viele Schlüssel für die verschiedenen Verschlüsselungsalgorithmen vorgehalten: :: => ssh-keygen -l -f /etc/ssh/ssh_host_ed25519_key.pub :: => ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key.pub 2. | Beim ersten Verbingsaufbau von **Clients** via mit ssh, scp oder sftp wird der öffentliche Schlüssel automatisch vom Server heruntergeladen und ein Fingerabruck daraus generiert, der nun mit dem Fingerabdruck, der auf dem Server ausgegeben wurde, verglichen werden muss. Stimmt er überein, Unterschreibt der Client mit **yes** die Echtheit der Serveridentität. | Danach wird die IP-Adresse bzw. der Hostname des Servers zusammen mit dem eben heruntergeladenen Public-Key des Servers in der benutzerdefinierten Datei ``~/.ssh/known_hosts`` gespeichert. Dieser vertrauensbildende Vorgang kann auch vom Admin durchgeführt werden, die systemweite Datenbankdatei ist dann: ``/etc/ssh/known_hosts`` 3. Stimmt etwas mit der Serveridentität nicht, weil eine andere Netzwerkkarte eingebaut wurde, ein anderer Verschlüsselungsalgorithmus zum Einsatz kommt oder tatsächlich ein MITM-Angriff vorliegt, äußert sich das in etwa so: :: artix:[tux]:~$ ssh 192.168.2.200 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY! Someone could be eavesdropping on you right now (man-in-the-middle attack)! It is also possible that a host key has just been changed. The fingerprint for the RSA key sent by the remote host is SHA256:3yTKcd6THD+8tc3+tHfmXWYMRjNnm+vd6qW7rqQNUaM. Please contact your system administrator. Add correct host key in /home/tux/.ssh/known_hosts to get rid of this message. Offending ED25519 key in /home/tux/.ssh/known_hosts:47 Host key for localhost has changed and you have requested strict checking. Host key verification failed. artix:[tux]:~$ 4. Der Client bestimmt, welches Verschlüsselungsverfahren angewendet wird, will er RSA für die Kommunikation, schiebt er das Ganze so an: :: ssh -o HostKeyAlgorithms=ssh-rsa-cert-v01@openssh.com,\ ssh-dss-cert-v01@openssh.com,ssh-rsa-cert-v00@openssh.com,\ ssh-dss-cert-v00@openssh.com,ssh-rsa,ssh-dss tux@deb7 :: (Oft funktioniert auch die Kurzform: "HostKeyAlgorithms=ssh-rsa") 4. Die Clientseitige Datenbankdatei ``~/.ssh/known_hosts`` kann durchsucht u. bearbeitet werden: a. Bei nicht gehashten Adressen/Hostnamen: grep/vi b. Bei gehashten Adressen/Hostnamen: ``ssh-keygen -F `` bzw: ``ssh-keygen -R `` Letztere Zeile entfernt (``-R``, remove) einen bestimmten Host aus der Liste der wohlbekannten, vertrauten Server. Dies wird benötigt, um das unter 3. geschilderte Problem mit der Serveridentität zu beheben. Konfiguration der Secure Shell ============================== - Dateiname: ``/etc/ssh/sshd_config`` (Wegen dem Daemon ist ein ***d*** im Dateinamen) - Eine wichtige Einstellung, die root-Login verbietet: ``PermitRootLogin no`` - Falls ein Login mittels eigenen Schlüsselpaaren erzwungen werden soll: ``PasswordAuthentication no`` - Festlegen, welche Nutzer Zugriff bekommen sollen: Parameter ``AllowUsers``, ``DenyUsers``, ``AllowGroups`` und ``DenyGroups`` - Einen Verschlüsselungsalgorithmus nicht mehr anbieten, Zeile löschen: ``HostKey /etc/ssh/ssh\_host_ecdsa_key`` - Dateiname: ``/etc/ssh/ssh_config`` (Ohne ***d***!) - Bequemlichkeitseinstellung (Der Client kann dann ``-X`` weglassen): ``ForwardX11 yes`` - Festlegen, dass Clients einen anderen als den voreingestellten (einkompilierten) Verschlüsselungsalgorithmus nutzen sollen: ``HostKeyAlgorithms ssh-rsa-cert-v01@openssh.com,…`` (s.o.) Eigenes clientseitiges Schlüsselpaar erzeugen ============================================= **Zur Orientierung:** Das Ganze geschieht auf dem Client, er legt zum Schluss lediglich seinen öffentlichen Schlüssel unter dem Namen ``authorized_keys`` auf dem Server ab. - Ziele: - Zweifaktorauthentifizierung - Automatischer Login für Backup-Tools wie ``rdiff-backup`` - Erzeugung eines eigenen Schlüsselpaares auf dem Client (= CentOS) ohne Passphrase für Autologin :: ssh-keygen -t rsa -b 4096 -N "" - | Kopieren des Inhaltes von ``~/.ssh/id_rsa.pub`` auf den entfernten Server in die Datei ``~/.ssh/authorized_keys``, es handelt sich hierbei um den öffentlichen Schlüssel -- nur er darf herausgegeben werden! 1. Kopieren auf manuelle Art (alles auf dem Client): - Sicherstellen, dass es auf dem Server den Ordner ``~/.ssh`` gibt: :: tux@client> ssh tux@server "mkdir -p ~/.ssh" - Die Public-Key-Datei kopieren und umbenennen (ACHTUNG: Nur beim ersten Mal, sonst droht Datenverlust!) :: tux@client> scp ~/.ssh/id_rsa.pub tux@server:.ssh/authorized_keys 2. Komfortables Kopieren ebenfalls auf dem Client): :: ssh-copy-id tux@server - Tipps fürs Testen: - Der besseren Übersicht halber erst einmal mit gleichen Benutzernamen arbeiten: tux@client ⇒ tux@server (Entsprechend wird auf beiden Seiten automatisch */home/tux/.ssh* erwartet) - Nach erfolgreichem Login nicht auf dem Server eingeloggt bleiben (Man will ja wahrscheinlich noch nicht wirklich den Server fernadministrieren, sondern erst einmal die Client-History zu Dokumentationszwecken sichten.): :: exit history 20 > ssh-versuche-histfile-01.txt Automatisches Synchronisieren von Verzeichnissen ================================================ Motivation: Dank des eigenen passphraselosen Schlüssels kann nun leicht einen Master/Slave-Mirror eingerichtet werden. Die Synchonisierung kann später von ``cron`` ausgeführt werden. 1. Ziel- und Quell-Verzeichnis definieren bzw. anlegen: a. Lokaler Ausgangspunkt: *~/Dokumente* b. Entfernter Zielordner (auf Debian/Rasbian): ``mkdir /home/tux/Backup/Dokumente/`` 2. Installation der Software auf beiden Seiten: a. Verschlüsselung via ``sshd`` (= erfüllte Voraussetzung) b. Vom Samba-Team stammendes ``rsync`` 3. Ein einfacher Aufruf, der alle Dateien auf dem Server löscht, die nicht auf der sendenden Seite beim Client existieren kann so aussehen: :: #rsync ARCHIVING MASTER/SLAVE SENDER=CLIENT EMPFÄNGER=SERVER rsync -a --delete ~/Dokumente/ tux@deb7:/home/tux/Backup/Dokumente/ # ^ # | # Wenn dieser "Directory"-Slash fehlt, wird # der Ordener als Unterverzeichnis in den Zielordner kopiert! **History-Mitschnitt für Experimente.** **Anmerkung:** Im folgenden Historyauszug ist beim ersten ``rsync``-Aufruf (Zeile 06) weder ein Login-Prompt noch eine Ausgabe, was im Einzelnen getan wird, zu sehen. Beim zweiten Aufruf (Zeile 15) wird die Option *``-v``* (verbose) verwendet, die für den Testfall mehr Anschaulichkeit bringt. :: 01 [tux@cent7 ~]$ echo 123 > Dokumente/datei01.txt 02 [tux@cent7 ~]$ echo 123 > Dokumente/datei02.txt 03 [tux@cent7 ~]$ echo 123 > Dokumente/datei03.txt 04 [tux@cent7 ~]$ 05 [tux@cent7 ~]$ 06 [tux@cent7 ~]$ rsync -a --delete ~/Dokumente/ tux@deb7:/home/tux/Backup/Dokumente/ 07 [tux@cent7 ~]$ 08 [tux@cent7 ~]$ 09 [tux@cent7 ~]$ ### Testen, ob das Master-Slave-Verhalten funktioniert; wird eine Datei auf dem 10 [tux@cent7 ~]$ # Master gelöscht, zieht das eine entsprechende Löschaktion auf dem Slave nach 11 [tux@cent7 ~]$ # sich: 12 [tux@cent7 ~]$ 13 [tux@cent7 ~]$ rm Dokumente/datei01.txt 14 [tux@cent7 ~]$ 15 [tux@cent7 ~]$ rsync -a -v --delete ~/Dokumente/ tux@deb7:/home/tux/Backup/Dokumente/ 16 sending incremental file list 17 ./ 18 deleting datei01.txt 19 20 sent 83 bytes received 15 bytes 196.00 bytes/sec 21 total size is 8 speedup is 0.08 22 [tux@cent7 ~]$ **Fragen/Aufgaben zur Wiederholung** 1. Nennen Sie die beiden Dateien (benutzerdefiniert und systemweit), die die clientseitigen Vertrauenstellungen zu ssh-Servern beinhalten. :: a) ~/.ssh/known_hosts b) /etc/known_hosts 2. Wie lautet die Kommandozeile, mit der Sie sich ein eigenes ssh-Schlüsselpaar erzeugen können? :: ssh-keygen -t rsa -b 4096 3. Welchen Namen muss die Public-Key-Datei Ihres eigenen Schlüsselpaares auf dem Server aufweisen, wenn Sie sich dort mittels dieses Paares authentifizieren wollen? (Volle Pfadangabe) :: ~/.ssh/authorized_keys 4. Wie heißen die Konfigurationsdateien von ``sshd`` und ``ssh``? :: /etc/ssh/sshd_config ( D = Daemon ) /etc/ssh/ssh_config 5. Mit welcher Direktive kann man in der Konfigurationsdatei des ``sshd`` einen ssh-Login von *root* verhindern? :: PermitRootLogin no 6. Welchen TCP-Port verwendet standardmäßig der ``sshd``? :: 22 ( siehe /etc/services ) Tunnelbau mit SSH ================= Grafische Anwendungen verschlüsselt weiterleiten ------------------------------------------------ Im einfachsten Falle lässt sich X11 durchtunneln, dazu braucht es nur die Option '-X' (das alte, klassische X11-Forwarding ist vollkommen unverschlüsselt!): :: ssh -X tux@cent7 :: => nautilus & => yast2 & (bei SuSE Linux) Lokaler SSH-Tunnel für HTTP --------------------------- Prinzipiell lässt sich auf diese Art jede HTTP-Kommunikation absichern, so könnte man z.B. aus dem Verzeichnis ``~/public_html`` heraus mittels :: $ python -m http.server einen Webserver starten, der am Port 8000 lauscht. Der Clientzugriff kann nach dem offenzuhaltenden ssh-Login (Option '-L' = lokale Portweiterleitung) z.B. mit ``wget`` via verschlüsselten Tunnel und dem zugehörigen Port 8888 erfolgen: :: $ ssh -L 8888:localhost:8000 zielserver $ ... $ wget http://localhost:8888/my-important-file.txt Weiterführende Dokumente: - http://www.computersecuritystudent.com/UNIX/SSH/lesson9/ - https://solitum.net/an-illustrated-guide-to-ssh-tunnels/ Verschlüsselung mit GnuPG ************************* Anders als beim zertifikatsbasierten, pyramidenförmigen Vertrauensmodell von X.509 liegt hier keine solch starke Bindung an übergeordnete Autoritäten vor. Das Motto lautet "Ich vertraue nur denen, den ich vertrauen möchte." Jeder hat sozusagen seinen persönlichen Schlüsselbund im *web of trust*. Schlüssel erzeugen und signieren ================================ - Eigenen Schlüsselbund erzeugen: :: apt install haveged # Vorher guten Zufallszahlengenerator installieren gpg --gen-key (Bestätigung am Schluss mit 'F' [fertig]) - Public-Key exportieren :: gpg --export --armor -o axelPemmann.pub "Axel Pemmann" - Rückrufszertifikat erzeugen (Am besten NICHT in eine Datei speichern, die man ja verschlüsselt ablegen müsste, sondern ausdrucken! :: gpg --gen-revoke -o axelPemmann-revoke.crt "Axel Pemmann" - Öffentlichen Schlüssel auf einen Key-Sever hochladen (oder einfach per Mail versenden, was die beste Lösung ist, weil sich auf den Key-Servern viele Schlüssel mit falscher Identität tummeln): :: gpg --send-key ... - Fingerprint für spätere Authentizitätsprüfung ausgeben (kontra MITM) :: gpg --fingerprint "Axel Pemmann" > axelPemmann-fingerprint.txt - Schlüssel der Kommunikationspartner importieren :: gpg --import gerald.pub :: gpg --import maik.pub :: gpg --keyserver certserver.pgp.com --recv-key 0x47110815 :: --> oder suchen via: http://pgp.mit.edu/ - Die importierten Schlüssel prüfen und signieren :: gpg --edit-key gerald :: gpg> list (Schlüssel auflisten, optional) gpg> fpr gerald (Fingerabdruck des Partners ausgeben, optional) :: <--- SNIP: Per Telefon Fingerprint vegleichen ---> :: gpg> sign (Unterzeichnung (j)) gpg> check gpg> quit Verschlüsselung =============== Nach dem gegenseitigen Austauschen des öffentlichen Schlüssels und dem entsprechenden Signieren (Key-Signing Party) kann es losgehen: - Eine Datei verschlüsseln :: gpg --output datei-richter.txt.gpg --encrypt --recipient richter datei.txt - Entschlüsselung der Datei beim Partner :: gpg --decrypt datei-pemmann.txt.gpg [--output ] - Heruntergeladene Dateien verifizieren :: gpg --verify source.tar.gz - Verschlüsselung und Archivierung mit ``gpg-zip`` (komplette Verzeichnisse) :: gpg-zip --encrypt --output GnuPG.cryptdir --gpg-args "-r axel@pemmann.de" GnuPG/ - Entschlüsseln und Entpacken mit ``gpg-zip`` :: cd /tmp gpg-zip --decrypt ~/GnuPG.cryptdir Signieren von Dateien ===================== In Zeiten vermehrter Onlineaktivitäten ist es sinnvoll, Verträge o.ä. digital zu unterschreiben. Zur späteren Überprüfung der Unterschrift durch den Partner mittels ``gpg --verify ...`` muss er meinen öffentlichen Schlüssel erhalten und an seinen Schlüsselbund angehängt haben. Für die Unterzeichnung ist die Option ``--detach-sign`` empfehlenswert, weil dadurch die Signatur nicht die Originaldatei verändert, sondern als abgetrennte, separate Datei mit übermittelt werden kann (= '.sig'-Datei): :: gpg --detach-sign -o Vertrag-0815-unterschrieben.pdf.sig Vertrag-0815-unterschrieben.pdf Das Ganze kann man sich in eine kleine Programmdatei namens ``gpgsign.sh`` schreiben: .. highlight:: bash :: #!/bin/sh # gpgsign.sh # Diesem kleinen Skript muss als ersten Übergabeparameter einfach # nur die zu signierende Datei mitgegeben werden. gpg --detach-sign -o ${1}.sig --armor $1