syslog.warten.de

Schlüssel Für Repository in Secure APT Importieren

Mit Debian 4.0 (Etch) hat Secure APT Einzug in die Paketverwaltung gefunden. Es soll sicherstellen, dass nur vom Herausgeber signierte Debian-Archive installiert werden. Die Repositories enthalten hierfür eine Datei “Release”, die neben Informationen über die Releases selbst auch Prüfsummen der Paketindizes beinhaltet. Die Datei “Release” wird anhand einer GnuPG-Signatur verifiziert.

Für die Hauptrepositories sind die öffentlichen Schlüssel (public keys) bereits hinterlegt. Möchte man weitere Installationsquellen hinzufügen, beklagt die Paketverwaltung, dass der zuständige Schlüssel fehlt.

W: GPG error: http://dl.google.com stable Release: The following signatures couldn’t be verified because the public key is not available: NO_PUBKEY A040830F7FAC5991  
W: You may want to run apt-get update to correct these problems 

Mit den folgenden drei Schritten lässt sich der fehlende Schlüssel importieren:

  1. Der gewünschte Schlüssel kann von Keyservern heruntergeladen werden.

    # gpg –keyserver subkeys.pgp.net –recv-key A040830F7FAC5991  
    gpg: requesting key 7FAC5991 from hkp server subkeys.pgp.net  
    gpg: key 7FAC5991: public key “Google, Inc. Linux Package Signing Key ” imported  
    gpg: no ultimately trusted keys found  
    gpg: Total number processed: 1  
    gpg: imported: 1 
    
  2. Prüfen Sie den Fingerabdruck des neuen Schlüssels.

    # gpg –fingerprint A040830F7FAC5991  
    pub 1024D/7FAC5991 2007-03-08  
        Key fingerprint = 4CCA 1EAF 950C EE4A B839 76DC A040 830F 7FAC 5991  
    uid Google, Inc. Linux Package Signing Key   
    sub 2048g/C07CB649 2007-03-08 
    
  3. Können Sie davon ausgehen, dass es sich um den passenden Schlüssel für das hinzugefügte Repository handelt, exportieren Sie ihn aus Ihrem Schlüsselbund in ASCII-Armor-Form und übergeben ihn an apt-key.

    # gpg –armor –export 7FAC5991 | apt-key add -  
    OK
    

Magic SysRq Keys Benutzen

Wenn ein Linux-System nicht mehr reagiert, ist der Reset-Knopf nur die letzte, aber nicht die einzige Option. Sollte man noch Zugang zum betroffenen System haben, können über das im Linux-Kernel integrierte sysrq-Interface Befehle übergeben werden.

Der Kernel muss mit Unterstützung für sysrq (CONFIG_MAGIC_SYSRQ) übersetzt worden sein. Im /proc-Dateisystem existiert dann der Eintrag sysrq-trigger.

Wenn Sie Zugriff auf die Console des Systems haben, betätigen Sie die Tastenkombination [Alt]-[Druck] ([S-Abf]). Danach können Sie mit einer weiteren Taste den gewünschten Befehl ausführen.
Es folgt eine der Kernel-Dokumentation entnommenen Liste der unterstützten Befehle.

  • ‘r’ – Turns off keyboard raw mode and sets it to XLATE.
  • ‘k’ – Secure Access Key (SAK) Kills all programs on the current virtual console. NOTE: See important comments below in SAK section.
  • ‘b’ – Will immediately reboot the system without syncing or unmounting your disks.
  • ‘c’ – Will perform a kexec reboot in order to take a crashdump.
  • ‘d’ – Shows all locks that are held.
  • ‘o’ – Will shut your system off (if configured and supported).
  • ‘s’ – Will attempt to sync all mounted filesystems.
  • ‘u’ – Will attempt to remount all mounted filesystems read-only.
  • ‘p’ – Will dump the current registers and flags to your console.
  • ‘t’ – Will dump a list of current tasks and their information to your console.
  • ‘m’ – Will dump current memory info to your console.
  • ‘n’ – Used to make RT tasks nice-able.
  • ‘v’ – Dumps Voyager SMP processor info to your console.
  • ‘w’ – Dumps tasks that are in uninterruptable (blocked) state.
  • ‘x’ – Used by xmon interface on ppc/powerpc platforms.
  • ’0′-’9′ – Sets the console log level, controlling which kernel messages will be printed to your console. (’0′, for example would make it so that only emergency messages like PANICs or OOPSes would make it to your console.)
  • ‘f’ – Will call oom_kill to kill a memory hog process.
  • ‘e’ – Send a SIGTERM to all processes, except for init.
  • ‘g’ – Used by kgdb on ppc platforms.
  • ‘i’ – Send a SIGKILL to all processes, except for init.
  • ‘h’ – Will display help (actually any other key than those listed above will display help. but ‘h’ is easy to remember :-)

