TeamViewer: Ein Konzept macht noch keine Sicherheit

Heute hatte ich das Vergnügen, die Bekanntschaft mit dem TeamViewer zu machen - einem Tool, das es ermöglicht, VPN-Verbindungen durch restriktive Firewalls hindurch aufzubauen. Das ganze funktioniert mit einer User-ID und einem Passwort, was gerade dazu einlädt, diese einfache Lösung zu verwenden. Aber wie genau funktioniert das dann? Und wie sicher ist der Verbindungsaufbau und die darüber übertragenen Daten?

Einen ersten Anhaltspunkt gibt die Menge der Konfiguration - annähernd null, ziemlich wenig für eine typische VPN-Verbindung. Die Verwendung einer User-ID lässt den Schluss zu, dass ein zentraler Server beim Verbindungsaufbau involviert ist. Weiteren Aufschluss über die Vorgänge beim Verbindungsaufbau gibt das Dokument, das die "Teamviewer Sicherheitsinformationen" enthält.

Dort wird lang und breit erklärt, wie viele Zertifizierungen man hat, dass man tollen ISO-Standards entspricht, europäische Server verwendet, viel Wert auf den Schutz personenbezogener Daten legt und Technologie einsetzt, die - so ähnlich - bereits anderswo erfolgreich eingesetzt werden. Ein Statement interessiert mich dabei besonders, nämlich:

Wie später im Abschnitt „Verschlüsselung und Authentifizierung“ beschrieben, können auch wir als Betreiber der Routingserver den verschlüsselten Datenverkehr nicht einsehen.

Allerdings stellt sich die Frage, ob das wirklich so ist. Sehen wir uns im ersten Schritt die Registrierung der Schlüssel an. Diese werden von den jeweiligen Clients "A" und "B" generiert und der Public Key jeweils und an den Server "S" übertragen. Die Schlüssel werden mit dem öffentlichen Masterschlüssel des Servers verschlüsselt. Da jedoch Server und Masterschlüssel unter der Kontrolle von TeamViewer sind, stellt das kein Hindernis dar. Eine weitere Validierung findet laut dem Dokument nicht statt.

TeamViewer: Key Ceremony

TeamViewer: Key Ceremony

Kommen wir also zum eigentlichen Verbindungsaufbau zwischen zwei Clients. Die jeweilige Authentisierung der Clients via SRP lasse ich an dieser Stelle außen vor, da diese nur zwischen einem Client und dem Server stattfindet, aber nicht unter den Clients.

Als erstes erfragt Client A vom Server den Public Key von Client B - die Anfrage ist mit dem öffentlichen Masterschlüssel des Servers verschlüsselt. Der Public Key von Client B wird vom Server an Client A geschickt - verschlüsselt mit dem Public Key von Client A und signiert mit dem Masterschlüssel des Servers. Beide Daten sind TeamViewer natürlich bekannt.
Nun erzeugt Client A einen symmetrischen AES-256 Schlüssel, verschlüsselt ihn mit dem vom Server erhaltenen Public Key von Client B und signiert ihn mit seinem eigenen Private Key. Dieses Paket X wird nun an den Server geschickt, damit dieser es an den Client B weiterleitet.
Nach dem Erhalt fragt der Client B den Public Key von Client A beim Server an - die Anfrage ist wiederum mit dem öffentlichen Masterschlüssel des Servers verschlüsselt. Der Server antwortet mit dem Public Key von Client A, den er mit dem öffentlichen Schlüssel von Client B vor der Übertragung verschlüsselt und mit seinem eigenen Masterschlüssel signiert.
Nun prüft Client B die Signatur des Paket X mit dem erhaltenen Public Key von Client A und kann anschließend den symmetrischen AES-256 Schlüssel mit seinem eigenen Private Key entschlüsseln.

TeamViewer: Connection Establishment

TeamViewer: Connection Establishment

Damit haben nun Client A und Client B einen gemeinsamen, symmetrischen AES-256 Schlüssel und können diesen verwenden, um verschlüsselt untereinander zu kommunizieren. Da TeamViewer die privaten Schlüssel der Clients nicht kennt, können sie auch nicht den ausgetauschten symmetrischen Schlüssel in Erfahrung bringen...

...oder?

