TOFU - Trust On First Use - SSH Zertifikate

O.K., worum geht es hier eigentlich?

Verbinden wir uns das erste mal mit einem neuen System, sehen wir in aller Regel erst einmal so was in der Art:

 $ ssh -Y vml172042
The authenticity of host 'vml172042 (172.17.2.42)' can't be established.
ED25519 key fingerprint is SHA256:kIe5Ki/ItvQq9Cpfw/qLReo1K14U503r5P1nN3r8nO4.       
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])?

So und nun mal Hand aufs Herz was machen wir hier? Klar wir nun jeder sagen, bzw. was bekommen wir als Antworten wenn wir da mal etwas genauer nachfragen? Mögliche Antworten können nun sein:

  1. Woot? Mir egal, ich antworte hier mit yes weil mit no komme ich nicht weiter und so habe ich Ruhe, die Meldung kommt nicht wieder! Und ganz ehrlich ich weiß nicht was das soll.

  2. Pfff, ich rufe entweder ssh mit den Optionen -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null auf, bzw. ich habe in meiner SSH-Clientconfig unter ~/.ssh/config die folgenden Zeilen eingetragen bei meinen Hosts:
    Host *
      StrictHostKeyChecking=no
      UserKnownHostsFile=/dev/null

    Problem gelöst!

  3. Natürlich, prüfe ich den Fingerprint, ich kenne den ja auswendig (in unserem obigen Beispiel SHA256:kIe5Ki/ItvQq9Cpfw/qLReo1K14U503r5P1nN3r8nO4) oder ich habe eine Liste aller möglichen 1860 Host vor mir und tippe den dann vor dem ersten Verbindungsaufbau ein, weil ich weiss was TOFU bedeutet und nehme das ernst.

O.K., Antwort 1 und 2 will man definitiv nicht hören! Bei Antwort 3 sagt mir mein innerstes ICH „echt, Du machst das wirklich so oder da nimmst Du mich doch eher auf den Arm?“.

Wie können wir nun dieses Dilemma beim ersten Verbindungsaufbau nun elegant umschiffen und dies sauber uns auch sicher lösen? Das wollen wir uns nun im nächsten Abschnitt noch etwas genauer ansehen.

Soviel sei vorab schon mal erwähnt:

Das Securitymodell TOFU1) dient dazu zwischen einer Client-Software und einem Ziel-System ein Vertrauen herzustellen, für den zuvor kein Vertrauen aufgebaut wurde. Im obigen Abschnitt Ausgangssituation haben wir schon gesehen, dass beim ersten Verbindungsaufbau uns mitgeteilt wird, dass der erkannte Fingerprint des ssh_host_ed25519_key unbekannt ist und daher dem System erst einmal nicht vertraut wird. Wie weiss der SSH-Client dies nun? Der SSH-Client versucht die die Kennung des Zielsystems, in der Regel eine Art öffentlichen Schlüssel, in ihrer lokalen Vertrauensdatenbank zu finden. Kann diese im Falle der SSH in der ~/.ssh/known_hosts dort nicht gefunden werden, wendet sich der SSH-Client in der Regel an den Benutzer, um festzustellen, ob dem Rechner vertraut werden soll. Ist diese Entscheidung positiv, wird die Kennung des Zielsystems in der Vertrauensdatenbank der (SSH-)Client-Software für künftige Verbindungen gespeichert.

Im obigen Abschnitt Ausgangssituation haben wir schon gesehen, dass beim ersten Verbindungsaufbau uns mitgeteilt wird, dass der erkannte Fingerprint des ssh_host_ed25519_key unbekannt ist und daher dem System erst einmal nicht vertraut wird. Üblich ist nun hier, den Fingerprint zu akzeptieren wenn man sich das erste Mal mit einem Host verbindet. Die präsentierte Warnung wird also einfach als notwendiges Übel abgetan. Und genau hier sind wir nun mittendrin beim Thema TOFU! Was sollen, nein was werden wir nun tun? Ganz einfach, wir nehmen diese SSH-Warnung ernst und tun sie nicht ab also lästiges vernachlässigbares Übel!

Ja, eine Verbindung ist später dann verschlüsselt dank des SSH-Schlüsselmaterials von Client und Server von dessen Public-Key die jeweiligen Endstellen Kenntnis haben. Tatsache ist aber auch dass SSH die Authentizität des Hosts nicht überprüfen kann und das ist ein ernstes Problem! Verschlüsselte Kommunukation ist sehr gut aber ist sie denn auch vertrauenswürdig, sprich haben wir uns wirklich mit dem Zielsystem verbunden, oder ist da ein kompromittiertes System als MITM2) im Einsatz? Was das bei Passwort gestützten SSH-Verbindungen bedeutet, ist wohl jedem glasklar - ja genau daher kommt bei uns auch auch nur Schlüsselbasierter Zugriff zum Einsatz!

Beim ersten Verbindungsaufbau werden wir also nun in unserem Beispiel hier eben darauf hingewiesen, dass wir dem System noch nicht vertrauen und wir das Vertrauen entweder bestätigen oder vielleicht auch auf andere Weise anderweitig herstellen wollen. Doch hierzu später mehr im Abschnitt Lösung(smöglichkeit).

Bestätigen wir nun das Vertrauen bei der ersten Verbindungsaufbau/-verwendung (TOFU3)) beim Initialen Verbindungsaufbau wir uns in unserer ~/.ssh/authorized_keys ein entsprechender Eintrag hinzugefügt, welcher später dann als Anker dient und wir ohne TOFU-Meldung uns sofort mit den Zielsystem verbinden. Das bedeutet natürlich dass bei entsprechend vielen Zielsystemen entsprechend viele Zeilen dort sich ansammeln und sind dann auch noch wechselnde IP-Adressen im Spiel,das Ganze noch schneller anschwillt.

Ändern sich dann auch noch ssh_host_ed25519_key von Zielsystemen, da z.B. bei Virtualisierungsumgebungen Virtuelle Maschinen getauscht oder erneuert werden, sind wir wiederum sehr schnell bei TOFU-Meldungen. Nach dem Hinzufügen von Verbindungen sind diese dauerhaft aktiv und die Daten in der ~/.ssh/authorized_keys gepflegt werden.

Letztendlich es kann da sehr schnell mitunter auch „hässlich“ werden. Das war z.B. auch bei einem Sicherheits-Audit genau diese Antwort des Auditors bei meiner Frage, warum er denn etwas gegen authorized_keys habe!

Zusammengefasst kann man also schon mal folgende Dinge Festhalten:

Der Zweck von TOFU ist: Das Vertrauen bei der ersten Nutzung ist ein Mechanismus und hat das Ziel ein Vertrauen zu schaffen, wo es vorher keines gab. In der Regel passiert das auf der Grundlage einer Benutzerentscheidung. Bei TOFU überlässt man es im Grunde dem Benutzer, zu entscheiden, ob ein Rechner legitim ist und ob er zu erkennen vermag das bei dieser initialen Verbindung kein Angreifer anwesend ist.

Das Ganze ist also durchaus anfällig, denn die erste Entscheidung, ob einem Rechner vertraut wird ist eine Entscheidung, auf die sich alle nachfolgenden Entscheidungen stützen! Gelingt es einem Angreifer diesen Prozess zu infiltrieren und als vertrauenswürdiger Rechner aufgenommen zu werden, ist die Verbindung und mehr völlig ungeschützt!

Aber wie wir wissen, neigen Benutzer und Administratoren doch auch dazu nicht immer die richtigen Entscheidungen zu treffen - man kann also durchaus auch das als Schwachstelle des TOFU-Modells ausmachen!

Wie gehen wir nun am besten mit dem Dilemma um bzw. wie lösen wir es? Hier gibt es wie im Leben immer, natürlich nicht nur den einen einzigartigen Lösungsweg, sondern mehrere, von denen wir uns nun mal zwei genauer ansehen wollen.

Rufen wir uns aber kurz nochmals in Erinnerung wie das Ganze bei der SSH und der Authentifizierung funktioniert:

Die Authentifizierung mit öffentlichem Schlüssel funktioniert wie folgt: Das Verfahren basiert auf der Public-Key-Kryptografie, die Kryptosysteme verwendet, bei denen die Ver- und Entschlüsselung mit getrennten Schlüsseln erfolgt und es nicht möglich ist, den Entschlüsselungsschlüssel aus dem Verschlüsselungsschlüssel abzuleiten. Die Idee ist, dass jeder Benutzer ein öffentliches/privates Schlüsselpaar für Authentifizierungszwecke erstellt. Der Server kennt den öffentlichen Schlüssel, und nur der Benutzer kennt den privaten Schlüssel.

Die SSH implementiert das Protokoll zur Authentifizierung mit öffentlichem Schlüssel automatisch, wobei einer der Algorithmen DSA, ECDSA, Ed25519 oder RSA verwendet wird.

Die Datei ~/.ssh/authorized_keys listet die öffentlichen Schlüssel auf, die für das Einloggen erlaubt sind. Wenn sich der Benutzer anmeldet, teilt das ssh-Programm dem Server mit, welches Schlüsselpaar es für die Authentifizierung verwenden möchte. Der Client weist nach, dass er Zugriff auf den privaten Schlüssel hat, und der Server prüft, ob der entsprechende öffentliche Schlüssel berechtigt ist, das Konto zu akzeptieren.

Der Server kann den Client über Fehler informieren, die den Erfolg der Authentifizierung mit dem öffentlichen Schlüssel verhindert haben, nachdem die Authentifizierung mit einer anderen Methode abgeschlossen wurde. Diese können angezeigt werden, indem der LogLevel auf DEBUG oder höher erhöht wird (z. B. durch Verwendung der Option -v).

O.K. diejenigen unter uns, die nun bei der Betrachtung der Ausgangssituation und bei der Erklärung - Was versteht man unter Trust On First Use (TOFU) noch fleissig mit dem Kopf nickten, zeigen wir nun im ersten Schritt eine Möglichkeit auf das Thema TOFU bestmöglich zu begegnen.

Gehen wir erst einmal noch einen Schritt zurück und bauen unsere erste Verbindung zum gewählten Zielsystem auf.

 $ ssh -Y vml172042
The authenticity of host 'vml172042 (172.17.2.42)' can't be established.
ED25519 key fingerprint is SHA256:kIe5Ki/ItvQq9Cpfw/qLReo1K14U503r5P1nN3r8nO4.       
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])?

Uns wird also der Fingerprint SHA256:kIe5Ki/ItvQq9Cpfw/qLReo1K14U503r5P1nN3r8nO4 des Zielsystems genauer gesagt vom /etc/ssh/ssh_host_ed25519_key des Ziel-Host präsentiert. Doch wie kommen wir nun an diesen?

Den Fingerprint des ED25519-Hostkey vom Server vml172042 könnte man sich ja nun wie folgt ermitteln:

 $ ssh-keyscan -t ed25519 vml172042
# vml172042:22 SSH-2.0-OpenSSH_7.4
# vml172042:22 SSH-2.0-OpenSSH_7.4
256 SHA256:syMNF0jPr8b7hgqoCLgUZpSZhMulGeoGKFU/FWm3UKY vml172042 (ED25519)

O.K., wir haben zwar den Fingerprint des Server-Keys, aber wir haben diesen mit Hilfe des Programms ssh-keyscan ermittelt der ja on-the-fly eine Verbindung zum Zielhost aufbaut und dessen präsentierten Schlüssel auswertet. Wenn das aber nun das kompromittierte MITM-System wäre, würden wir uns ja dessen Fingerprint für später merken.

Wir sehen, Idee war vom Ansatz her schon mal nicht schlecht, aber die Umsetzung doch sehr fehlerbehaftet und daher verwerfen wir diese Variante auch gleich wieder!

Also melden wir uns am besten direkt an der Konsole des Zielsystems an, wenn wir physisch vor diesem stehen. Oder wir verbinden uns mit der GUI des Virtualisierungs-Hosts oder einem RemoteManageBoard wie IPMI oder iDrac je nachdem was der Hardwarehersteller uns hier anbietet. Dort ermitteln wir mit den entsprechenden Rechten den Fingerprint unseres Server-Keys.

 # ssh-keygen -E sha256 -lf /etc/ssh/ssh_host_ed25519_key
256 SHA256:kIe5Ki/ItvQq9Cpfw/qLReo1K14U503r5P1nN3r8nO4 /etc/ssh/ssh_host_ed25519_key.pub (ED25519)

Diesen notieren wir nun und hinterlegen diesen für alle Admins im Intranet, im WIKI, in GitHub bzw. GitLab, wo immer auch unsere Admins Zugriff haben um diesen zu finden um beim späteren Verbindungsaufbau dann verwenden zu können.

Jetzt verbinden uns nun mit dem uns noch unbekanntem Zielsystem, dessen Key-Fingerprint wir ja nun auf anderem Wege zur Verfügung gestellt bekommen haben:

 $ ssh -Y vml172042
The authenticity of host 'vml172042 (172.17.2.42)' can't be established.
ED25519 key fingerprint is SHA256:kIe5Ki/ItvQq9Cpfw/qLReo1K14U503r5P1nN3r8nO4.       
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])?

Ja wir könnten nun visuell den Fingerprint vergleichen und dann mit yes bestätigen. Aber Hand aufs Herz wie schnell verguckt man sich da beim optischen Vergleich? Besser ist es, wenn wir unseren Fingerprint den wir z.B.im Intranet gefunden haben, dort manuell eingeben oder cut'n'pasten.

Wollen wir doch mal sehen,was passiert wenn wir uns vertippen (die drei X am Ende!):

Are you sure you want to continue connecting (yes/no/[fingerprint])? SHA256:kIe5Ki/ItvQq9Cpfw/qLReo1K14U503r5P1nN3r8XXX
Please type 'yes', 'no' or the fingerprint: 

Aha, die beiden Fingerprints stimmt also nicht überein:

SHA256:kIe5Ki/ItvQq9Cpfw/qLReo1K14U503r5P1nN3r8nO4
SHA256:kIe5Ki/ItvQq9Cpfw/qLReo1K14U503r5P1nN3r8XXX

O.K. wir bestätigen also nun den richtigen Fingerprint:

Please type 'yes', 'no' or the fingerprint:SHA256:kIe5Ki/ItvQq9Cpfw/qLReo1K14U503r5P1nN3r8nO4

Nun erhalten wir einen Hinweis dass unser Host nun dauerhaft bekannt ist:

Warning: Permanently added '172.17.2.42' (ED25519) to the list of known hosts.

… und voila wir sind auf dem Zielhost:

 [django@vml172042 ~]$ 

Verbinden wir uns nun ab sofort, erneut mit dem Zielhost erneut bekommen wir keine TOFU-Warnung mehr präsentiert, sondern gelangen direkt ohne Umwege auf unseren Zielhost. Verantwortlich ist der letzte Eintrag der vorhin bei ersten Aufbau in unserer ~./.ssh/know_hosts eingetragen wurde!

Ja aber, wir vielleicht nun jemand sagen, wir haben noch immer das Problem mit den wechselnden Host-Keys! Ändert nun jemand aus welchem Grund auch immer den ssh_host_key auf einem der vielen Zielsysteme oder wird die virtuelle Maschine getauscht ändert sich in aller Regel auch dessen Host-Key. Was wird also vermutlich passiere, wenn wir uns nun erneut mit einem zuvor als validem Zielsystem erkannten System verbinden wollen?

 $ ssh -Y vml172042
The authenticity of host 'vml172042 (172.17.2.42)' can't be established.
ED25519 key fingerprint is SHA256:syMNF0jPr8b0j4N90154933khMulGeoGKFU/FWm3UKY.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])?

Da wir ja nun bestens mit der TOFU-Thematik auseinandergesetzt haben wissen wir Bescheid, wie besorgen uns den neuen Fingerprint des Servers, vergleichen diesen mit dem präsentierten oder geben den neu bekannt gegebenen Fingerprint ein. O.K. wir sind wieder auf dem richtigen Zielhost, den wir vertrauen.

ABER, was erneut passiert ist der Eintag in der known_hosts, der bestehende alte verbleibt dort ebenso! Diese wird also unweigerlich zum steten Anwachsen der ~/.ssh/know_hosts führen, mit vielen hunderten oder gar tausenden Zeilen mit zum Teil alten verwaisten Daten → nicht schön, will man so eigentlich nicht haben sondern vermeiden wollen.

Die OpenSSH-Implementierung von SSH, bei der Benutzer SSH-Hosts und umgekehrt Hosts SSH-Benutzern vertrauen, unterstützt einen zertifikatsbasierten Mechanismus, der zur Reduktion von Komplexität und Verminderungen von Administrationsaufwänden genutzt werden kann. Anstelle eines Satzes von öffentlichen/privaten Schlüsseln werden signierte Zertifikate verwendet. Dies hat den Vorteil, dass eine einzige vertrauenswürdige Zertifizierungsstelle anstelle vieler öffentlicher/privater Schlüssel verwendet werden kann.

Im Abschnitt AUTHENTICATION der Manual-Page von ssh und im Abschnitt CERTIFICATES der Manual-Page von ssh-keygen finden sich, etwas versteckt nicht auf den ersten Blick jedem sofort ersichtlich, hierzu tiefer gehende Erklärungen und Beispiele.

Bei Bedarf wirft man also einen Blick in besagte Manual-Pages (zum Öffnen der im WIKI abgelegten Man-Pages auf die grauen Balken klicken!) :

$ man ssh

SSH(1)                                               General Commands Manual                                              SSH(1)

NAME
       ssh — OpenSSH remote login client

SYNOPSIS
       ssh   [-46AaCfGgKkMNnqsTtVvXxYy]   [-B  bind_interface]  [-b  bind_address]  [-c  cipher_spec]  [-D  [bind_address:]port]
           [-E log_file] [-e escape_char]  [-F  configfile]  [-I  pkcs11]  [-i  identity_file]  [-J  destination]  [-L  address]
           [-l  login_name]  [-m  mac_spec]  [-O  ctl_cmd]  [-o  option]  [-P  tag]  [-p  port]  [-Q  query_option] [-R address]
           [-S ctl_path] [-W host:port] [-w local_tun[:remote_tun]] destination [command [argument ...]]