Beim Zugriff aus der Ferne senden Sie als Benutzer root die Befehle an /proc/sysrq-trigger. Mit echo s > /proc/sysrq-trigger weisen Sie Linux an, seine Puffer auf die Festplatten zurückzuschreiben (“sync”). Wenig später können mit [e] die laufenden Prozesse beendet werden (“SIGTERM”); Prozesse, die diesem Befehl nicht Folge leisten werden mit [i] erledigt (“SIGKILL”). Danach können Sie mit echo u > /proc/sysrq-trigger alle Dateisysteme read-only remounten und mit echo b > /proc/sysrq-trigger einen Reset auslösen.

Wer eine serielle RemoteConsole an einem entfernten Server nutzt, kann mitunter über spezielle Tastenkombinationen Befehle an sysrq zu übergeben. Bei der RemoteConsole von STRATO-Servern ist über die Tastenfolge [~]-[b]-[r]-[e]-[a]-[k] und einer weiteren Taste ein Befehl ausführen.

Damit die sysctl-Schnittstelle nicht mißbraucht wird, gibt es einen Schutzmechanismus: Erst wenn in /proc/sys/kernel/sysrq ein Wert größer als 0 eingetragen ist, reagiert das System überhaupt auf den Tastendruck oder die Ausgaben nach /proc/sysrq-trigger. Gegebenenfalls müssen Sie die Funktion erst mit echo 1 > /proc/sys/kernel/sysrq einschalten.

Fehlersuche Bei CGI-Skripten (Perl)

Kann ein CGI-Skript nicht ausgeführt werden, zeigt der Browser einen Fehler 500 “Internal Server Error” an. Diese Meldung gibt nur an, dass ein Fehler aufgetreten ist. Die Ursache bleibt unbekannt.

Als Erstes sollte geprüft werden, ob die Datei “ausführbar” ist, also die Zugriffsrechte der Datei das eXecutiable-Bit gesetzt haben. Die Zugriffsrechte sollten “-rwxr-xr-x” oder 755 lauten. Die Zugriffsrechte können mit den meisten FTP-Programmen oder über den SSH-Zugang mit dem Kommando chmod 755 /pfad/zur/datei.cgi geändern werden.

Sind die Zugriffsrechte in Ordnung, muss der Skriptcode geprüft werden. Die erste Zeile eines Perl-Skripts muss das Shebang sein. Die Shebang-Zeile enthält den Pfad zum Perl-Interpreter. In vielen Fällen ist das /usr/bin/perl.

Weitere Einschränkungen können durch fehlerhafte Zeichencodierung auftreten. Enthält das Skript Windows-Zeilenumbrüche, kann es nicht ausgeführt werden. In diesem Fall ist die Datei vorher mit Unix-Zeilenumbrüchen zu konvertieren. Eine solche Funktion wird von vielen Texteditoren angeboten.
Einschränkungen können auch auftreten, wenn die Datei per FTP als Binary übertragen wurde. Die Skriptdatei muss im ASCII-Modus übertragen werden.

Damit ein Perl-Skript Ausgaben an den Browser ausliefern kann, muss der Content-type übermittelt werden.

print "Content-type: text/html\n\n";