Hier schlägt nun nämlich ein großes Problem zu: der zentrale Server. Die Clients müssen diesem blind vertrauen. Während des Schlüsselaustauschs ist er jedoch in solcher einer Machtposition, dass überhaupt nicht ersichtlich ist, ob er tatsächlich keinen Zugriff auf den symmetrischen AES-256 Schlüssel hat.

Nehmen wir uns mal folgendes Szenario: Der Client A möchte gern eine Verbindung zu Client B aufbauen und muss dazu den öffentlichen Schlüssel von Client B erfragen. Der zentrale Server könnte nun mit einem öffentlichen Fake-Schlüssel für Client B antworten, zu dem der Server auch den passenden privaten Fake-Schlüssel kennt.
Der Client A würde nun mit diesem öffentlichen Fake-Schlüssel den symmetrischen AES-256 Schlüssel verschlüsseln und mit seinem privaten Schlüssel signieren. Dieses Paket X würde der Client A nun an den Server schicken, damit dieser es an Client B weiterleitet.
Anstatt es jedoch einfach weiterzuleiten, entschlüsselt der Server den symmetrischen AES-256 Schlüssel mit dem passenden privaten Fake-Schlüssel, verschlüsselt den symmetrischen AES-256 Schlüssel mit dem tatsächlichen öffentlichen Schlüssel von Client B und signiert das ganze mit einem privaten Fake-Schlüssel für Client A und schickt dieses neue Paket Y erst dann an Client B weiter.
Nach dem Erhalt fragt der Client B den Public Key von Client A beim Server an - dieser antwortet jedoch stattdessen mit dem öffentlichen Fake-Schlüssel für Client A.
Die Signatur des Paket Y passt mit dem öffentlichen Fake-Schlüssel überein, der symmetrische AES-256 Schlüssel ist mit dem korrekten öffentlichen Schlüssel von Client B verschlüsselt, also muss das erhaltene Paket Y ja valide sein und der enthaltene Schlüssel kann verwendet werden.

TeamViewer: Possible MITM Attack

TeamViewer: Possible MITM Attack

Praktischerweise bestimmt nun auch noch TeamViewer, ob eine direkte TCP-/UDP-Verbindung aufgebaut wird oder ob die Routingserver von TeamViewer verwendet werden. Dank des schwachen Schlüsselaustauschs kann den Routingservern der notwendige symmetrische AES-256 Schlüssel gegeben werden, die nun in der Lage sind, den gesamten Traffic zu entschlüsseln. Die Aussage aus dem Dokument, dass dieses Mitlesen nicht möglich wäre, ist also schlichtweg falsch.

Ob es Absicht ist, dass TeamViewer sämtliche Datenverbindungen mitlesen kann? Ich weiß es nicht genau. Es ist jedoch auffällig, dass sie bei der Authentisierung zwischen Client und Server ein relativ komplexes, Diffie-Hellmann-ähnliches Verfahren einsetzen, während sie beim Austausch des symmetrischen Schlüssels nicht auf ein Verfahren setzen, das aus einem gemeinsamen Geheimnis - zum Beispiel ausgetauscht über einen zweiten Kanal - einen sicheren Sitzungsschlüssel erzeugt.

Die Entscheidung, ob man einer zentralen Instanz Zugriff auf sämtliche übertragenen Daten geben möchte, sollte an dieser Stelle jeder für sich selbst treffen.

MITM-Grüße, Kenny

TLS-Client-Authentication mit Nginx und PHP-FPM

Seit ich es bei StartSSL.com gesehen habe, habe ich mich gefragt, wie ein ordentlicher Login über TLS-Client-Zertifikate funktionieren kann. So schwierig, wie man es sich im ersten Moment vorstellt, ist es eigentlich gar nicht.

Als erstes muss man sich einmal um die PKI-Infrastruktur kümmern. Genauer gesagt muss man eine Certificate Authority anlegen, die die benötigten Client-Zertifikate erstellt. Für kleinere Installationen und Tests kann man das natürlich erst einmal via OpenSSL tun. Für größere Installationen würde ich hingegen zu ordentlichen CA-Lösungen raten (wie z.B. der EJCBA).

Wir fangen also mit dem Erstellen der CA und des selbstsignierten CA-Zertifikats an. An dieser Stelle ist es in Ordnung, dass das CA-Root-Zertifikat selbstsigniert ist, da ihr ja auch später die Client-Zertifikate ausgeben werdet. Im Gegensatz zu TLS-Server-Zertifikaten gibt es hier keinen weit verbreiteten Truststore in den einzelnen Browsern, den ihr berücksichtigen müsst. Sogar im Gegenteil: Schließlich wollt nur ihr in der Lage sein, jemandem Zugriff auf eure Anwendung zu geben.