DESCRIPTION
       ssh (SSH client) is a program for logging into a remote machine and for executing commands on a remote  machine.   It  is
       intended  to  provide  secure encrypted communications between two untrusted hosts over an insecure network.  X11 connec‐
       tions, arbitrary TCP ports and Unix-domain sockets can also be forwarded over the secure channel.

       ssh connects and logs into the specified destination, which may be specified as either [user@]hostname or a  URI  of  the
       form ssh://[user@]hostname[:port].  The user must prove their identity to the remote machine using one of several methods
       (see below).

       If  a command is specified, it will be executed on the remote host instead of a login shell.  A complete command line may
       be specified as command, or it may have additional arguments.  If supplied, the arguments will be appended  to  the  com‐
       mand, separated by spaces, before it is sent to the server to be executed.

       The options are as follows:

       -4      Forces ssh to use IPv4 addresses only.

       -6      Forces ssh to use IPv6 addresses only.

       -A      Enables  forwarding of connections from an authentication agent such as ssh-agent(1).  This can also be specified
               on a per-host basis in a configuration file.

               Agent forwarding should be enabled with caution.  Users with the ability to bypass file permissions on the remote
               host (for the agent's Unix-domain socket) can access the local agent through the forwarded  connection.   An  at‐
               tacker  cannot  obtain  key  material from the agent, however they can perform operations on the keys that enable
               them to authenticate using the identities loaded into the agent.  A safer alternative may be to use a  jump  host
               (see -J).

       -a      Disables forwarding of the authentication agent connection.

       -B bind_interface
               Bind  to the address of bind_interface before attempting to connect to the destination host.  This is only useful
               on systems with more than one address.

       -b bind_address
               Use bind_address on the local machine as the source address of the connection.  Only useful on systems with  more
               than one address.

       -C      Requests  compression  of  all  data  (including  stdin,  stdout,  stderr,  and  data  for forwarded X11, TCP and
               Unix-domain connections).  The compression algorithm is the same used by gzip(1).  Compression  is  desirable  on
               modem  lines  and other slow connections, but will only slow down things on fast networks.  The default value can
               be set on a host-by-host basis in the configuration files; see the Compression option in ssh_config(5).

       -c cipher_spec
               Selects the cipher specification for encrypting the session.  cipher_spec is a comma-separated  list  of  ciphers
               listed in order of preference.  See the Ciphers keyword in ssh_config(5) for more information.

       -D [bind_address:]port
               Specifies  a  local  “dynamic” application-level port forwarding.  This works by allocating a socket to listen to
               port on the local side, optionally bound to the specified bind_address.  Whenever a connection is  made  to  this
               port, the connection is forwarded over the secure channel, and the application protocol is then used to determine
               where  to  connect  to from the remote machine.  Currently the SOCKS4 and SOCKS5 protocols are supported, and ssh
               will act as a SOCKS server.  Only root can forward privileged ports.  Dynamic port forwardings can also be speci‐
               fied in the configuration file.

               IPv6 addresses can be specified by enclosing the address in square brackets.   Only  the  superuser  can  forward
               privileged  ports.  By default, the local port is bound in accordance with the GatewayPorts setting.  However, an
               explicit bind_address may be used to bind the connection to a specific address.  The bind_address of  “localhost”
               indicates  that  the listening port be bound for local use only, while an empty address or ‘*’ indicates that the
               port should be available from all interfaces.

       -E log_file
               Append debug logs to log_file instead of standard error.

       -e escape_char
               Sets the escape character for sessions with a pty (default: ‘~’).  The escape character is only recognized at the
               beginning of a line.  The escape character followed by a dot (‘.’) closes the connection; followed  by  control-Z
               suspends the connection; and followed by itself sends the escape character once.  Setting the character to “none”
               disables any escapes and makes the session fully transparent.

       -F configfile
               Specifies  an alternative per-user configuration file.  If a configuration file is given on the command line, the
               system-wide configuration file (/etc/ssh/ssh_config) will be ignored.  The default for the per-user configuration
               file is ~/.ssh/config.  If set to “none”, no configuration files will be read.

       -f      Requests ssh to go to background just before command execution.  This is useful if ssh is going to ask for  pass‐
               words  or  passphrases,  but the user wants it in the background.  This implies -n.  The recommended way to start
               X11 programs at a remote site is with something like ssh -f host xterm.

               If the ExitOnForwardFailure configuration option is set to “yes”, then a client started with -f will wait for all
               remote port forwards to be successfully established before placing itself in the background.  Refer  to  the  de‐
               scription of ForkAfterAuthentication in ssh_config(5) for details.

       -G      Causes ssh to print its configuration after evaluating Host and Match blocks and exit.

       -g      Allows  remote  hosts to connect to local forwarded ports.  If used on a multiplexed connection, then this option
               must be specified on the master process.

       -I pkcs11
               Specify the PKCS#11 shared library ssh should use to communicate with a PKCS#11 token providing keys for user au‐
               thentication.

       -i identity_file
               Selects a file from which the identity (private key) for public key authentication is read.  You can also specify
               a public key file to use the corresponding private key that is loaded in ssh-agent(1) when the private  key  file
               is  not  present  locally.  The default is ~/.ssh/id_rsa, ~/.ssh/id_ecdsa, ~/.ssh/id_ecdsa_sk, ~/.ssh/id_ed25519,
               ~/.ssh/id_ed25519_sk and ~/.ssh/id_dsa.  Identity files may also be specified on a per-host basis in the configu‐
               ration file.  It is possible to have multiple -i options (and  multiple  identities  specified  in  configuration
               files).  If no certificates have been explicitly specified by the CertificateFile directive, ssh will also try to
               load certificate information from the filename obtained by appending -cert.pub to identity filenames.

       -J destination
               Connect  to  the target host by first making an ssh connection to the jump host described by destination and then
               establishing a TCP forwarding to the ultimate destination from there.  Multiple jump hops may be specified  sepa‐
               rated by comma characters.  This is a shortcut to specify a ProxyJump configuration directive.  Note that config‐
               uration  directives  supplied  on  the command-line generally apply to the destination host and not any specified
               jump hosts.  Use ~/.ssh/config to specify configuration for jump hosts.

       -K      Enables GSSAPI-based authentication and forwarding (delegation) of GSSAPI credentials to the server.

       -k      Disables forwarding (delegation) of GSSAPI credentials to the server.

       -L [bind_address:]port:host:hostport
       -L [bind_address:]port:remote_socket
       -L local_socket:host:hostport
       -L local_socket:remote_socket
               Specifies that connections to the given TCP port or Unix socket on the local (client) host are to be forwarded to
               the given host and port, or Unix socket, on the remote side.  This works by allocating a socket to listen to  ei‐
               ther a TCP port on the local side, optionally bound to the specified bind_address, or to a Unix socket.  Whenever
               a connection is made to the local port or socket, the connection is forwarded over the secure channel, and a con‐
               nection is made to either host port hostport, or the Unix socket remote_socket, from the remote machine.

               Port  forwardings  can  also  be  specified in the configuration file.  Only the superuser can forward privileged
               ports.  IPv6 addresses can be specified by enclosing the address in square brackets.

               By default, the local port  is  bound  in  accordance  with  the  GatewayPorts  setting.   However,  an  explicit
               bind_address may be used to bind the connection to a specific address.  The bind_address of “localhost” indicates
               that the listening port be bound for local use only, while an empty address or ‘*’ indicates that the port should
               be available from all interfaces.

       -l login_name
               Specifies  the  user  to  log in as on the remote machine.  This also may be specified on a per-host basis in the
               configuration file.

       -M      Places the ssh client into “master” mode for connection sharing.  Multiple -M options places  ssh  into  “master”
               mode  but  with  confirmation  required  using ssh-askpass(1) before each operation that changes the multiplexing
               state (e.g. opening a new session).  Refer to the description of ControlMaster in ssh_config(5) for details.

       -m mac_spec
               A comma-separated list of MAC (message authentication code) algorithms, specified in order  of  preference.   See
               the MACs keyword in ssh_config(5) for more information.

       -N      Do  not  execute  a  remote  command.   This  is  useful  for just forwarding ports.  Refer to the description of
               SessionType in ssh_config(5) for details.

       -n      Redirects stdin from /dev/null (actually, prevents reading from stdin).  This must be used when ssh is run in the
               background.  A common trick is to use this to run X11  programs  on  a  remote  machine.   For  example,  ssh  -n
               shadows.cs.hut.fi  emacs & will start an emacs on shadows.cs.hut.fi, and the X11 connection will be automatically
               forwarded over an encrypted channel.  The ssh program will be put in the background.  (This does not work if  ssh
               needs  to  ask  for  a password or passphrase; see also the -f option.)  Refer to the description of StdinNull in
               ssh_config(5) for details.

       -O ctl_cmd
               Control an active connection multiplexing master process.  When the -O option is specified, the ctl_cmd  argument
               is  interpreted  and passed to the master process.  Valid commands are: “check” (check that the master process is
               running), “forward” (request forwardings without command execution), “cancel” (cancel forwardings),  “exit”  (re‐
               quest the master to exit), and “stop” (request the master to stop accepting further multiplexing requests).

       -o option
               Can  be used to give options in the format used in the configuration file.  This is useful for specifying options
               for which there is no separate command-line flag.  For full details of the options listed below, and their possi‐
               ble values, see ssh_config(5).

                     AddKeysToAgent
                     AddressFamily
                     BatchMode
                     BindAddress
                     CanonicalDomains
                     CanonicalizeFallbackLocal
                     CanonicalizeHostname
                     CanonicalizeMaxDots
                     CanonicalizePermittedCNAMEs
                     CASignatureAlgorithms
                     CertificateFile
                     CheckHostIP
                     Ciphers
                     ClearAllForwardings
                     Compression
                     ConnectionAttempts
                     ConnectTimeout
                     ControlMaster
                     ControlPath
                     ControlPersist
                     DynamicForward
                     EnableEscapeCommandline
                     EscapeChar
                     ExitOnForwardFailure
                     FingerprintHash
                     ForkAfterAuthentication
                     ForwardAgent
                     ForwardX11
                     ForwardX11Timeout
                     ForwardX11Trusted
                     GatewayPorts
                     GlobalKnownHostsFile
                     GSSAPIAuthentication
                     GSSAPIDelegateCredentials
                     HashKnownHosts
                     Host
                     HostbasedAcceptedAlgorithms
                     HostbasedAuthentication
                     HostKeyAlgorithms
                     HostKeyAlias
                     Hostname
                     IdentitiesOnly
                     IdentityAgent
                     IdentityFile
                     IPQoS
                     KbdInteractiveAuthentication
                     KbdInteractiveDevices
                     KexAlgorithms
                     KnownHostsCommand
                     LocalCommand
                     LocalForward
                     LogLevel
                     MACs
                     Match
                     NoHostAuthenticationForLocalhost
                     NumberOfPasswordPrompts
                     PasswordAuthentication
                     PermitLocalCommand
                     PermitRemoteOpen
                     PKCS11Provider
                     Port
                     PreferredAuthentications
                     ProxyCommand
                     ProxyJump
                     ProxyUseFdpass
                     PubkeyAcceptedAlgorithms
                     PubkeyAuthentication
                     RekeyLimit
                     RemoteCommand
                     RemoteForward
                     RequestTTY
                     RequiredRSASize
                     SendEnv
                     ServerAliveInterval
                     ServerAliveCountMax
                     SessionType
                     SetEnv
                     StdinNull
                     StreamLocalBindMask
                     StreamLocalBindUnlink
                     StrictHostKeyChecking
                     TCPKeepAlive
                     Tunnel
                     TunnelDevice
                     UpdateHostKeys
                     User
                     UserKnownHostsFile
                     VerifyHostKeyDNS
                     VisualHostKey
                     XAuthLocation

       -P tag  Specify a tag name that may be used to select configuration in ssh_config(5).  Refer to the Tag  and  Match  key‐
               words in ssh_config(5) for more information.
       -p port
               Port to connect to on the remote host.  This can be specified on a per-host basis in the configuration file.

       -Q query_option
               Queries  for  the  algorithms  supported  by one of the following features: cipher (supported symmetric ciphers),
               cipher-auth (supported symmetric ciphers that support authenticated encryption), help (supported query terms  for
               use  with  the -Q flag), mac (supported message integrity codes), kex (key exchange algorithms), key (key types),
               key-ca-sign (valid CA signature algorithms for certificates), key-cert (certificate key types),  key-plain  (non-
               certificate  key types), key-sig (all key types and signature algorithms), protocol-version (supported SSH proto‐
               col versions), and sig (supported signature  algorithms).   Alternatively,  any  keyword  from  ssh_config(5)  or
               sshd_config(5) that takes an algorithm list may be used as an alias for the corresponding query_option.

       -q      Quiet mode.  Causes most warning and diagnostic messages to be suppressed.

       -R [bind_address:]port:host:hostport
       -R [bind_address:]port:local_socket
       -R remote_socket:host:hostport
       -R remote_socket:local_socket
       -R [bind_address:]port
               Specifies  that  connections to the given TCP port or Unix socket on the remote (server) host are to be forwarded
               to the local side.

               This works by allocating a socket to listen to either a TCP port or to a Unix socket on the remote  side.   When‐
               ever a connection is made to this port or Unix socket, the connection is forwarded over the secure channel, and a
               connection  is  made from the local machine to either an explicit destination specified by host port hostport, or
               local_socket, or, if no explicit destination was specified, ssh will act as a SOCKS 4/5 proxy and forward connec‐
               tions to the destinations requested by the remote SOCKS client.

               Port forwardings can also be specified in the configuration file.  Privileged ports can be  forwarded  only  when
               logging  in  as  root  on the remote machine.  IPv6 addresses can be specified by enclosing the address in square
               brackets.

              By default, TCP listening sockets on the server will be bound to the loopback interface only.  This may be  over‐
               ridden by specifying a bind_address.  An empty bind_address, or the address ‘*’, indicates that the remote socket
               should listen on all interfaces.  Specifying a remote bind_address will only succeed if the server's GatewayPorts
               option is enabled (see sshd_config(5)).

               If  the  port  argument  is  ‘0’, the listen port will be dynamically allocated on the server and reported to the
               client at run time.  When used together with -O forward, the allocated port will be printed to the standard  out‐
               put.

       -S ctl_path
               Specifies  the  location  of  a control socket for connection sharing, or the string “none” to disable connection
               sharing.  Refer to the description of ControlPath and ControlMaster in ssh_config(5) for details.

       -s      May be used to request invocation of a subsystem on the remote system.  Subsystems facilitate the use of SSH as a
               secure transport for other applications (e.g. sftp(1)).  The subsystem is specified as the remote command.  Refer
               to the description of SessionType in ssh_config(5) for details.

       -T      Disable pseudo-terminal allocation.

       -t      Force pseudo-terminal allocation.  This can be used to execute arbitrary screen-based programs on  a  remote  ma‐
               chine, which can be very useful, e.g. when implementing menu services.  Multiple -t options force tty allocation,
               even if ssh has no local tty.

       -V      Display the version number and exit.

       -v      Verbose  mode.   Causes ssh to print debugging messages about its progress.  This is helpful in debugging connec‐
               tion, authentication, and configuration problems.  Multiple -v options increase the verbosity.  The maximum is 3.

       -W host:port
               Requests that standard input and output on the client be forwarded to host on port over the secure channel.   Im‐
               plies  -N,  -T, ExitOnForwardFailure and ClearAllForwardings, though these can be overridden in the configuration
               file or using -o command line options.

       -w local_tun[:remote_tun]
               Requests tunnel device forwarding with the specified tun(4) devices between the client (local_tun) and the server
               (remote_tun).

               The devices may be specified by numerical ID or the keyword “any”, which uses the next available  tunnel  device.
               If  remote_tun  is  not  specified,  it  defaults  to  “any”.  See also the Tunnel and TunnelDevice directives in
               ssh_config(5).

               If the Tunnel directive is unset, it will be set to the default tunnel mode, which  is  “point-to-point”.   If  a
               different Tunnel forwarding mode it desired, then it should be specified before -w.

       -X      Enables X11 forwarding.  This can also be specified on a per-host basis in a configuration file.

               X11  forwarding  should be enabled with caution.  Users with the ability to bypass file permissions on the remote
               host (for the user's X authorization database) can access the local X11 display through the forwarded connection.
               An attacker may then be able to perform activities such as keystroke monitoring.

               For this reason, X11 forwarding is subjected to X11 SECURITY extension restrictions by default.  Refer to the ssh
               -Y option and the ForwardX11Trusted directive in ssh_config(5) for more information.

       -x      Disables X11 forwarding.

       -Y      Enables trusted X11 forwarding.  Trusted X11 forwardings are not subjected to the  X11  SECURITY  extension  con‐
               trols.

       -y      Send log information using the syslog(3) system module.  By default this information is sent to stderr.

       ssh  may  additionally obtain configuration data from a per-user configuration file and a system-wide configuration file.
       The file format and configuration options are described in ssh_config(5).

AUTHENTICATION
       The OpenSSH SSH client supports SSH protocol 2.

       The methods available for authentication are: GSSAPI-based authentication, host-based authentication, public key  authen‐
       tication,  keyboard-interactive authentication, and password authentication.  Authentication methods are tried in the or‐
       der specified above, though PreferredAuthentications can be used to change the default order.

       Host-based authentication works as follows: If the machine the user  logs  in  from  is  listed  in  /etc/hosts.equiv  or
       /etc/ssh/shosts.equiv  on  the  remote machine, the user is non-root and the user names are the same on both sides, or if
       the files ~/.rhosts or ~/.shosts exist in the user's home directory on the remote machine and contain a  line  containing
       the name of the client machine and the name of the user on that machine, the user is considered for login.  Additionally,
       the  server  must  be  able  to  verify  the  client's  host  key  (see  the  description of /etc/ssh/ssh_known_hosts and
       ~/.ssh/known_hosts, below) for login to be permitted.  This authentication method closes security holes due to IP  spoof‐
       ing,  DNS  spoofing,  and  routing spoofing.  [Note to the administrator: /etc/hosts.equiv, ~/.rhosts, and the rlogin/rsh
       protocol in general, are inherently insecure and should be disabled if security is desired.]

       Public key authentication works as follows: The scheme is based on public-key cryptography, using cryptosystems where en‐
       cryption and decryption are done using separate keys, and it is unfeasible to derive the decryption key from the  encryp‐
       tion  key.   The  idea is that each user creates a public/private key pair for authentication purposes.  The server knows
       the public key, and only the user knows the private key.  ssh implements public  key  authentication  protocol  automati‐
       cally, using one of the DSA, ECDSA, Ed25519 or RSA algorithms.  The HISTORY section of ssl(8) contains a brief discussion
       of the DSA and RSA algorithms.

       The  file ~/.ssh/authorized_keys lists the public keys that are permitted for logging in.  When the user logs in, the ssh
       program tells the server which key pair it would like to use for authentication.  The client proves that it has access to
       the private key and the server checks that the corresponding public key is authorized to accept the account.

       The server may inform the client of errors that prevented public key authentication from succeeding after  authentication
       completes using a different method.  These may be viewed by increasing the LogLevel to DEBUG or higher (e.g. by using the
       -v flag).

       The  user  creates  their  key  pair  by  running  ssh-keygen(1).   This  stores  the private key in ~/.ssh/id_dsa (DSA),
       ~/.ssh/id_ecdsa    (ECDSA),    ~/.ssh/id_ecdsa_sk    (authenticator-hosted    ECDSA),    ~/.ssh/id_ed25519     (Ed25519),
       ~/.ssh/id_ed25519_sk   (authenticator-hosted   Ed25519),   or   ~/.ssh/id_rsa   (RSA)   and  stores  the  public  key  in
       ~/.ssh/id_dsa.pub   (DSA),   ~/.ssh/id_ecdsa.pub   (ECDSA),    ~/.ssh/id_ecdsa_sk.pub    (authenticator-hosted    ECDSA),
       ~/.ssh/id_ed25519.pub  (Ed25519),  ~/.ssh/id_ed25519_sk.pub (authenticator-hosted Ed25519), or ~/.ssh/id_rsa.pub (RSA) in
       the user's home directory.  The user should then copy the public key to ~/.ssh/authorized_keys in their home directory on
       the remote machine.  The authorized_keys file corresponds to the conventional ~/.rhosts file, and has one key  per  line,
       though the lines can be very long.  After this, the user can log in without giving the password.

       A variation on public key authentication is available in the form of certificate authentication: instead of a set of pub‐
       lic/private keys, signed certificates are used.  This has the advantage that a single trusted certification authority can
       be used in place of many public/private keys.  See the CERTIFICATES section of ssh-keygen(1) for more information.

       The  most  convenient  way  to  use  public  key  or certificate authentication may be with an authentication agent.  See
       ssh-agent(1) and (optionally) the AddKeysToAgent directive in ssh_config(5) for more information.

       Keyboard-interactive authentication works as follows: The server sends an arbitrary "challenge" text and  prompts  for  a
       response,  possibly  multiple  times.   Examples  of  keyboard-interactive authentication include BSD Authentication (see
       login.conf(5)) and PAM (some non-OpenBSD systems).

       Finally, if other authentication methods fail, ssh prompts the user for a password.  The password is sent to  the  remote
       host  for  checking; however, since all communications are encrypted, the password cannot be seen by someone listening on
       the network.

       ssh automatically maintains and checks a database containing identification for all hosts it has  ever  been  used  with.
       Host keys are stored in ~/.ssh/known_hosts in the user's home directory.  Additionally, the file /etc/ssh/ssh_known_hosts
      is automatically checked for known hosts.  Any new hosts are automatically added to the user's file.  If a host's identi‐
       fication  ever  changes,  ssh warns about this and disables password authentication to prevent server spoofing or man-in-
       the-middle attacks, which could otherwise be used to circumvent the encryption.  The StrictHostKeyChecking option can  be
       used to control logins to machines whose host key is not known or has changed.

       When  the user's identity has been accepted by the server, the server either executes the given command in a non-interac‐
       tive session or, if no command has been specified, logs into the machine and gives the user a normal shell as an interac‐
       tive session.  All communication with the remote command or shell will be automatically encrypted.

       If an interactive session is requested, ssh by default will only request a pseudo-terminal (pty) for interactive sessions
       when the client has one.  The flags -T and -t can be used to override this behaviour.

       If a pseudo-terminal has been allocated, the user may use the escape characters noted below.

       If no pseudo-terminal has been allocated, the session is transparent and can be used to reliably  transfer  binary  data.
       On most systems, setting the escape character to “none” will also make the session transparent even if a tty is used.

       The  session  terminates  when the command or shell on the remote machine exits and all X11 and TCP connections have been
       closed.

ESCAPE CHARACTERS
       When a pseudo-terminal has been requested, ssh supports a number of functions through the use of an escape character.

       A single tilde character can be sent as ~~ or by following the tilde by a character other  than  those  described  below.
       The  escape  character must always follow a newline to be interpreted as special.  The escape character can be changed in
       configuration files using the EscapeChar configuration directive or on the command line by the -e option.

       The supported escapes (assuming the default ‘~’) are:

       ~.      Disconnect.

       ~^Z     Background ssh.

       ~#      List forwarded connections.

       ~&      Background ssh at logout when waiting for forwarded connection / X11 sessions to terminate.

       ~?      Display a list of escape characters.

       ~B      Send a BREAK to the remote system (only useful if the peer supports it).

       ~C      Open command line.  Currently this allows the addition of port forwardings using the -L, -R and -D  options  (see
               above).   It  also  allows  the  cancellation of existing port-forwardings with -KL[bind_address:]port for local,
               -KR[bind_address:]port for remote and -KD[bind_address:]port for dynamic port-forwardings.  !command  allows  the
               user  to  execute  a  local  command if the PermitLocalCommand option is enabled in ssh_config(5).  Basic help is
               available, using the -h option.

       ~R      Request rekeying of the connection (only useful if the peer supports it).

       ~V      Decrease the verbosity (LogLevel) when errors are being written to stderr.

       ~v      Increase the verbosity (LogLevel) when errors are being written to stderr.

TCP FORWARDING
       Forwarding of arbitrary TCP connections over a secure channel can be specified either on the command line or in a config‐
       uration file.  One possible application of TCP forwarding is a secure connection to  a  mail  server;  another  is  going
       through firewalls.

       In  the  example  below, we look at encrypting communication for an IRC client, even though the IRC server it connects to
       does not directly support encrypted communication.  This works as follows: the user connects to  the  remote  host  using
       ssh,  specifying the ports to be used to forward the connection.  After that it is possible to start the program locally,
       and ssh will encrypt and forward the connection to the remote server.

       The following example tunnels an IRC session from the client to an IRC server at  “server.example.com”,  joining  channel
       “#users”, nickname “pinky”, using the standard IRC port, 6667:

           $ ssh -f -L 6667:localhost:6667 server.example.com sleep 10
           $ irc -c '#users' pinky IRC/127.0.0.1

       The  -f  option backgrounds ssh and the remote command “sleep 10” is specified to allow an amount of time (10 seconds, in
       the example) to start the program which is going to use the tunnel.  If no connections are made within  the  time  speci‐
       fied, ssh will exit.

X11 FORWARDING
       If  the  ForwardX11 variable is set to “yes” (or see the description of the -X, -x, and -Y options above) and the user is
       using X11 (the DISPLAY environment variable is set), the connection to the X11 display is automatically forwarded to  the
       remote  side  in such a way that any X11 programs started from the shell (or command) will go through the encrypted chan‐
       nel, and the connection to the real X server will be made from the local machine.   The  user  should  not  manually  set
       DISPLAY.  Forwarding of X11 connections can be configured on the command line or in configuration files.

       The DISPLAY value set by ssh will point to the server machine, but with a display number greater than zero.  This is nor‐
       mal, and happens because ssh creates a “proxy” X server on the server machine for forwarding the connections over the en‐
       crypted channel.

       ssh  will  also  automatically set up Xauthority data on the server machine.  For this purpose, it will generate a random
       authorization cookie, store it in Xauthority on the server, and verify that any forwarded connections carry  this  cookie
       and  replace  it  by  the real cookie when the connection is opened.  The real authentication cookie is never sent to the
       server machine (and no cookies are sent in the plain).

       If the ForwardAgent variable is set to “yes” (or see the description of the -A and -a options above) and the user is  us‐
       ing an authentication agent, the connection to the agent is automatically forwarded to the remote side.

VERIFYING HOST KEYS
       When connecting to a server for the first time, a fingerprint of the server's public key is presented to the user (unless
       the option StrictHostKeyChecking has been disabled).  Fingerprints can be determined using ssh-keygen(1):

             $ ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key

       If  the  fingerprint  is  already known, it can be matched and the key can be accepted or rejected.  If only legacy (MD5)
       fingerprints for the server are available, the ssh-keygen(1) -E option may be used to downgrade the fingerprint algorithm
       to match.

       Because of the difficulty of comparing host keys just by looking at fingerprint strings, there is also support to compare
       host keys visually, using random art.  By setting the VisualHostKey option to “yes”, a small ASCII graphic gets displayed
       on every login to a server, no matter if the session itself is interactive or not.   By  learning  the  pattern  a  known
       server  produces,  a  user  can easily find out that the host key has changed when a completely different pattern is dis‐
       played.  Because these patterns are not unambiguous however, a pattern that looks similar to the pattern remembered  only
       gives a good probability that the host key is the same, not guaranteed proof.

       To  get  a listing of the fingerprints along with their random art for all known hosts, the following command line can be
       used:

             $ ssh-keygen -lv -f ~/.ssh/known_hosts

       If the fingerprint is unknown, an alternative method of verification is available: SSH fingerprints verified by DNS.   An
       additional resource record (RR), SSHFP, is added to a zonefile and the connecting client is able to match the fingerprint
       with that of the key presented.

       In  this example, we are connecting a client to a server, “host.example.com”.  The SSHFP resource records should first be
       added to the zonefile for host.example.com:

             $ ssh-keygen -r host.example.com.

       The output lines will have to be added to the zonefile.  To check that the zone is answering fingerprint queries:

             $ dig -t SSHFP host.example.com

       Finally the client connects:

             $ ssh -o "VerifyHostKeyDNS ask" host.example.com
             [...]
             Matching host key fingerprint found in DNS.
             Are you sure you want to continue connecting (yes/no)?

       See the VerifyHostKeyDNS option in ssh_config(5) for more information.