Diese Zeile sollte möglichst zu Beginn des Skripts, aber auf jeden Fall vor der ersten Ausgabe erfolgen.
Der Content-type kann auch auf anderen Wegen übermittelt werden. Macht das Skript etwa vom Modul CGI Gebrauch, kann der Content-type mit der Funktion header() übergeben werden.

Einfache Beispiele für Perl-CGI-Skripte:

#!/usr/bin/perl  
print “Content-type: text/htmlnn“;  
print “Hello, world!”;



#!/usr/bin/perl  
use CGI;  
my $query = new CGI;  
my $message = “Hello, world!”;  
print $query->header,  
      $query->start_html( -title=>$message ),  
      $query->p( $message ),  
      $query->end_html;

Sind alle diese Bedingungen erfüllt, muss eine fehlerhafte Anweisung im Skript verantwortlich für den “Internal Server Error” sein. Die Einschränkung sollte zu einer Fehlermeldung des Perl-Interpreters führen, die aber leider nicht im Browser angezeigt wird. Dieses Verhalten lässt sich unterdrücken, indem im Skript mit der folgenden Zeile Perl angewiesen wird, Fehlermeldungen an den Browser auszuliefern:

use CGI::Carp qw( fatalsToBrowser );

Hat man SSH-Zugriff kann das Skript direkt auf der Shell ausgeführt werden und die Fehlermeldung wird auch ohne oben genannte Änderung ausgegeben.

Eine Syntax-Prüfung kann auf der Shell mit folgendem Kommando durchgeführt werden:

perl -c /pfad/zum/skript.cgi 

Das folgende Skript demonstriert die Ausgabe einer Fehlermeldung an den Browser. In der letzten Zeile wird Perl angewiesen 1 durch 0 zu teilen. Die Division durch Null ist unzulässig und Perl liefert eine Fehlermeldung:

#!/usr/bin/perl  
use CGI::Carp qw( fatalsToBrowser );  
print “Content-type: text/htmlnn“;  
print “Hello, world!”;  
print “Division durch Null: “ . 1/;

Ohne die zweite Zeile wäre die Ausgabe nur der Fehler 500 “Internal Server Error”.
Anhand der Fehlermeldung sollte es nun möglich sein, den Fehler im Skript zu finden und zu beheben.

Eigene Perl-Module Auf STRATO Webhosting Installieren

Wenn man eigene Perl-Module in STRATO Webhosting-Paketen nutzen möchte, kann man diese selbst installieren.
Das Array @INC enthält die Verzeichnisse, in denen Perl nach Modulen sucht, die über Skripte nachgeladen werden sollen. Das Array enthält auch das Verzeichnis ‘.’, das das aktuelle Verzeichnis repräsentiert.

Dies ermöglicht es dem Benutzer, ausgehend vom Skriptpfad, Module nachzuinstallieren. Die folgende Anleitung beschreibt anhand des CPAN-Moduls CGI::Session die Installation eigener Module.
Wenn man auf der Suche nach einer bestimmten Funktion ist, kann diese vielleicht bei CPAN, einer Suchmaschine für Perl-Module gefunden werden.
Holen und entpacken Sie das Modul CGI::Session.

Üblicherweise befindet sich im Archiv ein Verzeichnis /lib, das Unterverzeichnisse mit den Moduldateien enthält. In diesem Fall liegt in /lib das Verzeichnis CGI.
Der Pfad zum Perl-Modul ergibt sich aus seinem Namen: Das Modul CGI::Session muss im Verzeichnis ./CGI/Session.pm liegen. (Ein Modul Test::Example::Hello müsste unter ./Test/Example/Hello.pm abgelegt werden.) Es ist auf jeden Fall die Großkleinschreiben zu beachten.

Kopieren Sie diese Verzeichnisse in das Verzeichnis /cgi-bin auf Ihrem Webspace. Das Modul ist jetzt installiert und kann nun aus Ihren Skripten heraus aufgerufen werden. Erstellen Sie ein kleines Testskript mit folgendem Inhalt:

#!/usr/bin/perl58  
use CGI::Session;  
$session = new CGI::Session();  
$CGISESSID = $session->id();  
[print][3] $session->header();

