IOException.de

Icon

Ausgewählter Nerdkram von Informatikstudenten der Uni Ulm

Today I learned: vi-mode in der shell UND in fast allen Kommandozeilen-Tools

Ich bin ein großer Fan des Text-Editors vi. Wenn auch nicht ganz einfach zu erlernen, ermöglicht er es einem – sobald man sich ein wenig damit auskennt – sehr effizient Texte zu editieren. Die meisten Shells bieten die Möglichkeit eines vi-mode (mit dem Befehl set -o vi). In diesem Modus lässt sich die Kommandozeile mit vi-Tasten bedienen, was das arbeiten damit nochmals deutlich effizienter macht. Mein Problem bisher lag darin, dass der vi-mode nicht funktioniert hat, sobald ich ein anderes interaktives Kommandozeilen-Tool in der Shell öffnete (z.B. sftp). Neulich kam jedoch ein Freund zu mir und sagte: “Doch! Das geht!”
Hier ist die Lösung. Man legt eine Datei ~/.inputrc mit folgendem Inhalt an:
set keymap vi
set editing-mode vi

…und schon funktionieren die vi keybindings in nahezu allen Kommandozeilen-Tools :D

tmux ohne root-Rechte installieren

Ich bin seit langer Zeit begeisteter Nutzer von tmux. Tmux ist ein Terminal Multiplexer (wie auch GNU Screen). Das bedeutet, dass man mit tmux mehrere (oder auch sehr viele oder auch nur eine) Shells in einem einzigen Terminal haben kann, was in sehr sehr vielen Fällen unheimlich praktisch ist. Ich verwende tmux unter anderem für folgende Zwecke:

  • Um mehrere (Kommandozeilen-)Programme gleichzeitig sehen zu können. Früher habe ich dafür einfach das Terminal-Programm mehrfach geöffnet. Das hat auch seine Berechtigung, wenn man z.B. seine Window-Manager-Funktionen nutzen möchte, um zwischen den Terminals zu wechseln. Auf Dauer hat sich hier tmux aber als praktischer herausgestellt. Unter anderem auch wegen des folgenden Punkts:
  • Um Text in der selben Shell oder zwischen verschiedenen Shells kopieren und einfügen zu können (Copy & Paste). Tmux bietet hierfür wunderbare Unterstützung.
  • Um in einer Shell zurück-scrollen zu können. Klar, fast alle Terminal-Programme können das auch. Aber mit tmux kann ich dann auch gleich noch Text kopieren. Und es funktioniert auch in Terminals, die nicht auf einer grafischen Oberfläche laufen.
  • Um meine laufenden Prozesse nicht zu verlieren, wenn aus irgendwelchen Gründen das Terminal geschlossen wird. Wenn ich mich z.B. auf einem Server per SSH anmelde, dann starte ich zuallererst einen tmux. Wenn jetzt die Internetverbindung abbricht, dann läuft der tmux auf dem Server weiter und ich kann mich einfach neu verbinden. Das Gleiche gilt natürlich, wenn man versehentlich sein grafisches Terminal schließt, oder X11 abstürzt.

Das alles sind eher Kleinigkeiten, die sich aber in der täglichen Arbeit als ungeheuer wertvoll herausstellen. Ich wüsste gar nicht mehr, wie ich ohne meinen tmux klar kommen sollte.

Jetzt ist tmux nicht unbedingt auf allen Rechnern, mit denen man so zu tun hat, verfügbar. Die Rechner des Linux-Pools der Uni-Ulm haben zum Beispiel keinen tmux installiert. Da ich aber unbedingt einen haben wollte, habe ich mich entschieden, diesen einfach selber zu kompilieren. Das ist nicht ganz trivial, da tmux einige Abhängigkeiten hat. Während meiner Recherche bin ich dann auf ein Skript gestoßen, welches tmux lokal installiert, sodass man keine root-Rechte benötigt. Vielen Dank an den Autor für diese Hilfe! Ich habe das Skript nicht komplett ausgeführt, sondern einzelne Befehle davon verändert angewandt, da ich einige der Schritte darin schon selbst erledigt hatte. Man kann es also auch wunderbar als Nachschlagewerk verwenden.

Damit war’s das auch für heute.
Bis bald,
Matou

Git als Update-Mechanismus

In diesem Beitrag möchte ich einen einfachen Mechanismus beschreiben, um in einer Client-Server Infrastruktur Updates an die Clients auszuliefern. Ich hatte bei einem Projekt einige Clients in ubiquitären Umgebungen und war dafür auf der Suche nach solch einem System. Die Clients sind einfache Kleincomputer mit einer schlanken Linux-Distribution und müssen ohne technische Wartung auskommen.