SSH-BASED VIRTUAL PRIVATE NETWORKS
       ssh contains support for Virtual Private Network (VPN) tunnelling using the tun(4) network  pseudo-device,  allowing  two
       networks  to  be  joined securely.  The sshd_config(5) configuration option PermitTunnel controls whether the server sup‐
       ports this, and at what level (layer 2 or 3 traffic).

       The following example would connect client network 10.0.50.0/24 with remote network 10.0.99.0/24 using  a  point-to-point
       connection  from  10.1.1.1  to  10.1.1.2,  provided  that the SSH server running on the gateway to the remote network, at
       192.168.1.15, allows it.

       On the client:

             # ssh -f -w 0:1 192.168.1.15 true
             # ifconfig tun0 10.1.1.1 10.1.1.2 netmask 255.255.255.252
             # route add 10.0.99.0/24 10.1.1.2

       On the server:

             # ifconfig tun1 10.1.1.2 10.1.1.1 netmask 255.255.255.252
             # route add 10.0.50.0/24 10.1.1.1

       Client access may be more finely tuned via the /root/.ssh/authorized_keys file (see below) and the PermitRootLogin server
       option.  The following entry would permit connections on tun(4) device 1 from user “jane” and on tun device 2  from  user
       “john”, if PermitRootLogin is set to “forced-commands-only”:

         tunnel="1",command="sh /etc/netstart tun1" ssh-rsa ... jane
         tunnel="2",command="sh /etc/netstart tun2" ssh-rsa ... john

       Since  an SSH-based setup entails a fair amount of overhead, it may be more suited to temporary setups, such as for wire‐
       less VPNs.  More permanent VPNs are better provided by tools such as ipsecctl(8) and isakmpd(8).

ENVIRONMENT
       ssh will normally set the following environment variables:

       DISPLAY               The DISPLAY variable indicates the location of the X11 server.  It is automatically set by  ssh  to
                             point  to  a  value  of  the form “hostname:n”, where “hostname” indicates the host where the shell
                             runs, and ‘n’ is an integer ≥ 1.  ssh uses this special value to forward X11 connections  over  the
                             secure  channel.   The user should normally not set DISPLAY explicitly, as that will render the X11
                             connection insecure (and will require the user to manually copy any  required  authorization  cook‐
                             ies).

       HOME                  Set to the path of the user's home directory.

       LOGNAME               Synonym for USER; set for compatibility with systems that use this variable.

       MAIL                  Set to the path of the user's mailbox.

       PATH                  Set to the default PATH, as specified when compiling ssh.

       SSH_ASKPASS           If ssh needs a passphrase, it will read the passphrase from the current terminal if it was run from
                             a  terminal.   If  ssh  does not have a terminal associated with it but DISPLAY and SSH_ASKPASS are
                             set, it will execute the program specified by SSH_ASKPASS and  open  an  X11  window  to  read  the
                             passphrase.   This  is  particularly  useful  when  calling ssh from a .xsession or related script.
                             (Note that on some machines it may be necessary to redirect the input from /dev/null to  make  this
                             work.)

       SSH_ASKPASS_REQUIRE   Allows further control over the use of an askpass program.  If this variable is set to “never” then
                             ssh  will  never  attempt  to  use  one.  If it is set to “prefer”, then ssh will prefer to use the
                             askpass program instead of the TTY when requesting passwords.  Finally, if the variable is  set  to
                             “force”,  then  the  askpass  program  will  be used for all passphrase input regardless of whether
                             DISPLAY is set.

       SSH_AUTH_SOCK         Identifies the path of a Unix-domain socket used to communicate with the agent.

       SSH_CONNECTION        Identifies the client and server ends of the connection.  The variable  contains  four  space-sepa‐
                             rated values: client IP address, client port number, server IP address, and server port number.

       SSH_ORIGINAL_COMMAND  This  variable  contains the original command line if a forced command is executed.  It can be used
                             to extract the original arguments.

       SSH_TTY               This is set to the name of the tty (path to the device) associated with the current shell  or  com‐
                             mand.  If the current session has no tty, this variable is not set.

       SSH_TUNNEL            Optionally  set  by  sshd(8)  to  contain the interface names assigned if tunnel forwarding was re‐
                             quested by the client.

       SSH_USER_AUTH         Optionally set by sshd(8), this variable may contain a pathname to a file that lists the  authenti‐
                             cation  methods  successfully used when the session was established, including any public keys that
                             were used.

       TZ                    This variable is set to indicate the present time zone if it was set when the  daemon  was  started
                             (i.e. the daemon passes the value on to new connections).

       USER                  Set to the name of the user logging in.

       Additionally,  ssh  reads ~/.ssh/environment, and adds lines of the format “VARNAME=value” to the environment if the file
       exists and users are allowed to change their environment.  For more information, see the PermitUserEnvironment option  in
       sshd_config(5).

FILES
       ~/.rhosts
               This  file  is  used for host-based authentication (see above).  On some machines this file may need to be world-
               readable if the user's home directory is on an NFS partition, because sshd(8) reads it  as  root.   Additionally,
               this  file  must be owned by the user, and must not have write permissions for anyone else.  The recommended per‐
               mission for most machines is read/write for the user, and not accessible by others.

       ~/.shosts
               This file is used in exactly the same way as .rhosts, but allows host-based authentication without permitting lo‐
               gin with rlogin/rsh.

       ~/.ssh/
               This directory is the default location for all user-specific configuration and authentication information.  There
               is no general requirement to keep the entire contents of this directory secret, but the  recommended  permissions
               are read/write/execute for the user, and not accessible by others.

       ~/.ssh/authorized_keys
               Lists  the  public  keys  (DSA, ECDSA, Ed25519, RSA) that can be used for logging in as this user.  The format of
               this file is described in the sshd(8) manual page.  This file is not highly sensitive, but the  recommended  per‐
               missions are read/write for the user, and not accessible by others.

       ~/.ssh/config
               This  is  the  per-user  configuration  file.   The  file  format  and  configuration  options  are  described in
               ssh_config(5).  Because of the potential for abuse, this file must have strict permissions:  read/write  for  the
               user, and not writable by others.

       ~/.ssh/environment
               Contains additional definitions for environment variables; see “ENVIRONMENT”, above.

       ~/.ssh/id_dsa
       ~/.ssh/id_ecdsa
       ~/.ssh/id_ecdsa_sk
       ~/.ssh/id_ed25519
       ~/.ssh/id_ed25519_sk
       ~/.ssh/id_rsa
               Contains  the  private  key for authentication.  These files contain sensitive data and should be readable by the
               user but not accessible by others (read/write/execute).  ssh will simply ignore a private key file if it  is  ac‐
               cessible by others.  It is possible to specify a passphrase when generating the key which will be used to encrypt
               the sensitive part of this file using AES-128.

       ~/.ssh/id_dsa.pub
       ~/.ssh/id_ecdsa.pub
       ~/.ssh/id_ecdsa_sk.pub
       ~/.ssh/id_ed25519.pub
       ~/.ssh/id_ed25519_sk.pub
       ~/.ssh/id_rsa.pub
               Contains  the public key for authentication.  These files are not sensitive and can (but need not) be readable by
               anyone.

       ~/.ssh/known_hosts
               Contains a list of host keys for all hosts the user has logged into that are not already in the  systemwide  list
               of known host keys.  See sshd(8) for further details of the format of this file.

       ~/.ssh/rc
               Commands  in  this  file  are executed by ssh when the user logs in, just before the user's shell (or command) is
               started.  See the sshd(8) manual page for more information.

       /etc/hosts.equiv
               This file is for host-based authentication (see above).  It should only be writable by root.

       /etc/ssh/shosts.equiv
               This file is used in exactly the same way as hosts.equiv, but allows host-based authentication without permitting
               login with rlogin/rsh.

       /etc/ssh/ssh_config
               Systemwide configuration file.  The file format and configuration options are described in ssh_config(5).

       /etc/ssh/ssh_host_key
       /etc/ssh/ssh_host_dsa_key
       /etc/ssh/ssh_host_ecdsa_key
       /etc/ssh/ssh_host_ed25519_key
       /etc/ssh/ssh_host_rsa_key
               These files contain the private parts of the host keys and are used for host-based authentication.

       /etc/ssh/ssh_known_hosts
               Systemwide list of known host keys.  This file should be prepared by the system administrator to contain the pub‐
       /etc/ssh/ssh_host_dsa_key
       /etc/ssh/ssh_host_ecdsa_key
       /etc/ssh/ssh_host_ed25519_key
       /etc/ssh/ssh_host_rsa_key
               These files contain the private parts of the host keys and are used for host-based authentication.

       /etc/ssh/ssh_known_hosts
               Systemwide list of known host keys.  This file should be prepared by the system administrator to contain the pub‐
               lic host keys of all machines in the organization.  It should be world-readable.  See sshd(8) for further details
               of the format of this file.

       /etc/ssh/sshrc
               Commands in this file are executed by ssh when the user logs in, just before the user's  shell  (or  command)  is
               started.  See the sshd(8) manual page for more information.

EXIT STATUS
       ssh exits with the exit status of the remote command or with 255 if an error occurred.

SEE ALSO
       scp(1), sftp(1), ssh-add(1), ssh-agent(1), ssh-keygen(1), ssh-keyscan(1), tun(4), ssh_config(5), ssh-keysign(8), sshd(8)