1
2
3
4
5
6
mkdir -p /var/www/ssl/client/
chmod 700 /var/www/ssl/client/
cd /var/www/ssl/client/

openssl genrsa -des3 -out ./ca.key 4096
openssl req -new -x509 -days 365 -key ./ca.key -out ./ca.crt

Als nächstes wollen wir das erste Client-Zertifikat erstellen. Dieses wird in diesem Fall direkt von der Root-CA signiert. Ihr könnt natürlich noch eine Zwischen-CA erstellen, aber für kleinere Installationen und Tests ist das nicht unbedingt notwendig.

1
2
3
4
5
cd ~/

openssl genrsa -des3 -out ./client.key 1024
openssl req -new -key ./client.key -out ./client.csr
openssl x509 -req -days 365 -in ./client.csr -CA /var/www/ssl/client/ca.crt -CAkey /var/www/ssl/client/ca.key -set_serial 01 -out ./client.crt

Ihr habt nun ein Zertifikat (in der Datei "client.crt") und den zugehörigen privaten Schlüssel (in der Datei "client.key") - diese müsst ihr nun in euren jeweiligen Browser importieren. Das Vorgehen dazu unterscheidet sich von Browser zu Browser und System zu System. In meinem Fall musste ich erst alles in eine *.p12-Datei überführen, damit die Schlüsselbundverwaltung von Mac OS X das Schlüsselpaar importieren konnte. Dazu musste ich noch folgendes aufrufen:

1
2
3
cd ~/

openssl pkcs12 -export -clcerts -inkey ./client.key -in ./client.crt -out ./client.p12 -name "<sprechender Name>"

Nachdem das erledigt ist, müssen wir Nginx beibringen, die Zertifikate zu verarbeiten. Dabei setze ich auf die SSL-Funktionen von Nginx auf. Wie die eingerichtet werden, hatte ich bereits vor einiger Zeit beschrieben. Die Pfade in der Server-Konfiguration sind reine Platzhalter.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
server {
  listen 80;
  listen 443 ssl;

  ssl_certificate     /var/www/ssl/example_com.crt;
  ssl_certificate_key /var/www/ssl/example_com.key;

  ssl_client_certificate /var/www/ssl/client/ca.crt;
  ssl_verify_client      optional;
  #ssl_verify_client      on;

  server_name example.com;

  access_log /home/sftpuser/example_com/logs/access.log;
  error_log  /home/sftpuser/example_com/logs/error.log info;

  root /home/sftpuser/example_com/docs/;

  # switch on HSTS
  add_header Strict-Transport-Security "max-age=604800";
  add_header X-Frame-Options           "SAMEORIGIN";

  # enable php
  location ~ ^(.*)\.php$ {
    if (!-f $request_filename) {
      return 404;
    }

    include      /srv/conf/nginx/fastcgi_params;
    fastcgi_pass unix:/var/www/sockets/example_com.socket;

    fastcgi_param TLS_SUCCESS $ssl_client_verify;
    fastcgi_param TLS_DN      $ssl_client_s_dn;
    fastcgi_param TLS_CERT    $ssl_client_cert;
  }

  #deactivate later on
  #autoindex on;
}

Im ersten Schritt benötigt der Server ein TLS-Server-Zertifikat, welches von einem vertrauenswürdigen Zertifikatsersteller stammen sollte. Anschließend muss Nginx die CA bekannt gemacht werden, die die Client-Zertifikate ausstellt - dabei handelt es sich um die gerade erst erstellte, eigene CA. Zudem muss über "ssl_verify_client" die TLS-Client-Authentication aktiviert werden. Hier gibt es die Möglichkeit, sie per "on" verpflichtend für alle Nutzer zu aktivieren oder aber per "optional" die Client-Authentication optional machen. Ist sie verpflichtend, dann werden alle fehlerhaften Anfragen abgewiesen.

Damit nun das Backend PHP-FPM weiß, dass sich ein Client per TLS-Client-Authentisierung eingeloggt hat und vor allem, welcher Nutzer das war, müssen wir noch ein paar CGI-Parameter bereitstellen. Diese stehen den eigentlichen PHP-Scripten dann über die Variable "$_SERVER[]" zur Verfügung. (Wie Nginx zusammen mit PHP-FPM aufgesetzt werden können, kann in einem früheren Blogartikel nachgelesen werden.)

