Anleitungen

In diesem Bereich finden sich kurze Anleitungen (Howtos) mit Lösungsvorschlägen zu speziellen Hardware- und Software-Problemen, die mir selbst widerfahren sind.

Oft ist die Behebung eines solchen Problems relativ einfach, man muss nur darauf kommen. Für den Fall, dass auch eine umfangreiche Internetrecherche für mich kein befriedigendes Ergebnis lieferte oder nur Teilschritte, die man erst – womöglich in der richtigen Reihenfolge und ergänzt durch eigene Ansätze – zusammensetzen muss, stelle ich hier einige selbst angewandte Lösungen vor, die bei mir zum Erfolg geführt haben.

Eine Gewährleistung für eine allgemeine Anwendbarkeit gibt es natürlich nicht.

Bereich:

Webserver im Sandkasten

Es gibt verschiedene Techniken, um Sandbox-Umgebungen herzustellen. Hier verwenden wir die Firejail Security Sandbox, die es ermöglicht, einem Dienst und allen zugehörigen Prozessen Betriebsmittel wie Netzwerkzugriff, Prozesstabelle oder Dateisystem in einem privaten, abgeschotteten Bereich zuzuteilen. Der Dienst sieht damit nur seine eigenen Prozesse und kann nur auf den Teil des Dateisystems zugreifen, der ihm zugeordnet wird.

Eine sehr hilfreiche Quelle für diese Anleitung war der Artikel How To Use Firejail to Set Up a WordPress Installation in a Jailed Environment, der eine WordPress-Installation mit Firejail, Nginx und MySQL beschreibt. Im Unterschied dazu beschränken wir uns hier auf die Installation der Grunddienste Web- und Datenbankserver, und zwar speziell Apache und PostgreSQL; darauf kann der geneigte Leser dann beliebige Content-Management-Systeme (wie Drupal oder eben auch WordPress) oder ganz andere Dienste wie gewohnt aufsetzen. Ein weiterer Unterschied ist, dass alle Skripte eine gegebene Ziel-IP-Adresse verarbeiten, d. h., auf der Maschine können unabhängig von den hier beschriebenen noch andere Dienste laufen, die auf sonstige IP-Adressen reagieren.

Wir werden die Dienste so einrichten, dass sie über eine Bridge untereinander und mit der Außenwelt kommunizieren. Die dabei beteiligten IP-Adressen stellt folgende Tabelle dar:

Dienst Öffentliche IP-Adresse Bridge-IP-Adresse
Host xxx.xxx.xxx.xxx 10.10.20.1
Webserver keine 10.10.20.10
Datenbankserver keine 10.10.20.20

Inhalt

1 Vorbereitung

2 Einrichten des Datenverkehrs

3 Erstellen der Dateisysteme

4 Einrichten der Dienste

4.1 Webserver

4.2 Datenbank

5 Starten der Dienste

6 Schlussfolgerung

1. Vorbereitung

Diese Anleitung bezieht sich speziell auf Debian-Systeme.

 

Falls – wie bei Debian 7 ("Wheezy") – Firejail nicht als Systempaket verfügbar ist, muss es von Firejail/Download heruntergeladen und installiert werden.

 

Desweiteren benötigen wir ein Paket zum Einrichten eines minimalen Dateisystems

 

apt-get install debootstrap

 

und Hilfsprogramme für die Bridge-Einrichtung

 

apt-get install bridge-utils

In /etc/network/interfaces muss die öffentliche IP-Adresse unseres Hosts eingerichtet sein, z. B.

iface eth0 inet static
    address yyy.yyy.yyy.yyy
    netmask 255.255.255.0
    gateway yyy.yyy.yyy.1
   
    up ip addr add xxx.xxx.xxx.xxx/32 dev eth0 label eth0:0

wenn yyy.yyy.yyy.yyy die "Haupt"-IP-Adresse unserer Maschine ist und xxx.xxx.xxx.xxx die öffentliche Adresse des mit dieser Anleitung zu konfigurierenden Hosts.