STANDARDS
       S. Lehtinen and C. Lonvick, The Secure Shell (SSH) Protocol Assigned Numbers, RFC 4250, January 2006.

       T. Ylonen and C. Lonvick, The Secure Shell (SSH) Protocol Architecture, RFC 4251, January 2006.

       T. Ylonen and C. Lonvick, The Secure Shell (SSH) Authentication Protocol, RFC 4252, January 2006.

       T. Ylonen and C. Lonvick, The Secure Shell (SSH) Transport Layer Protocol, RFC 4253, January 2006.

       T. Ylonen and C. Lonvick, The Secure Shell (SSH) Connection Protocol, RFC 4254, January 2006.

       J. Schlyter and W. Griffin, Using DNS to Securely Publish Secure Shell (SSH) Key Fingerprints, RFC 4255, January 2006.

       F.  Cusack and M. Forssen, Generic Message Exchange Authentication for the Secure Shell Protocol (SSH), RFC 4256, January
       2006.

       J. Galbraith and P. Remaker, The Secure Shell (SSH) Session Channel Break Extension, RFC 4335, January 2006.

       M. Bellare, T. Kohno, and C. Namprempre, The Secure Shell (SSH) Transport Layer Encryption Modes, RFC 4344, January 2006.

       B. Harris, Improved Arcfour Modes for the Secure Shell (SSH) Transport Layer Protocol, RFC 4345, January 2006.

       M. Friedl, N. Provos, and W. Simpson, Diffie-Hellman Group Exchange for the Secure Shell (SSH) Transport Layer  Protocol,
       RFC 4419, March 2006.

       J. Galbraith and R. Thayer, The Secure Shell (SSH) Public Key File Format, RFC 4716, November 2006.

       D.  Stebila  and  J.  Green, Elliptic Curve Algorithm Integration in the Secure Shell Transport Layer, RFC 5656, December
       2009.

       A. Perrig and D. Song, Hash Visualization: a New Technique to improve Real-World Security, 1999,  International  Workshop
       on Cryptographic Techniques and E-Commerce (CrypTEC '99).

AUTHORS
       OpenSSH  is  a  derivative  of the original and free ssh 1.2.12 release by Tatu Ylonen.  Aaron Campbell, Bob Beck, Markus
       Friedl, Niels Provos, Theo de Raadt and Dug Song removed many bugs, re-added newer features and created OpenSSH.   Markus
       Friedl contributed the support for SSH protocol versions 1.5 and 2.0.

GNU                                                       July 23, 2023                                                   SSH(1)

$ man ssh-keygen

SSH-KEYGEN(1)                                        General Commands Manual                                       SSH-KEYGEN(1)

NAME
       ssh-keygen — OpenSSH authentication key utility

SYNOPSIS
       ssh-keygen  [-q]  [-a  rounds]  [-b  bits]  [-C  comment] [-f output_keyfile] [-m format] [-N new_passphrase] [-O option]
                  [-t dsa | ecdsa | ecdsa-sk | ed25519 | ed25519-sk | rsa] [-w provider] [-Z cipher]
       ssh-keygen -p [-a rounds] [-f keyfile] [-m format] [-N new_passphrase] [-P old_passphrase] [-Z cipher]
       ssh-keygen -i [-f input_keyfile] [-m key_format]
       ssh-keygen -e [-f input_keyfile] [-m key_format]
       ssh-keygen -y [-f input_keyfile]
       ssh-keygen -c [-a rounds] [-C comment] [-f keyfile] [-P passphrase]
       ssh-keygen -l [-v] [-E fingerprint_hash] [-f input_keyfile]
       ssh-keygen -B [-f input_keyfile]
       ssh-keygen -D pkcs11
       ssh-keygen -F hostname [-lv] [-f known_hosts_file]
       ssh-keygen -H [-f known_hosts_file]
       ssh-keygen -K [-a rounds] [-w provider]
       ssh-keygen -R hostname [-f known_hosts_file]
       ssh-keygen -r hostname [-g] [-f input_keyfile]
       ssh-keygen -M generate [-O option] output_file
       ssh-keygen -M screen [-f input_file] [-O option] output_file
       ssh-keygen   -I   certificate_identity   -s   ca_key   [-hU]   [-D   pkcs11_provider]   [-n   principals]   [-O   option]
                  [-V validity_interval] [-z serial_number] file ...
       ssh-keygen -L [-f input_keyfile]
       ssh-keygen -A [-a rounds] [-f prefix_path]
       ssh-keygen -k -f krl_file [-u] [-s ca_public] [-z version_number] file ...
       ssh-keygen -Q [-l] -f krl_file file ...
       ssh-keygen -Y find-principals [-O option] -s signature_file -f allowed_signers_file
       ssh-keygen -Y match-principals -I signer_identity -f allowed_signers_file
       ssh-keygen -Y check-novalidate [-O option] -n namespace -s signature_file
       ssh-keygen -Y sign [-O option] -f key_file -n namespace file ...
       ssh-keygen   -Y   verify   [-O  option]  -f  allowed_signers_file  -I  signer_identity  -n  namespace  -s  signature_file
                  [-r revocation_file]

DESCRIPTION
       ssh-keygen generates, manages and converts authentication keys for ssh(1).  ssh-keygen can create keys  for  use  by  SSH
       protocol version 2.

       The  type of key to be generated is specified with the -t option.  If invoked without any arguments, ssh-keygen will gen‐
       erate an Ed25519 key.

       ssh-keygen is also used to generate  groups  for  use  in  Diffie-Hellman  group  exchange  (DH-GEX).   See  the  “MODULI
       GENERATION” section for details.

       Finally, ssh-keygen can be used to generate and update Key Revocation Lists, and to test whether given keys have been re‐
       voked by one.  See the “KEY REVOCATION LISTS” section for details.

       Normally  each  user wishing to use SSH with public key authentication runs this once to create the authentication key in
       ~/.ssh/id_dsa, ~/.ssh/id_ecdsa, ~/.ssh/id_ecdsa_sk, ~/.ssh/id_ed25519, ~/.ssh/id_ed25519_sk or ~/.ssh/id_rsa.   Addition‐
       ally, the system administrator may use this to generate host keys, as seen in /etc/rc.

       Normally  this program generates the key and asks for a file in which to store the private key.  The public key is stored
       in a file with the same name but “.pub” appended.  The program also asks for a passphrase.  The passphrase may  be  empty
       to  indicate  no  passphrase  (host  keys  must  have an empty passphrase), or it may be a string of arbitrary length.  A
       passphrase is similar to a password, except it can be a phrase with a series of words, punctuation, numbers,  whitespace,
       or  any string of characters you want.  Good passphrases are 10-30 characters long, are not simple sentences or otherwise
       easily guessable (English prose has only 1-2 bits of entropy per character, and provides very bad passphrases), and  con‐
       tain a mix of upper and lowercase letters, numbers, and non-alphanumeric characters.  The passphrase can be changed later
       by using the -p option.

       There  is  no  way to recover a lost passphrase.  If the passphrase is lost or forgotten, a new key must be generated and
       the corresponding public key copied to other machines.

       ssh-keygen will by default write keys in an OpenSSH-specific format.  This format is preferred as it offers  better  pro‐
       tection for keys at rest as well as allowing storage of key comments within the private key file itself.  The key comment
       may  be  useful  to help identify the key.  The comment is initialized to “user@host” when the key is created, but can be
       changed using the -c option.

       It is still possible for ssh-keygen to write the previously-used PEM format private keys using the -m flag.  This may  be
       used when generating new keys, and existing new-format keys may be converted using this option in conjunction with the -p
       (change passphrase) flag.

       After a key is generated, ssh-keygen will ask where the keys should be placed to be activated.

       The options are as follows:

       -A      Generate  host  keys  of  all default key types (rsa, ecdsa, and ed25519) if they do not already exist.  The host
               keys are generated with the default key file path, an empty passphrase, default bits for the key  type,  and  de‐
               fault  comment.   If -f has also been specified, its argument is used as a prefix to the default path for the re‐
               sulting host key files.  This is used by /etc/rc to generate new host keys.

       -a rounds
               When saving a private key,  this  option  specifies  the  number  of  KDF  (key  derivation  function,  currently
               bcrypt_pbkdf(3))  rounds  used.  Higher numbers result in slower passphrase verification and increased resistance
               to brute-force password cracking (should the keys be stolen).  The default is 16 rounds.

       -B      Show the bubblebabble digest of specified private or public key file.

       -b bits
               Specifies the number of bits in the key to create.  For RSA keys, the minimum size is 1024 bits and  the  default
               is 3072 bits.  Generally, 3072 bits is considered sufficient.  DSA keys must be exactly 1024 bits as specified by
               FIPS  186-2.  For ECDSA keys, the -b flag determines the key length by selecting from one of three elliptic curve
               sizes: 256, 384 or 521 bits.  Attempting to use bit lengths other than these three values  for  ECDSA  keys  will
               fail.  ECDSA-SK, Ed25519 and Ed25519-SK keys have a fixed length and the -b flag will be ignored.

       -C comment
               Provides a new comment.

       -c      Requests changing the comment in the private and public key files.  The program will prompt for the file contain‐
               ing the private keys, for the passphrase if the key has one, and for the new comment.

       -D pkcs11
               Download  the  public keys provided by the PKCS#11 shared library pkcs11.  When used in combination with -s, this
               option indicates that a CA key resides in a PKCS#11 token (see the “CERTIFICATES” section for details).

       -E fingerprint_hash
               Specifies the hash algorithm used when displaying key fingerprints.  Valid options are: “md5” and “sha256”.   The
               default is “sha256”.

       -e      This option will read a private or public OpenSSH key file and print to stdout a public key in one of the formats
               specified  by  the -m option.  The default export format is “RFC4716”.  This option allows exporting OpenSSH keys
               for use by other programs, including several commercial SSH implementations.

       -F hostname | [hostname]:port
               Search for the specified hostname (with optional port number) in a  known_hosts  file,  listing  any  occurrences
               found.  This option is useful to find hashed host names or addresses and may also be used in conjunction with the
               -H option to print found keys in a hashed format.
       -f filename
               Specifies the filename of the key file.

       -g      Use generic DNS format when printing fingerprint resource records using the -r command.

       -H      Hash a known_hosts file.  This replaces all hostnames and addresses with hashed representations within the speci‐
               fied  file; the original content is moved to a file with a .old suffix.  These hashes may be used normally by ssh
               and sshd, but they do not reveal identifying information should the file's contents be  disclosed.   This  option
               will  not  modify  existing hashed hostnames and is therefore safe to use on files that mix hashed and non-hashed
               names.

       -h      When signing a key, create a host certificate instead of a user certificate.  See the “CERTIFICATES” section  for
               details.

       -I certificate_identity
               Specify the key identity when signing a public key.  See the “CERTIFICATES” section for details.

       -i      This  option  will  read an unencrypted private (or public) key file in the format specified by the -m option and
               print an OpenSSH compatible private (or public) key to stdout.  This option  allows  importing  keys  from  other
               software, including several commercial SSH implementations.  The default import format is “RFC4716”.

       -K      Download  resident  keys  from a FIDO authenticator.  Public and private key files will be written to the current
               directory for each downloaded key.  If multiple FIDO authenticators are attached, keys will  be  downloaded  from
               the first touched authenticator.  See the “FIDO AUTHENTICATOR” section for more information.

       -k      Generate a KRL file.  In this mode, ssh-keygen will generate a KRL file at the location specified via the -f flag
               that  revokes  every  key  or  certificate presented on the command line.  Keys/certificates to be revoked may be
               specified by public key file or using the format described in the “KEY REVOCATION LISTS” section.

       -L      Prints the contents of one or more certificates.

       -l      Show fingerprint of specified public key file.  For RSA and DSA keys ssh-keygen tries to find the matching public
               key file and prints its fingerprint.  If combined with -v, a visual ASCII art representation of the key  is  sup‐
               plied with the fingerprint.

       -M generate
               Generate   candidate   Diffie-Hellman   Group   Exchange   (DH-GEX)   parameters   for   eventual   use   by  the
               ‘diffie-hellman-group-exchange-*’ key exchange methods.  The numbers generated by this operation must be  further
               screened before use.  See the “MODULI GENERATION” section for more information.

       -M screen
               Screen  candidate parameters for Diffie-Hellman Group Exchange.  This will accept a list of candidate numbers and
               test that they are safe (Sophie Germain) primes with acceptable group generators.  The results of this  operation
               may be added to the /etc/ssh/moduli file.  See the “MODULI GENERATION” section for more information.

       -m key_format
               Specify  a  key  format  for  key  generation, the -i (import), -e (export) conversion options, and the -p change
               passphrase operation.  The latter may be used to convert between OpenSSH private key and PEM private key formats.
               The supported key formats are: “RFC4716” (RFC 4716/SSH2 public or private key), “PKCS8” (PKCS8 public or  private
               key)  or  “PEM”  (PEM public key).  By default OpenSSH will write newly-generated private keys in its own format,
               but when converting public keys for export the default format is “RFC4716”.  Setting a format of “PEM” when  gen‐
               erating  or  updating  a supported private key type will cause the key to be stored in the legacy PEM private key
               format.

       -N new_passphrase
               Provides the new passphrase.

       -n principals
               Specify one or more principals (user or host names) to be included in a certificate when signing a key.  Multiple
               principals may be specified, separated by commas.  See the “CERTIFICATES” section for details.

       -O option
               Specify a key/value option.  These are specific to the operation that ssh-keygen has been requested to perform.

               When signing certificates, one of the options listed in the “CERTIFICATES” section may be specified here.

               When performing moduli generation or screening, one of the options listed in the “MODULI GENERATION” section  may
               be specified.

               When  generating  FIDO  authenticator-backed  keys, the options listed in the “FIDO AUTHENTICATOR” section may be
               specified.

               When performing signature-related options using the -Y flag, the following options are accepted:

               hashalg=algorithm
                       Selects the hash algorithm to use for hashing the message to be signed.  Valid  algorithms  are  “sha256”
                       and “sha512.” The default is “sha512.”

               print-pubkey
                       Print the full public key to standard output after signature verification.

               verify-time=timestamp
                       Specifies  a  time to use when validating signatures instead of the current time.  The time may be speci‐
                       fied as a date or time in the YYYYMMDD[Z] or in YYYYMMDDHHMM[SS][Z] formats.  Dates and times will be in‐
                       terpreted in the current system time zone unless suffixed with a Z character, which causes them to be in‐
                       terpreted in the UTC time zone.

               When generating SSHFP DNS records from public keys using the -r flag, the following options are accepted:

               hashalg=algorithm
                       Selects a hash algorithm to use when printing SSHFP records using the  -D  flag.   Valid  algorithms  are
                       “sha1” and “sha256”.  The default is to print both.

               The -O option may be specified multiple times.

       -P passphrase
               Provides the (old) passphrase.

       -p      Requests  changing  the passphrase of a private key file instead of creating a new private key.  The program will
               prompt for the file containing the private key, for the old passphrase, and twice for the new passphrase.

       -Q      Test whether keys have been revoked in a KRL.  If the -l option is also specified then the contents  of  the  KRL
               will be printed.

       -q      Silence ssh-keygen.

       -R hostname | [hostname]:port
               Removes  all  keys belonging to the specified hostname (with optional port number) from a known_hosts file.  This
               option is useful to delete hashed hosts (see the -H option above).

       -r hostname
               Print the SSHFP fingerprint resource record named hostname for the specified public key file.

       -s ca_key
               Certify (sign) a public key using the specified CA key.  See the “CERTIFICATES” section for details.

               When generating a KRL, -s specifies a path to a CA public key file used to revoke certificates directly by key ID
               or serial number.  See the “KEY REVOCATION LISTS” section for details.

       -t dsa | ecdsa | ecdsa-sk | ed25519 | ed25519-sk | rsa
               Specifies the  type  of  key  to  create.   The  possible  values  are  “dsa”,  “ecdsa”,  “ecdsa-sk”,  “ed25519”,
               “ed25519-sk”, or “rsa”.

               This  flag  may also be used to specify the desired signature type when signing certificates using an RSA CA key.
               The available RSA signature variants are  “ssh-rsa”  (SHA1  signatures,  not  recommended),  “rsa-sha2-256”,  and
               “rsa-sha2-512” (the default).

       -U      When  used in combination with -s or -Y sign, this option indicates that a CA key resides in a ssh-agent(1).  See
               the “CERTIFICATES” section for more information.

       -u      Update a KRL.  When specified with -k, keys listed via the command line are added to the existing KRL rather than
               a new KRL being created.

       -V validity_interval
               Specify a validity interval when signing a certificate.  A validity interval may consist of a single time,  indi‐
               cating  that  the certificate is valid beginning now and expiring at that time, or may consist of two times sepa‐
               rated by a colon to indicate an explicit time interval.

               The start time may be specified as:
               •   The string “always” to indicate the certificate has no specified start time.
               •   A date or time in the system time zone formatted as YYYYMMDD or YYYYMMDDHHMM[SS].
               •   A date or time in the UTC time zone as YYYYMMDDZ or YYYYMMDDHHMM[SS]Z.
               •   A relative time before the current system time consisting of a minus sign followed by an interval in the for‐
                   mat described in the TIME FORMATS section of sshd_config(5).
               •   A raw seconds since epoch (Jan 1 1970 00:00:00 UTC) as a hexadecimal number beginning with “0x”.

               The end time may be specified similarly to the start time:
               •   The string “forever” to indicate the certificate has no specified end time.
               •   A date or time in the system time zone formatted as YYYYMMDD or YYYYMMDDHHMM[SS].
               •   A date or time in the UTC time zone as YYYYMMDDZ or YYYYMMDDHHMM[SS]Z.
               •   A relative time after the current system time consisting of a plus sign followed by an interval in the format
                   described in the TIME FORMATS section of sshd_config(5).
               •   A raw seconds since epoch (Jan 1 1970 00:00:00 UTC) as a hexadecimal number beginning with “0x”.

               For example:

               +52w1d  Valid from now to 52 weeks and one day from now.

               -4w:+4w
                       Valid from four weeks ago to four weeks from now.

               20100101123000:20110101123000
                       Valid from 12:30 PM, January 1st, 2010 to 12:30 PM, January 1st, 2011.

               20100101123000Z:20110101123000Z
                       Similar, but interpreted in the UTC time zone rather than the system time zone.

               -1d:20110101
                       Valid from yesterday to midnight, January 1st, 2011.

               0x1:0x2000000000
                       Valid from roughly early 1970 to May 2033.

               -1m:forever
                       Valid from one minute ago and never expiring.

       -v      Verbose mode.  Causes ssh-keygen to print debugging messages about its progress.  This is helpful  for  debugging
               moduli generation.  Multiple -v options increase the verbosity.  The maximum is 3.

       -w provider
               Specifies  a path to a library that will be used when creating FIDO authenticator-hosted keys, overriding the de‐
               fault of using the internal USB HID support.

       -Y find-principals
               Find the principal(s) associated with the public key of a signature, provided using the -s flag in an  authorized
               signers  file  provided  using the -f flag.  The format of the allowed signers file is documented in the “ALLOWED
               SIGNERS” section below.  If one or more matching principals are found, they are returned on standard output.

       -Y match-principals
               Find principal matching the principal name provided using the -I flag in the authorized  signers  file  specified
               using the -f flag.  If one or more matching principals are found, they are returned on standard output.

       -Y check-novalidate
               Checks  that  a  signature generated using ssh-keygen -Y sign has a valid structure.  This does not validate if a
               signature comes from an authorized signer.  When testing a signature, ssh-keygen accepts a  message  on  standard
               input  and  a  signature namespace using -n.  A file containing the corresponding signature must also be supplied
               using the -s flag.  Successful testing of the signature is signalled by ssh-keygen returning a zero exit status.

       -Y sign
               Cryptographically sign a file or some data using an SSH key.  When signing, ssh-keygen accepts zero or more files
               to sign on the command-line - if no files are specified then ssh-keygen will sign data presented on standard  in‐
               put.   Signatures  are  written  to the path of the input file with “.sig” appended, or to standard output if the
               message to be signed was read from standard input.

               The key used for signing is specified using the -f option and may refer to either a private key, or a public  key
               with  the  private half available via ssh-agent(1).  An additional signature namespace, used to prevent signature
               confusion across different domains of use (e.g. file signing vs email signing) must be provided via the -n  flag.
               Namespaces  are arbitrary strings, and may include: “file” for file signing, “email” for email signing.  For cus‐
               tom uses, it is recommended to use names following a NAMESPACE@YOUR.DOMAIN pattern to generate unambiguous  name‐
               spaces.

       -Y verify
               Request to verify a signature generated using ssh-keygen -Y sign as described above.  When verifying a signature,
               ssh-keygen  accepts a message on standard input and a signature namespace using -n.  A file containing the corre‐
               sponding signature must also be supplied using the -s flag, along with the identity of the signer using -I and  a
               list  of  allowed  signers via the -f flag.  The format of the allowed signers file is documented in the “ALLOWED
               SIGNERS” section below.  A file containing revoked keys can be passed using the -r flag.  The revocation file may
               be a KRL or a one-per-line list of public keys.  Successful verification by an authorized signer is signalled  by
               ssh-keygen returning a zero exit status.

       -y      This option will read a private OpenSSH format file and print an OpenSSH public key to stdout.

       -Z cipher
               Specifies  the  cipher to use for encryption when writing an OpenSSH-format private key file.  The list of avail‐
               able ciphers may be obtained using "ssh -Q cipher".  The default is “aes256-ctr”.

       -z serial_number
               Specifies a serial number to be embedded in the certificate to distinguish this certificate from others from  the
               same  CA.   If the serial_number is prefixed with a ‘+’ character, then the serial number will be incremented for
               each certificate signed on a single command-line.  The default serial number is zero.

               When generating a KRL, the -z flag is used to specify a KRL version number.

MODULI GENERATION
       ssh-keygen may be used to generate groups for the Diffie-Hellman Group  Exchange  (DH-GEX)  protocol.   Generating  these
       groups  is  a  two-step process: first, candidate primes are generated using a fast, but memory intensive process.  These
       candidate primes are then tested for suitability (a CPU-intensive process).

       Generation of primes is performed using the -M generate option.  The desired length of the primes may be specified by the

             # ssh-keygen -M generate -O bits=2048 moduli-2048.candidates

       By default, the search for primes begins at a random point in the desired length range.  This may be overridden using the
       -O start option, which specifies a different start point (in hex).

       Once a set of candidates have been generated, they must be screened for suitability.  This may be performed using the  -M
       screen  option.   In  this mode ssh-keygen will read candidates from standard input (or a file specified using the -f op‐
       tion).  For example:

             # ssh-keygen -M screen -f moduli-2048.candidates moduli-2048

       By default, each candidate will be subjected to 100 primality tests.  This may be overridden using the -O prime-tests op‐
       tion.  The DH generator value will be chosen automatically for the prime under consideration.  If a specific generator is
       desired, it may be requested using the -O generator option.  Valid generator values are 2, 3, and 5.

       Screened DH groups may be installed in /etc/ssh/moduli.  It is important that this file contains moduli of a range of bit
       lengths.

       A number of options are available for moduli generation and screening via the -O flag:

       lines=number
               Exit after screening the specified number of lines while performing DH candidate screening.

       start-line=line-number
               Start screening at the specified line number while performing DH candidate screening.

       checkpoint=filename
               Write the last line processed to the specified file while performing DH candidate screening.  This will  be  used
               to skip lines in the input file that have already been processed if the job is restarted.

       memory=mbytes
               Specify the amount of memory to use (in megabytes) when generating candidate moduli for DH-GEX.

       start=hex-value
               Specify start point (in hex) when generating candidate moduli for DH-GEX.

       generator=value
               Specify desired generator (in decimal) when testing candidate moduli for DH-GEX.

CERTIFICATES
       ssh-keygen  supports  signing of keys to produce certificates that may be used for user or host authentication.  Certifi‐
       cates consist of a public key, some identity information, zero or more principal (user or host) names and a  set  of  op‐
       tions  that are signed by a Certification Authority (CA) key.  Clients or servers may then trust only the CA key and ver‐
       ify its signature on a certificate rather than trusting many user/host keys.  Note that OpenSSH certificates are  a  dif‐
       ferent, and much simpler, format to the X.509 certificates used in ssl(8).

       ssh-keygen  supports  two types of certificates: user and host.  User certificates authenticate users to servers, whereas
       host certificates authenticate server hosts to users.  To generate a user certificate:

             $ ssh-keygen -s /path/to/ca_key -I key_id /path/to/user_key.pub

       The resultant certificate will be placed in /path/to/user_key-cert.pub.  A host certificate requires the -h option:

             $ ssh-keygen -s /path/to/ca_key -I key_id -h /path/to/host_key.pub

       The host certificate will be output to /path/to/host_key-cert.pub.

       It is possible to sign using a CA key stored in a PKCS#11 token by providing the token library using -D  and  identifying
       the CA key by providing its public half as an argument to -s:

             $ ssh-keygen -s ca_key.pub -D libpkcs11.so -I key_id user_key.pub

       Similarly,  it  is  possible for the CA key to be hosted in a ssh-agent(1).  This is indicated by the -U flag and, again,
       the CA key must be identified by its public half.

             $ ssh-keygen -Us ca_key.pub -I key_id user_key.pub

       In all cases, key_id is a "key identifier" that is logged by the server when the certificate is used for authentication.

       Certificates may be limited to be valid for a set of principal (user/host) names.  By default, generated certificates are
       valid for all users or hosts.  To generate a certificate for a specified set of principals:

             $ ssh-keygen -s ca_key -I key_id -n user1,user2 user_key.pub
             $ ssh-keygen -s ca_key -I key_id -h -n host.domain host_key.pub

       Additional limitations on the validity and use of user certificates may be specified through certificate options.  A cer‐
       tificate option may disable features of the SSH session, may be valid only when  presented  from  particular  source  ad‐
       dresses or may force the use of a specific command.

       The options that are valid for user certificates are:

       clear   Clear  all enabled permissions.  This is useful for clearing the default set of permissions so permissions may be
               added individually.

       critical:name[=contents]
       extension:name[=contents]
               Includes an arbitrary certificate critical option or extension.  The specified name should include a domain  suf‐
               fix,  e.g. “name@example.com”.  If contents is specified then it is included as the contents of the extension/op‐
               tion encoded as a string, otherwise the extension/option is created with no contents (usually indicating a flag).
               Extensions may be ignored by a client or server that does not recognise them, whereas  unknown  critical  options
               will cause the certificate to be refused.

       force-command=command
               Forces  the  execution  of  command instead of any shell or command specified by the user when the certificate is
               used for authentication.

       no-agent-forwarding
               Disable ssh-agent(1) forwarding (permitted by default).

       no-port-forwarding
               Disable port forwarding (permitted by default).

       no-pty  Disable PTY allocation (permitted by default).

       no-user-rc
               Disable execution of ~/.ssh/rc by sshd(8) (permitted by default).

       no-x11-forwarding
               Disable X11 forwarding (permitted by default).

       permit-agent-forwarding
               Allows ssh-agent(1) forwarding.

       permit-port-forwarding
               Allows port forwarding.

       permit-pty
               Allows PTY allocation.

       permit-user-rc
               Allows execution of ~/.ssh/rc by sshd(8).

       permit-X11-forwarding
               Allows X11 forwarding.

       no-touch-required
               Do not require signatures made using this key include demonstration of user presence (e.g.  by  having  the  user
               touch  the  authenticator).   This  option  only  makes  sense for the FIDO authenticator algorithms ecdsa-sk and
               ed25519-sk.

       source-address=address_list
               Restrict the source addresses from which the certificate is considered valid.  The address_list is a  comma-sepa‐
               rated list of one or more address/netmask pairs in CIDR format.

       verify-required
               Require  signatures  made using this key indicate that the user was first verified.  This option only makes sense
               for the FIDO authenticator algorithms ecdsa-sk and ed25519-sk.  Currently PIN authentication  is  the  only  sup‐
               ported verification method, but other methods may be supported in the future.

       At present, no standard options are valid for host keys.

       Finally,  certificates  may be defined with a validity lifetime.  The -V option allows specification of certificate start
       and end times.  A certificate that is presented at a time outside this range will not be considered valid.   By  default,
       certificates are valid from the Unix Epoch to the distant future.

       For certificates to be used for user or host authentication, the CA public key must be trusted by sshd(8) or ssh(1).  Re‐
       fer to those manual pages for details.

FIDO AUTHENTICATOR
       ssh-keygen  is able to generate FIDO authenticator-backed keys, after which they may be used much like any other key type
       supported by OpenSSH, so long as the hardware authenticator is attached when the keys are used.  FIDO authenticators gen‐
       erally require the user to explicitly authorise operations by touching or tapping them.  FIDO keys consist of two  parts:
       a  key  handle  part stored in the private key file on disk, and a per-device private key that is unique to each FIDO au‐
       thenticator and that cannot be exported from the authenticator hardware.  These are combined by the hardware at authenti‐
       cation time to derive the real key that is used to sign authentication challenges.  Supported key types are ecdsa-sk  and
       ed25519-sk.

       The options that are valid for FIDO keys are:

       application
               Override  the  default  FIDO application/origin string of “ssh:”.  This may be useful when generating host or do‐
               main-specific resident keys.  The specified application string must begin with “ssh:”.

       challenge=path
               Specifies a path to a challenge string that will be passed to the FIDO authenticator during key generation.   The
               challenge string may be used as part of an out-of-band protocol for key enrollment (a random challenge is used by
               default).

       device  Explicitly specify a fido(4) device to use, rather than letting the authenticator middleware select one.

       no-touch-required
               Indicate  that  the generated private key should not require touch events (user presence) when making signatures.
               Note that sshd(8) will refuse such signatures by default, unless overridden via an authorized_keys option.

       resident
               Indicate that the key handle should be stored on the FIDO authenticator itself.  This makes it easier to use  the
               authenticator  on  multiple  computers.  Resident keys may be supported on FIDO2 authenticators and typically re‐
               quire that a PIN be set on the authenticator prior to generation.  Resident keys may be loaded off the  authenti‐
              cator  using  ssh-add(1).  Storing both parts of a key on a FIDO authenticator increases the likelihood of an at‐
               tacker being able to use a stolen authenticator device.

       user    A username to be associated with a resident key, overriding the empty default username.   Specifying  a  username
               may be useful when generating multiple resident keys for the same application name.

       verify-required
               Indicate  that this private key should require user verification for each signature.  Not all FIDO authenticators
               support this option.  Currently PIN authentication is the only supported verification method, but  other  methods
               may be supported in the future.

       write-attestation=path
               May  be  used  at key generation time to record the attestation data returned from FIDO authenticators during key
               generation.  This information is potentially sensitive.  By default, this information is discarded.

KEY REVOCATION LISTS
       ssh-keygen is able to manage OpenSSH format Key Revocation Lists (KRLs).  These binary files specify keys or certificates
       to be revoked using a compact format, taking as little as one bit per certificate if they are  being  revoked  by  serial
       number.

       KRLs  may  be generated using the -k flag.  This option reads one or more files from the command line and generates a new
       KRL.  The files may either contain a KRL specification (see below) or public keys, listed one  per  line.   Plain  public
       keys are revoked by listing their hash or contents in the KRL and certificates revoked by serial number or key ID (if the
       serial is zero or not available).

       Revoking  keys  using a KRL specification offers explicit control over the types of record used to revoke keys and may be
       used to directly revoke certificates by serial number or key ID without having the complete original certificate on hand.
       A KRL specification consists of lines containing one of the following directives followed by a colon and some  directive-
       specific information.

       serial: serial_number[-serial_number]
               Revokes a certificate with the specified serial number.  Serial numbers are 64-bit values, not including zero and
               may  be  expressed in decimal, hex or octal.  If two serial numbers are specified separated by a hyphen, then the
               range of serial numbers including and between each is revoked.  The CA  key  must  have  been  specified  on  the
               ssh-keygen command line using the -s option.

       id: key_id
               Revokes  a  certificate  with the specified key ID string.  The CA key must have been specified on the ssh-keygen
               command line using the -s option.

       key: public_key
               Revokes the specified key.  If a certificate is listed, then it is revoked as a plain public key.

       sha1: public_key
               Revokes the specified key by including its SHA1 hash in the KRL.

       sha256: public_key
               Revokes the specified key by including its SHA256 hash in the KRL.  KRLs that revoke keys by SHA256 hash are  not
               supported by OpenSSH versions prior to 7.9.

       hash: fingerprint
               Revokes  a  key using a fingerprint hash, as obtained from a sshd(8) authentication log message or the ssh-keygen
               -l flag.  Only SHA256 fingerprints are supported here and resultant KRLs are not supported  by  OpenSSH  versions
               prior to 7.9.

       KRLs may be updated using the -u flag in addition to -k.  When this option is specified, keys listed via the command line
       are merged into the KRL, adding to those already there.

       It  is  also possible, given a KRL, to test whether it revokes a particular key (or keys).  The -Q flag will query an ex‐
       isting KRL, testing each key specified on the command line.  If any key listed on the command line has been  revoked  (or
      an error encountered) then ssh-keygen will exit with a non-zero exit status.  A zero exit status will only be returned if
       no key was revoked.

ALLOWED SIGNERS
       When  verifying  signatures,  ssh-keygen uses a simple list of identities and keys to determine whether a signature comes
       from an authorized source.  This "allowed signers" file uses a format patterned after the AUTHORIZED_KEYS FILE FORMAT de‐
       scribed in sshd(8).  Each line of the file contains the following space-separated fields: principals,  options,  keytype,
       base64-encoded key.  Empty lines and lines starting with a ‘#’ are ignored as comments.

       The principals field is a pattern-list (see PATTERNS in ssh_config(5)) consisting of one or more comma-separated USER@DO‐
       MAIN  identity  patterns  that  are  accepted for signing.  When verifying, the identity presented via the -I option must
       match a principals pattern in order for the corresponding key to be considered acceptable for verification.

       The options (if present) consist of comma-separated option specifications.  No spaces are permitted, except within double
       quotes.  The following option specifications are supported (note that option keywords are case-insensitive):

       cert-authority
               Indicates that this key is accepted as a certificate authority (CA) and that certificates signed by this  CA  may
               be accepted for verification.

       namespaces=namespace-list
               Specifies  a pattern-list of namespaces that are accepted for this key.  If this option is present, the signature
               namespace embedded in the signature object and presented on the verification command-line must match  the  speci‐
               fied list before the key will be considered acceptable.

       valid-after=timestamp
               Indicates  that  the key is valid for use at or after the specified timestamp, which may be a date or time in the
               YYYYMMDD[Z] or YYYYMMDDHHMM[SS][Z] formats.  Dates and times will be interpreted in the current system time  zone
               unless suffixed with a Z character, which causes them to be interpreted in the UTC time zone.

       valid-before=timestamp
               Indicates that the key is valid for use at or before the specified timestamp.

       When verifying signatures made by certificates, the expected principal name must match both the principals pattern in the
       allowed signers file and the principals embedded in the certificate itself.

       An example allowed signers file:

          # Comments allowed at start of line
          user1@example.com,user2@example.com ssh-rsa AAAAX1...
          # A certificate authority, trusted for all principals in a domain.
          *@example.com cert-authority ssh-ed25519 AAAB4...
          # A key that is accepted only for file signing.
          user2@example.com namespaces="file" ssh-ed25519 AAA41...

ENVIRONMENT
       SSH_SK_PROVIDER
               Specifies  a  path to a library that will be used when loading any FIDO authenticator-hosted keys, overriding the
               default of using the built-in USB HID support.

FILES
       ~/.ssh/id_dsa
       ~/.ssh/id_ecdsa
       ~/.ssh/id_ecdsa_sk
       ~/.ssh/id_ed25519
       ~/.ssh/id_ed25519_sk
       ~/.ssh/id_rsa
               Contains the DSA, ECDSA, authenticator-hosted ECDSA, Ed25519, authenticator-hosted Ed25519 or RSA  authentication
               identity  of  the  user.   This  file should not be readable by anyone but the user.  It is possible to specify a
               passphrase when generating the key; that passphrase will be used to encrypt the private part of this  file  using
               unless suffixed with a Z character, which causes them to be interpreted in the UTC time zone.

       valid-before=timestamp
               Indicates that the key is valid for use at or before the specified timestamp.

       When verifying signatures made by certificates, the expected principal name must match both the principals pattern in the
       allowed signers file and the principals embedded in the certificate itself.

       An example allowed signers file:

          # Comments allowed at start of line
          user1@example.com,user2@example.com ssh-rsa AAAAX1...
          # A certificate authority, trusted for all principals in a domain.
          *@example.com cert-authority ssh-ed25519 AAAB4...
          # A key that is accepted only for file signing.
          user2@example.com namespaces="file" ssh-ed25519 AAA41...

ENVIRONMENT
       SSH_SK_PROVIDER
               Specifies  a  path to a library that will be used when loading any FIDO authenticator-hosted keys, overriding the
               default of using the built-in USB HID support.

FILES
       ~/.ssh/id_dsa
       ~/.ssh/id_ecdsa
       ~/.ssh/id_ecdsa_sk
       ~/.ssh/id_ed25519
       ~/.ssh/id_ed25519_sk
       ~/.ssh/id_rsa
               Contains the DSA, ECDSA, authenticator-hosted ECDSA, Ed25519, authenticator-hosted Ed25519 or RSA  authentication
               identity  of  the  user.   This  file should not be readable by anyone but the user.  It is possible to specify a
               passphrase when generating the key; that passphrase will be used to encrypt the private part of this  file  using
               128-bit AES.  This file is not automatically accessed by ssh-keygen but it is offered as the default file for the
               private key.  ssh(1) will read this file when a login attempt is made.

       ~/.ssh/id_dsa.pub
       ~/.ssh/id_ecdsa.pub
       ~/.ssh/id_ecdsa_sk.pub
       ~/.ssh/id_ed25519.pub
       ~/.ssh/id_ed25519_sk.pub
       ~/.ssh/id_rsa.pub
               Contains  the DSA, ECDSA, authenticator-hosted ECDSA, Ed25519, authenticator-hosted Ed25519 or RSA public key for
               authentication.  The contents of this file should be added to ~/.ssh/authorized_keys on all  machines  where  the
               user  wishes  to  log in using public key authentication.  There is no need to keep the contents of this file se‐
               cret.

       /etc/ssh/moduli
               Contains Diffie-Hellman groups used for DH-GEX.  The file format is described in moduli(5).

SEE ALSO
       ssh(1), ssh-add(1), ssh-agent(1), moduli(5), sshd(8)

       The Secure Shell (SSH) Public Key File Format, RFC 4716, 2006.

AUTHORS
       OpenSSH is a derivative of the original and free ssh 1.2.12 release by Tatu Ylonen.  Aaron  Campbell,  Bob  Beck,  Markus
       Friedl,  Niels Provos, Theo de Raadt and Dug Song removed many bugs, re-added newer features and created OpenSSH.  Markus
       Friedl contributed the support for SSH protocol versions 1.5 and 2.0.

GNU                                                     September 4, 2023                                          SSH-KEYGEN(1)

Wie wir den Manual-Pages entnehmen konnten, unterstützt die OpenSSH-Implementierung von SSH einen zertifikatsbasierten Mechanismus. Dieser kann dazu beitragen, die Komplexität zu reduzieren sobald sich berechtigte Administratoren sich die SSH zu Hilfe nehmen und dabei eben Benutzer den SSH-Hosts und Hosts den SSH-Benutzern vertrauen (müssen).

Bevor wir uns nun mit der Konfiguration und dem Umgang mit Zertifiklaten und signierten Schlüsselmaterial eingehender beschäftigen, sei noch der Hinweis gestattet: Die hier vorgestellte Lösung mit der Verwendung von SSH-Zertifikaten ist kein Allheilmittel für die Sicherheit. Wie jede andere technische Lösung hat diese natürlich Vor- und Nachteile - hier seien nur mal DNS, Implementierung, Zertifikatsenrollment, Revocation-Lists, Handling und Verständnis der handelnden Personen genannt - die mit den bestehenden Anforderungen abgewogen werden müssen!

Glücklicherweise enthalten aktuelle Versionen4) von SSH viele Verbesserungen, die uns die Möglichkeit geben, authorized_keys mit AuthorizedKeysCommand zu zentralisieren und besser und leichter zu verwalten. Allerdings bieten SSH-Zertifikate neben der Lösung des TOFU-Problems viele weitere Vorteile/Funktionen (z. B. Ablauf des Zertifikats, Verwendung von Auftraggebern usw.), die die SSH-Authentifizierungsverwaltung verbessern und von allen Organisationen, die SSH verwenden, genutzt werden sollten.