Nach dieser Fingerübung muss Nginx neu gestartet werden.

1
/etc/init.d/nginx restart

Nun kann bereits das erste Mal getestet werden, ob die Grundkonfiguration stimmt. Man sollte entsprechend (je nach Browser und System) soweit kommen, dass die Authentisierung funktioniert.

Safari will auf das Schlüsselpaar zugreifen

Safari will auf das Schlüsselpaar zugreifen

Wenn das funktioniert, könnt ihr euch eine Testseite bauen. In "/home/sftpuser/example_com/docs/index.php" könnte z.B. folgendes stehen, womit einfach nur die CGI-Parameter ausgegeben werden:

1
2
3
4
5
<?php
  print("TLS_SUCCESS: " . $_SERVER["TLS_SUCCESS"] . "<br/>\n");
  print("TLS_DN: " . $_SERVER["TLS_DN"] . "<br/>\n");
  print("TLS_CERT: " . $_SERVER["TLS_CERT"] . "<br/>\n");
?>

Sollte auch das funktionieren, seid ihr bereits fertig mit dem Einrichten und Testen der TLS-Client-Authentisierung in Nginx und PHP-FPM.

PHP-Seite zeigt Daten der TLS-Client-Authentisierung

PHP-Seite zeigt Daten der TLS-Client-Authentisierung

Mit diesem Setup kann man nun einige tolle Dinge anstellen: Zum Beispiel kann man nun sämtliche Nutzerpasswörter bei kritischen Applikationen durch TLS-Zertifikate ersetzen oder aber eine Zwei-Faktor-Authentisierung mit Hilfe dieser Zertifikate realisieren. Genauso kann man auf diese Art und Weise einen Single-Sign-On realisieren. Die Nutzer der einzelnen Anwendungen würden jeweils über "TLS_DN" identifiziert werden und bräuchten praktischerweise nur ein Zertifikat für alle Anwendungen. Wichtig dafür wäre nur, dass alle Anwendungen der gleichen Root-CA vertrauen - der Rest erledigt sich dann von selbst.

Authentisierte Grüße, /CN=Kenny

iOS 8, Mac OS X Yosemite, Swift und anderer Kram

Am Montag war es soweit und Apple hat auf der WWDC 2014 (World-Wide Developer Conference) die Zukunft seiner Betriebssysteme und der darunterlegenden Technik gezeigt. Viele hatten auch mit neuer Hardware gerechnet und wurden entsprechend enttäuscht, andere waren von vorne herein davon ausgegangen, dass dieses Mal nur Software gezeigt werden würde. Ich persönlich habe kein Problem damit, dass keine neue Hardware gezeigt wurde - ich tue mich jedoch teilweise schwer mit den Fortschritten, die gezeigt wurden.

Fangen wir bei dem Positiven an: Continuity. Apple wird seine beiden Systeme iOS und Mac OS X stärker miteinander integrieren. So soll es möglich sein, Arbeiten auf dem einen System zu beginnen und nahtlos auf das andere System zu wechseln, um dort die Arbeit zu beenden - zum Beispiel das Schreiben von E-Mails oder das Browsen im Web. Auch soll es möglich sein, Telefonate via Mac OS X anzunehmen, zu führen und auch zu initiieren. Was bisher nicht bekannt ist, ist, ob das ganze nur für Anwendungen von Apple funktionieren wird oder ob auch Drittanbieter die Funktion nutzen können. Auch ist noch nicht bekannt, wie das ganze funktionieren wird. Man hofft, dass es, wie AirDrop und AirPlay auf das lokale Netzwerk begrenzt sein wird und keine Daten über die iCloud geschleust werden.

Es wurde auch beworben, dass AirDrop nun zwischen iOS und Mac OS X funktioniert, doch ehrlich gesagt halte ich eher das bisherige Fehlen dieser Integration für einen Bug. Das ganze als Feature zu bezeichnen, halte ich für übertrieben. Das war es dann - in meinen Augen - aber auch schon mit den großen positiven Neuerungen. Wenden wir uns also den negativen Dingen zu.

