Verschlüsselung, Secure Shell
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
undrsh
) ⇒ Fernadministration (remote control)scp (ersetzt
rcp
) ⇒ remote copysftp (ersetzt mit reduziertem Befehlssatz einen klassische
ftpd
)
Aufbau einer Vertrauensbasis
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
- 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
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]:~$
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")
Die Clientseitige Datenbankdatei
~/.ssh/known_hosts
kann durchsucht u. bearbeitet werden:Bei nicht gehashten Adressen/Hostnamen: grep/vi
Bei gehashten Adressen/Hostnamen:
ssh-keygen -F <HOST>
bzw:ssh-keygen -R <HOST>
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
undDenyGroups
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!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
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.
Ziel- und Quell-Verzeichnis definieren bzw. anlegen:
Lokaler Ausgangspunkt: ~/Dokumente
Entfernter Zielordner (auf Debian/Rasbian):
mkdir /home/tux/Backup/Dokumente/
Installation der Software auf beiden Seiten:
Verschlüsselung via
sshd
(= erfüllte Voraussetzung)Vom Samba-Team stammendes
rsync
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
Nennen Sie die beiden Dateien (benutzerdefiniert und systemweit), die die clientseitigen Vertrauenstellungen zu ssh-Servern beinhalten.
a) ~/.ssh/known_hosts b) /etc/known_hosts
Wie lautet die Kommandozeile, mit der Sie sich ein eigenes ssh-Schlüsselpaar erzeugen können?
ssh-keygen -t rsa -b 4096
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
Wie heißen die Konfigurationsdateien von
sshd
undssh
?/etc/ssh/sshd_config ( D = Daemon ) /etc/ssh/ssh_config
Mit welcher Direktive kann man in der Konfigurationsdatei des
sshd
einen ssh-Login von root verhindern?PermitRootLogin no
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:
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 <DATEINAME>]
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:
#!/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