Wie wir wissen, müssen wir nun sicherstellen dass beide Parteien sich gegenseitig vertrauen können. Bewerkstelligt wird dies unter Zuhilfename einer Zertifizierungsstelle, die hilft allen Kommunikationspartnern eine Vertrauensstellung einzuräumen. Hierzu sind zwei Zertifizierungsstellen nötig, wobei hier Zertifizierungsstelle ein doch eher sehr klingender Name, aber im SSH-Umfeld bei eingehender und genauerer Betrachtung eigentlich „nur“ je ein weiterer SSH-Schlüssel (wieder mit öffentlichem SSH-Schlüssel und seinem privaten SSH-Schlüssel), ist. Statt nun komplexe Zertifikate im X.509-Stil zu verwenden, hat sich SSH für sein eigenes, einfacheres Zertifikatsformat entschieden, das mit der CLI ssh-keygen einfach verwaltet werden kann.

  • Host-Zertifizierungsstelle (Host CA): Ein SSH-Schlüsselpaar, bei dem mit Hilfe des privater SSH-Schlüssel die Ausstellung von Host-Zertifikaten verwendet wird. Ihr öffentlicher SSH-Schlüssel wiederum wird von den Administratoren verwendet, um zu überprüfen, ob denn nun die Host-Zertifikate von der Host-Zertifizierungsstelle ausgestellt wurden, der sie vertrauen.
  • Benutzerzertifizierungsstelle (User CA): Ein SSH-Schlüsselpaar, dessen privater SSH-Schlüssel bei der Ausstellung von Benutzerzertifikaten Anwendung findet. Dessen öffentlicher SSH-Schlüssel wird von Hosts bei der Prüfung verwendet, ob die Benutzerzertifikate von der Benutzerzertifizierungsstelle ausgestellt wurden, der sie vertrauen.