Falls auf dem System noch ein Apache läuft, der auf andere IP-Adressen hören soll als der hier von uns aufgesetzte, muss dieser so eingerichtet sein, dass er genau auf jene Adressen reagiert. Dazu müssen etwaige _default_-Einträge in den Konfigurationsdateien in die tatsächliche IP-Adresse geändert werden. Als Vorlage kann man die Einträge zu ports.conf und sites-available/* in der Tabelle im Abschnitt Webserver verwenden.

2. Einrichten des Datenverkehrs

Wir beginnen mit einigen Definitionen.

Die öffentliche Zieladresse unseres Services muss natürlich individuell angepasst werden:

DESTINATION_IP="xxx.xxx.xxx.xxx"

Die weiteren Definitionen kann man in der Regel unverändert übernehmen:

INTERFACE="eth0+"
TCP_SERVICES="80 443" #web browsing
BRIDGE_HOST_IP="10.10.20.1"
BRIDGE_HOST_IP_RANGE=$BRIDGE_HOST_IP"/24"
BRIDGE_WEBSERVER_IP="10.10.20.10"
BRIDGE_DBSERVER_IP="10.10.20.20"

Wir erzeugen und konfigurieren unsere Bridge:

brctl addbr br0
ifconfig br0 $BRIDGE_HOST_IP_RANGE

Das Betriebssytem ermöglicht das Weiterleiten von IP-Adressen mittels:

echo "1" > /proc/sys/net/ipv4/ip_forward

Wir erlauben Datenverkehr, der für unseren Webserver bestimmt ist, durch unsere Bridge zu leiten:

for PORT in $TCP_SERVICES; do
  iptables -t nat -A PREROUTING -d $DESTINATION_IP -p tcp --dport $PORT -j DNAT --to $BRIDGE_WEBSERVER_IP:$PORT
done

Umgekehrt soll Datenverkehr, der nach außen geht, mit der öffentlichen Adresse maskiert werden:

iptables -t nat -A POSTROUTING -o $INTERFACE -j MASQUERADE

Datenverkehr von den dedizierten Ports in unsere Bridge ist erlaubt:

for PORT in $TCP_SERVICES; do
  iptables -A FORWARD -i $INTERFACE -o br0 -p tcp -m tcp --dport $PORT -j ACCEPT
done

Ebenso eingehender Verkehr bereits bestehender Verbindungen:

iptables -A FORWARD -i $INTERFACE -o br0 -m state --state RELATED,ESTABLISHED -j ACCEPT

Jeglicher Datenverkehr, der von unserer Bridge kommt ist zu erlauben, damit die Jails untereinander und mit der Außenwelt kommunizieren können:

iptables -A FORWARD -i br0 -j ACCEPT

Alle anderen Weiterleitungen werden dagegen gesperrt:

iptables -P FORWARD DROP

Optional können wir noch Datenverkehr erlauben, der von unserem Host kommt und auf den Datenbankserver zugreifen will:

iptables -I OUTPUT -p tcp -s $BRIDGE_HOST_IP -d $BRIDGE_DBSERVER_IP -j ACCEPT

Das ist nützlich, wenn wir etwa die Datenbank mit einem Service (wie phpPgAdmin) über eine separate IP-Adresse administrieren wollen.

Eine Vorlage für ein /etc/init.d-Skript findet man im Anhang. Vor dem Einsatz muss unbedingt mindestens die öffentliche IP-Adresse des Hosts in DESTINATION_IP gesetzt werden.

3. Erstellen der Dateisysteme

Wir erstellen ein Verzeichnis für die später in der Sandbox "gefangenen" Dateisysteme, gehen dort hinein

mkdir /jail

cd /jail

erzeugen ein minimales Dateisystem für den Webserver

debootstrap --arch=amd64 stable www

und kopieren es für den Datenbankserver

rsync -a www/ db

Letzteres ist weniger aufwändig als ein erneutes debootstrap, das man natürlich auch machen könnte.

Übrigens muss das Sandbox-Betriebssystem nicht unbedingt mit dem Wirtssystem übereinstimmen. Zum Zeitpunkt der Erstellung dieses Dokuments war mein Debian-7-Wirtssystem schon "oldstable", trotzdem funktioniert es mit "debootstrap ... stable ..." und man kann dann auch Software aus dem Stable-Zweig innerhalb des Jails installieren.

4. Einrichten der Dienste

4.1 Webserver

Zum Einrichten des Webservers starten wir firejail in dem zuvor erstellten Dateisystem

firejail --chroot=/jail/www/ --name=www

und installieren die Webserver-Software (in diesem Fall Apache):

apt-get update

apt-get install apache2

Nun gilt es noch, den Apache für die Umgebung, in der er laufen soll, geeignet zu konfigurieren. Wir können das innerhalb der mit firejail gestarteten Umgebung tun (dann bewegen wir uns in dem Verzeichnis /etc/apache2) oder von außerhalb (dann gehört die Konfiguration in das Verzeichnis /jail/www/etc/apache2); in beiden Fällen bearbeiten wir ein und dasselbe Verzeichnis, nur ist die Wurzel des Dateisystems jeweils eine andere.

Die nachstehende Tabelle zeigt die wesentlichen Eintragungen, die vorzunehmen sind:

Datei Änderung
ports.conf Listen-Direktive auf 10.10.20.10:80 bzw. 10.10.20.10:443 setzen
conf-available/servername.conf (Datei ggf. neu anlegen) Nur ein Eintrag: ServerName 10.10.20.10
sites-available/000-default.conf VirtualHost und ServerName auf 10.10.20.10:80 setzen
sites-available/default-ssl.conf VirtualHost und ServerName auf 10.10.20.10:443 setzen
envvars (optional) export APACHE_LOG_DIR=/var/local/log/apache2$SUFFIX (siehe unten)

Beim Starten des Jails wird das Verzeichnis /var/log an einen temporären Ort verschoben. Um die Apache-Logdateien permanent zu halten, können wir das Logverzeichnis wie oben beschrieben in der Konfigurationsdatei envvars ändern (hier in /var/local/log/apache2), müssen dann die entsprechende Verzeichnisstruktur aber manuell anlegen, also mkdir -p /var/local/log/apache2 (innerhalb des Jails).

Um den Servernamen zu aktivieren, setzen wir (innerhalb des Jails) den Befehl

a2enconf servername.conf

ab. Dann sind noch alle "normalen" Konfigurationen vorzunehmen, die für den Betrieb der Website nötig oder erwünscht sind.

Falls der Webserver schon läuft, sollten wir ihn mit

service apache2 stop

anhalten, bevor wir die firejail-Umgebung mit

exit

verlassen.

4.2 Datenbank

Für den Datenbankserver gehen wir analog vor, also zunächst

firejail --chroot=/jail/db/ --name=db

(jetzt mit db als chroot und Name) und dann (für PostgreSQL)

apt-get update
apt-get install postgresql

In der Datei /etc/postgresql/9.4/main/postgresql.conf (innerhalb des Jails, die Versionsnummer ist selbstverständlich anzupassen) sind folgende Einstellungen vorzunehmen:

Eintrag Wert Bemerkung
listen_addresses '10.10.20.20' Horchen auf unsere Bridge-IP.
logging_collector on Optional für Logging.
log_directory '/var/local/log/postgresql' Optional, um mit dem www-Logging konsistent zu sein.

Falls wir uns für das alternative log_directory entscheiden, müssen wir es auch erzeugen und die passenden Berechtigungen setzen (innerhalb des Jails):

mkdir -p /var/local/log/postgresql

chmod -R g-rwx,o-rwx /var/local/log/postgresql

chown -R postgres:postgres /var/local/log/postgresql

Natürlich sind auch hier alle sonstigen "normalen" Einstellungen für den Betrieb vorzunehmen.

Falls der Datenbankserver schon läuft, sollten wir ihn mit

service postgresql stop

anhalten, bevor wir die firejail-Umgebung mit

exit

verlassen.

Anmerkung: Trotz intensiver Versuche mit diversen Konfigurationen und umfangreichen Recherchen über mehrere Tage hinweg ist es mir nicht gelungen, einen MySQL-Server in einem Firejail aufzusetzen: Der Server startet zwar, beendet sich aber sofort wieder ohne brauchbare Fehlermeldungen oder Log-Dateieinträge zu hinterlassen. Daher habe ich mich schließlich für PostgreSQL entschieden.

5. Starten der Dienste

Zwecks Einrichtung konnten wir die Jails wie oben beschrieben starten. Um ihnen auch die Netzanbindung zu geben und die Server dabei automatisch im Hintergrund zu starten, verwenden wir die Kommandos

firejail --name=www --chroot=/jail/www --private --net=br0 --ip=10.10.20.10 sh -c "service apache2 start; sleep inf" &

firejail --name=db --chroot=/jail/db --private --net=br0 --ip=10.10.20.20 sh -c "service postgresql start; sleep inf" &

Die Option --private sorgt dafür, dass bestimmte Verzeichnisse des originalen Dateisystems wie /root oder /home nicht sichtbar sind, mit --net und --ip wird das Routing eingerichtet und der nachfolgende Befehl wird mit diesen Parametern im Jail ausgeführt: der Web- bzw. Datenbankserver wird gestartet und mit sleep inf wird erreicht, dass die Sandbox weiterläuft, auch wenn der Apache- oder PostgreSQL-Prozess beendet wird oder abstürzt (das mag für administrative Zwecke von Interesse sein). Anmerkung: sh -c ist hervorgehoben, weil es abweichend von anderen Beschreibungen bei mir ohne das nicht funktioniert.

Zum Auflisten der laufenden firejail-Prozesse dient:

firejail --list

Um eine laufende Sandbox zu betreten, rufen wir

firejail --join=www

oder

firejail --join=db

auf.

Falls wir die Server wieder stoppen wollen, geht das über

firejail --shutdown=www

firejail --shutdown=db

Skripte für init.d findet man im Anhang.

6. Schlussfolgerung

Mit der beschriebenen Vorgehensweise erhält man einen Webserver und einen Datenbankserver, die jeweils in einem abgeschotten Jail, jedoch auf der gleichen Maschine in einem internen IP-Bereich laufen.

Im Webserver-Jail kann man jetzt z. B. ein CMS wie Drupal oder Wordpress wie gewohnt installieren, muss dabei lediglich beachten, dass die Datenbank unter einer internen IP-Adresse (10.10.20.20) anzusprechen ist.

Durch die Abschottung erreicht man, dass etwa ein per SQL-Injektion eingedrungener Angreifer lediglich im Datenbankjail Schaden anrichten kann, aber nicht im Rest des Systems. Auch wenn solche Sicherheitsmaßnahmen nie perfekt sein können, haben wir zumindest dem Angreifer eine sehr hohe Hürde gesetzt.

AttachmentSize
Binary Data jailbridge.template.gz1.24 KB
Binary Data jail-www.gz472 bytes
Binary Data jail-db.gz471 bytes

Bereich:

System: 
Debian GNU/Linux
Version: 
7
Symptom: 
Ein Webserver und zugehörige Dienste wie ein Datenbankserver sollen in jeweils abgeschlossenen Umgebungen (jail bzw. sandbox) laufen, so dass diese auf andere Prozesse oder Dateisystembereiche des Betriebssystems nicht oder nur eingeschränkt zugreifen können.

Verbessern der Reputation eines Mailservers

Es ist nicht allzu schwer, einen eigenen Mailserver aufzusetzen, jedoch landen die versandten Mails oftmals im Spam- oder Junk-Ordner der Empfänger – wenn überhaupt. Das liegt daran, dass die meisten Provider eingehende Mails blockieren, wenn sie sie für unerwünscht oder gar gefährlich halten.

Es gibt ein paar Maßnahmen, die man treffen kann, um die Reputation des eigenen Mailservers zu steigern, so dass versandte Mails von den meisten Providern akzeptiert werden. Ziemlich sicher reichen einzelne davon nicht aus, sondern man muss schon alle implementieren.

  1.  Reverse DNS
    Stelle sicher, dass reverse DNS-Lookups die korrekte Domain liefern. Normalerweise kann man das über die Administrationsoberfläche des Webspace-Hosters (nicht des Domain-Hosters) bewerkstelligen. Verbinde die IP des Servers, auf dem dein Mailserver läuft, mit der Domain, von der deine Mails versendet werden.

  2. Hostname
    Sorge dafür, dass das
    hostname-Kommando den korrekten Servernamen liefert, z. B.
     
    hostname example.org

  3. SPF (Sender Policy Framework)
    Füge einen TXT-Record der Domain hinzu mit dem Inhalt
     
    v=spf1 a mx ~all
    Das geht normalerweise über die Administrationsoberfläche des Domains-Hosters. Es stellt sicher, dass E-Mails, die behaupten von deiner Domain zu kommen, von einer IP-Adresse gesandt werden müssen, die dem A- oder MX-Record deiner Domain entsprechen.

  4. DKIM (Domain Keys Identified Mail)
    Diese Maßnahme hängt vom verwendeten Mailprogramm ab. Hier ist ein Beispiel für exim4 auf einem Debian-System.
    Erzeuge zunächst einen privaten und dazugehörigen öffentlichen Schlüssel im Verzeichnis
    /etc/exim4/dkim/:
      openssl genrsa -out example.org-private.pem 2048
      openssl rsa -in example.org-private.pem -out example.org.pem -pubout -outform PEM

    Füge einen TXT-Record namens <selector>._domainkey der Domain hinzu, welcher enthält
       
    v=DKIM1;k=rsa;p=
    gefolgt vom oben generierten öffentlichen Schlüssel. Ersetze dabei <selector>  durch eine beliebige Zeichenkette, die dem zugehörigen Eintrag in /etc/exim4/exim4.conf.localmacros entspricht (s. u.). Falls der Domain-Service den Record aufgrund seiner Länge ablehnt, zerlege ihn in durch Anführungszeichen getrennte Teile.
    Danach passe
    /etc/exim4/exim4.conf.localmacros wie folgt an
      DKIM_CANON = relaxed
      DKIM_SELECTOR = 20190215
      DKIM_DOMAIN = example.org
      DKIM_PRIVATE_KEY = /etc/exim4/dkim/example.org-private.pem

    und führe
      update-exim4.conf
      service exim4 restart

    aus.

Bereich:

System: 
Alle
Symptom: 
Mails, die vom eigenen Server versendet werden, landen im Spam- oder Junk-Ordner der Empfänger.

Extrahieren mehrerer Teilbäume aus einem Git-Archiv

Git bietet verschiedene Ansätze, um die gestellte Aufgabe zu lösen. Hier verwenden wir das git-subtree-Kommando, mit dem die herauszulösenden Teilbäume in Zweige übertragen werden können, welche sich dann wiederum von einem anderen Archiv aus importieren lassen. Quellen waren die Handbuchseite (man git-subtree) und dieser Beitrag auf stackoverflow zusammen mit einigen dort aufgeführten Kommentaren.

Gegeben sei ein Git-Archiv bigrepo.git, dessen Inhalt folgende Verzeichnisstruktur aufweist:

    src            
      main         
        lib        
        prg        
        etc        
      test         
        lib        
        prg        
        etc        

 

Vielleicht hat es sich nun herausgestellt, das die Dateien unter lib eine Bibliothek ergeben, die nicht nur für dieses Projekt brauchbar, sondern von allgemeinem Interesse ist. Also möchte man daraus ein eigenständiges Projekt machen und die lib-Teilbäume unter main und test in ein separates Git-Archiv auslagern.

Für die folgenden Schritte benötigen wir zunächst eine Arbeitskopie des Archivs. Falls es sich bei bigrepo.git also um ein Bare-Archiv handelt, erzeugen wir im aktuellen Arbeitsverzeichnis eine solche:

    git clone /srv/git/bigrepo.git

(unter der Annahme, dass sich bigrepro.git unter /srv/git befindet). Ist kein Bare-Archiv verfügbar, macht man am besten trotzdem eine Kopie, dann vereinfacht man sich am Ende das Aufräumen.

Jetzt wechseln wir in das soeben geklonte neue Archiv und erstellen mit dem Unterbefehl split von git-subtree zwei Zweige – einen für jeden zu extrahierenden Teilbaum –, die wir z. B. split-lib-main und split-lib-test nennen:

    cd bigrepo

    git subtree split -P src/main/lib -b split-lib-main

    git subtree split -P src/test/lib -b split-lib-test

Die beiden erzeugten Zweige enthalten jeweils alle Dateien und Verzeichnisse unterhalb des mit der Option -P angegebenen Pfads inklusive der gesamten Versionsgeschichte; die Pfadangaben hinter -P dürfen keine voranstehenden oder angehängten Schrägstriche enthalten. Die Option -b spezifiziert den Namen des Zweiges, den man hier beliebig wählen kann.

Allerdings gehen bei dieser Vorgehensweise in den neuen Zweigen die Pfadpräfixe verloren. Das heißt, die Dateien und Verzeichnisse etwa in split-lib-main enthalten keine Information mehr darüber, dass sie ursprünglich unter src/main/lib angesiedelt waren. Die darunter liegende Struktur bleibt aber erhalten.

Behalten wir das im Hinterkopf und gehen zur Erzeugung des neuen Archivs – nennen wir es librepo – über, das nur noch die extrahierten Teile enthält. Der Einfachheit halber erstellen wir das neue Archiv auf der gleichen Ebene wie bigrepo. Da wir uns nach den obigen Aktivitäten  noch in bigrepo befinden, tun wir zunächst Folgendes:

    cd ..

    mkdir librepo

    cd librepo

    git init

Damit haben wir ein leeres Archiv, das die oben extrahierten Dateien aufnehmen kann. Leider funktioniert der sogleich verwendete Befehl in einem leeren Archiv nicht. Daher fügen wir einfach irgendeine Datei ein, z. B. eine, die wir später wahrscheinlich sowieso gebrauchen:

    touch .gitignore

    git add .gitignore

    git commit -m "Ignore file added." .gitignore

Auf diese Weise können wir nun die Extrahierung abschließen:

    git subtree add -P src/main/lib ../bigrepo split-lib-main

    git subtree add -P src/test/lib ../bigrepo split-lib-test

Über die Option -P fügen wir die verloren gegangenen Teile des Pfads wieder hinzu; stattdessen hätten wir aber auch einen anderen, neuen Pfad angeben können.

Falls es noch einzelne Dateien gibt, die in librepo gehören, aber über diese Methode nicht extrahiert werden können – etwa Konfigurationsdateien für Maven, Lizenz- oder README-Dateien aus dem Stammverzeichnis des Projekts –, so kann man diese am besten manuell hinzufügen (unter Verlust der Versionsgeschichte, was bei solchen Dateien aber wohl nicht problematisch ist).

Unser librepo enthält nun alle Dateien und Verzeichnisse, die in bigrepo unter scr/main/lib und src/test/lib gespeichert sind nebst allen zugehörigen Versionsinformationen. Wir können daraus mit den üblichen Git-Befehlen ein Bare-Repository erzeugen und es an beliebigen Orten ablegen.

An diesem Punkt bietet git-subtree sogar noch die Möglichkeit, die extrahierten Bestandteile in beiden Archiven (bigrepo und librepo) parallel weiterzupflegen. Das ist aber jenseits der beschriebenen Problemstellung und führt ohnehin in aller Regel zu Konsistenzproblemen. Diese Möglichkeit wird daher hier nicht weiter vertieft.

Was also noch bleibt, ist das Aufräumen: Da wir am Anfang eine Kopie des Ursprungsarchivs erstellt haben, können  wir diese Kopie einfach wegwerfen. Oder wir können die herausgelösten Zweige zu Referenzzwecken in das Ursprungsarchiv pushen. In jedem Fall sollten wir allerdings die extrahierten Bestandteile aus dem Ursprungsarchiv löschen (nachdem wir uns davon überzeugt haben, dass alles vollständig in librepo enthalten ist, versteht sich), um auseinanderdriftenden Parallelentwicklungen vorzubeugen.

Bereich:

Tags:

System: 

Git

Version: 
2.1.4
Symptom: 

Aus der Verzeichnisstruktur eines Git-Archivs sollen mehrere Teilbäume herausgelöst und unter Beibehaltung der Versionsgeschichte in ein neues Archiv übertragen werden.

Crontab ohne Dauerbetrieb

Unix-Systeme einschließlich Linux verfügen über einen Mechanismus, der Programme automatisch zu bestimmten Zeiten ausführen kann – etwa täglich zu einer gewissen Uhrzeit oder wöchentlich oder monatlich an einem bestimmten Tag und hier wiederum zu einer festgelegten Uhrzeit. Gesteuert wird das Ganze über eine Datei namens crontab, die üblicherweise im Verzeichnis /etc residiert (also /etc/crontab) und die entsprechenden Angaben enthält.

Unix-Workstations, auf denen dieser Mechanismus ursprünglich eingeführt wurde, sind in der Regel durchgängig im 24-Stunden-Betrieb. Daher wirkt die crontab-Steuerung nur exakt zum jeweils eingestellten Zeitpunkt. Ist der Rechner zu dieser Zeit nicht in Betrieb, verfällt der Eintrag und das fragliche Programm wird nicht gestartet.

Linux-PCs sind oft nicht im Dauerbetrieb. Was man hier braucht, ist ein Verfahren, bei dem die crontab-Steuerung zu einem späteren Zeitpunkt einsetzt, falls der PC zur tatsächlich eingestellten Zeit ausgeschaltet war. Programme, deren Ausführung über crontab zum eigentlichen Zeitpunkt versäumt wurde, sollten also nachträglich gestartet werden, sobald der PC wieder in Betrieb ist.

Es gibt dafür alternative Lösungen wie anacron, die aber anscheinend nicht mehr so recht in die aktuelle Systemlandschaft passen. OpenSUSE verwendet einen anderen Ansatz: /etc/crontab enthält einen Eintag, der das Programm /usr/lib/cron/run-crons in kurzen Zeitabständen (alle 15 Minuten) ausführt. Dieses wiederum sucht in den Verzeichnissen /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly und /etc/cron.monthly nach Programmskripten, die es startet, sobald seit der letzten Ausführung jeweils mindestens 60 Minuten, 24 Stunden, 7 Tage bzw. 30 Tage vergangen sind.

Auf diese Weise kann man also in den betreffenden /etc/cron.*-Verzeichnissen Programme unterbringen, die in regelmäßigen Zeitabständen ausgeführt werden sollen. Für den Systemadministrator ist es allerdings nicht unbedingt die beste Wahl, diese Systemverzeichnisse anzufassen, daher befindet sich unter OpenSUSE standardmäßig im Verzeichnis /etc/cron.daily ein Skript, etwa suse.de-cron-local, das wiederum das Skript /root/bin/cron.daily.local ausführt (falls dieses existiert). Somit kann der Administrator täglich auszuführende Aufgaben über sein eigenes /root/bin-Verzeichnis definieren.

Leider gibt es standardmäßig keine entsprechenden Skripte für stündliche, wöchentliche oder monatliche Zeiträume. Man kann suse.de-cron-local aber so erweitern, dass es sich in diesem Sinne universell verwenden lässt. Im Anhang stelle ich mein Shellskript cron-local zur Verfügung, das eine solche Erweiterung realisiert.

Nach dem Herunterladen und Entpacken von cron-local.gz kopiert oder verlinkt man cron-local einfach in die Verzeichnisse /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly und /etc/cron.monthly (je nach Bedarf); dabei sollte man nicht vergessen, die jeweilige Datei ausführbar zu machen. (/etc/cron.daily lässt man entweder aus oder löscht das Standardskript suse.de-cron-local o. ä. – wenn vorhanden –, um doppelte Ausführungen zu vermeiden!)

Anschließend kann der Administrator in seinem /root/bin-Verzeichnis Skripte cron.hourly.local, cron.daily.local, cron.weekly.local oder cron.monthly.local (je nach den oben gewählten Verzeichnissen) anlegen, die dann in entsprechenden Zeitabständen ausgeführt werden. Natürlich ist das immer noch optional: Falls eine Datei fehlt, wird das einfach ignoriert.

AttachmentSize
Binary Data cron-local.gz458 bytes

Bereich:

System: 
OpenSUSE
Version: 
11.3
Symptom: 

Crontab-gesteuerte Ereignisse finden nicht statt, wenn der PC zur fraglichen Zeit ausgeschaltet ist.

AWStats: Daten von anderem Profil übernehmen

Wenn AWStats-Daten von einem anderen, z. B. älteren, Profil übernommen werden sollen, tue Folgendes.

Sorge zunächst dafür, dass während dieser Prozedur keine ungewollten Updates der betroffenen Profile stattfinden. Also entferne etwa alle AWStats-Update-Befehle aus der crontab.

Kopiere die alten Daten in das neue Profilverzeichnis. Der Ort des Verzeichnisses wird in der Konfigurationsdatei mit der DirData-Direktive definiert, üblicherweise als /var/lib/awstats/<config>, wobei <config> für den Profilnamen steht. Die Konfigurationsdatei selbst findet man normalerweise unter /etc/awstats als awstats.<config>.conf.

Benenenne die kopierten Dateien um gemäß dem Schema

awstats<MMYYYY>.<config>.txt

Hier steht <MMYYYY> für einen 6-stelligen Zifferncode bestehend aus 2 Ziffern für den Monat und 4 Ziffern für das Jahr (dieser Code sollte schon im alten Namen enthalten sein und nicht geändert werden) und <config> für den neuen Profilnamen.

Bei Überschneidungen (d. h., wenn es mehrere Profilversionen einer Datei gibt, z. B. awstats032018.profil1.txt und awstats032018.profil2.txt) bevorzuge die ältere Datei, sofern die entsprechenden neueren Daten noch in der aktuellen Log-Datei vorliegen; die neueren Daten werden dann beim nächsten Update wiederhergestellt. Liegen die mehrfach vorhandenen Dateien vor dem letzten Logrotate, ist die Sache komplizierter und wird hier nicht weiter erörtert.

Dann lösche

dnscachelastupdate.<config>.hash

und führe

/usr/lib/cgi-bin/awstats.pl -config=<config> -update

aus. Läuft alles reibungslos, kann man zum Tagesgeschäft übergehen und die AWStats-Update-Befehle wieder in die crontab aufnehmen.

Bereich:

Tags:

System: 
AWStats
Version: 
7.0
Symptom: 
Das AWStats-Profil wurde gewechselt und ältere Statistiken sollen übernommen werden.

AWStats reparieren

Folgende Situation tritt auf (bei mir das erste Mal nach mehreren Jahren Nutzung): AWStats wird über crontab ausgeführt,  aktualisiert aber plötzlich keine Statistiken mehr; ein Fehler bezüglich der Ausführung von crontab kann ausgeschlossen werden. Ein manueller Aufruf wie

/usr/lib/cgi-bin/awstats.pl -config=<config> -update

wobei <config> für die fragliche Konfiguration steht,  ergibt eine Fehlermeldung der Art

AWStats did not find any valid log lines that match your LogFormat parameter, in the 50th first non commented lines read of your log.
Your log file /var/log/apache2/ssl_access.log must have a bad format or LogFormat parameter setup does not match this format.
Your AWStats LogFormat parameter is:
1
This means each line in your web server log file need to have "combined log format" like this:
xxx.xxx.xxx.xxx - - [10/Jan/2001:02:14:14 +0200] "GET / HTTP/1.1" 200 1234 "http://www.fromserver.com/from.htm" "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)"
And this is an example of records AWStats found in your log file (the record number 50 in your log):
xxx.xxx.xxx.xxx - - [31/May/2017:20:45:53 +0200] "-" 408 1447 "-" "-"

Offenbar sieht AWStats Log-Dateieinträge mit leeren Feldern, also

xxx.xxx.xxx.xxx - - [31/May/2017:20:45:53 +0200] "-" 408 1447 "-" "-"

(wobei xxx.xxx.xxx.xxx für eine konkrete IP-Adresse steht), als unzulässig an.

Solche Einträge tauchen öfters in Webserver-Log-Dateien auf und sind normalerweise kein Problem. Wenn aber mehr als 50 davon lückenlos hintereinander auftreten, stellt AWStats seinen Dienst ab diesem Punkt und für die Zukunft (genauer: bis zum Austausch der Log-Datei) komplett ein.

Zur Abhilfe kann man die betreffenden Zeilen aus der Log-Datei löschen (mindestens so viele, dass weniger als 50 davon in ununterbrochener Folge übrig bleiben). Vorher sollte man den Webserver stoppen (z. B. service apache2 stop) und danach wieder starten (service apache2 start). Anschließend nimmt AWStats seine Arbeit wieder auf (wenn als Cron-Job konfiguriert) und aktualisiert die Statistiken ab der zuvor fehlerhaften Stelle.

Bereich:

System: 
AWStats
Version: 
7.0
Symptom: 
AWStats aktualisiert die Statistiken nicht mehr, obwohl es bisher reibungslos funktioniert hat. Die konfigurierten Cron-Jobs laufen nach wie vor, auch manuelle Aufrufe führen nicht zum Erfolg.

Upgrade von openSUSE aus dem laufenden System heraus

Update: Das im Text besprochene Skript wurde durch eine neue Version mit vereinfachter Handhabung ersetzt. Einzelheiten dazu siehe im Kommentar Neue Version mit vereinfachter Nutzung.

Die Aktualisierung eines Systems ist immer gefährlich und heikel. Diese Anleitung ist nur für erfahrene Administratoren, die ohne weiteres in der Lage sind, ein „normales” Upgrade eines openSUSE-Systems vorzunehmen, und geeignete Maßnahmen treffen können, wenn irgendetwas schief läuft. Dies ist also definitiv nichts für Anfänger, es sei denn zu Lernzwecken. Auf jeden Fall beachte man die folgenden Warnungen.

Warnung: Benutze weder das angehängte Skript noch die hier eingestellten Anweisungen, wenn Du nicht weißt, was Du tust! Prüfe zuvor das Skript und die Anweisungen, ob sie Deinen und Deines Systems Notwendigkeiten entsprechen. Anderenfalls kann Dein System ernsthaft beschädigt werden!

Bei Verwendung des Skripts ist insbesondere zu beachten, dass nach Anzeige einer Meldung wie "***Now disabling old repositories. Continue (y/n)?" bei Zustimmung und späterem Abbruch des Verfahrens alle Repositories des alten Systems verloren sind.

Außerdem wird bei Fortsetzung nach einer Meldung der Art "
***Finally starting the upgrade. Continue (y/n)?" und späterem Abbruch das System unvollständig und definitiv unbrauchbar sein.

So weit die Warnungen. Wir entwickeln hier eine Prozedur, um ein openSUSE-System zu aktualisieren (derzeit auf Version 12.1), und zwar aus dem laufenden System heraus, ohne feste Installationsmedien zu benutzen. Vorlage war ein Eintrag auf opensuse.org; leider kann ich die genaue URL nicht mehr finden, weil die Dokumentationssparte auf opensuse.org in letzter Zeit ziemlich durcheinandergewirbelt wurde. Am Ende des Beitrags ist ein vollständiges Skript angehängt; hier beschreiben wir einige wichtige Teile davon..

Zunächst definieren wir einige Variablen: für das Betriebssystem (OS), um das es geht, den Server, der die benötigten Dateien zur Verfügung stellt, und die neue Version (NEW_VER), die zu installieren ist.

OS=openSUSE
SERVER=http://download.opensuse.org
NEW_VER=12.1

 

Als Nächstes sorgen wir dafür, dass die Distributionsaktualisierung einen zuverlässigen Ausgangspunkt hat, d. h., wir machen ein gewöhnliches Update der aktuellen Version. Dies erledigt ein Auffrischen der aktuellen Repositories und anschließendes Update mit zypper.

zypper refresh
zypper update

Jetzt müssen alle alten Repoistories deaktiviert werden, da das zu aktualisierende System nicht von diesen sondern von neuen Repositories zu laden ist. Warnung: Ab diesem Punkt startet die Aktualisierung; es ist nicht mehr möglich, das Verfahren abzubrechen, ohne Probleme zu bekommen oder sogar Zerstörungen anzurichten.

zypper modifyrepo --all --disable

Nun fügen wir die neuen Standard-Repositories hinzu; diese sind weitgehend obligatorisch für die neue Installation. Das allgemeine Format dafür ist

zypper ar -cf -n <Name> <URI> <Alias>

wobei ar für addrepo steht (füge Repository hinzu) und -cf beinhaltet Prüfung des URI sowie automatisches Auffrischen des Repositories. Außerdem lässt sich die Priorität eines Repositories ändern durch

zypper mr -p <Priority> <Alias>

Die voreingestellte Priorität ist 99. Es ist nicht so offensichtlich, was die Prioritäten eigentlich bedeuten; es scheint, dass ein Paket einer gegebenen Version vom Repository mit der niedrigsten Prioritätszahl geladen wird.

Um konkret zu werden, die folgenden drei Repositories sind Standard und sollten immer eingebunden werden:

zypper ar -cf -n "${OS}-${NEW_VER} OSS" ${SERVER}/distribution/${NEW_VER}/repo/oss/ ${OS}-${NEW_VER}-oss
zypper ar -cf -n "${OS}-${NEW_VER} Non-OSS" ${SERVER}/distribution/${NEW_VER}/repo/non-oss/ ${OS}-${NEW_VER}-non-oss
zypper ar -cf -n "${OS}-${NEW_VER} Updates" ${SERVER}/update/${NEW_VER}/ ${OS}-${NEW_VER}-update

 

Optional können weitere Standard-Repositories (source, debug) hinzugefügt werden. In diesem Fall benutzen wir das Format

zypper ar -cdf -n <Name> <URI> <Alias>

wobei ar bedeutet addrepo und -cdf beinhaltet Prüfung des URI, jedoch Deaktivierung, obwohl automatisches Auffrischen des Repositories, soweit anwendbar. Entferne 'd' von "-cdf", um ein Repository zu aktivieren. Die Repositories in dieser Kategorie sind wahrscheinlich nur für Entwickler von Interesse. Auch hier lässt sich die Priorität eines Repositories ändern wie zuvor; Standard ist wieder  99.

Entsprechend der Regel bekommen wir diese Source- und Debug-Repositories:

zypper ar -cdf -n "${OS}-${NEW_VER} Source" ${SERVER}/source/distribution/${NEW_VER}/repo/oss/ ${OS}-${NEW_VER}-source
zypper ar -cdf -n "${OS}-${NEW_VER} Debug" ${SERVER}/debug/distribution/${NEW_VER}/repo/oss/ ${OS}-${NEW_VER}-debug
zypper ar -cdf -n "${OS}-${NEW_VER} Debug Updates" ${SERVER}/debug/update/${NEW_VER}/ ${OS}-${NEW_VER}-debug-update

 

Das angehängte Skript enthält viele weitere Repositories wie openSUSE-BuildServices, Packman, usw. Alle diese sind standardmäßig auskommentiert; entferne das '#'-Zeichen, um ein Repository hinzuzufügen und ändere das "-cdf"-Argument in "-cf", um es zu aktivieren oder andersherum. An dieser Stelle wären auch weitere Repositories hinzuzufügen oder existierende auszukommentieren oder zu löschen – so wie es den eigenen Anforderungen entspricht.

Eine Liste der neuen Repositories erhalten wir so:

zypper repos --uri

Bevor wir fortsetzen, sollten die neuen Repositories aufgefrischt werden:

zypper refresh

Danach sollte zuerst zypper selbst auf die neue Version aktualisiert werden. Dies ist sicherlich eine angrebachte Maßnahme, wobei dies bereits einen beträchtlichen Teil des neuen Systems aktualisieren wird, was einige Zeit in Anspruch nehmen mag.

zypper update zypper

Schließlich starten wir die Distributionsaktualisierung. (Das mag mehrere Stunden dauern!).

zypper dist-upgrade

Nach Abschluss sollte das Sytem so bald wie möglich neu gestartet werden.

Da die angehängte Datei ein einfaches Skript ist, wird sie  – entgegen der Ausführungen im  blog – unter dieser einfachen Lizenz veröffentlicht:

This program is distributed WITHOUT ANY WARRANTY, express or implied.

Permission is granted to make and distribute verbatim copies of this document provided that the copyright notice and this permission notice are preserved on all copies.

Permission is granted to copy and distribute modified versions of this document under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one.

 

Zuletzt ist noch zu sagen, dass das Skript nicht zur Stapelverarbeitung geeignet ist. Es stellt viele Fragen – einige kommen vom Skript selbst, andere vom aufgerufenen Programm zypper  –, die zu beantworten sind (meistens mit „ yes” oder „no”). Also muss man an seinem Terminal bleiben und sehen was passiert.

AttachmentSize
Binary Data suse_upgrade.sh_.gz1.42 KB

Bereich:

System: 
openSUSE
Version: 
12.1 - 13.2
Symptom: 

Ein openSUSE-System soll auf eine neue Distribution aktualisiert werden, ohne Medien wie DVD, CD, USB-Stäbe o. ä. zu benutzen. Stattdessen  soll die Aktualisierung aus dem laufenden System heraus erfolgen.
 

Aktualisierung eines Drupal-6.x-Systems

Diese Beschreibung versteht sich als Kurzanleitung für erfahrene Drupal-Administratoren, die eine Checkliste für Aktualisierungen des Systems haben wollen. Es wird also vorausgesetzt, dass der grundsätzliche Aktualisierungsmechanismus einschließlich der Verzeichnisstruktur auf dem Server bekannt ist. Desweiteren wird als selbstverständlich vorausgesetzt, dass die administrativen Aktionen auf der Website mit entsprechenden Berechtigungen ausgeführt werden. Schließlich sei betont, dass es hier ausschließlich um die Aktualisierung einer Drupal-Version 6.x1 auf 6.x2 oder eines Zusatzmoduls für 6.x geht (sog. minor update); Aktualisierungen der Hauptversion (etwa von 5.x1 auf 6.x2 oder 6.x1 auf 7.x2) sowie von Zusatzmodulen zwischen verschiedenen Hauptversionen werden hier nicht betrachtet.

Eine ausführliche Anleitung zur Aktualisierung insbesondere des Grundsystems (innerhalb der 6.x-Reihe) findet man im Administration Guide von drupal.org in diesem Howto. Anfänger sollten zuerst dort nachsehen.

Die Schritte zum Aktualisieren von Zusatzmodulen beinhalten im Wesentlichen eine Teilmenge der entsprechenden Schritte zur Aktualisierung des Grundsystems. Daher wird hier beides zusammen dargestellt, wobei Schritte, die nur das Grundsystem betreffen, farblich sowie durch die Markierung [core] textlich hervorgehoben sind.

Die Aktualisierung eines Systems ist immer gefährlich und kann zur Folge haben, dass es anschließend nicht mehr funktioniert oder gar weitergehende Zerstörungen anrichtet. Die folgenden Schritte sind daher auf eigene Gefahr und ohne Gewährleistung anzuwenden!

  1. Lade die zu aktualisierenden Dateien herunter und packe sie ggf. aus. [core] Lösche aus der lokalen Kopie die Dateien .htaccess, robots.txt und das Verzeichnis sites, falls nicht angesagt ist, dass diese aktualisiert wurden. Falls doch, müssen ggf. manuelle Änderungen vorgenommen werden; dann sollte man die betroffenen Dateien unbedingt in die Sicherungskopie der Dateien vom Server (s. u.) einschließen.
  2. Schalte die Website in den Wartungsmodus.
  3. [core] Erstelle eine Sicherungskopie der Dateien vom Server. Benutze dazu ein geeignetes FTP-Programm, z. B. FileZilla oder Konquerer. Ob man nun alle Server-Dateien sichert, oder nur die aus sites/default (letzteres enthält u. a. die Einstellungen für die Website und hochgeladene Dateien), ist dem Anwender überlassen. Es ist kein Fehler, diesen Punkt auch bei Zusatzmodulaktualisierugen anzuwenden, obwohl bei sorgfältiger Vorgehensweise nicht unbedingt notwendig.
  4. Mache eine Sicherungskopie der Datenbank. Dies ist unerlässlich, da bei jedem Update nicht vorhersehbare Dinge passieren können. Man kann dazu z. B. das backup_migrate-Modul verwenden oder auch etwa phpMyAdmin. Es ist keine schlechte Idee, gelegentlich die eine oder die andere Methode zu verwenden, um im Fall der Fälle verschiedene Wiederherstellmöglichkeiten zu haben.
  5. [core] Deaktiviere alle Zusatzmodule. Notiere zuvor den aktuellen Status etwa als Bildschirmfoto vermöge Firefox Shooter oder manuell. Dies wird bei der Reaktivierung gebraucht!
  6. Falls Zusatzmodule aktualisiert werden, lösche die betroffenen alten Dateien vom Server. Dies ist zu empfehlen, da sonst alte, nicht überschriebene Dateien Inkonsistenzen hervorrufen können. [core] Für eine Aktualisierung des Grundsystems allein ist das i. Allg. nicht erforderlich, solange man sich innerhalb einer Hauptversion (hier: 6.x) bewegt.
  7. Kopiere die neuen Dateien auf den Server in das jeweils zugeordnete Verzeichnis (i. Allg. unter sites/all/modules oder [core] das Stammverzeichnis).
  8. Führe update.php aus.
  9. [core] Reaktiviere alle zuvor abgeschalteten Zusatzmodule und führe update.php erneut aus.
  10. Schalte den Wartungsmodus ab.
  11. Prüfe die aktualisierte Website.

Bereich:

System: 
Drupal
Version: 
6.x
Symptom: 

Ein Drupal-System soll innerhalb der 6.x-Reihe aktualisiert werden – das Grundsystem, Zusatzmodule oder beides.

Probleme bei der Konfiguration des Anmeldebildschirms mit dem Anmeldungsmanager von KDE4

Wenn ein Linux-System (bei mir openSUSE), das mit KDE3 läuft, auf eine Version mit KDE4 aktualisiert wird, kann es passieren, dass der Anmeldebildschirm über den KDE4-Anmeldungsmanager (Systemeinstellungen|System|Anmeldungsmanager) nicht mehr geändert werden kann. Zwar werden dort vorgenommene Einstellungen korrekt am vorgesehenen Ort

/usr/share/kde4/config/kdm

abgelegt, jedoch hat dies offenbar keinen Effekt. Eine Konfiguration über den KDE3-Anmeldungsmanager ist hingegen weiterhin möglich; diesen kann man allerdings nach Installation von KDE4 nur noch über die Kommandozeile mittels

kcontrol &

aufrufen (und dann Systemverwaltung|Anmeldungsmanager).

Um solche Konfigurationen mit dem KDE4-Anmeldungsmanager vornehmen zu können, muss man in /etc/sysconfig/displaymanager den Eintrag

DISPLAYMANAGER="kdm4"

setzen. (Ist der Wert einfach gleich "kdm", ruft das System anscheinend immer die KDE3-Variante auf.) Unter openSUSE benutzt man zum Setzen dieses Wertes am einfachsten YaST: Wähle System|Editor für /etc/sysconfig und dann Desktop|Display manager|DISPLAYMANAGER (hier kdm4 per Hand eingeben, wenn es nicht über die Auswahlliste verfügbar ist).

Damit sollte der KDE4-Anmeldungsmanager funktionieren. Will man allerdings auch das Design des Anmeldebildschirms verändern, muss man unter openSUSE zusätzlich noch den Standardeintrag

DISPLAYMANAGER_KDM_THEME="SUSE"

in /etc/sysconfig/displaymanager durch

DISPLAYMANAGER_KDM_THEME=""

ersetzen, was man wieder über YaST vornehmen kann: System|Editor für /etc/sysconfig und dann Desktop|Display manager|DISPLAYMANAGER_KDM_THEME (hier leeren Wert eingeben).

Bereich:

System: 
KDE 4.3 / KDE 3.5 / KDM
openSUSE 11.2 (x86_64)
Symptom: 

Einstellungen, die über den Anmeldungsmanager von KDE4 getätigt werden, wirken sich nicht auf den Anmeldebildschirm aus.

Soundprobleme nach KDE-Update

Nach dem Update von openSUSE 11.1 auf Version 11.2 und dem damit verbundenen Übergang von KDE 3.5 auf 4.3 funktionierte auf einem Rechner der von KDE-Programmen (einschließlich der Systemnachrichten) generierte Sound nur noch gelegentlich: Nach dem Anmelden einer Sitzung war er bis zum Ende derselben entweder da oder eben nicht, wobei dieses Verhalten rein zufällig und nicht reproduzierbar erschien. Nicht-KDE-Programme dagegen zeigten keine solchen Macken, hier funktionierte der Sound einwandfrei.

Offenbar ein Initialisierungsproblem: Irgendetwas störte das KDE-Soundsystem beim Sitzungsstart und je nachdem, ob KDE oder das andere System bei der Initialisierung gewann bzw. schneller war, kam es zu den beschriebenen Symptomen.

Die KDE-Hilfe liefert keine Lösung für das Problem. Diverse Internetforen beschreiben ähnliche Symptome und bieten Lösungsansätze, vieles habe ich erfolgslos ausprobiert, bis endlich der entscheidende Hinweis kam (leider weiss ich die Quelle nicht mehr): KDE4 und PulseAudio in den jeweils aktuellen Versionen vertragen sich nicht.

In der Tat war auf meinem System PulseAudio aktiviert. Diese Einstellung wurde durch das Update von der früheren Installation übernommen, bei vollständiger Neuinstallation von openSUSE 11.2 bleibt PulseAudio standardmäßig deinstalliert (so jedenfalls auf einem anderen Rechner), so dass das besagte Problem in so einem Fall nicht auftritt.

Nachdem einmal die Ursache des Problems erkannt ist, gestaltet sich die Lösung recht einfach:

  1. Deinstalliere pulseaudio und die davon abhängigen Pakete. Prüfe bei der Gelegenheit, ob phonon und phonon-backend-xine installiert und alle Abhängigkeiten aufgelöst sind.
  2. Leider funktioniert jetzt der Nicht-KDE-Sound nicht mehr. Das liegt daran, dass das System zwei Umgebungsvariablen setzt, SDL_AUDIODRIVER und ALSA_CONFIG_PATH, die noch auf das PulseAudio-System verweisen. Dies erfolgt unter openSUSE in der Datei /etc/environment, wo man die entsprechenden Einträge löschen oder auskommentieren sollte:
    #ALSA_CONFIG_PATH=/etc/alsa-pulse.conf
    #SDL_AUDIODRIVER=pulse                

    Nach einem Neustart müssten jetzt sowohl KDE- als auch Nicht-KDE-Programme Sound liefern.
  3. Sollte es immer noch nicht funktionieren, kann man etwa noch Folgendes versuchen: phonon-backend-gstreamer und arts deinstallieren, die Systemvariable PULSEAUDIO_ENABLE auf "no" setzen (in /etc/sysconfig/sound oder über den Menüpunkt Hardware/Soundcard im Sysconfig-Editor), den Benutzer der Gruppe audio hinzufügen.

 

Bereich:

System: 
KDE 4.3.1
openSUSE 11.2 (x86_64)
Symptom: 

KDE-Sound ertönt nur sporadisch, obwohl er bei Nicht-KDE-Programmen funktioniert.

Kartennavigation auf Smartphones mit GpsMid

Mit GpsMid steht eine hervorragende Navigationssoftware für Java-Smartphones zur Verfügung. Sie ist nicht nur selbst frei und quelloffen, sondern verwendet auch das freie Kartenmaterial von OpenStreetMap. Software und Kartendaten können – verpackt in einer JAR-Datei als MIDlet – vom PC auf das Mobiltelefon geladen werden; sofern man von dort aus keine weiteren Daten nachlädt, fallen also keine Mobilfunk-Übertragungskosten an. Darüber hinaus lässt sich das Programm – auch wenn der Name anderes suggeriert – problemlos auch ohne GPS-Gerät verwenden; man muss dann halt die Navigation per Hand vornehmen, was sich aber schon dadurch relativiert, dass die Vor-Ort-Navigation ohnehin nur einen Spezialfall der allgemeinen Kartennutzung darstellt.

Wie bekomme ich nun die Karte aufs Smartphone? Am einfachsten geht es, wenn man eines der gebrauchsfertigen Pakete von der GpsMid-Projektseite verwenden kann. In diesem Fall muss man nur die entsprechende JAR- und optional JAD-Datei auf den PC herunterladen, aufs Handy kopieren, dort installieren und fertig. (Wie das Installieren auf dem Smartphone selbst erfolgt, hängt vom Modell ab und wird hier nicht weiter betrachtet.)

Was aber, wenn gerade mein gewünschter Kartenausschnitt nicht dabei ist oder das Handybetriebssystem die Installation der JAR-Datei verweigert? Letzteres kann passieren, obwohl auf der Speicherkarte noch genügend Platz ist, da es hier oft Beschränkungen für die Größe einer einzelnen zu installierenden JAR-Datei gibt. Wenn man auf diese Weise also nicht weiterkommt, kann man auf dem PC ein MIDlet in Form einer JAR- und zugehöriger JAD-Datei mit dem passenden Kartenausschnitt selbst erstellen; auch mehrere Ausschnitte in einer Datei sind möglich.

Dazu benögt man auf dem PC zunächst Folgendes:

  1. Das Java Runtime Environment (JRE), mindestens in der Version 1.5.

  2. Das Programm Osm2GpsMid von der GpsMid-Downloadseite (aktuelle Dateiversion Osm2GpsMid-0.6.jar zum Zeitpunkt des Schreibens dieser Anleitung).

  3. Eine OSM-Datei, die die OpenStreetMap-Daten mindestens des gewünschten Ausschnitts in XML-Form enthält. Die Osm2GpsMid-Projektseite verweist auf einige mögliche Downloadquellen. Ich selbst habe gute Erfahrungen mit der Geofabrik gemacht.

  4. Eine Properties-Datei, die die Erzeugung des resultierenden Kartenmaterials durch Osm2GpsMid steuert. Diese Konfigurationsdatei mit obligatorischer Namensendung .properties muss man selbst erstellen, ggf. aus einer Vorlage. Wie man das macht, wird sogleich erläutert.

Der wichtigste Eintrag in der .properties-Datei ist der gewünschte Kartenausschnitt. Diesen definiert man durch Angabe des jeweils minimalen und maximalen Breiten- und Längengrades, z. B.

bundle.name = berlin
region.1.lat.min = 52.5008
region.1.lat.max = 52.5406
region.1.lon.min = 13.4047
region.1.lon.max = 13.4671

Man kann hintereinander bis zu 9 durchnummerierte Regionen für Kartenausschnitte aus den nach Punkt 3 heruntergeladenen Rohdaten angeben. Die benötigten Breiten- und Längengrade gewinnt man am besten von openstreetmap.org, indem man dort zunächst den gewünschten Ausschnitt wählt, dann auf Export geht, hier bei Bedarf den Bereich noch mal manuell anpasst und anschließend die Bereichsdaten abliest: unten und oben für die Breitengrade (lat), links und rechts für die Längengrade (lon). Den Export selbst muss man an dieser Stelle natürlich nicht durchführen, man braucht nur die Zahlen. Sollte sich die am Ende ergebende JAR-Datei wie oben erwähnt als zu groß erweisen, muss man einen kleineren Ausschnitt wählen; notfalls muss man den gewünschten Kartenausschnitt auf mehrere MIDlets verteilen (s. u.).

Weitere Einstellungen, die man in der .properties-Datei vornehmen kann (aber nicht muss), betreffen spezielle Zielsysteme (app), die Angabe einer Stildatei (style-file) oder die Möglichkeit, Streckenführung bzw. Editierung ein- oder auszuschalten (useRouting und EnableEditing); mehr dazu findet man auf der Osm2GpsMid-Projektseite. Die meisten dieser Einstellungen beeinflussen die Größe der resultierenden JAR-Datei.

Eine interessante Möglichkeit bietet noch die Einstellung midlet.name. Dadurch kann man dem Endprodukt einen besonderen Namen geben (statt des Standardnamens GpsMid), womit mehrere Instanzen des Programms mit verschiedenen Kartendaten auf das Mobiltelefon geladen werden können; etwa

midlet.name=GpsMidBerlin

Ein Beispiel für eine komplette .properties-Datei (optimiert für geringen Speicherverbrauch) findet sich im Anhang. Sie produziert mit den Rohdaten aus berlin.osm.bz2 von der Geofabrik-Downloadseite für Deutschland (s. Punkt 3 oben) mit der nachfolgend beschriebenen Prozedur eine Datei GpsMidBerlin-0.6.jar von knapp 800 KiB.

Nachdem man nun alle benötigten Utensilien zusammengestellt hat, kopiert man die nach Punkt 2 bis 4 erhaltenen Dateien in ein Verzeichnis auf dem PC. Dieses sollte dann enthalten:

  • Das Java-Archiv Osm2GpsMid-0.6.jar (oder eine neuere Version davon, falls erhältlich).
  • Eine OSM-Datei, die den oder die zu generierenden Kartenausschnitt(e) enthält (in diesem Beispiel berlin.osm.bz2).
  • Die erstellte Konfigurationsdatei, etwa berlin.properties aus dem Anhang (ggf. angepasst an die eigenen Belange).

Aus diesem Verzeichnis heraus ruft man dann etwa den Befehl

java -Xmx1024M -jar Osm2GpsMid-0.6.jar berlin.osm.bz2 berlin

auf. Dieser startet – in diesem Beispiel – das Osm2GpsMid-Programm zur Erzeugung eines MIDlets zur Kartennavigation aus den Rohdaten von berlin.osm.bz2 unter Berücksichtigung der Konfigurationsdaten in berlin.properties; der Parameter -X teilt der Java-Maschine (hoffentlich) genügend Arbeitsspeicher zu.

Das Resultat sind – wieder in diesem Beispiel – zwei Dateien, GpsMidBerlin-0.6.jad und GpsMidBerlin-0.6.jar, die man wie oben beschrieben aufs Smartphone laden und dort installieren kann.

AttachmentSize
Binary Data berlin.properties1.28 KB

Bereich:

System: 
GpsMid 0.6
Java ME/MIDP 2.0
(getestet auf LG KP500)
Symptom: 

GpsMid soll mit Kartenmaterial auf einem Java-Smartphone installiert werden. Unter Umständen sprengt die resultierende JAR-Datei ein von der Systemsoftware vorgegebenes Limit.