Da wäre als erstes das neue, flache Design von Mac OS X. Ich denke, es ist nichts schlechtes daran, dass Apple hier dem Trend seines Mobilsystems folgt. Ich halte jedoch die Umsetzung für Apple-unwürdig. Es wurde zum Beispiel damit geworben, dass es nun ein einheitlicheres Fensterdesign gäbe. Dieser Meinung bin ich überhaupt nicht. Um Platz zu sparen, wird nun die Titelleiste der Fenster mit Buttons und Eingabefeldern zugemüllt - individuell je Anwendung. Zudem kommen - wie auch schon bei iOS - nun semi-transparente Oberflächen zum Einsatz. Leider konnte man sich offenbar nicht darauf einigen, wann welcher Bereich einer App transparent sein darf. Deshalb hat jede Anwendung andere Bereiche, in denen sie durchscheinend ist. Konsistenz ist in meinen Augen etwas anderes.

In der Notification Area beider Systeme halten nun Widgets Einzug. Ich bin gespannt, wie Apple absichern will, dass diese zusätzlichen Informationsblöcke die Akku-Laufzeit nicht unnötig in die Knie zwingen.

Sowohl bei Mac OS X als auch bei iOS wird nun auch Spotlight stark überarbeitet. Bereits bei der Sucheingabe sollen auch Ergebnisse aus dem Internet (z.B. Wikipedia und Suchmaschine) herangezogen werden. Mit anderen Worten: Tastenanschläge in Spotlight werden - nach dem Willen von Apple - nun auch direkt bei Drittunternehmen landen, sollte man diese Funktion nicht ausschalten können.

Und auch Apple möchte gern noch mehr Daten von seinen Nutzern erhalten. So möchte man die Fotogalerie gern komplett über die iCloud laufen lassen. Auch sollen zukünftig E-Mail-Anhänge, die "zu groß für den Versand" sind, in der iCloud abgelegt und dort vom E-Mail-Empfänger abgerufen werden. Ich für meinen Fall haben in den letzten Tagen jedenfalls erstmal wieder ausprobiert, iCloud komplett zu deaktivieren - vorsorglich.

Die architekturell größten Einschnitte wird es hingegen bei iOS geben. Apple tut nun relativ viel dafür, dass Apps von Drittanbietern sich tiefer ins System eingraben können. So soll nun Inter-App-Kommunikation stärker unterstützt werden. Fremd-Apps sollen sich z.B. in systemseitige Auswahl-Menüs einklinken können. Auch das Ersetzen der On-Screen-Tastatur soll zukünftig möglich sein. Und es soll Entwicklern nun möglich sein, näher an die Hardware heran zu kommen, um deren Performance besser ausreizen zu können. Alle diese Änderungen klingen für mich danach, dass man bewusst Sicherheitsschichten im System durchlöchert, um näher an Android heranzukommen. Es wird sich zeigen müssen, ob sie sich damit nicht Probleme einhandeln, die sie lieber von ihrer Plattform ferngehalten hätten.

Die wahrscheinlich größte Überraschung war jedoch die Einführung von Swift - einer neuen Programmiersprache, die zukünftig bevorzugt für die Entwicklung von iOS-Apps und Mac OS X Anwendungen genutzt werden soll. Es wurde direkt ein kostenloses Handbuch angeboten, in dem die Sprache beschrieben ist. Ich habe es mir nicht nehmen lassen, mir einmal die ersten Kapitel anzusehen - bin jedoch gelinde gesagt enttäuscht. Man hat eine riesige Nutzerbasis, sodass sich die Sprache durchsetzen wird - man hat die Chance jedoch nicht genutzt, eine wirklich gut gestaltete Sprache einzuführen, sondern hat sich offenbar mit einem inkonsistenten Schnellschuss zufrieden gegeben.

So werden beispielsweise Variablen mit dem Wort "var" eingeleitet, Konstanten hingegen mit dem Wort "let". Während "var" eine Abkürzung des passendes Substantivs "Variable" ist, handelt es sich bei "let" um ein Verb, aus dem sich die Zuordnung zu "Constants" nicht ableiten lässt.

Ein anderes Beispiel sind Optionals: Apple hat erkannt, dass es praktisch ist, Variablen neben ihrem eigenen Wertebereich optional auch einen "leeren" Wert zuweisen zu können, der z.B. aussagt, dass eine Berechnung in einem bestimmten Zahlenbereich nicht erfolgreich war. Um zu prüfen, ob eine Variable diesen leeren Wert beinhaltet, muss eine if-Abfrage genutzt werden:

1
if (optionalVariable) {}

Auf die gleiche Weise wird jedoch auch abgefragt, ob eine Boolean-Variable den Wert "true" enthält:

1
if (boolVariable) {}

Trotzdem behauptet man, total typensicher zu sein, weshalb man es verbietet, Integer-Werte in einfachen if-Statements auf ihren Zustand zu prüfen:

1
2
3
if (intVariable) {} // wirft einen Compiler-Error

if (intVariable != 0) {} // funktioniert

Wer gern auf Inkonsistenz- und WTF-Jagd gehen will, kann sich gern das Manual zu dieser Sprache ansehen.

Was mich an Swift jedoch am meisten aufregt: Apple wirbt mit der höheren Geschwindigkeit dieser Sprache gegenüber Objective-C und Python. Geschwindigkeit. Der Sprache. Dass die Geschwindigkeit von den Libraries, APIs und der Implementierung des Compilers abhängt, aber ganz sicher nicht von der formalen Sprache, sollte eigentlich jedem bei Apple einleuchten, der etwas mit Programmierung zu tun hat. Trotzdem wird dieser Schwachsinn verbreitet.

Und um den ganzen die Krone aufzusetzen: Es gibt bereits eine Programmiersprache namens Swift - die Paper zu dieser Sprache reichen zurück bis ins Jahre 2007. Well done, Apple!

Facepalm, Kenny m(

OpenSSH mit Two-Factor-Authentication absichern

Vor einiger Zeit hatte ich einmal einen Artikel zur Absicherung von OpenSSH veröffentlicht. Jeder hat da ja so seine eigene Philosophie. Während die einen auf Authentisierung via Schlüsseldateien schwören, setzen andere zusätzliche Maßnahmen wie Port-Knocking oder vorgeschaltete VPNs ein, um den kostbaren Systemzugang abzusichern.

Ich bin da hingegen von der einfachen Sorte. Die Gefahr, den privaten Schlüssel für den Login zu verlieren oder in einer dringenden Situation nicht verfügbar zu haben, ist mir persönlich zu hoch - trotz entsprechender Vorkehrungen. Deshalb habe ich mich bisher auf meine starken Passwörter verlassen. Doch warum nicht ein wenig Sicherheit einführen, wenn es einfach und sinnvoll ist?

Das dachte ich mir zumindest, als ich hörte, dass es zum Google Authenticator auch ein passendes PAM gibt. PAM steht hierbei für Pluggable Authentication Modules, die es unter Linux ermöglichen, eigene Authentisierungsmechanismen für den Systemlogin einzubinden. Also machte ich mich an die Arbeit und kümmerte mich um die Installation. Dabei hatte ich das Ziel, als Systembetreiber entscheiden zu können, welche Nutzer die Zwei-Faktor-Authentisierung nutzen müssen. Die einzelnen Schritte sind ziemlich einfach. So ziemlich jeder Linux-Admin sollte in der Lage sein, sie nachzuverfolgen.

Als erstes sollte man natürlich die Google Authenticator App aus dem App-Store seiner Wahl laden - zum Beispiel aus dem Google Play Store oder dem Apple iTunes Store. Sollte man weder Android-Smartphone noch iPhone besitzen, muss man die Hoffnung trotzdem nicht gleich aufgeben. Die ganze Codegenerierung basiert auf dem RFC-6238, in dem der relativ simple Time-based One-Time Password Algorithmus (TOTP) beschrieben ist.

Als nächstes sollte man sein System vorbereiten. Die Installation der folgenden Bibliothek ist zwar nicht zwingend erforderlich, sie vereinfacht jedoch die Nutzung, da man seinen geheimen Schlüssel später nicht abtippen braucht, sondern einfach einen QR-Code abscannen kann:

1
sudo apt-get install libqrencode3

Als nächstes ladet ihr das Google-Authenticator Modul herunter und installiert es:

1
2
3
4
5
cd ~

wget http://ftp.us.debian.org/debian/pool/main/g/google-authenticator/libpam-google-authenticator_20130529-2_amd64.deb

sudo dpkg -i ./libpam-google-authenticator_20130529-2_amd64.deb

Da ich möchte, dass sich nur eine bestimmte Gruppe von Nutzern per Zwei-Faktor-Authentisierung einloggen muss, lege ich mir vorher noch die entsprechende Gruppe "google-auth" im System an:

1
sudo groupadd google-auth

Nun solltet ihr OpenSSH mitteilen, dass die Zwei-Faktor-Authentisierung genutzt werden soll. Dazu öffnet ihr die Datei "/etc/ssh/sshd_conf" und tragt dort folgende Zeile ein:

1
ChallengeResponseAuthentication yes

Anschließend müsst ihr dem System noch mitteilen, dass das entsprechende PAM genutzt werden soll. Dazu öffnet ihr die Datei "/etc/pam.d/sshd" und tragt dort folgendes mit ein (ich habe es unter die restlichen "auth"-Einträge geschrieben):

1
2
auth [success=1 default=ignore] pam_succeed_if.so user notingroup google-auth
auth required pam_google_authenticator.so

Die erste der beiden Zeilen prüft, ob der Nutzer, der sich gerade einloggen möchte, in der Gruppe "google-auth" befindet. Ist das der Fall, so wird der nächste "auth"-Eintrag berücksichtigt. Befindet er sich hingegen nicht in der Gruppe, so sorgt "success=1" dafür, dass der nächst folgende "auth"-Eintrag einfach ignoriert wird.

Jetzt müsst ihr nur noch OpenSSH neu starten. Bleibt danach jedoch am besten noch eingeloggt. Sollte bis hier hin etwas schief gelaufen sein, wäre es schlecht, wenn ihr euch den SSH-Zugang versperrt. So könnt ihr im Problemfall die bisherigen Änderungen rückgängig machen:

1
sudo /etc/init.d/ssh restart

Öffnet am besten einen neuen Terminal und versucht, ob ihr euch immernoch normal per SSH einloggen könnt. Klappt das? Sehr gut! Dann könnt ihr mit den folgenden Schritten weitermachen. :)