Zertifizierungsstellen (Host und User CA)

Wenn es um Vertrauen geht, kann uns bei diesem Unterfangen eine Zertifizierungsstelle sehr hilfreich sein. Wir werden uns also jeweils eine erstellen, damit die Benutzer den Hosts vertrauen können und eine, damit die Hosts den Benutzern vertrauen können.

Die SSH-Zertifizierungsstelle (CA) kann theoretisch auf jedem Computer mit ssh-keygen eingerichtet werden. Auf Grund der Wichtigkeit die wir dieser CA einräumen, werden wir natürlich hierzu einem separaten Host der sich in einer entsprechenden Schutzzone befindet verwenden, auf dem dann nur ein sehr ausgewählter Administratorenkreis Zugriff bekommen wird. Die SSH-Zertifizierungsstelle ist bei genauer Betrachtung „lediglich nur“ jeweils ein ist ein Schlüsselpaar, das zum Signieren öffentlicher SSH-Schlüssel verwendet wird, um Zertifikate zu erzeugen. Daher werden wir uns nun zu erst jeweils ein Schlüsselpaar für jede Zertifizierungsstelle„ generieren.

Wie wir der man-page von ssh-keygen entnehmen konnten, werden wir nun diese beiden keys (CA) anlegen, nachdem wir uns zwei zugehörige Unterverzeichnisse angelegt haben. Somit haben wir es später beim täglichen Gebrauch dann doch leichter die Ganze Sache überblicken zu können.

 # mkdir /etc/ssh/ssh_ca

Nun erstellen wir uns mit den Optionen -t ed25519 (Schlüsseltyp), -C "Host CA key" (Kommentar ab Ende des Public-Keys) und -f /etc/ssh/ssh_ca_host/ssh_ca_host (Speicherort und Name der Schlüsseldateien) die Schlüssel für die Host CA:

 # ssh-keygen -t ed25519 -C "Host CA key" -f /etc/ssh/ssh_ca/ssh_ca_host_key
Generating public/private ed25519 key pair.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /etc/ssh/ssh_ca/ssh_ca_host_key
Your public key has been saved in /etc/ssh/ssh_ca/ssh_ca_host_key.pub
The key fingerprint is:
SHA256:wOyuN+fm0j83vkViB9Lx2PIiQHRkWD9jBJKRqhEplzk Host CA key
The key's randomart image is:
+--[ED25519 256]--+
|     + .=B*.o    |
|  . Eo .++ + =   |
|   o o+.. . X o  |
|    .... . o *   |
|     o. S . + +  |
|    ..     o =   |
|      ..      .  |
|     .+ + . o.   |
|    .. Bo..+oo   |
+----[SHA256]-----+

Entsprechend verfahren wir nun auch noch und erstellen das Schlüsselpaar für unsere User CA:

 # ssh-keygen -t ed25519 -C "User CA key" -f /etc/ssh/ssh_ca/ssh_ca_user_key
Generating public/private ed25519 key pair.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /etc/ssh/ssh_ca/ssh_ca_user_key
Your public key has been saved in /etc/ssh/ssh_ca/ssh_ca_user_key.pub
The key fingerprint is:
SHA256:iRZv/JZQRbMjshPjKavpy7X5mvxRzAOERXrnUzhHGiU User CA key
The key's randomart image is:
+--[ED25519 256]--+
|       ++ Eo*    |
|      .o   B o   |
|      o * B =    |
|       B # = .   |
|      + S B      |
|     . + = +     |
|      o . +      |
|   . = + o       |
|   .*.*+o        |
+----[SHA256]-----+

Wir haben nun im betreffenden Verzeichnis pro CA je zwei Dateien, einmal den privaten und einmal den öffentlichen Schlüssel für unsere beiden CAs:

 # ls -Al /etc/ssh/ssh_ca
total 16
-rw------- 1 root root 444 Nov 26 15:57 ssh_ca_host_key
-rw-r--r-- 1 root root  93 Nov 26 15:57 ssh_ca_host_key.pub
-rw------- 1 root root 444 Nov 26 15:59 ssh_ca_user_key
-rw-r--r-- 1 root root  93 Nov 26 15:59 ssh_ca_user_key.pub

Dank des Kommentars, den wir bei der Generierung der Schlüssel angegeben hatten, erkennen wir auch später an Hand des Kommentars um welches Schlüssel sprich welche CA es sich handelt.

 # cat /etc/ssh/ssh_ca/ssh_ca_host_key.pub /etc/ssh/ssh_ca/ssh_ca_user_key.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAID4Z+nMbZeGy2ugFDZri+y5aDCNHJkcxCk1w++iWZDLL Host CA key
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPQNQsEBk4c7vF//uWKix5QA8lHS0JMoWbMar9eP94BB User CA key

Was nun noch fehlt ist die SSH-Schlüsselwiderrufsliste KRL5), welche die Liste aller widerrufenen Zertifikate dann halten wird. Denn schliesslich könnte ja ein Zertifikat später mal gesperrt werden müssen, weil ein Schlüssel abhanden gekommen ist oder ein Personalabgang bei den handelnden Personen erfolgt.

 # ssh-keygen -k -f /etc/ssh/ssh_ca/ssh_ca_krl

Im Zielverzeichnis finden wir nun auch diese Datei.

 # ls -Al /etc/ssh/ssh_ca/ssh_ca_krl
-rw-r--r-- 1 root root 44 Nov 26 16:11 /etc/ssh/ssh_ca/ssh_ca_krl

Das Handling mit dieser KRL werden wir uns später noch genauer in diesem Abschnitt dann zu Gemüte führen.

Wir müssen jetzt anschliessend nur noch sowohl Server und auch unsere Administratoren/Clients dazu bringen mit den noch zu signierenden Zertifikaten, oder sprechen wir im SSH-Umfeld doch lieber von signierten Schlüsseln, umzugehen.

Erzeugen des Hostkey-Zertifikates

Im nächsten Schritt werden wir nun das nötige Vertrauen vorbereiten, welches unseren Administratoren dann Hilft beim Thema TOFU nicht überfordert zu werden.

Wir holen bzw. kopieren zunächst den SSH-Public-Key - dies wir unter aktuell verwendeten ED25519 Schlüsselmaterial entsprechend die Datei /etc/ssh/ssh_host_ed25519_key.pub - unseres bzw. später unserer Zielhosts auf unseren geschützten Host, auf dem wir zuvor unsere Keys und die KRL angelegt hatten. Diesen Schlüssel legen wir am Besten unter eigenem Namen in unseren CA-Verzeichnis /etc/ssh/ssh_ca ab.

Beispiel:

 # cat /etc/ssh/ssh_ca/ssh_host_ed25519_pml010002_key.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDY4Wzo8EUH3nl4Xea6hpt3pOi3HL4PxSr6x351NPbv5 KVM-Host 1

Diesen Öffentlichen Schlüssel signieren wir nun mit dem öffentlichen CA-Key der Host CA, dabei verwenden bzw. setzen wir die Optionen wie folgt:

  • -h : Host-Zertifikat erstellen
  • -s /etc/ssh/ssh_ca/ssh_ca_host_key : CA-Schlüssel (private key) mit dem wir den öffentlichen Schlüssel des Zielhosts signieren und dadurch beglaubigen.
  • -z 1000 : Gibt eine Seriennummer an, die in das Zertifikat eingebettet wird, um es von anderen Zertifikaten der derselben CA zu unterscheiden. Diese Seriennummer ist später z.B. sehr hilfreich, wenn es darum geht gezielt ein Zertifikat als ungültig zu deklarieren, sprich zu revoken. Sofern wir der serial_number ein '+'-Zeichen voranstellen, wird die Seriennummer für jedes jedes in einer einzigen Befehlszeile signierte Zertifikat erhöht. Die Standard-Seriennummer ist hier Null „0“.
  • -V +52w1d : Definiert die Zeit die das Zertifikat gültig sein soll, die also beim Signieren des Host-Schlüssels verwendet wird. Das Gültigkeitsintervall kann aus einem einzigen Zeitpunkt bestehen, der angibt, dass das Zertifikat ab jetzt gültig ist und zu diesem Zeitpunkt abläuft, oder es kann aus zwei Zeitpunkten bestehen, die durch einen Doppelpunkt durch einen Doppelpunkt getrennt sein, um ein explizites Zeitintervall anzugeben. In unserem Konfigurationsbeispiel also 52 Wochen und ein Tag zusätzlich → also in einem Jahr.
  • -I kvm : Der Key-Identifier ein „Schlüsselbezeichner“, der vom Server protokolliert wird, wird herangezogen sobald das Zertifikat zur Authentifizierung verwendet wird. Wir verwenden hier also unseren beautyfied short-Hostname kvm für den Host pml010002.intra.nausch.org.
  • -n kvm,kvm.intra.nausch.org,pml010002,pml010002.intra.nausch.org : Gibt einen oder mehrere Principals (Benutzer- oder Hostnamen) an, die beim Signieren eines Schlüssels in ein Zertifikat aufgenommen werden. Es können mehrere Principals angegeben werden, die durch Kommas getrennt sind. in unserem Fall also die hostnames und zusätzlich noch der fqdns.
  • ssh_host_ed25519_pml010002_key.pub : Schlüsseldatei des Hosts, die von der CA signiert werden wird.
 # ssh-keygen -h \
              -s /etc/ssh/ssh_ca/ssh_ca_host_key \
              -z 1000 \
              -V +52w1d \
              -I kvm \
              -n kvm,kvm.intra.nausch.org,pml010002,pml010002.intra.nausch.org \
              /etc/ssh/ssh_ca/ssh_host_ed25519_pml010002_key.pub
Enter passphrase:

Nach Eingabe der Passphrase unseres Host CA Schlüssels erhalten wir dann die Information der erfolgreichen Ausstellung unseres Zertifikates angezeigt.

Signed host key /etc/ssh/ssh_ca/ssh_host_ed25519_pml010002_key-cert.pub: id "kvm" serial 1000 for kvm,kvm.intra.nausch.org,pml010002,pml010002.intra.nausch.org valid from 2023-11-26T23:11:00 to 2024-11-25T23:12:51

In unserem CA Host Verzeichnis /etc/ssh/ssh_ca/ haben wir nun also neben der Datei ssh_host_ed25519_pml010002_key.pub, die den öffentlichen Schlüssel unseres host bereithält, nun auch die Datei mit dem signierten Schlüssel ssh_host_ed25519_pml010002_key-cert.pub, sprich unser Server-Zertifikat.

Wir können natürlich auch einen Blick in dieses Zertifikat werfen. hierzu benutzen wir folgenden Befehl:

 # ssh-keygen -L -f /etc/ssh/ssh_ca/ssh_host_ed25519_pml010002_key-cert.pub
/etc/ssh/ssh_ca/ssh_host_ed25519_pml010002_key-cert.pub:
        Type: ssh-ed25519-cert-v01@openssh.com host certificate
        Public key: ED25519-CERT SHA256:kIe5Ki/ItvQq9Cpfw/qLReo1wiVkdREVOz6a67I8nO4
        Signing CA: ED25519 SHA256:wOyuN+fm0j83vkViB9Lx2PIiQHRkWD9jBJKRqhEplzk (using ssh-ed25519)
        Key ID: "kvm"
        Serial: 1000
        Valid: from 2023-11-26T23:11:00 to 2024-11-25T23:12:51
        Principals: 
                kvm
                kvm.intra.nausch.org
                pml010002
                pml010002.intra.nausch.org
        Critical Options: (none)
        Extensions: (none)

Hostkey-Zertifikate ablegen und konfigurieren

