Host-Key aus ~/.ssh/known_hosts entfernen

Gelegentlich wird auf einem Host ein Host-Key geändert, entweder manuell oder eventuell automatisch durch einen Update von OpenSSH. Beim Login per ssh auf den betreffenden Host bekommt man dann die folgende Meldung:

$ ssh aix01
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
SHA256:xYglDF3cuHCCrxtbFUbpofpmhNs9MiO114vAT4qVX2M.
Please contact your system administrator.
Add correct host key in /home/as/.ssh/known_hosts to get rid of this message.
Offending RSA key in /home/as/.ssh/known_hosts:2
RSA host key for aix01 has changed and you have requested strict checking.
Host key verification failed.
$

Viele Administratoren verwenden dann vi (oder einen anderen Editor) um den Eintrag mit dem alten Host-Key aus der known_hosts zu entfernen. Eine Hilfe ist dabei die Angabe der Zeilennummer in der Ausgabe oben, /home/as/.ssh/known_hosts:2 bedeutet der Eintrag steht in der Zeile 2 der Datei.

Man kann den veralteten Host-Key aber viel einfacher mit Hilfe des Kommandos ssh-keygen und der Option „-R“ (remove) entfernen:

$ ssh-keygen -R aix01
# Host aix01 found: line 2
/home/as/.ssh/known_hosts updated.
Original contents retained as /home/as/.ssh/known_hosts.old
$ 

Das Kommando erstellt eine Kopie der Datei mit der Endung „.old“ und entfernt den gewünschten Eintrag. Das ist um einiges einfacher als mit dem Editor!

Möchte man wissen ob ein Host-Key für ein System schon in der known_hosts existiert, gibt es dafür die Option „-F“ (find):

$ ssh-keygen -F aix02
# Host aix02 found: line 49 
aix02,192.168.178.49 ssh-rsa AAAAB3NzaC1yc2E...
$

Es wird der Public Host-Key, sowie die Zeile für das System ausgegeben.

sshd: fatal: permanently_set_uid: was able to restore old [e]gid

Beim Versuch sich auf einem System per ssh einzuloggen bekommt ein Benutzer die folgende Meldung:

$ ssh mars

Connection to mars closed by remote host.

Connection to mars closed.

$

Auf dem Server findet man die folgende Fehlermeldung:

Jul 16 19:57:24 mars auth|security:info sshd[51511616]: Accepted publickey for user5 from X.X.X.X port 57523 ssh2
Jul 16 19:57:24 mars auth|security:crit sshd[49414624]: fatal: permanently_set_uid: was able to restore old [e]gid

Die Ursache des Problems, ist in diesem Fall, das der betreffende User zum einen lokal angelegt ist:

$ lsuser -R files user5
user5 id=1005 pgrp=staff groups=staff home=/home/user5 shell=/usr/bin/ksh

Zum anderen aber auch über einen Namensdienst (hier LDAP) existiert, allerdings mit unterschiedlichen Gruppen:

$ lsuser -R LDAP user5
user5 id=1005 pgrp=develop groups=develop home=/home/user5 shell=/bin/bash gecos=XXXX

Der Benutzer soll eigentlich aus LDAP kommen, vor der Anbindung an LDAP gab es den Benutzer aber schon lokal. Nach der Anbindung an LDAP wurde vergessen den lokalen Benutzer-Account zu löschen.

Nachdem der lokale Benutzer-Account gelöscht wurde:

# rmuser -R files -p user5

funktioniert der SSH-Login auch wieder korrekt.

 

ssh: PTY allocation request failed on channel 0

Manchmal kann es vorkommen, das ein SSH-Login auf ein System fehlschlägt, mit der obigen Meldung:

$ ssh aix09
PTY allocation request failed on channel 0