Bittet die Nutzer, die die Zwei-Faktor-Authentisierung nutzen sollen, sich einzuloggen und folgenden Befehl auszuführen:

1
google-authenticator

Nach dem Ausführen des Befehls wird ein riesiger QR-Code angezeigt, den ihr mit der Google Authenticator App abscannen könnt. Alternativ könnt ihr händisch den "secret key" in die App eintippen. Ihr solltet euch zudem unbedingt die "emergency scratch codes" an einem sicheren Ort notieren. Das sind Einmal-Zugangscodes, die ihr verwenden könnt, falls ihr eure Google Authenticator App verloren haben solltet.

Euch werden zudem ein paar Fragen gestellt, die die Sicherheit des Verfahrens betreffen. Folgendermaßen würde ich an dieser Stelle antworten:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Do you want me to update your "~/.google_authenticator" file (y/n) y

Do you want to disallow multiple uses of the same authentication
token? This restricts you to one login about every 30s, but it increases
your chances to notice or even prevent man-in-the-middle attacks (y/n) y

By default, tokens are good for 30 seconds and in order to compensate for
possible time-skew between the client and the server, we allow an extra
token before and after the current time. If you experience problems with poor
time synchronization, you can increase the window from its default
size of 1:30min to about 4min. Do you want to do so (y/n) n

If the computer that you are logging into isn't hardened against brute-force
login attempts, you can enable rate-limiting for the authentication module.
By default, this limits attackers to no more than 3 login attempts every 30s.
Do you want to enable rate-limiting (y/n) y

Damit habt ihr es fasst geschafft. Der letzte Schritt ist es, den Nutzer, der die Zwei-Faktor-Authentisierung nutzen soll, in die Gruppe "google-auth" aufzunehmen - dabei muss "<username>" durch den Namen des Nutzers ersetzt werden:

1
sudo usermod -a -G google-auth <username>

Nun könnt ihr in einem neuen Terminal versuchen, euch mit dem jeweiligen Nutzer einzuloggen. Sollte auch das immernoch funktionieren, seid ihr fertig! Ihr habt erfolgreich eine Zwei-Faktor-Authentisierung in OpenSSH eingerichtet und diese für einen eurer Nutzer aktiviert. :)

Zweifache Grüße, Kenny

MacBook Air – Das Abenteuer geht weiter

Vor knapp drei Jahren habe ich den Schritt gewagt und bin von Windows XP zu Mac OS X migriert. Damals hatte ich mir ein gebrauchtes, vier Jahre altes MacBook White bei Ebay ersteigert. Letztes Jahr begann ich dann, mir zu überlegen, welches Notebook ich mir als nächstes holen sollte. Grund für die Überlegung war, dass mein MacBook White kein Update mehr auf Mountain Lion erhalten hatte. Trotzdem bekam es weiter Updates und auch jetzt nach dem Erscheinen von Mac OS X Mavericks erhalte ich noch Security Patches.