Wenn Sie das Skript auf der Shell ausführen, werden Sie sehen, dass ein Cookie erzeugt wurde:

> ./session.cgi  
Set-Cookie: CGISESSID=7d070ddee98d8287ed1827b9e37391c0; path=/  
Date: Tue, 05 Jun 2007 13:08:57 GMT  
Content-Type: text/html; charset=ISO-8859-1 

Das Modul wurde erfolgreich installiert und kann benutzt werden.

Movable Type Auf STRATO Webhosting Installieren

Die folgende Anleitung beschreibt die notwendigen Schritte, um Movable Type auf einem STRATO Webhosting-Paket zu installieren. Für die Installation wird der SSH-Zugang benutzt, der zum Leistungsumfang der Premium-Pakete und des PowerWeb S gehört.

Das Installationsarchiv wird auf dem Webspace abgelegt. Im Beispiel heisst es MT-3.35-en.tar.gz und liegt im Grundverzeichnis. Die Installation erfolgt weitestgehend nach Anleitung des Herstellers: Das Archiv wird in /cgi-bin entpackt, umbenannt und das Verzeichnis mt-static in den Homepagebereich verschoben.

example.com> ls -l ~/MT-3.35-en.tar.gz  
-rw-r–r– 1 123456 customer 2479696 May 22 08:30 MT-3.35-en.tar.gz  
example.com> cd ~/cgi-bin/  
example.com> tar xzf ~/MT-3.35-en.tar.gz  
example.com> mv MT-3.35-en mt  
example.com> cd mt/  
example.com> mv mt-static ~ 

Soll Movable Type auf einer intern umgeleiteten Domain (in einem Unterverzeichnis) installiert werden, sind die Pfade entsprechend anzupassen.

Da STRATO als traditionsbewusster Webhoster unter /usr/bin/perl das 1999 veröffentlichte Perl 5.004_05 zur Verfügung stellt, muss die Shebang-Zeile der CGI-Skripte angepasst werden. Bei STRATO ist eine aktuellere Perl-Version unter /usr/bin/perl58 zu finden.

example.com> bash  
bash-3.00$ for i in *.cgi; do perl -i -pe ‘s#/usr/bin/perl#/usr/bin/perl58#’ $i; done 

Wenn Movable Type in einem PowerWeb-Paket installiert werden soll, muss das Suffix der Skripte geändert werden. In den PowerWeb-Paketen können eigene CGI-Skripte nur mit der Dateiendung .pl ausgeführt werden.

bash-3.00$ for i in *.cgi; do mv “$i” “${i/.cgi}”.pl; done 

Ich empfehle, die Konfigurationsdatei mt-config.cgi nicht selbst zu editieren, sondern vom Installationsskript erstellen zu lassen. Es wird automatisch ausgeführt, wenn Movable Type aufgerufen wird.

http://www.example.com/cgi-bin/mt/mt.cgi

Es wird der static web path URL abgefragt. Im Beispiel ist das http://example.com/mt-static. Im nächsten Schritt ist der Zugang zur Datenbank zu konfigurieren und der letzte Teil der Konfiguration fragt den Pfad zu sendmail ab. Bei STRATO ist es unter /usr/lib/sendmail zu finden.
Damit ist die Installation von Movable Type auf einem STRATO Webhosting-Paket abgeschlossen.

Debian-Pakete Aus Source Packages Bauen

Debian bietet sehr viele Programme fertig kompiliert als binary packages zur einfachen Installation über die distributionseigene Paketverwaltung an. Ist man mit den angebotenen Paketen aus irgend einem Grund nicht zufrieden, kann man sich die Vorteile vom Opensource-Prinzip zu Nutze machen und selbst den Compiler starten.

Wie ein Debian package aus einem source package gebaut wird, beschreibt die folgende Anleitung am Beispiel von FuzzyOCR. (Da FuzzyOCR ein Perl-Skript ist, muss es nicht kompiliert werden. Die Schritte auf dem Weg zum fertigen Paket ändern sich dadurch aber nicht und lassen sich auf Quellcode-Pakete in zu kompilierenden Sprachen übertragen, da der build-Prozess automatisch erfolgt.)