Es konnte kein Pseudo-Terminal mehr alloziert werden, d.h. alle verfügbaren Pseudo-Terminals sind schon in Benutzung. Dies hat in der Regel eine von 2 Ursachen:

  • Entweder sind tatsächlich schon alle Pseudo-Terminals in Verwendung, weil es z.B. extrem viele Logins auf das System gibt, oder
  • die Pseudo-Terminals sind vom Kernel nicht korrekt freigegeben worden.

Als erstes stellt sich die Frage wie man dennoch auf die Maschine kommt, ohne z.B. die Konsole benutzen zu müssen. Mit einer der beiden folgenden Varianten sollte man sich auf das System mit SSH einloggen können:

$ ssh aix09 bash -i
bash: cannot set terminal process group (-1): A specified file does not support the ioctl system call.
 bash: no job control in this shell
aix09 $
oder
$ ssh aix09 ksh -i
aix09 $

Ist man nun eingeloogt, kann man zunächst untersuchen, ob tatsächlich alle Pseudo-Terminals in Verwendung sind. Das geht am einfachsten mit Hilfe des Kommandos fuser:

aix09 $ cd /dev/pts
aix09 $ fuser *
0:66126088
1:60096860
...
254:  62062964
255:  59310558

Die Anzahl der verfügbaren Pseudo-Terminals ist durch das Attribut ATTnum des Geräts pty0 bestimmt:

aix09 $ lsattr -El pty0
ATTnum     256       Maximum number of Pseudo-Terminals     True
BSDnum     16        Maximum number of BSD Pseudo-Terminals True
autoconfig available STATE to be configured at boot time    True
csmap      sbcs      N/A                                    True

Die Anzahl lässt sich leicht mit dem chdev Kommando erhöhen:

aix09 # chdev -l pty0 -a ATTNum=368
pty0 changed

Es stehen sofort die zusätzlichen Pseudo-Terminals zur Verfügung, was man nach dem Einloggen mittels SSH auch mit dem Kommando tty überprüfen kann:

aix09 $ tty
/dev/pts/256

Wann wird ein cron-Job das nächste Mal gestartet

Der Dienst cron wird auf vielen Unix-Systemen ausgiebig verwendet. Die Möglichkeiten anzugeben, wann ein Kommando mittels cron gestartet werden soll, sind vielfältig. Hier erst mal einige Beispiel-Zeilen aus einer möglichen crontab eines Benutzers:

5 0 * * * /usr/local/bin/daily.job
15 14 1 * * /usr/local/bin/monthly.job
0 22 * * 1-5 /usr/local/bin/weekdays.job

Die Korn-Shell 93 (auf vielen Systemen als ksh93 verfügbar) bietet eine einfache Möglichkeit den nächsten Start eines cron-Jobs anzeigen zu lassen, und zwar mittels der eingebauten Funktion printf und der Format Angabe %T für Datumsausgaben:

ksh93 $ printf "%T\n" "5 0 * * *"
Fr 19 Jan 00:05:00 2018

Man verwendet als erstes Argument im Format-String das %T für Datum und gibt im entsprechenden Argument (hier das zweite) die Intervall-Angabe aus dem crontab-Eintrag an. Das Resultat ist in diesem Fall der Zeitpunkt wann der Job daily.job aus dem Beispiel oben das nächste Mal gestartet wird.

Hier ein Beispiel für den zweiten Job monthly.job:

ksh93 $ printf "monthly.job: %T\n" "15 14 1 * *"
monthly.job: Do 1 Feb 14:15:00 2018

Arbeitet man nicht in der ksh93 selbst, dann kann man die folgende Variante nutzen:

bash $ ksh93 -c 'printf "%T\n" "0 22 * * 1-5"'
Do 18 Jan 22:00:00 2018

Hinweis: Auf einigen Systemen ist die Korn-Shell 93 als ksh verfügbar. Das kann man mit dem folgenden Kommando überprüfen:

$ ksh
$ print ${.sh.version}
Version AJM 93u+ 2012-08-01

Im AIX-Talk crontab & cron wird die Datumsausgabe für crontab-Einträge demonstriert.