Anforderungen an den Update-Mechanismus sind:

  • Authentifizierung
    Die Verbindung zum Update-Server muss authentifiziert sein.
    Das war in den großen Betriebssystemen früher ein großes Problem und ist in vielen Programmen noch immer ein Schwachpunkt. Der Instant Messenger-Exploit Anfang dieses Jahr war etwa ein Beispiel, in dem der Update-Server nicht authentifiziert wurde.
  • Fallbacks
    Falls ein Update schiefgeht sollte es sehr einfach möglich sein den alten Stand wiederherzustellen. Es ist nicht akzeptabel, dass Daten verloren gehen. Alles muss abgespeichert werden.
  • Scripting
    Ich will an jeden Zeitpunkt des Updateprozesses einen Hook setzen können (vor dem Update, danach, etc.). Dies kann später benutzt werden um beispielsweise das Gerät nach dem Einspielen von Neuerungen zu rebooten, um zu überprüfen ob das Update erfolgreich verlaufen ist oder um etwa Datenbankänderungen durchzuführen.
  • Autorisierung
    Der Updateserver darf nicht öffentlich verfügbar sein — Clients müssen sich ihm gegenüber autorisieren um Zugriff auf Updates zu bekommen. Die Option später eine gruppenbasierte License-Policy für verschiedene Softwareversionen nachrüsten zu können soll offengehalten werden.

Ich habe mich letztlich dazu entschieden hierfür git zu verwenden. Die Versionsverwaltung deckt bereits im Vornherein einen großen Teil der Anforderungen ab. Git bot sich an, da ich auch sonst sehr gerne mit dem Tool arbeite und damit also schon umgehen konnte. Der Aufbau meines Systems sieht inzwischen so aus:

 

System-Aufbau

 

Auf der Serverseite

  • Webserver, Zugriff nur über HTTPS möglich, selbstsigniertes X.509 Zertifikat.
  • Ein “bare” git repository, geschützt über HTTP-Authentifizierung: https://updates.foo.net/bar.git.
    Neue Updates werden zu diesem Repository gepusht.
  • hooks/post-update: Wird ausgeführt nachdem neue Updates gepusht wurden.

    # wird von git für HTTP repositories benötigt
    git update-server-info  
    
    # korrekte Zugriffsrechte
    find ~/bar.git -exec chmod o+rx '{}' \;  
    

 

Auf der Client-Seite

  • Cronjob. Überprüft regelmäßig ob neue Updates vorliegen. check.sh enthält:
    #!/bin/sh
    
    # unser Update-Repository
    cd "~/bar.git"
    
    # neue Updates fetchen, git legt diese dann in FETCH_HEAD ab
    git fetch
    
    # liegen im origin-Repository neue Änderungen vor?
    newUpdatesAvailable=`git diff HEAD FETCH_HEAD`
    
    if [ "$newUpdatesAvailable" != "" ]
    then
            # fallback erstellen
            git branch fallbacks
            git checkout fallbacks
    
            git add .
            git add -u
            git commit -m `date "+%Y-%m-%d"`
            echo "fallback created"
    
            git checkout master
            git merge FETCH_HEAD
            echo "merged updates"
    else
            echo "no updates available"
    fi
    
  • Unter hooks/post-merge können Aktionen definiert werden, die nach dem Einspielen der Änderungen ausgeführt werden (Reboot, Validierung des Updateverlaufs, etc.).

Der Client hat eine Kopie des Server-Zertifikats und benutzt dieses um die Verbindung zu authentifizieren. So können die Geräte sicher sein, dass sie zum richtigen Server verbunden sind. Die passende ~/bar.git/.gitconfig sieht in etwa so aus:

[core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
[remote "origin"]
        fetch = +refs/heads/*:refs/remotes/origin/*
        url = https://user@updates.foo.net/bar.git
[http]
        sslVerify = true
        sslCAInfo = ~/server.crt
[core]
        askpass = ~/echo_your_https_authorization_pw.sh

 
Was sind Nachteile dieses Aufbaus?
Ich habe mich bewusst für ein Versionierungssystem entschieden, da meine wichtigste Anforderung ist, dass die Geräte auf keinen Fall Daten verlieren. Dies ist gleichzeitig auch ein Nachteil des Systems, da letztlich alles archiviert wird kann dies bei Geräten mit geringem Speicher kritisch sein. Ein ähnliches Problem tritt auf, falls häufig ein großer Teil des Systems geändert werden muss. In diesem Fall würde eine Lösung mittels rsync oder ähnlichen Tools eventuell mehr Sinn machen. rdiff-backup führt etwa inkrementelle Backups durch und bietet dazu noch die Möglichkeit die Anzahl der Versionen die behalten werden zu beschränken.

Do not use SSH.
Ein einfacherer Weg solch ein System aufzubauen wären SSH-Zugänge mit eingeschränkten Dateirechten für die Clients. Das Problem hierbei ist, dass Geräte Zugriff auf den Server bekommen. Ein Angreifer könnte sich mit dem private key des Clients zum Server verbinden. Es ist nicht aussergewöhnlich, dass in Betriebssystem-Kernen oder in System-Bibliotheken Sicherheitslücken entdeckt werden. Im schlimmsten Fall könnte ein Angreifer so die Dateien innerhalb des Repositories manipulieren. Die Clients würden automatischen den manipulierten Inhalten fetchen. Das manipulierter Inhalt ausgeliefert wird, ist auch in meinem Setup nicht ausgeschlossen, dazu muss der Angreifer aber über einen Zugang zu dem Server verfügen.

Ubuntu: Ohne Cisco Client ins VPN der Uni Ulm

Mit dem VPN verbunden

Mit dem VPN verbunden

Entgegen der Aussage von verantwortlichen Personen am Rechenzentrum der Universität Ulm ist es auch ohne Cisco-VPN Client möglich ins Universitäts-VPN zu gelangen – und das mit etwas Vorarbeit  recht komfortabel. In der folgenden Anleitung zeigen wir Dir Schritt für Schritt, wie Du das mit der aktuellen Ubuntu Version 9.10 komfortabel einrichtest.

Einleitung

Ziel dieses Projekts ist es, dass wir nutzerfreundlich und GUI-orientiert über den Gnome-Networkmanager ins Netz der Universität Ulm kommen, egal ob wir schon im WLAN vor Ort sind oder gerade Zuhause sitzen und mal wieder nicht an Dateien kommen, die nur über das Uninetz erreichbar sind.
Befinden wir uns gerade schon in der Universität, haben wir hiermit den Vorteil, auf die KIZ-Anmeldemaske beim Verbinden verzichten zu können. Zudem ist unser gesamter WLAN-Traffic auch gleich noch verschlüsselt.

Installation

Wir befinden uns in unserem Homeverzeichnis und erstellen uns ein temporäres Verzeichnis vpnc. Da die Anmeldung am VPN der Uni Ulm mittels hybrider Authentifizierung funktioniert, müssen wir selbst etwas am Quellcode modifizieren. Zuerst holen wir uns also den Quellcode und lösen eventuelle Abhängigkeiten auf.

cd vpnc
apt-get source vpnc
sudo apt-get build-dep vpnc

Möglicherweise werden wir darauf hingewiesen das Paket dpkg-dev zu installieren. Zusätzlich benötigen wir noch dieses Paket:

sudo apt-get install libssl-dev

Wir wechseln nun in das Verzeichnis ~/vpnc/vpnc-0.5.3 und öffnen die Makefile mit einem Editor unserer Wahl und entfernen die Raute vor diesen Zeilen und speichern die Datei.

#OPENSSL_GPL_VIOLATION = -DOPENSSL_GPL_VIOLATION
#OPENSSLLIBS = -lcrypto

VPN konfigurieren im Network-Manager-Applet

VPN konfigurieren im Network-Manager-Applet

Jetzt noch ins Unterverzeichnis debian wechseln um die Datei changelog zu modifizieren. Damit wir unser frisch modifiziertes Werk bequem über den Paketmanager verwalten können müssen wir einen neuen Eintrag in diese Datei oben einfügen, am besten mit einer hohen Nummer. In unserem Fall sieht das so aus:
vpnc (ioexeption-ssl-2010.0.5.3-1-2010) unstable; urgency=low

* added ssl support for hybrid authentication on private network
-- Achim Strauss Mon, 15 Dec 2010 17:52:20 -0800


und dann das ganze Speichern.

Ein jungfräuliches Ubuntu hat vor dem nächsten Schritt gerne noch diese Pakete installiert

sudo apt-get install debhelper libgcrypt11-dev dpatch

Jetzt sind wir bereit das ganze aus dem Verzeichnis vpnc-0.5.3 heraus mit folgendem Befehl zu kompilieren:

fakeroot dpkg-buildpackage -b -uc

Am Ende des Prozesses sollte in ~/vpnc ein komfortabel zu installierendes Debian-Package mit Namen ioexeption-ssl-2010.0.5.3-1-2010_i386.deb stehen. Installiere dieses Paket und teste die erfolgreiche Installation mittels

vpnc --version

Die korrekte Installation erkennst du an der Ausgabe von

Built with openssl (certificate) support. Be aware of the license implications.

Prinzipiell sind wir nun bereit uns mit einem VPN zu verbinden, es fehlt aber noch an einem Plugin für den Networkmanager. Dieses bekommen wir, indem wir das folgende Repository zu unserer /etc/apt/sources.list hinzufügen.

deb http://ppa.launchpad.net/sroecker/ppa/ubuntu karmic main

Danach einfach noch diese Schritte ausführen:

sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 588AC16B
sudo apt-get update
sudo apt-get install network-manager-vpnc

Der erste Befehl sagt aus, dass wir dem oben genannten Repository in Zukunft vertrauen wollen. Dieser Schritt ist nicht zwingend notwendig, schützt uns aber vor zukünftigen Warnmeldungen. Die beiden anderen Schritte sind jedoch essentiell für die Installation des Plugins.

Eingabemaske für Einstellungen des VPN

Eingabemaske für Einstellungen des VPN

Konfiguration

Nun richten wir uns noch ein verstecktes Verzeichnis in unserem Homeverzeichnis ein ~/.vpnc . Hierein speichern wir das KIZ Zertifikat, sowie dieses Verbindungsprofil (aus dem Uninetz).

Über das Network-Manager-Applet können wir nun über VPN-Verbindung ->VPN-konfigurieren -> importieren im Verzeichnis ~/.vpnc das heruntergeladene Verbindungsprofil wählen. Die meisten Felder sind durch diese Vorgabe bereits ausgefüllt, der Rest ist wie auf diesem Screenshot mit den eigenen KIZ-Userdaten zu befüllen. Außerdem unter CA-File  die Zertifikatsdatei (KIZ-CA.crt) ebenfalls aus ~/.vpnc wählen.

Nutzung

Ab sofort kannst du dich mit wenigen Klicks über das Network-Manager-Applet → VPN-Verbindungen → <VPN-Name> in das VPN einwählen. Deine Passwörter werden nun auch bequem über den Gnome-Schlüsselbund verwaltet.

Eingerichtetes VPN auswählen

Eingerichtetes VPN auswählen

ioexception.de

Benjamin Erb [] studiert seit 2006 Medieninformatik und interessiert sich insbesondere für Java, Web-Technologien, Ubiquitous Computing, Cloud Computing, verteilte Systeme und Informationsdesign.


Raimar Wagner studiert seit 2005 Informatik mit Anwendungsfach Medizin und interessiert sich für C++ stl, boost & Qt Programmierung, Scientific Visualization, Computer Vision und parallele Rechenkonzepte.


David Langer studiert seit 2006 Medieninformatik und interessiert sich für Web-Entwicklung, jQuery, Business Process Management und Java.


Sebastian Schimmel studiert seit 2006 Informatik mit Anwendungsfach Medizin und interessiert sich für hardwarenahe Aspekte, Robotik, webOs, C/C++ und UNIX/Linux.


Timo Müller studiert seit 2006 Medieninformatik. Er interessiert sich allen voran für Mobile and Ubiquitous Computing, systemnahe Enwticklung und verteilte Systeme, sowie Computer Vision.


Achim Strauß studiert seit 2006 Medieninformatik. Seine Interessen liegen in Themen der Mensch-Computer Interaktion sowie Webentwicklung und UNIX/Linux.


Tobias Schlecht studiert seit 2006 Medieninformatik und interessiert sich vor allem für Software Engineering, Model Driven Architecture, Requirements Engineering, Usability Engineering, Web-Technologien, UML2 und Java.


Fabian Groh studiert seit 2006 Medieninformatik. Seine Interessengebiete sind Computer Graphics, Computer Vision, Computational Photography sowie Ubiquitos Computing.


Matthias Matousek studiert seit 2007 Medieninformatik und interessiert sich besonders für Skriptsprachen, Echtzeitsysteme und Kommunikation.


Michael Müller [] studiert seit 2009 Medieninformatik. Er interessiert sich vor allem für Web-Technologien, Ubiquitous Computing, User-Interfaces, UNIX und Creative Coding.


Falco Nogatz [] studiert seit 2010 Informatik mit Anwendungsfach Mathematik. Er interessiert sich für Web-Technologien, Programmierparadigmen und theoretische Grundlagen.

Archiv

Februar 2015
M D M D F S S
« Mrz    
 1
2345678
9101112131415
16171819202122
232425262728