FuzzyOCR ist nicht in der stable Distribution (etch) enthalten. Die Sourcen aus anderen Distributionen (in diesem Fall testing) können gegen stable Pakete kompiliert und somit verfügbar gemacht werden. Um an das Quelltext-Paket zu kommen, muss in diesem Beispiel die sources.list erweitert werden.

# cat /etc/apt/sources.list  
[...]  
deb-src http://ftp.de.debian.org/debian/ testing main contrib non-free 

Um source packages bauen zu können, müssen einige Pakete vorhanden sein. Im Beispiel waren dpkg-dev, fakeroot und debhelper nachzuinstallieren (da mit diesem System noch kein source package kompiliert wurde).

# aptitude install dpkg-dev fakeroot debhelper 

Abhängigkeiten von Paketen, die zum Kompilieren von source packages benötigt werden, lassen sich mit dem Modus build-dep von apt-get auflösen und installieren.

# apt-get build-dep fuzzyocr 

Um den Quelltext zu empfangen, wird der nächste Befehl ausgeführt.

# apt-get source fuzzyocr 

Im aktuellen Verzeichnis finden sich nach dem Download neben dem Originalquellcodearchiv (.orig.tar.gz), Debian-Patches (.diff.gz) und der Paketbeschreibung (.dsc) ein Verzeichnis, das den entpackten und gepatchten Sourcecode enthält.

# ls -l  
total 140  
[...]  
drwxr-xr-x 4 root root  4096 May 19 15:07 fuzzyocr-2.3b  
-rw-r–r– 1 root root  8327 Jan  6 11:02 fuzzyocr_2.3b-2.diff.gz  
-rw-r–r– 1 root root   556 Jan  6 11:02 fuzzyocr_2.3b-2.dsc  
-rw-r–r– 1 root root   849 May 19 15:07 fuzzyocr\_2.3b-2\_i386.changes  
-rw-r–r– 1 root root 76411 Dec  7 12:02 fuzzyocr_2.3b.orig.tar.gz 

In diesem Verzeichnis können bei Bedarf Änderungen am Code oder der Konfiguration vorgenommen werden, bevor mit dem folgenden Kommando das Paket gebaut wird. Sind keine Änderungen vorgesehen, kann das Paket gleich mit apt-get -b source fuzzyocr erstellt werden.

# dpkg-buildpackage -rfakeroot -uc -b 

Bevor FuzzyOCR installiert werden kann, müssen noch Abhängigkeiten aufgelöst werden. Danach kann das neue Paket installiert werden.

# aptitude install gocr netpbm libungif-bin libstring-approx-perl  
# dpkg -i fuzzyocr\_2.3b-2\_all.deb

Ftplicity: Timeout Der FTP-Verbindung

Als Backup-Lösung wird auf einem meiner Server ftplicity (duplicity) eingesetzt. Seit ein paar Wochen kam es beim Erstellen der inkrementellen Backups gelegentlich zu Abbrüchen mit Fehlermeldungen wie der folgenden.

Traceback (most recent call last):
File "/usr/bin/duplicity", line 373, in ?
if __name__ == "__main__": main()
File "/usr/bin/duplicity", line 367, in main
else: incremental_backup(sig_chain)
File "/usr/bin/duplicity", line 170, in incremental_backup
bytes_written = write_multivol("inc", tarblock_iter, globals.backend)
File "/usr/bin/duplicity", line 89, in write_multivol
backend.put(tdp, dest_filename)
File "/usr/lib/python2.4/site-packages/duplicity/backends.py", line 349, in put
self.error_wrap('storbinary', "STOR " remote_filename, source_file)
File "/usr/lib/python2.4/site-packages/duplicity/backends.py", line 335, in error_wrap
except ftplib.all_errors, e: raise BackendException(e)
duplicity.backends.BackendException