Das gerade generierte Host-Key-Zertifikat kopieren wir nun auf unseren Zielhost und legen es im Verzeichnis /etc/ssh zu den anderen Schlüsseldateien.

  1. Key auf Host kopieren
    Im ersten Schritt kopieren wir nun die Datei von unserem geschützten SSH-CA-Host auf den Ziel-Host:
     $ scp /etc/ssh/ssh_ca/ssh_host_ed25519_pml010002_key-cert.pub kvm:
  2. Key in Zielverzeichnis kopieren
    Anschliessend kopieren wir auf dem Zielhost die Datei aus dem User-Verzeichnis /home/django unseres Admins - in diesem Beispiel vom User django - in das Zielverzeichnis.
     # cp /home/django/ssh_host_ed25519_pml010002_key-cert.pub /etc/ssh/ssh_host_ed25519_key-cert.pub

    wir haben nunmehr drei ED25519-Schlüsseldateien, den

    • Private-Key : /etc/ssh/ssh_host_ed25519_key
    • Public-Key : /etc/ssh/ssh_host_ed25519_key.pub
    • Zertifikat: /etc/ssh/ssh_host_ed25519_key-cert.pub den von der HOST CA signierten Public-Key.

      $ ls -Al /etc/ssh/ssh_host_ed*
      -rw-r-----. 1 root ssh_keys 387 Apr  7  2021 /etc/ssh/ssh_host_ed25519_key
      -rw-r--r--  1 root root     545 Nov 27 12:31 /etc/ssh/ssh_host_ed25519_key-cert.pub
      -rw-r--r--. 1 root root      82 Apr  7  2021 /etc/ssh/ssh_host_ed25519_key.pub
  3. SSH-Damon konfigurieren und neu starten
    Nun weisen wir denn SSH-Daemon auf dem Zielhost an, nicht nur den Fingerprint des Server-Keys zu präsentieren, sondern auch unser neues Server-Zertificat. Wir ergänzen dazu die Konfigurationmsdatei vom SSH-Daemon entsprechend.
     # vim /etc/ssh/sshd_config
    ...
    # Specifies a file containing a private host key used by SSH. The default 
    # is /etc/ssh/ssh_host_key for protocol version 1, and 
    # /etc/ssh/ssh_host_rsa_key and /etc/ssh/ssh_host_dsa_key for protocol 
    # version 2. Note that sshd(8) will refuse to use a file if it is 
    # group/world-accessible. It is possible to have multiple host key files.
    # ''rsa1'' keys are used for version 1 and ''dsa'' or ''rsa'' are used for
    # version 2 of the SSH protocol. 
    HostKey /etc/ssh/ssh_host_ed25519_key
     
    # Django : 2023-11-26
    # Specifies a file containing a public host certificate. The certificate's
    # public key must match a private host key already specified by HostKey.
    # The default behaviour of sshd is not to load any certificates.
    HostCertificate /etc/ssh/ssh_host_ed25519_key-cert.pub
     
    ... 

    Dies weist den SSH-Daemon an, bei Bedarf das signierte Zertifikat vorzuzeigen. Zum Aktivieren starten wir nun den SSH-Daemon einmal neu:

     # systemctl restart sshd.service

    Zur Sicherheit können wir auch noch den Status des SSH-Damon abfragen.

     # systemctl status sshd.service

    sshd.service - OpenSSH server daemon
       Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled)
       Active: active (running) since Sun 2023-11-26 23:20:39 CET; 11s ago
         Docs: man:sshd(8)
               man:sshd_config(5)
     Main PID: 1777 (sshd)
        Tasks: 1
       CGroup: /system.slice/sshd.service
               └─1777 /usr/sbin/sshd -D
    
    Nov 26 23:20:38 pml010002.intra.nausch.org systemd[1]: Starting OpenSSH server daemon...
    Nov 26 23:20:39 pml010002.intra.nausch.org sshd[16129]: Server listening on 10.0.10.2 port 22.
    Nov 26 23:20:39 pml010002.intra.nausch.org systemd[1]: Started OpenSSH server daemon.
    

  4. Ablegen des öffentlichen Schlüssels ssh_ca_host_key der SSH HOST CA auf dem Admin-Rechner
    Damit später der Client auch die Validät des angebotenen Server-Zertifikats überprüfen kann, benötigt dieser den öffentlichen Schlüssel der SSH HOST CA, den wir hier erstellt hatten. Diesen holen wir uns nun noch auf unseren Admin-Rechner und packen diesen bzw den Inhalt dieser Datei in entweder bei jedem Admin in das File ~/.ssh/known_hosts oder als Systemvorgabe in die Datei /etc/ssh/ssh_known_hosts. Diese Datei wird künftig pro verwendeter SSH HOST CA lediglich nur noch eine oder wenige Zeilen enthalten!
     $ echo "@cert-authority *.nausch.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAID4Z+nMbZeGy2ugFDZri+y5aDCNHJkcxCk1w++iWZDLL Host CA key" > ~/.ssh/known_hosts


    Verfügt der Client NICHT über den richtigen öffentlichen Schlüssel der SSH HOST CA (aus seiner eigenen ~/.ssh/known_hosts oder der für alle User geltenden aus /etc/ssh/ssh_known_hosts bzw. ist dieser nicht mehr gültig wird der vertrauensbekannte Verbindungsaufbau zum Zielhost erst einmal fehl schlagen und dem Anwender die obligatorische TOFU Frage stellen: This key is not known by any other names - Are you sure you want to continue connecting (yes/no/[fingerprint])? . Man kann dies auch sehr gut beim Aufruf von shh mit der OPtion -v erkennen.

     $ ssh kvm
    ...
    
    debug1: Server host certificate: ssh-ed25519-cert-v01@openssh.com SHA256:kIe5Ki/ItvQq9Cpfw/qLReo1wiVkdREVOz6a67I8nO4, serial 1000 ID "voip" CA ssh-ed25519 SHA256:wOyuN+fm0j83vkViB9Lx2PIiQHRkWD9jBJKRqhEplzk valid from 2023-11-26T22:12:00 to 2023-11-25T22:20:11
    ...
    debug1: No matching CA found. Retry with plain key
    The authenticity of host 'kvm.intra.nausch.org (10.0.10.2)' can't be established.
    ED25519 key fingerprint is SHA256:kIe5Ki/ItvQq9Cpfw/qLReo1wiVkdREVOz6a67I8nO4.
    This key is not known by any other names
    Are you sure you want to continue connecting (yes/no/[fingerprint])?


    Wird jedoch ein gültiges Zertifikat und ein gültiger SSH HOST CA verwendet und sind ferner die Hostnamen im DNS gepflegt wird ein Verbindungsaufbau zum Zielhost anstandslos klappen. Wir entfernen aber noch mit Hilfe des Befehls ssh-keygen -f ~/.ssh/known_hosts -R <hostname> den bisher genutzten Eintrag für unseren Host, damikt auch wirklich ausgeschlossen werden kann dass uns ein alter Eintrag hier „in die Suppe spucken könnte“. In unserem Beispiel entfernen wir den Eintrtag für den Host kvm.

    $ ssh-keygen -f ~/.ssh/known_hosts -R kvm.intra.nausch.org
    # Host kvm.intra.nausch.org found: line 1408
    /home/django/.ssh/known_hosts updated.
    Original contents retained as /home/django/.ssh/known_hosts.old

    Nun starten wir eine SSH-Session zu unserem Zielhost.

      $ ssh kvm.intra.nausch.org -v
    ...
    
    debug1: Server host certificate: ssh-ed25519-cert-v01@openssh.com SHA256:kIe5Ki/ItvQq9Cpfw/qLReo1wiVkdREVOz6a67I8nO4, serial 1000 ID "kvm" CA ssh-ed25519 SHA256:wOyuN+fm0j83vkViB9Lx2PIiQHRkWD9jBJKRqhEplzk valid from 2023-11-27T12:27:00 to 2024-11-26T12:28:44
    debug1: Host 'kvm.intra.nausch.org' is known and matches the ED25519-CERT host certificate.
    debug1: Found CA key in /etc/ssh/ssh_known_hosts:1
    ...
    [django@pml010002 ~]$ 

Sofern die Aufgabenstellung war, „nur“ dafür zu sorgen, den Admins die manuelle|visuelle Prüfung von SSH-Key Fingerprints beim ersten Verbindungsausbau abzunehmen, oder ausufernde ~/.ssh/known_hosts abzunehmen, können wir hir unsere Aufgabe abschließen und direkt zum Anschnitt Fazit und Ausblick springen.

Erzeugen der|des Userkey-Zertifikate(s)

Für die Erzeugung von signierten Client-Zertifikaten für unseren Client/Adminuser django führen wir folgenden Schritte aus:

  1. Kopieren des Public-Keys unseres Adminusers auf den SSH CA Host
    In unserem Beispiel kopieren wir nun den public-ssh-key ~/.ssh/id_ed25519.pub vom Admin django auf den Zielhost ssh-ca.idmz.nausch.org.
     $ scp ~/.ssh/id_ed25519.pub ssh-ca.idmz.nausch.org:
  2. Kopieren des Admin-Public-SSH-Keys in das Verzeichnis unserer SSH CA
    Hier kopieren wir dann den public-key in unser CA-Verzeichnis /etc/ssh/ssh_ca. Dabei vermerken wir den Namen des betreffenden Admins im Dateinamen der Schlüsseldatei. So haben wir es später leichter diese auseinander zu halten.
     cp /home/django/id_ed25519.pub /etc/ssh/ssh_ca/id_ed25519_django.pub

    Somit haben wir in unserem Beispiel hier den Public-Key zur Verfügung:

     # cat /etc/ssh/ssh_ca/id_ed25519_django.pub
    ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDYjDCtBTfrpbHHkRrqH1khsMagrrD5d+IbkU6ddoBSp django@nausch.org
  3. Generieren des User-Zertifikates
    Analog zur Erstellung des Host-Zertifikates signieren wir nun diesen Schlüssel des Users mit dem öffentlichen CA-Key der User CA, dabei verwenden bzw. setzen wir die Optionen wie folgt:
    • -s /etc/ssh/ssh_ca/ssh_ca_user_key : Zertifizieren (signieren) eines öffentlichen User-Keys mit dem angegebenen CA-Schlüssel (private key).
    • -z 1 : Gibt eine Seriennummer an, die in das Zertifikat eingebettet wird, um es von anderen Zertifikaten der derselben CA zu unterscheiden. Sofern wir der serial_number ein '+'-Zeichen voranstellen, wird die Seriennummer für jedes jedes in einer einzigen Befehlszeile signierte Zertifikat erhöht. Die Standard-Seriennummer ist hier Null „0“.
    • -V +52w1d : Definiert die Zeit die das Zertifikat gültig sein soll, die also beim Signieren des Host-Schlüssels verwendet wird. Das Gültigkeitsintervall kann aus einem einzigen Zeitpunkt bestehen, der angibt, dass das Zertifikat ab jetzt gültig ist und zu diesem Zeitpunkt abläuft, oder es kann aus zwei Zeitpunkten bestehen, die durch einen Doppelpunkt durch einen Doppelpunkt getrennt sein, um ein explizites Zeitintervall anzugeben. In unserem Konfigurationsbeispiel also 52 Wochen und ein Tag zusätzlich → also in einem Jahr.
    • -I django : Der Key-Identifier ein „Schlüsselbezeichner“, der vom Server protokolliert wird, wird herangezogen sobald das Zertifikat zur Authentifizierung verwendet wird. Wir verwenden hier also den Namen unseres Admin-Users von dem wir den public-key erhalten hatten.
    • Definiert den beim Signieren eines öffentlichen Server-Schlüssels die Schlüsselidentität der CA.
    • -n django : Gibt einen oder mehrere Principals (Benutzer- oder Hostnamen) an, die beim Signieren eines Schlüssels in ein Zertifikat aufgenommen werden. Es können mehrere Principals angegeben werden, die durch Kommas getrennt sind.
    • id_ed25519_django.pub : Datei mit dem public-key des Admin-Users, die von der CA signiert werden wird.
       # ssh-keygen -s /etc/ssh/ssh_ca/ssh_ca_user_key \
                    -z 1 \
                    -V +52w1d \
                    -I django \
                    -n django \
                    /etc/ssh/ssh_ca/id_ed25519_django.pub
      Enter passphrase:

      Nach Eingabe der Passphrase unseres USER CA Schlüssels erhalten wir dann die Information der erfolgreichen Ausstellung unseres Zertifikates angezeigt.

      Signed user key /etc/ssh/ssh_ca/id_ed25519_django-cert.pub: id "django" serial 10 for django valid from 2023-11-26T18:17:00 to 2024-11-25T18:18:33

      In unserem CA User Verzeichnis /etc/ssh/ssh_ca# haben wir nun also neben der Datei id_ed25519_django.pub, die den öffentlichen Schlüssel unseres Admins django bereithält, nun auch die Datei mit dem signierten Schlüssel id_ed25519_django-cert.pub, also das signierte User-Zertifikat.
      Wir können natürlich auch einen Blick in dieses Zertifikat werfen. Hierzu benutzen wir folgenden Befehl:

       # ssh-keygen -L -f /etc/ssh/ssh_ca/id_ed25519_django-cert.pub
      /etc/ssh/ssh_ca/id_ed25519_django-cert.pub:
              Type: ssh-ed25519-cert-v01@openssh.com user certificate
              Public key: ED25519-CERT SHA256:IqPRdnvM1+xSqaESGaxmfevXUsay8yRKPm9sn3eHTz0
              Signing CA: ED25519 SHA256:iRZv/JZQRbMjshPjKavpy7X5mvxRzAOERXrnUzhHGiU (using ssh-ed25519)
              Key ID: "django"
              Serial: 1
              Valid: from 2023-11-26T22:27:00 to 2024-11-25T22:28:37
              Principals: 
                      django
              Critical Options: (none)
              Extensions: 
                      permit-X11-forwarding
                      permit-agent-forwarding
                      permit-port-forwarding
                      permit-pty
                      permit-user-rc
  4. Zertifikat/Signierte Key Datei auf Host kopieren
    Das gerade generierte User-Key-Zertifikat kopieren wir nun auf unseren Zielhost und legen es zu den anderen Schlüsseldateien im ~/.ssh Verzeichnis. Dazu kopieren wir nun die Datei von unserem geschützten SSH-CA-Host auf den Ziel-Host:
     $ scp /etc/ssh/ssh_ca/id_ed25519_django-cert.pub admin-pc:
  5. Zertifikat/Signierte Key Datei kopieren
    Anschliessend verschieben wir auf dem Zielhost die Datei aus dem User-Verzeichnis ~/.ssh/ unseres Admins in das Zielverzeichnis.
     # mv ~/id_ed25519_dmz_django-cert.pub ~/.ssh/id_ed25519_dmz-cert.pub
  6. Ablegen des öffentlichen Schlüssels ssh_ca_host_key der SSH HOST CA auf dem Admin-Rechner
    Den öffentlichen Schlüssel der SSH HOST CA, den wir Hostkey-Zertifikate ablegen und konfigurieren erstellt hatten, haben wir ja in dem vorherigen Abschnitt schon auf unseren Admin-Rechner geholt und entsprechende Konfigurationsanpassungen in der ~/.ssh/known_hosts bzw. ~/etc/ssh/ssh_known_hosts vorgenommen.
  7. Konfiguration des SSH-Client
    Damit der SSH-Client beim Verbindungsaufbau auch weiß, welches Zertifikat er präsentieren soll, hinterlegen wir dieses noch in der zugehörigen Client-Konfiguirationsdatei ~/.ssh/config.
     $ vim ~/.ssh/config
    Host kvm
      Hostname kvm.intra.nausch.org
      User django
      CertificateFile ~/.ssh/id_ed25519-cert.pub
  8. Konfigurieren des SSH-Daemon auf dem Zielsystem
    Damit der Host auf dem wir uns anmelden können, muss natürlich wissen, ob das Zertifikat soweit vertraut werden kann. Dazu benötigt der Host unter anderem das Zertifikat unserer CA. welches wir bei der Anlage der User CA bereits erzeugt hatten. Diese Datei /etc/ssh/ssh_ca/ssh_ca_user_key.pub kopieren wir nun auf unseren Zielhost und legen diese Date im Verzeichnis /etc/ssh ab.
     # ls -Al /etc/ssh/*ca_user*
    -rw-r--r-- 1 root root 93 Nov 26 22:25 /etc/ssh/ssh_ca_user_key.pub

    Damit unser SSH-Daemon diese Key-Datei auch nutzen kann, müssen wir diesem noch mitteilen wo die Datei liegt. Dazu erweitern wir die Konfigurationsdatei unseres SSH-Daemon /etc/ssh/sshd_config wie folgt.

     vim /etc/ssh/sshd_config
    ...
    
    # Specifies a file containing public keys of certificate authorities that 
    # are trusted to sign user certificates for authentication, or none to not
    # use one. Keys are listed one per line; empty lines and comments starting
    # with ‘#’ are allowed. If a certificate is presented for authentication 
    # and has its signing CA key listed in this file, then it may be used for 
    # authentication for any user listed in the certificate's principals list.
    # Note that certificates that lack a list of principals will not be per-
    # mitted for authentication using TrustedUserCAKeys.
    TrustedUserCAKeys /etc/ssh/ssh_ca_user_key.pub
    
    ...

    Das Neustarten des Daemons verschieben wir noch etwas, da wir noch eine weitere Anpassung vornehmen werden.
    Damit nun nicht jeder Admin sich auf jedem System mit Hilfe seines User-Zertifikates anmelden kann, bietet uns SSH die Option AuthorizedPrincipalsFile an. Hiermit kann festgelegt werden, ob sich der Admin, der gerade sein Zertifikat präsentiert, auch wirklich autorisiert ist sich anzumelden. Es könnte ja sein, dass unterschiedliche Admins sich nur auf eine begrenzte Anzahl von Maschinen verbinden darf, andere Admins unterliegen nicht dieser Beschränkung. Bevor man nun auf die Idee kommt hierzu viele User CAs hierfür anzulegen, nutzen wir doch lieber Prüfung des principals, den wir beim Erstellen des User-Zertifikates angegeben hatten. Werfen wirdazu kurz einen Blick in das Zertifikat.

     $ ssh-keygen -L -f ~/.ssh/id_ed25519-cert.pub
    /home/django/.ssh/id_ed25519-cert.pub:
            Type: ssh-ed25519-cert-v01@openssh.com user certificate
            Public key: ED25519-CERT SHA256:IqPRdnvM1+xSqaESGaxmfevXUsay8yRKPm9sn3eHTz0
            Signing CA: ED25519 SHA256:iRZv/JZQRbMjshPjKavpy7X5mvxRzAOERXrnUzhHGiU (using ssh-ed25519)
            Key ID: "django"
            Serial: 5
            Valid: from 2023-11-27T18:02:00 to 2024-11-26T18:03:05
            Principals: 
                    django
            Critical Options: (none)
            Extensions: 
                    permit-X11-forwarding
                    permit-agent-forwarding
                    permit-port-forwarding
                    permit-pty
                    permit-user-rc

    Hier haben wir also bei den Principals den Wert django. In der Datei /etc/ssh/ssh_auth_principals wird nun definiert welche Admins/User sich anmelden darf, sprich wer ist in dieser Datei gelistet und wer nicht. Wir hinterlegen als den Principal-Namen aus dem Zertifikat in dieser Liste.

     # vim /etc/ssh/ssh_auth_principals
    /etc/ssh/ssh_auth_principals
    # Liste aller Administratoren, die berechtigt sind sich hier mit Hilfe der SSH zu verbinden.
    django
    michael

    In diesem Beispiel wären das die User michael und django, der User christoph könnte sich nicht anmelden, selnst wenn er ein gültiges User-Zertifikat der gleichen User CA hätte, wie der User michael. Damit der SSH-Daemon diese Liste auch verwerten kann, muss er natürlich wissen dass es sie gibt und wo er sie findet; hierzu ergänzen wir die /etc/ssh/sshd_config um folgenden Abschnitt.

     # vim /etc/ssh/sshd_config
    ...
    
    # Specifies a file that lists principal names that are accepted for certifi-
    # cate authentication. When using certificates signed by a key listed in 
    # TrustedUserCAKeys, this file lists names, one of which must appear in the
    # certificate for it to be accepted for authentication. Names are listed 
    # one per line preceded by key options (as described in AUTHORIZED_KEYS FILE
    # FORMAT. Empty lines and comments starting with ‘#’ are ignored.
    
    # Arguments to AuthorizedPrincipalsFile accept the tokens described in the 
    # TOKENS section. After expansion, AuthorizedPrincipalsFile is taken to be 
    # an absolute path or one relative to the user's home directory. The default
    # is none, i.e. not to use a principals file – in this case, the username of
    # the user must appear in a certificate's principals list for it to be 
    # accepted.
    
    # Note that AuthorizedPrincipalsFile is only used when authentication pro-
    # ceeds using a CA listed in TrustedUserCAKeys and is not consulted for 
    # certification authorities trusted via ~/.ssh/authorized_keys, though the
    # principals= key option offers a similar facility.
    AuthorizedPrincipalsFile /etc/ssh/ssh_auth_principals
    
    ...

    Da wir die Konfiguration des SSH-Daemon nun vorerst abgeschlossen haben, ist es an der Zeit diesen neu zu starten. Zum Aktivieren starten wir nun den SSH-Daemon einmal neu:

     # systemctl restart sshd.service

    Zur Sicherheit können wir auch noch den Status des SSH-Damon abfragen.

     # systemctl status sshd.service

    sshd.service - OpenSSH server daemon
       Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled)
       Active: active (running) since Sun 2023-11-26 23:20:39 CET; 11s ago
         Docs: man:sshd(8)
               man:sshd_config(5)
     Main PID: 1777 (sshd)
        Tasks: 1
       CGroup: /system.slice/sshd.service
               └─1777 /usr/sbin/sshd -D
    
    Nov 26 23:57:38 pml010002.intra.nausch.org systemd[1]: Starting OpenSSH server daemon...
    Nov 26 23:57:39 pml010002.intra.nausch.org sshd[16129]: Server listening on 10.0.10.2 port 22.
    Nov 26 23:57:39 pml010002.intra.nausch.org systemd[1]: Started OpenSSH server daemon.
    

    Nun ist es an der Zeit unsere Konfiguration auch zu testen. Bis jetzt haben wir vermutlich mit Einträgen in der ~/.ssh/authorized_keys gearbeitet. bei Anmeldung mit Zertifikat benötigen wir die Option aber nicht mehr, da der SSH-Client ja sein Zertifikat dem Server zur Authentifizierung schickt.

     $ rm ~/.ssh/authorized_keys<code> Die Anmeldung mit Hilfe des privaten SSH-Keys des Admins ist nunmehr unterbunden. Der Administrator kann sich nunmehr nur nur mit (s)einem gültigen Zertifikat anmelden. <code> # ssh -v kvm.intra.nausch.org

    Der SSH-Server präsentiert dem Client sein Host-Zertifikat und wir sehen auch dass kein known_hosts-Dateien mehr benitzt werden (können).:

    ...
    
    debug1: Server host certificate: ssh-ed25519-cert-v01@openssh.com SHA256:kIe5Ki/ItvQq9Cpfw/qLReo1wiVkdREVOz6a67I8nO4, serial 1000 ID "kvm" CA ssh-ed25519 SHA256:wOyuN+fm0j83vkViB9Lx2PIiQHRkWD9jBJKRqhEplzk valid from 2023-11-27T12:27:00 to 2024-11-26T12:28:44
    debug1: load_hostkeys: fopen /home/django/.ssh/known_hosts2: No such file or directory
    debug1: load_hostkeys: fopen /etc/ssh/ssh_known_hosts2: No such file or directory
    debug1: Host 'kvm.intra.nausch.org' is known and matches the ED25519-CERT host certificate.
    debug1: Found CA key in /etc/ssh/ssh_known_hosts:1
    
    ...

    Anschließend päsentiert der Client dem Server das entsprechende Clientzertifikat des Admins django.

    ...
    
    debug1: Authentications that can continue: publickey
    debug1: Next authentication method: publickey
    debug1: Offering public key: /home/django/.ssh/id_ed25519_dmz-cert.pub ED25519-CERT SHA256:IqPRdnvM1+xSqaESGaxmfevXUsay8yRKPm9sn3eHTz0 explicit
    debug1: Server accepts key: /home/django/.ssh/id_ed25519_dmz-cert.pub ED25519-CERT SHA256:IqPRdnvM1+xSqaESGaxmfevXUsay8yRKPm9sn3eHTz0 explicit
    Authenticated to kvm.intra.nausch.org ([10.0.10.2]:22) using "publickey".
    
    ...

    … und schon sind wir angemeldet.

    [django@pml010002 ~]$

