OpenSSH für OTP - Grundlegendes

Um einen Host, der sowohl von intern als auch von extern per SSH erreichbar sein soll, möglichst gut absichern zu können bietet es sich an, für den externen Zugriff Einmalkennwörter einzusetzen.
Somit ist ein Ausspähen von Kennwörtern, z.B. in Internet-Cafés ausgeschlossen, da ein einmal eingegebenes Kennwort sofort nach der Eingabe seine Gültigkeit verliert.
Dennoch soll es aus Gründen der Bequemlichkeit weiterhin möglich sein den Host von intern durch Authentifizierungsmethoden wie Pubkey oder Passwort zu erreichen.
Um das zu erreichen muss es zwei OpenSSH Server mit unterschiedlichen Konfigurationen geben.
Das hier beschriebene Vorgehen funktioniert nicht mit dem Standard SSHD von Debian, Ubuntu und ähnlichen Derivaten. Offenbar wurde hier beim Kompilieren  die PAM- Konfiguration statisch vorgegeben, was die eigentliche dynamische namensbasierte Konfiguration unmöglich macht- siehe auch weiter unten.
Die folgende Beschreibung verwendet den Port 22 für den Zugriff aus dem internen Netz und Port 2222 für den Zugriff von extern.

Konfiguration

!!!ACHTUNG!!! Fehler beim Ändern in der Konfiguration des SSHd's könnten bewirken, dass das System von Remote nicht mehr erreichbar ist!!!

Alle Pfadangaben beziehen sich auf ein Ubuntu- Linux. Die Reproduktion des Vorgehens sollte jedoch auf allen anderen Derivaten nach Anpassung der Pfade problemlos möglich sein.
Als erstes müssen sämtliche Pakete für OTP auf dem System vorhanden sein. D.h. Befehle wie opieinfo, opiekey und opiepasswd müssen funktionieren.
Unter Ubuntu sind das die Pakete  
libpam-opie - Use OTPs for PAM authentication
opie-client - OPIE programs for generating OTPs on client machines
opie-server - OPIE programs for maintaining an OTP key file
  Nun geht es an die Konfiguration von OpenSSH:
Unter /etc/ssh findet sich die zentrale Konfigurationsdatei von OpenSSH sshd_config. Diese kopieren wir uns nach sshd_config_opie und passen dann beide an. Gezeigt werden hier nur die relevanten Einträge. 
sshd_configsshd_config_opie
Port 22Port 2222
PidFile /var/run/sshd.pidPidFile /var/run/sshd-opie.pid
RSAAuthentication yesRSAAuthentication no
PubkeyAuthentication yesPubkeyAuthentication no
ChallengeResponseAuthentication noChallengeResponseAuthentication yes
PasswordAuthentication yesPasswordAuthentication no
UsePAM yes
UsePAM yes
Nun brauchen wir noch eine Kopie des eigentlichen Binarys. Damit bei Updates von OpenSSH aber beide Versionen auf ein und dem gleichen Stand sind bietet es sich an keine echte Kopie, sondern lediglich einen symbolischen Link zu erzeugen:  
ln s- /usr/sbin/sshd /usr/sbin/sshd-opie
  Damit beim Systemstart auch beide SSH Daemons gestartet werden muss nun noch das Startscript angepasst/ dupliziert werden.
Hierzu wird unter /etc/init.d die Datei ssh nach ssh-opie kopiert:  
cp /etc/init.d/ssh /etc/init.d/ssh-opie
  In der neuen ssh-opie werden nun alle Vorkommen von /usr/sbin/sshd durch /usr/sbin/sshd-opie und /var/run/sshd.pid durch /var/run/sshd-opie.pid ersetzt. Nach einem  
update-rc.d ssh-opie defaults 
  ist die Konfiguration der Startdateien auch schon komplett.
Nun geht es an die Konfiguration von PAM. Die zuständigen Configfiles finden sich unter /etc/pam.d. Hier kopieren wir ebenfalls die Konfigurationsdatei:  
cp /etc/pam.d/sshd /etc/pam.d/sshd-opie
  Wichtig ist hierbei, dass der Name der Konfigurationsdatei dem Namen des Binaries entspricht, da dieses dann automatisch aufgerufen wird. Der Relevante Teil hierzu findet sich in den Sources von OpenSSH in der Datei auth-pam.h:  
---
#if !defined(SSHD_PAM_SERVICE)
# define SSHD_PAM_SERVICE               __progname
#endif
---
  Und genau das ist der Teil, der unter Debian und Ubuntu (vielleicht auch weiteren Distributionen) dafür verantwortlich ist, dass es mit dem Paket OpenSSH aus den Repositories nicht klappt. Irgendwas oder -wer hat beim Kompilieren offenbar den Wert von SSHD_PAM_SERVICE mit dem statischen Wert "ssh" überschrieben.