Unabhängig davon wurde mir vor kurzem ein gebrauchtes MacBook Air angeboten - zwei Jahre alt, elf Zoll klein, mit 8GB RAM und einer 128GB SSD zu einem echt guten Preis. Ich konnte nicht widerstehen, trotz der amerikanischen Tastatur. :D

MacBook Air IMG_8676
IMG_8677 IMG_8679

MacBook Air

Ich bin mit den bisherigen Erfahrungen jedenfalls sehr zufrieden. Das Gerät ist dank des Aluminium-Gehäuses äußerst stabil und fühlt sich sehr hochwertig an. Die SSD gibt einem zudem das sichere Gefühl, dass man das Gerät auch einmal grober anfassen kann. Auf der hintergrundbeleuchteten Tastatur lässt sich sehr gut schreiben - die Finger fliegen nur so über die Tasten. So langsam gewöhne ich mich auch an die neue Position der Sondertasten. Alles in allem bin ich sehr froh, dass ich mich zu dem Kauf entschlossen habe. :)

Der ein oder andere hat mich gefragt, was ich an einem MacBook denn so toll finde, dass ich den wesentlich höheren Preis für gerechtfertigt halte. Vor drei Jahren, als ich mir mein erstes MacBook kaufte, ging es mir ja primär darum, es einfach mal auszuprobieren, da ich schon so viel Gutes gehört hatte. Dieses Mal hingegen war es eine Faktenentscheidung. Ich habe Mac OS X in den letzten Jahren als sehr zuverlässiges System wahrgenommen, das dank seines unixoiden Unterbaus viele Möglichkeiten und Tools bietet, die ich so von einem Linux oder Windows nicht erwarten kann.

Bei Windows fehlen mir die vielen kleinen Abkürzungen, die man über die Shell nutzen kann - etwas, das einem das Gefühl gibt, mehr Kontrolle über das System zu haben. Wenn man bei Windows die Kommandozeile bemüht, wird man an allen Ecken und Enden ausgebremst. Das letzte Mal, dass Microsoft-Systeme über die Kommandozeile bedient werden sollten, war zu DOS-Zeiten - und genau in diesem Entwicklungsstatus befindet sich die Windows-Shell auch heute noch. Alles, was über simples Programme-mit-einem-Parameter-aufrufen hinausgeht, ist dort eine echte Qual.

Bei Linux hingegen hat man zwar eine tolle Shell, es fehlt jedoch das funktionierende System darüber. Ich will mir einfach keine Gedanken darüber machen müssen, warum meine Soundkarte nicht funktioniert, warum mein Touchpad rumspinnt, warum das USB-Stick-Symbol auf dem Desktop nicht verschwindet oder warum die Grafik bei Spielen so ruckelt. (Das ist auch der Grund, warum ich Linux bisher ausschließlich für Server empfehlen würde - denn dort arbeitet man eh nur auf der Shell.)

Apple kann einem einfach eine ordentlich auf einander abgestimmte Hardware- und Software-Kombination bieten - mit dem besten aus den Gebieten Usability und Funktionsumfang. Ich könnte mir ein ähnliches Nutzererlebnis vorstellen, wenn z.B. Canonical mit einem Computerhersteller zusammenarbeiten würde, um ein direkt auf einander abgestimmtes Produkt auf den Markt zu bringen. Das wird jedoch so schnell nicht geschehen.

Natürlich wird das bisher genutzte MacBook White nun nicht einfach verstauben. Mit seinem 2,1GHz DualCore-Prozessor, seinen 4GB RAM und seiner 500GB HDD ist es einfach noch viel zu gut. Es wird daher mein neuer Testserver zuhause werden, auf dem neue Webprojekte testweise installiert werden. Dafür verwende ich bisher ein inzwischen 12 Jahre altes IBM Thinkpad T23, das mit seinem 1,2GHz SingleCore-Prozessor und seinem 1GB RAM einfach nicht mehr auf der Höhe der Zeit ist. :D

Auf die nächsten spannenden Jahre im Appleversum. :)

Luftige Grüße, Kenny

Seite 1 von 78123...Letzte »