Key Revocation List

Was ist aber nun, wenn nun ein Administrator die Berechtigung verliert sich an Systemen anzumelden? Klar, früher hätte man auf dem System(en) in der authorized_keys die betreffenden Schlüsseleinträge gelöscht. Alternativ könnten wir in unserem Konfigurationsbeispiel hier den Principal-Eintrag auf dem oder den Servern löschen - für die temporäre Sperre ein durchaus gangbarer Weg. Was ist aber wenn ein User-Zertifikat abhanden gekommen ist oder wenn der Admin gekündigt hat oder in seinen wohlverdienten Ruhestand verabschiedet? Ganz einfach, wir sperren das kompromittierte Zertifikat und stellen dem Admin ein neues Zertifikat aus, oder im Falle des Ausscheidens begnügen wir uns mit der Sperre dieses einen Zertifikats.

Obwohl OpenSSH keinen Mechanismus zum Verteilen der Sperrliste bereitstellt, ist es immer noch einfacher, die Sperrliste zu erstellen und sie auf anderem Wege z.B. Orchestrierung mit Hilfe von Ansible zu verteilen, als die CA-Schlüssel und alle zuvor erstellten und verteilten Host- und Benutzerzertifikate zu ändern. Diese Sperrliste ssh_ca_krl haben wir bereits beim Anlegen unserer CAs im Abschnitt Zertifizierungsstellen HOST und USER CA angelegt. Diese befindet sich im CA-Verzeichnis auf unserem CA-Host unter /etc/ssh/ssh_ca. Diese Datei kopieren wir nun regelmässig auf unsere Maschinen und legen diese im Verzeichnis /etc/ssh/ ab.

Damit der SSH-Daemon dieseSperrliste auch berücksichtigen kann, muss dieser natürlich wissen, dass es diese gibt ond wo diese zu finden ist. Wir ergänzen also unsere SSH-Daemon-Konfiguration noch einmal.

 # vim /etc/ssh/sshd_config
...

# Specifies revoked public keys file, or none to not use one. Keys listed 
# in this file will be refused for public key authentication. Note that if
# this file is not readable, then public key authentication will be re-
# fused for all users. Keys may be specified as a text file, listing one 
# public key per line, or as an OpenSSH Key Revocation List (KRL) as gene-
# rated by ssh-keygen.
RevokedKeys /etc/ssh/ssh_ca_krl

...

Bevor wir den Daemon nun neu starten vergewissern wir uns nochmals, ob die Datei auch wirklich vorhanden ist, denn wenn diese Datei nicht lesbar ist wird die Authentifizierung mit öffentlichen Schlüsseln für alle Benutzer verweigert!

 # ls -Al /etc/ssh/ssh_ca_krl
-rw-r--r-- 1 root root 121 Nov 27 13:42 /etc/ssh/ssh_ca_krl

Alles klar, diese Datei ist vorhanden und für alle auch lesbar, wir können also den SSH-Daemon neu starten.

 # systemctl restart sshd.service 

sshd.service - OpenSSH server daemon
   Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled)
   Active: active (running) since Mon 2023-11-27 02:34:19 CET; 15s ago
     Docs: man:sshd(8)
           man:sshd_config(5)
 Main PID: 1777 (sshd)
    Tasks: 1
   CGroup: /system.slice/sshd.service
           └─1777 /usr/sbin/sshd -D

Nov 27 02:34:02 pml010002.intra.nausch.org systemd[1]: Starting OpenSSH server daemon...
Nov 27 02:34:02 pml010002.intra.nausch.org sshd[16129]: Server listening on 10.0.10.2 port 22.
Nov 27 02:34:02 pml010002.intra.nausch.org systemd[1]: Started OpenSSH server daemon.

Mit dem Programm ssh-keygen sind wir in der Lage, Key Revocation Lists (KRLs) im OpenSSH-Format zu verwalten. Diese Binärdateien geben die zu sperrenden Schlüssel oder Zertifikate in einem kompakten Format an, das nur ein Bit pro Zertifikat benötigt, wenn sie nach Seriennummer gesperrt werden.

KRLs können mit dem Option -k erzeugt werden. Diese Option liest eine oder mehrere Dateien von der Befehlszeile und erzeugt eine neue KRL. Die Dateien können entweder eine KRL-Spezifikation oder öffentliche Schlüssel enthalten, die einzeln pro Zeile aufgeführt werden. Einfache öffentliche Schlüssel werden widerrufen, indem ihr Hash oder ihr Inhalt in der KRL aufgelistet wird, und Zertifikate werden anhand der Seriennummer oder der Schlüssel-ID widerrufen.

Das Widerrufen von Schlüsseln mit Hilfe einer KRL-Spezifikation bietet eine explizite Kontrolle über die Arten von Aufzeichnungen, die zum Widerrufen von Schlüsseln verwendet werden, und kann verwendet werden, um Zertifikate direkt nach Seriennummer oder Schlüssel-ID zu widerrufen, ohne das vollständige Originalzertifikat zur Hand zu haben. Eine KRL-Spezifikation besteht aus Zeilen, die eine der folgenden Direktiven enthalten, gefolgt von einem Doppelpunkt und einigen richtlinienspezifischen Informationen.

  • serial: serial_number[-serial_number]
    Widerruft ein Zertifikat mit der angegebenen Seriennummer. Seriennummern sind 64-Bit-Werte (ohne Null) und können dezimal, hexadezimal oder oktal angegeben werden. Wenn zwei Seriennummern durch einen Bindestrich getrennt angegeben werden, dann wird der Bereich der Seriennummern einschließlich und zwischen den beiden Nummern widerrufen. Der CA-Schlüssel muss in der Befehlszeile von ssh-keygen mit der Option -s angegeben worden sein.
  • id: schlüssel_id
    Widerruft ein Zertifikat mit der angegebenen Schlüssel-ID-Zeichenkette. Der CA-Schlüssel muss in der Befehlszeile von ssh-keygen mit der Option -s angegeben worden sein.
  • key: public_key
    Widerruft den angegebenen Schlüssel. Wenn ein Zertifikat aufgeführt ist, wird es als einfacher öffentlicher Schlüssel widerrufen.
  • sha1: public_key
    Widerruft den angegebenen Schlüssel anhand seines SHA1-Hashes.

KRLs können mit dem Option -u zusätzlich zu -k aktualisiert werden. Wenn diese Option angegeben wird, werden die über die Befehlszeile aufgelisteten Schlüssel in die KRL eingefügt und zu den bereits vorhandenen hinzugefügt.

Es ist auch möglich, anhand einer KRL zu prüfen, ob sie einen bestimmten Schlüssel (oder mehrere Schlüssel) widerruft. Mit dem Flag -Q wird eine vorhandene KRL abgefragt, wobei jeder in der Befehlszeile angegebene Schlüssel getestet wird. Wurde ein in der Befehlszeile aufgeführter Schlüssel widerrufen wurde (oder ein Fehler aufgetreten ist), wird ssh-keygen mit einem Exit-Status ungleich Null beendet. Ein Exit-Status von Null wird nur zurückgegeben, wenn kein Schlüssel widerrufen wurde.

Beim Widerrufen Revoken eines Zertifikates gehen wir am besten wir folgt vor:

  1. Seriennummer des Zertifikats ermitteln
    Damit wir später ganz gezielt ein und nur ein ganz bestimmtes Zertifikat revoken können bedienen wir uns am Besten an der Serien-Nummer des Zertifikates. Diese ermitteln wir nun wie folgt.
     # ssh-keygen -L -f /etc/ssh/ssh_ca/id_ed25519_test-cert.pub
    /etc/ssh/ssh_ca/id_ed25519_test-cert.pub:
            Type: ssh-ed25519-cert-v01@openssh.com user certificate
            Public key: ED25519-CERT SHA256:IqPRdnvM1+xSqaESGaxmfevXUsay8yRKPm9sn3eHTz0
            Signing CA: ED25519 SHA256:iRZv/JZQRbMjshPjKavpy7X5mvxRzAOERXrnUzhHGiU (using ssh-ed25519)
            Key ID: "django"
            Serial: 4
            Valid: from 2023-11-27T17:58:00 to 2024-11-26T17:59:50
            Principals:
                    django
            Critical Options: (none)
            Extensions:
                    permit-X11-forwarding
                    permit-agent-forwarding
                    permit-port-forwarding
                    permit-pty
                    permit-user-rc

    Wir sehen also hier die Serial: 4 (Serien-Nummer) und den Principals: django. O.K. das haben wir geprüft, es ist genau das Zertifikat, welches wir vom Nutzer django auf die Sperrliste setzen sollen.

  2. Prüfen des Aktuellen Zertifikatsstatus
    Eine Vorabprüfung, ob das Zertifikat aktuell noch nicht revoked wurde, sehen wir hier:
     ssh-keygen -Qf /etc/ssh/ssh_ca/ssh_ca_krl /etc/ssh/ssh_ca/id_ed25519_test.pub
    /etc/ssh/ssh_ca/id_ed25519_test.pub (django@nausch.org): ok

    Das Zertifikat ist aktuell also noch gültig!

  3. Revoken des Zertifikates
    Zum Rückrufen des Zertifikates mit der Seriennummer 4 müssen wir nun die beiden Optionen -k zusammen mit der Option -u angeben, da wir einen Update der Sperrlistendatei vornehmen wollen. Mit der Option -f definieren wir die SPerrlistendatei selbst. Wichtigste Option ist nun die Seriennummer die wir mit der Option -z 4 angeben. Würden wir diese Option weglassen, würden wir ALLE Zertifikate des Benutzers revoken!
     # ssh-keygen -u -k -f /etc/ssh/ssh_ca/ssh_ca_krl -z 4 /etc/ssh/ssh_ca/id_ed25519_test-cert.pub
    Revoking from /etc/ssh/ssh_ca/id_ed25519_test-cert.pub

    Die Rückmeldung war entsprechend positiv, das Zertifikat kann ab sofort nicht mehr benutzt werden um sich an einem Host anzumelden.

  4. Prüfen des Aktuellen Zertifikatsstatus
    Eine erneute Prüfung, wie nun der aktuelle Status des Zertifikats ist, sehen wir hier:
     ssh-keygen -Qf /etc/ssh/ssh_ca/ssh_ca_krl /etc/ssh/ssh_ca/id_ed25519_test.pub
    /etc/ssh/ssh_ca/id_ed25519_test.pub (django@nausch.org): REVOKED

    Das Zertifikat ist also definitiv gesperrt/zurückgerufen!

Versucht der Admin sich nun erneut mit dem Host unter Verwendung seines Zertifikates, welches wir soeben revoked haben, wird dies erwartungsgemäss scheitern.

 $ ssh -v kvm
...

debug1: Server host certificate: ssh-ed25519-cert-v01@openssh.com SHA256:kIe5Ki/ItvQq9Cpfw/qLReo1wiVkdREVOz6a67I8nO4, serial 1000 ID "kvm" CA ssh-ed25519 SHA256:wOyuN+fm0j83vkViB9Lx2PIiQHRkWD9jBJKRqhEplzk valid from 2023-11-27T12:27:00 to 2024-11-26T12:28:44
debug1: load_hostkeys: fopen /home/django/.ssh/known_hosts2: No such file or directory
debug1: load_hostkeys: fopen /etc/ssh/ssh_known_hosts2: No such file or directory
debug1: Host 'kvm.intra.nausch.org' is known and matches the ED25519-CERT host certificate.
debug1: Found CA key in /etc/ssh/ssh_known_hosts:1

...

Der Server präsentierte sein gültiges Zertifikat, soweit so gut, aber der Entscheidende Punkt folgt sofort:

...

debug1: Offering public key: /home/django/.ssh/id_ed25519_dmz-cert.pub ED25519-CERT SHA256:IqPRdnvM1+xSqaESGaxmfevXUsay8yRKPm9sn3eHTz0 explicit
debug1: Authentications that can continue: publickey
debug1: Offering public key: /home/django/.ssh/id_ed25519_dmz ED25519 SHA256:IqPRdnvM1+xSqaESGaxmfevXUsay8yRKPm9sn3eHTz0 explicit agent
debug1: Authentications that can continue: publickey
debug1: No more authentication methods to try.
django@kvm.intra.nausch.org: Permission denied (publickey).

Der Client wird mit seinem Zertifikat zurückgewiesen, welches ja revoked wurde. Auch der Anmeldeversuch nur mit dem unsignierten SSH-Key schlägt fehl, da wir das ja auch explizit verboten hatten!

Möchte man das Thema TOFU sauber lösen, ist die Verwendung von Host Zertifikaten sicherlich ein sehr guter Weg, den man beim sicheren IT Betrieb aufgreifen sollte. Denn theoretische Sicherheit ist toll, aber was helfen alle theoretischen Vorüberlegungen, wenn der Admin bei der initialen Kontaktaufnahme sich überrumpeln oder ablenken lässt. Der Zugewinn an Sicherheit ist hier definitiv ein Punkt der für die Verwendung von Host-Zertifikaten spricht!

Ob man sich auch auf das Thema User-Zertifikate einlassen möchte, ist da schon mehr einer genauen Aufwands-Nutzenabwägung zu unterziehen. Wie werden z.B. die User-Zertifikate sicher verwahrt und abgesichert. Das Thema KRL ist dann sicher noch ein ganz besonderes Thema das Betrachtet werden muss. Diese beiden Themen manuell durch einen oder gar mehrere handelnde Personen erledigen zu lassen, wird aller Voraussicht nach lediglich die Administrationsaufwände signifikant erhöhen. Im schlimmsten Fall schafft man bei der manuellen Verwendung mehr Probleme und Risiken.

Lösungen für diese Herausforderungen können zum einen eine Versionierung mit Hilfe von Git und Orchestrierung der Aufgaben mit einem State-of-th-Art- Werkzeug wie Ansible sein. Alternativ könnte auch die eingehende Betrachtung und Überlegung in Richtung KEYPER gehen, sofern man sich auf Container einlassen kann|will. Keyper ist ein Open Source SSH-Schlüssel- und zertifikatsbasierter Authentifizierungsmanager, der auch als SSH-Zertifizierungsstelle (CA) fungiert.

Links


1) , 3)
TrustOfFirstUse
2)
ManInTheMiddle
4)
Stand: Dezember 2023
5)
KeyRevocationList
Diese Website verwendet Cookies. Durch die Nutzung der Website stimmen Sie dem Speichern von Cookies auf Ihrem Computer zu. Außerdem bestätigen Sie, dass Sie unsere Datenschutzbestimmungen gelesen und verstanden haben. Wenn Sie nicht einverstanden sind, verlassen Sie die Website.Weitere Information
  • linux/ssh/tofu_und_cert.txt
  • Zuletzt geändert: 17.03.2024 14:47.
  • von django