Nun geht es ans Anpassen der neuen PAM Konfiguration:
Hierzu wird die Zeile  
@include common-auth
  auskommentiert und zwei neue Zeilen kommen hinzu:  
auth        sufficient        pam_opie.so
auth        required          pam_deny.so
  Nach einem Neustart der beiden SSH Daemons kann man die Funktionalität nun erstmals testen:  
ssh localhost
ssh -p 2222 localhost
  Bei der ersten Zeile sollte ein normaler Login Prompt wie bisher erscheinen.
Bei der zweiten sollte ein Prompt ähnlich dem folgenden auftauchen:  
otp-md5 360 co9356 ext, Response:
  Sollte das nicht der Fall sein und auch bei der zweiten erst ein "normaler" Loginprompt erscheinen wird die PAM Konfiguration nicht gelesen bzw. die falsche verwendet. Dann hilft nur noch debuggen und suchen ;-)

Initialisierung und Benutzung

Nachdem das System nun soweit vorbereitet ist muss noch der gewünschte Benutzer bei OTP bekannt gemacht und initialisiert werden.
Hierzu meldet man sich über eine sichere Verbindung, bevorzugt direkt an der Konsole, als dieser Benutzer am System an und tippt folgenden Befehl:  
opiepasswd -cf
  Es erscheint folgende Ausgabe:  
---
Adding smeagul:
Only use this method from the console; NEVER from remote. If you are using
telnet, xterm, or a dial-in, type ^C now or exit with no password.
Then run opiepasswd without the -c parameter.
Using MD5 to compute responses.
Enter new secret pass phrase:
Again new secret pass phrase:
ID smeagul OTP key is 499 co4783
LENT GUM JUST COLD CODE TASK
---
  Die Passphrase muss zwischen 10 und 127 Zeichen lang sein. Bereits an der maximalen Länge erkennt man wie wichtig diese Passphrase ist!
Im obigen Beispiel ist co4783 der sogenannte Seed und 499 die Sequenznummer. Die Sequenznummer zählt pro Login nach unten, der Seed bleibt gleich.

Wie kommt man nun ans Passwort?
Zum einen kann man sich je nach Betriebssystem auf dem Client Keygen Programme besorgen, z.B.  für Windows winkey32 oder otpgen (Java) für Smartphones mit Java Unterstützung (letzteres läuft auf meinem Samsung Jet S8000 absolut problemlos).
Zum anderen gibt es die Möglichkeit sich eine Liste mit den nächsten Kennwörtern zu generieren. Diese sollte man selbstverständlich nicht verlieren!
Hierzu folgendes eingeben:  
opiekey -n 10 499 co4783
  Die Ausgabe:  
Using the MD5 algorithm to compute response.
Reminder: Don't use opiekey from telnet or dial-in sessions.
Sorry, but you don't seem to be on the console or a secure terminal.
Warning: Continuing could disclose your secret pass phrase to an attacker!
Enter secret pass phrase:
490: VOID KENT DAR FAN FIVE WAST
491: BALM ELSE GOLD YAWL TAUT MARS
492: LANG DOUR DOUG ONUS FOR NARY
493: BECK STEM RUTH LOVE UTAH NIP
494: HARM MALL BATE BITS TONG ROIL
495: RIFT SNAG SAC MUD NIL IQ
496: REEF BURL YAW NAIR HIT SORE
497: DATE BOCA MARK FAT MOOD JAVA
498: MICE WEEK TILT LIED WORN LYNN
499: LENT GUM JUST COLD CODE TASK
  Die Sequenz und der Seed sind eben die Werte, die bei der Generierung ausgegeben wurden. Die Zahl hinter -n gibt an wieviele Kennwörter erzeugt werden sollen. Sämtliche Warnmeldungen im obigen Beispiel tauchen auf weil die Erzeugung nicht direkt an der Konsole und somit über eine potentiell unsichere Verbindung erfolgt ist.
So, nun haben wir alles um uns anmelden zu können- also los gehts:  
ssh -p 2222 localhost
otp-md5 498 co4783 ext, Response:
  Als Response nehmen wir die Sequenz 498 von unserer Liste- also MICE WEEK TILT LIED WORN LYNN
Und voilà die Anmeldung ist komplett. Nun wieder abmelden und das Gleiche nochmal:  
ssh -p 2222 localhost
otp-md5 497 co4783 ext, Response:
  Und schon hat die Sequenz um 1 heruntergezählt. Das richtige Passwort ist also das in der Zeile, die mit 497 anfängt.
Zum Abschalten des OTP Zugangs für einen spezifischen Benutzer gibt man folgendes ein:  
opiepasswd -d BENUTZERNAME