Um eine Ursache für die Fehlermeldung zu finden, erstellte ich mit tcpdump einen Mitschnitt des Netzverkehrs zum Backupservers. Die Analyse ergab, dass die FTP-Verbindung getrennt wird, weil duplicity keine Daten mehr sendet. Nach einer Pause von fünf Minuten bricht der Server die Verbindung ab (timeout) und wenn der Client danach versucht, den Rest des Backups zu übertragen, kommt es zu oben genannter Fehlermeldung.

Eine Ursache für die eingelegte Pause von duplicity habe ich bisher nicht finden können. Bei meiner Suche stiess ich jedoch auf einen Patch, der duplicity um die Funktion erweitert, eine abgebrochene FTP-Verbindung wiederherzustellen. Damit läuft das Backup, mit Pausen, aber ohne Fehler, wieder durch.

Aufnehmen Einer Terminal-Session

Mit dem Programm script kann man ein Protokoll einer Terminal-Sitzung anfertigen, um beispielsweise einen Installationsprozess zu dokumentieren. Um die Protokollierung zu starten, wird das Programm wie folgt aufgerufen:

$ script -t 2>~/term-session.time -a ~/term-session.script 

Die Option -t gibt den zeitlichen Ablauf auf STDERR aus, das hier in eine Datei umgeleitet wird, und -a schreibt das Typescript in eine Datei. Beendet wird die Aufnahme mit CTRL-D oder indem auf der Eingabeaufforderung exit eingegeben wird.

Eine Wiedergabe des Scripts ist mit less -R möglich. Falls die Option -t von script benutzt wurde, kann das Programm scriptreplay verwendet werden, um die gesamte Sitzung wieder anzeigen zu lassen:

$ scriptreplay ~/term-session.time ~/term-session.script 

Mit script lässt sich einfach eine Mitlesegelegenheit für einen zweiten Benutzer einrichten. Führt der erste Benutzer den Befehl `mkfifo /tmp/terminal-session; script -f /tmp/terminal-session` aus, kann der zweite Benutzer mit `cat /tmp/terminal-session` die Terminal-Sitzung des ersten Benutzers überwachen.

Eine E-Mail Mit Telnet Und SMTP AUTH Relayen

Für das folgende Beispiel wird davon ausgegangen, dass der Mailserver PLAIN als Authentifizierungsmechanismus anbietet. Für SMTP AUTH müssen die Zugangsdaten als base64-kodierter String übergeben werden. Die Übersetzung generiert ein Perl-Einzeiler, wobei hier im Beispiel “username” als Benutzername und “password” als Passwort angegeben werden:

$ perl -MMIME::Base64 -e ‘print encode_base64(“usernameusernamepassword”);’  
dXNlcm5hbWUAdXNlcm5hbWUAcGFzc3dvcmQ= 

Mit dem ausgegebenen String kann nun die Authentifizierung durchgeführt werden.

$ telnet mail.example.com 25  
220 mail.example.com ESMTP Postfix  
EHLO client.example.com  
250-mail.example.com  
250-PIPELINING  
250-SIZE 10240000  
250-VRFY  
250-ETRN  
250-STARTTLS  
250-AUTH LOGIN PLAIN DIGEST-MD5 CRAM-MD5  
250 8BITMIME  
AUTH PLAIN dXNlcm5hbWUAdXNlcm5hbWUAcGFzc3dvcmQ=  
235 Authentication successful  
MAIL FROM:  
250 Ok  
RCPT TO:  
250 Ok  
DATA  
354 End data with .  
Some text  
.  
250 Ok: queued as 123456789A  
QUIT  
221 Bye

Hello, World!

Eine alte, ungeschriebene Regel besagt, dass jede Schrift über eine Programmiersprache mit dem “Hello, world!”-Programm beginnen muß. Es wird in diesem Blog nicht allein um eine Programmiersprache gehen, sondern um viele Themenbereiche der Informatik und die praktische Anwendung von Unix-artigen Betriebssystemen. Trotzdem möchte ich es der eingangs beschriebenen Tradition folgend beginnen (mit einer Variante in Java):

class HelloWorld {
    public static void main( String[] args ) {
        System.out.println( "Hello, world!" );
    }
}