Vielen Dateien eine andere Dateiendung geben

Ab und zu hat man bei der Administration die Aufgabenstellung vielen Datei eine andere Dateiendung zu geben. Hier eine kleine Programmzeile, mit der man diese Aufgabe sehr erleichtern kann. Mit dieser kann man unter Linux oder MacOSX an alle Dateien in einem Verzeichnis die Dateiendung „.pdf“ anhängen.

ls * | cat | while read n; do mv "$n" "$n.pdf"; done

Große Mengen an Dateien per Kommandozeile mit FTP löschen

Eine häufige Aufgabenstellung bei einem Dateitransfer per FTP (File Transfer Protocol) ist das löschen von großen Mengen von Dateien per FTP. Bei einem FTP-Client mit GUI ist dies mit wenigen Klicks gemacht. Wenn man das ganze jedoch per Kommandozeile mit dem Befehlt mdel machen möchte, ist dies mit der Schwierigkeit verbunden, dass der Befehl mdel bei jeder Datei nachfragt, ob er diese wirklich löschen soll. Dies kann bei vielen Dateien sehr anstrengend werden.

Wenn man jetzt nach einem Parameter sucht, der den Befehlt mdel dazu bringt ohne eine Nachfrage alle Dateien zu löschen, wird man nicht fündig. Dies liegt daran, dass es diesen gar nicht gibt.

Man kann das Problem aber dennoch anders lösen. Und zwar in dem man als erstes den Befehlt prompt eingibt. Dieser stellt den „interactive mode“ auf off. Dadurch laufen alle FTP-Befehle ohne Rückfragen oder Rückmeldungen. Somit läuft auch der Befehlt mdel, ohne bei jeder Datei nachzufragen, ob er diese wirklich löschen soll.

Reparatur eines Servers mit Ubuntu oder Debian bei Hetzner

Des öfteren habe ich einen Linux-Server in einem Rechenzentrum der nicht mehr bootet und bei dem man nicht direkt auf den Monitor schauen kann. Bei dem Anbieter Hetzner ist es z.B. so, dass zunächst ein Gerät an den Server angeschlossen werden muss, bevor man das Monitorbild des Servers angezeigt bekommt. Dies dauert etwas länger und man verliert wertvolle Zeit.

Wesentlich schneller ist man bei Hetzner, wenn man das Rescue-System bootet und von diesem aus den Server untersucht. Dazu muss man nur über die Management-Webseite von Hetzner das Rescue-System aktivieren und den Server rebooten.

Im folgenden habe ich mir ein paar nützliche Befehle notieret, mit denen man im Rescue-System den Server untersuchen und reparieren kann. Damit habe ich diese im Notfall immer schnell zur Hand und muss nicht lange im Wiki von Hetzner suchen.

Überprüfung des RAID (Plattenspiegelung)
mit dem Befehl cat /proc/mdstat kann man sich den Status des RAID-Systems ausgeben lassen. Dies ausgäbe sollte dann wie folgt aussehen, wenn alles o.k. ist.

root@rescue ~ $ cat /proc/mdstat
Personalities : [raid1]
md2 : active raid1 sda3[0] sdb3[1]
      1936077760 blocks super 1.2 [2/2] [UU]
 
md1 : active raid1 sda2[0] sdb2[1]
      523968 blocks super 1.2 [2/2] [UU]
 
md0 : active raid1 sda1[0] sdb1[1]
      16768896 blocks super 1.2 [2/2] [UU]

Filesystem-Check
Mit dem Befehlt fsck /dev/md1 und fsck /dev/md2 kann man dann die Filesysteme prüfen lassen. Wenn diese heil sind, sollte die Ausgabe wie folgt aussehen.

root@rescue ~ $ fsck /dev/md1
fsck from util-linux 2.25.2
e2fsck 1.42.12 (29-Aug-2014)
/dev/md1: recovering journal
/dev/md1: clean, 313/131072 files, 125273/523968 blocks
root@rescue ~ $ fsck /dev/md2
fsck from util-linux 2.25.2
e2fsck 1.42.12 (29-Aug-2014)
/dev/md2: recovering journal
Setting free blocks count to 440126453 (was 440126531)
/dev/md2: clean, 5444918/121012224 files, 43892987/484019440 blocks

Erneutes schreiben des Boot-Blocks
Oft ist auch nur der Boot-Block auf der Festplatte nicht vorhanden, oder beschädigt. Mit den folgenden Befehlen kann man diesen neu schreiben.

mount /dev/md2 /mnt
mount /dev/md1 /mnt/boot
mount -o bind /dev /mnt/dev
mount -o bind /sys /mnt/sys
mount -t proc /proc /mnt/proc
cp /proc/mounts /mnt/etc/mtab
chroot /mnt /bin/bash
grub-install /dev/sda
grub-install /dev/sdb
grub-install --recheck /dev/sda
grub-install --recheck /dev/sdb
mkdir /run/lock
cp /proc/mounts /etc/mtab
update-grub

10 Jahre Purrucker Blog und ein moderneres Layout

dsc_9873Mein alter Technik-Blog feiert seinen zehnten Geburtstag. Somit hatte er ziemlich genau 10 Jahren das gleiche Layout. Im Internet ist das eine Ewigkeit. Außerdem störte mich zunehmend der für Smartphones und Tabletts nicht ganz optimale Aufbau der Menüs und Widgets. Deshalb habe ich den Blog auf ein neues und moderneres Layout mit einem Responsive Webdesign umgestellt. Damit ist der Blog jetzt auch optimal auf mobilen Geräten zu lesen.

Backup mit duply

Seit geraumer Zeit sichere ich meine Linuxserver am liebsten mit der Software duply. Der Name duply ist die Abkürzung von „simple duplicity“. Wie der Name schon verrät, wurde diese Software entwickelt, um das komplexe aber gleichzeitig auch leistungsfähige Backupframework duplicity einfach bedienbar zu machen. Und dies ist meiner Meinung nach auch hervorragend gelungen.dsc_9889

In diesem Artikel blogge ich die einzelnen Schritte, mit denen ich ein duply auf einem Debian 8 oder Ubuntu 16.04 einrichte.

Als erstes muss duply und ein brauchbares FTP-Programm für die Datenübertragung installiert werden.

apt-get install duply
apt-get install lftp

Danach muss ein zentrales Verzeichnis für die Konfiguration unter /etc angelegt und danach eine Backup-Konfiguration erstellt werden. Es ist wichtig, dass das Verzeichnis als erstes angelegt wird, da duply die Konfiguration sonst in das home-Verzeichnis und nicht unter /etc ablegt. Als Namen für die Konfiguration wähle ich immer den vollen Hostnamen. Dies ist zumeist eindeutig und läßt sich im Nachhinein leichter Skripten.

mkdir /etc/duply
duply hostname.domain.de create

Danach erzeugt man sich einen GPG-Schlüssel.

gpg --gen-key

Sofern man einen bereits existierenden GPG-Schlüssel verwenden möchte, kann man natürlich auch Schlüssel in GPG importieren. Dabei sollte man dann aber nicht vergessen, neben dem öffentlichen auch den privaten Schlüssel und die Ownertrusts zu importieren. Ich habe die beiden Schlüssel und die Ownertrusts für diese Zwecke immer in drei Dateien mit den Namen backup-key.asc, backup-secret-key.asc und backup-ownertrusts.asc. Diese brauche ich dann nur übermitteln und importieren.

gpg --import backup-key.asc
gpg --import backup-secret-key.asc
gpg --import-ownertrust backup-ownertrusts.asc

Sobald man den Schlüssel angelegt oder importier hat, läßt man sich die Public-Key-ID des GPG-Schlüssels anzeigen. Diese muss man nämlich später in die Konfiguration von duply eintragen, damit die Backups mit GPG verschlüsselt werden. Dies führt zu einer zusätzlichen Datensicherheit, die gerade bei FTP-Servern im Internet zu empfehlen ist.

gpg --list-keys

Danach passt man die Konfiguration von duply entsprechend an.

cd /etc/duply/hostname.domain.de/
vi conf

Die Datei sollte ungefähr wie folgt aussehen. Dabei muss die Schlüssel-ID und die FTP-VErbindung natürlich auf die eigene Umgebung angepasst werden.

# gpg encryption settings, simple settings:
#  GPG_KEY='disabled' - disables encryption alltogether
#  GPG_KEY='<key1>[,<key2>]'; GPG_PW='pass' - encrypt with keys,
#   sign if secret key of key1 is available use GPG_PW for sign & decrypt
#  Note: you can specify keys via all methods described in gpg manpage,
#        section "How to specify a user ID", escape commas (,) via backslash (\)
#        e.g. 'Mueller, Horst', 'Bernd' -> 'Mueller\, Horst, Bernd'
#        as they are used to separate the entries
#  GPG_PW='passphrase' - symmetric encryption using passphrase only
GPG_KEY='1234567'
GPG_PW='Hier kommt das Passwort fuer den eigenen key hin'
# gpg encryption settings in detail (extended settings)
#  the above settings translate to the following more specific settings
#  GPG_KEYS_ENC='<keyid1>[,<keyid2>,...]' - list of pubkeys to encrypt to
#  GPG_KEY_SIGN='<keyid1>|disabled' - a secret key for signing
#  GPG_PW='<passphrase>' - needed for signing, decryption and symmetric
#   encryption. If you want to deliver different passphrases for e.g.
#   several keys or symmetric encryption plus key signing you can use
#   gpg-agent. Simply make sure that GPG_AGENT_INFO is set in environment.
#   also see "A NOTE ON SYMMETRIC ENCRYPTION AND SIGNING" in duplicity manpage
# notes on en/decryption
#  private key and passphrase will only be needed for decryption or signing.
#  decryption happens on restore and incrementals (compare archdir contents).
#  for security reasons it makes sense to separate the signing key from the
#  encryption keys. https://answers.launchpad.net/duplicity/+question/107216
#GPG_KEYS_ENC='<pubkey1>,<pubkey2>,...'
#GPG_KEY_SIGN='<prvkey>'
# set if signing key passphrase differs from encryption (key) passphrase
# NOTE: available since duplicity 0.6.14, translates to SIGN_PASSPHRASE
#GPG_PW_SIGN='<signpass>'
 
# uncomment and set a file path or name force duply to use this gpg executable
# available in duplicity 0.7.04 and above (currently unreleased 06/2015)
#GPG='/usr/local/gpg-2.1/bin/gpg'
 
# gpg options passed from duplicity to gpg process (default='')
# e.g. "--trust-model pgp|classic|direct|always"
#   or "--compress-algo=bzip2 --bzip2-compress-level=9"
#   or "--personal-cipher-preferences AES256,AES192,AES..."
#   or "--homedir ~/.duply" - keep keyring and gpg settings duply specific
#   or "--pinentry-mode loopback" - needed for GPG 2.1+ _and_
#      also enable allow-loopback-pinentry in your .gnupg/gpg-agent.conf
#GPG_OPTS=''
 
# disable preliminary tests with the following setting
#GPG_TEST='disabled'
 
# backend, credentials & location of the backup target (URL-Format)
# generic syntax is
#   scheme://[user[:password]@]host[:port]/[/]path
# eg.
#   sftp://bob:secret@backupserver.com//home/bob/dupbkp
# for details and available backends see duplicity manpage, section URL Format
#   http://duplicity.nongnu.org/duplicity.1.html#sect7
# NOTE:
#   some backends (eg. cloudfiles) need additional env vars to be set to
#   work properly, when in doubt consult the man page mentioned above.
# ATTENTION:
#   characters other than A-Za-z0-9.-_.~ in the URL have to be
#   replaced by their url encoded pendants, see
#     http://en.wikipedia.org/wiki/Url_encoding
#   if you define the credentials as TARGET_USER, TARGET_PASS below duply
#   will try to url_encode them for you if the need arises.
#TARGET='scheme://user[:password]@host[:port]/[/]path'
TARGET='ftp://user:passwort@ftphost.domain.de/'
# optionally the username/password can be defined as extra variables
# setting them here _and_ in TARGET results in an error
#TARGET_USER='_backend_username_'
#TARGET_PASS='_backend_password_'
# alternatively you might export the auth env vars for your backend here
# when in doubt consult (if existing) the NOTE section of your backend on
#  http://duplicity.nongnu.org/duplicity.1.html for details
# eg. for cloud files backend it might look like this (uncomment for use!)
#export CLOUDFILES_USERNAME='someuser'
#export CLOUDFILES_APIKEY='somekey'
#export CLOUDFILES_AUTHURL ='someurl'
 
# base directory to backup
SOURCE='/'
 
# a command that runs duplicity e.g.
#  shape bandwidth use via trickle
#  "trickle -s -u 640 -d 5120" # 5Mb up, 40Mb down"
#DUPL_PRECMD=""
 
# override the used python interpreter, defaults to "python2"
#   e.g. "python" or "/usr/bin/python2.7"
#PYTHON="python2"
 
# exclude folders containing exclusion file (since duplicity 0.5.14)
# Uncomment the following two lines to enable this setting.
#FILENAME='.duplicity-ignore'
#DUPL_PARAMS="$DUPL_PARAMS --exclude-if-present '$FILENAME'"
 
# Time frame for old backups to keep, Used for the "purge" command.
# see duplicity man page, chapter TIME_FORMATS)
MAX_AGE=3M
 
# Number of full backups to keep. Used for the "purge-full" command.
# See duplicity man page, action "remove-all-but-n-full".
MAX_FULL_BACKUPS=3
 
# Number of full backups for which incrementals will be kept for.
# Used for the "purge-incr" command.
# See duplicity man page, action "remove-all-inc-of-but-n-full".
#MAX_FULLS_WITH_INCRS=1
 
# activates duplicity --full-if-older-than option (since duplicity v0.4.4.RC3)
# forces a full backup if last full backup reaches a specified age, for the
# format of MAX_FULLBKP_AGE see duplicity man page, chapter TIME_FORMATS
# Uncomment the following two lines to enable this setting.
#MAX_FULLBKP_AGE=1M
#DUPL_PARAMS="$DUPL_PARAMS --full-if-older-than $MAX_FULLBKP_AGE "
 
# sets duplicity --volsize option (available since v0.4.3.RC7)
# set the size of backup chunks to VOLSIZE MB instead of the default 25MB.
# VOLSIZE must be number of MB's to set the volume size to.
# Uncomment the following two lines to enable this setting.
#VOLSIZE=50
#DUPL_PARAMS="$DUPL_PARAMS --volsize $VOLSIZE "
 
# verbosity of output (error 0, warning 1-2, notice 3-4, info 5-8, debug 9)
# default is 4, if not set
#VERBOSITY=5
 
# temporary file space. at least the size of the biggest file in backup
# for a successful restoration process. (default is '/tmp', if not set)
#TEMP_DIR=/tmp
 
# Modifies archive-dir option (since 0.6.0) Defines a folder that holds
# unencrypted meta data of the backup, enabling new incrementals without the
# need to decrypt backend metadata first. If empty or deleted somehow, the
# private key and it's password are needed.
# NOTE: This is confidential data. Put it somewhere safe. It can grow quite
#       big over time so you might want to put it not in the home dir.
# default '~/.cache/duplicity/duply_<profile>/'
# if set  '${ARCH_DIR}/<profile>'
#ARCH_DIR=/some/space/safe/.duply-cache
 
# DEPRECATED setting
# sets duplicity --time-separator option (since v0.4.4.RC2) to allow users
# to change the time separator from ':' to another character that will work
# on their system.  HINT: For Windows SMB shares, use --time-separator='_'.
# NOTE: '-' is not valid as it conflicts with date separator.
# ATTENTION: only use this with duplicity < 0.5.10, since then default file
#            naming is compatible and this option is pending depreciation
#DUPL_PARAMS="$DUPL_PARAMS --time-separator _ "
 
# DEPRECATED setting
# activates duplicity --short-filenames option, when uploading to a file
# system that can't have filenames longer than 30 characters (e.g. Mac OS 8)
# or have problems with ':' as part of the filename (e.g. Microsoft Windows)
# ATTENTION: only use this with duplicity < 0.5.10, later versions default file
#            naming is compatible and this option is pending depreciation
#DUPL_PARAMS="$DUPL_PARAMS --short-filenames "
 
# more duplicity command line options can be added in the following way
# don't forget to leave a separating space char at the end
#DUPL_PARAMS="$DUPL_PARAMS --put_your_options_here "

Bei Bedarf, kann man dann noch Verzeichnisse vom Backup ausschließen.

vi exclude

Anzeige der bereits gelaufenen Backups:

duply $(hostname -f) status

Starten eines Full-Backups:

duply $(hostname -f) full

Löschen veralteter Backups:

duply $(hostname -f) purge-full --force

Einrichtung einer täglichen, inkrementellen Sicherung mit anschließendem löschen der veralteten Backups:
Um duply jede Nacht ein Backup machen zu lassen, muss ein Cron-Job angelegt werden. Dazu legt man am besten die Datei /etc/cron.d/duply mit dem folgenden Befehlt an.

vi /etc/cron.d/duply

Wenn man jede Nacht um 2 Uhr eine Sicherung machen möchte, sollte in dieser Datei die folgende Zeile eingetragen werden.

0 2 * * * root /usr/sbin/duply.sh >/dev/null 2>&1

Danach muss die Datei /usr/sbin/duply.sh angelegt werden, die vom Cron-Job aufgerufen wird.

vi /usr/sbin/duply.sh

In dieser sollte dann das folgende stehen.

#!/bin/sh
#
# Script created on 04-10-2015 KPU
#
# This script was created to make Duplicity backups.
#
# 05.01.2016 K.Purrucker
# Ergaenzung: Es wird immer der Hostname als Konfigname verwendet
#
 
duply $(hostname -f) backup >>/var/log/duply.log
duply $(hostname -f) purge-full --force >>/var/log/duply.log
 
exit 0

Danach muss noch cron neu gestartet, die Datei ausführbar gemacht und das Log-File angelegt werden.

chmod a+x /usr/sbin/duply.sh
service cron restart
touch /var/log/duply.log

Beispiel: Rücksicherung einer 7 Tage alten Version der Datei etc/fstab in das Verzeichnis /root/:
duply $(hostname -f) fetch etc/fstab /root/fstab 7D

Umleitung auf einen anderen DNS-Namen und erzwingen von HTTPS innerhalb eines VirtualHosts

Wenn man eine Webseite mit mehreren DNS-Namen betreibt, möchte man meistens nur ein SSL-Zertifikat für diese erwerben. Eine solche Webseite wird bei einem Apache Webserver zudem meistens innerhalb eines VirtualHost konfiguriert. Daraus ergibt sich somit die Anforderung, innerhalb eines VirtualHost bei einem Apache Webserver gleich zwei Weiterleitungen zu konfigurieren.

  1. Eine Weiterleitung von http://<hostname1>.<domain>.de auf http://<hostname2>.<domain>.de
  2. Eine Weiterleitung von  http://<hostname2>.<domain>.de auf https://<hostname2>.<domain>.de

Damit der Browser keine Warnmeldung ausgibt, muss dass Zertifikat für den richtigen DNS-Namen ausgestellt sein. Deshalb ist es sehr wichtig, dass die Weiterleitungen nicht gleichzeitig sondern nacheinander ausgeführt werden. Beim ersten Aufruf der Seite muss nur auf den zweiten DNS-Namen umgeleitet werden. Beim zweiten Aufruf der Seite (der dann ja schon über den zweiten DNS-Namen erfolgt) muss dann von HTTP auf HTTPS umgeleitet werden.

Die serverseitige Umleitung von einer URL auf die andere Erfolg bei Apache üblicherweise über das Modul mod_rewrite. Bevor man dieses verwendet, muss es aktiviert werden. Dies geschieht bei Debien oder Ubuntu mit den folgendem Befehl.

a2enmod rewrite

Danach muss der Apache neu gestartet werden, damit das Modul geladen wird. Dies erledigt man bei einem neueren Ubuntu z.B. mit dem folgenden Befehl.

service apache2 restart

Die Regel für eine Weiterleitung besitzt bei Apache sogenannte Flags. Diese legen die genaue Funktionsweise der Weiterleitung fest. Um eine Weiterleitung durch Ersetzen zu erreichen wird das Flag R benötigt. Das Flag R steht für Replace und bedeutet, dass Teile der URL durch etwas anderes ersetzt werden. Wenn die Weiterleitung zudem dauerhaft sein soll, ist bei dem Flag R zudem ein Grund 301 hilfreich. Dieser Grund signalisiert, dass die Weiterleitung dauerhaft sein soll. Das Flag wird dann als „R=301“ geschrieben.

Obwohl die Konfiguration für beide Weiterleitungen in der Konfiguration von demselben VirtualHost steht, darf nur eine zur Zeit ausgeführt werden. Dies wird durch das Flag L erreicht. Dieses Flag steht für Last und bedeutet, dass beim Greifen der Rewrite-Regel keine weitere Rewrite-Regel ausgeführt wird. Es wird also immer nur eine Regel pro Aufruf ausgeführt.

Zudem ist wichtig, dass als erstes die Regel für die Weiterleitung auf den ersten DNS-Namen kommt. Erst danach darf die Regel für die Weiterleitung auf HTTPS kommen.

Wenn man all diese Bedingungen beachtet, sollten Rewrite-Regeln wie folgt aussehen.

RewriteEngine on
RewriteCond %{HTTP_HOST}   ^hostname1\.domain\.de$ [NC]
RewriteRule   ^/(.*)$ http://hostname2.domain.de/$1  [R=301,L]
 
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

Weitere Informationen zum mod_rewrite gibt es auf den entsprechenden Webseiten beim Apache-Projekt unter http://httpd.apache.org/docs/current/mod/mod_rewrite.html oder https://httpd.apache.org/docs/current/rewrite/flags.html zu finden.

SVN auf einem Ubuntu 14.04 mit Plesk installieren

Ich habe Heute ein SVN (Subversion) auf einem Ubuntu 14.04 Server mit einem SVN Plesk 12.5 installiert. Damit dies gelingt muss man ein Kleinigkeiten beachten. Zudem gibt es diverse Anleitungen im Netz, die sich nicht an die Vorgaben von Plesk halten. Wenn man eine solche Anleitung befolgt, kann dies Folgeproblemen verursachen. Kurz um … ich beschreibe hier mal, wie man die Installation richtig macht.

1. Installation von svn aus den Paketquellen von Ubuntu
Dazu loggt man sich per ssh auf dem Server ein und installiert die Pakete mit dem folgenden Befehl (muss als root ausgeführt werden):

apt-get install subversion libapache2-svn

2. Eine Subdomain in Plesk anlegen
In meinem Fall heißt die Subdomain save. Wie das geht ist im Handbuch von Plesk zu finden: https://docs.plesk.com/de-DE/12.5/customer-guide/websites-und-domains/domains-und-dns/hinzufügen-von-subdomains.65180/

3. Authentifizierung und die SVN-Einstellungen in die Konfiguration des vHost einbauen
Damit diese Konfiguration bei Änderungen in Plesk nicht überschrieben wird, sollte man sie über das Webinterface von Plesk einbauen. Dazu muss man in die „Web Server Settings. Um dorthin zugegangen, klickt man auf der Linken Seite auf „Hosting Services“ Domains bei der richtigen Domain auf „Hosting Settings“ Es geht ein Reiter auf. Auf diesem findet man die „Web Server Settings“
Plesk 12.5 Web Server Settings
Dort trägt man dann als „Alditional direktives“ für HTTP und HTTPS (sofern man https nutzen möchte) die folgenden Zeilen ein (dabei die Domain und Subdomain anpassen!):

<Location /svn>
DAV svn
SVNParentPath /var/www/vhosts/[DOMAIN NAME]/subdomain-name
SVNListParentPath On
 
AuthType Basic
AuthName "SVN Authorization Realm"
AuthUserFile /etc/apache2/mods-enabled/dav_svn.passwd
Require valid-user
</Location>

4. Benutzer, Verzeichnis und Repository anlegen
Dazu gibt man als root die folgenden Befehle ein:

htpasswd -c /etc/apache2/mods-enabled/dav_svn.passwd USERNAME
cd /var/www/vhosts/DOMAIN/subdomains/subdomain-name
mkdir svn
svnadmin create svn/projektname
chown -R www-data:www-data svn/
service apache2 restart

Danach sollte das SVN laufen. Falls nicht, sind hier noch ein paar weiterführende Informationen zur Fehlerbehebung zu finden: https://talk.plesk.com/threads/basic-subversion-svn-on-plesk-12-5.338617/

Wenn Server nach einem Neustart die Netzwerkkarten vertauscht haben

Ich hatte letztlich das Problem, dass sich Netzwerkkarten bei Linux und Windows nach einem Neustart immer wieder vertauschten. Da die Server dadurch über Netzwerk nicht mehr erreichbar sind und ausfallen, ist das natürlich sehr ärgerlich. Da ich jetzt gerade eine neuen Firewall auf Basis von Ubuntu Linux mit 9 Netzwerkkarten und 100 VPN-Tunneln eingerichtet habe, wollte ich das Problem auf jeden Fall verhindern. Deshalb habe ich das Problem noch mal genauer untersuch und viel Doku dazu gelesen. Jetzt ist mir klar warum das Problem auftritt und ich kann es zukünftig verhindern.

Ursache: Da die Betriebssysteme zum schnellen Booten alles parallel starten, kommt es beim Booten regelmäßig dazu, dass die Hardwaretreiber in anderer Reihenfolge geladen werden. Wenn man im Server zwei Netzwerkkarten mit unterschiedlichen Treibern hat, kann dabei die Reihenfolge vertauscht werden, in der die Treiber geladen werden. Da bei älteren Windows- und Linuxservern die Netzwerkkarten einfach nur anhand der Startreihenfolge durchnummeriert werden, kann es somit vorkommen, dass die IP-Konfiguratiuonen der Karten durcheinander gewürfelt werden.

Lösung bei neueren Betriebssystemen: Bei neueren Betriebssystemen wird das Vertauschen der Karten verhindert. Windows merkt sich inzwischen für welche Karte eine Konfiguration war und zählt bei neuen Karten einfach immer weiter hoch. Es bindet (vermutlich anhand der Mac-Adresse oder Seriennummer) die Konfiguration fest an eine Netzwerkkarte und vergibt eine bereits vergebene Nummer kein zweites mal. Deshalb hat man bei Windows auch machmal einen Netzwerkadapter 5 oder 6, obwohl aktuell nur eine Karte im Betriebssystem steckt. Bei Linux wird der Steckplatz der Karte mit in den Namen der Netzwerkkarte aufgenommen. Eine Netzwerkkarte auf PCI-Slot 2 heißt dann z.B. p2p1, wobei das p2 dann für den PCI-Slot 2 und das p1 für den ersten Port der Karte steht. Theoretisch kann man bei Linux also eine neue Karte in den gleichen Slot stecken und die Konfiguration sollte noch funktionieren.

Debian: Upgrade von 6.0 (Squeeze) auf 7.0 (Wheezy)

Ein Upgrade eines Debian Systems von Version 6.0 (Squeeze) auf Version 7.0 (Wheezy) ist so simpel geblieben wie das vorherige Upgrade. Ich habe das Upgrade für diverse Server wie folgt durchgeführt.

Datensicherung
Als erstes sollte das bestehende System mit einer Datensicherungssoftware gesichert werden. Dazu kommen eine ganze Reihe von Programmen wie cpio, tar, amanda oder rsnapshot infrage. Nähere Infos zu Backupsoftware unter Linux kann man in meinem Artikel Backup-Software für Linux nachlesen.

Danach sollte eine Liste der Installierten Software-Pakete erstellt werden, damit man im Notfall wieder ein System mit identischer Software installieren kann. Eine Anleitung dazu ist in meinem Artikel Ubuntu/Debian: Die gleiche Software auf einem neuen Computer installieren zu finden.

Einspielung aller Updates für das bestehende Debian
Bevor das eigentliche Upgrade auf die Version 6.0 gemacht wird sollten alle Updates für die alte Version eingespielt werden. Dazu muss zunächst die source-list aktualisiert werden:

aptitude update

Danach können die Updates installiert werden:

aptitude upgrade

Anpassen der sources-list
Damit die neuen Pakete gefunden werden, muss in der source-list das Wort lenny gegen squeeze getauschen werden. Die source-list befindet sich in der Datei /etc/apt/sources.list. Die Datei sollte nach den Änderungen etwa wie folgt aussehen:

deb http://ftp.de.debian.org/debian/ wheezy main
deb http://ftp.de.debian.org/debian/ wheezy contrib
deb http://ftp.de.debian.org/debian/ wheezy non-free
deb-src http://ftp.de.debian.org/debian/ wheezy main
 
# Security-Updates
deb http://security.debian.org/ wheezy/updates main contrib
deb-src http://security.debian.org/ wheezy/updates main contrib

Upgrade
Nun muss erneut die source-list aktualisiert werden:

aptitude update

Danach werden zuerst die Update-Werkzeuge aktualisiert:

aptitude install apt dpkg aptitude

Zum Schluss wird dann der Rest der Pakete aktualisiert:

aptitude full-upgrade

Während der Aktualisierung der einzelnen Software-Pakete wird dann ab und zu noch die ein oder andere Frage gestellt, bevor der abschließende Neustart fällig wird. Nach dem Neustart ist das Upgrade abgeschlossen.

Probleme bei der Virtualisierung mit Ubuntu 14.04 LTS und KVM

Nachdem Ubuntu 14.04 LTS jetzt schon über zwei Monate alt ist, habe ich die ersten Server migriert. Ich hatte gehofft, dass die meisten schlimmen Fehler inzwischen behoben sind und man das System ohne größere Probleme betreiben kann.

Als ich den ersten Server für Virtualisierung migrierte, erwies sich meine Annahme aber leider als falsch. Zunächst liefen die Gast-Betriebsysteme ohne Probleme und dank der Technik Hyper V von Microsoft auch viel schneller als vorher. Je nach Auslastung wurden sie aber zunehmend langsamer und stürzten nach 3 bis 12 Stunden ganz ab. Die Windows-Gäste standen dann im Bluescreen und die Linux-Gäste hatten eine Kernelpanik.

Wie sich zeigte gibt es im Linux-Kernel 3.13 von Ubuntu 14.04 wohl noch einige Bugs, die früher oder später für einen Absturz der Gast-Betriebssysteme sorgen:

Nach diversen erfolglosen Versuchen das Problem in den Griff zu bekommen, stieß ich auf einen Blog-Post von Peter Kieser. Dieser machte den Vorschlag, den erprobten Linux-Kenel 3.10 mit Langzeitsupport für Ubuntu 14.04 zu kompilieren. Dieser Kernel wird auch bei RedHat Enterprise Linux verwendet, ist für Virtualisierung erprobt und er löste alle meine Probleme! Und dies geht wie folgt (ggf. kann man natürlich auch einen neueren Patchlevel des 3.10er Kerbels verwenden):

apt-get -y install build-essential
cd /usr/local/src
wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.10.46.tar.xz
tar -Jxf linux-3.10.46.tar.xz
cd linux-3.10.46
cp /boot/config-`uname -r` .config
make olddefconfig
make -j`nproc` INSTALL_MOD_STRIP=1 deb-pkg
dpkg -i ../*.deb
apt-mark hold linux-libc-dev

Außerdem machte Peter Kieser noch einige Tuning Vorschläge, die er auch durch den Vergleich mit RedHat Enterprise Linux gefunden hatte. Ich habe mir davon die Verwendung des e1000 Netzwerkkartentreibers bei den Windows-Gästen, die Einträge für Hyper V in der Konfig der Windows-Gäste, die Anpassung von Grub und die Einträge in der /etc/sysctl.conf abgeschaut.

Einträge für Hyper V in der Konfig der Windows-Gäste

In die Konfig der Windows-Gäste müssen – sofern noch nicht vorhanden – die folgenden Zeilen in den Abschnitt „features“ eingetragen werden:

  <hyperv>
    <relaxed state='on'/>
    <vapic state='on'/>
    <spinlocks state='on' retries='4096'/>
  </hyperv>

In die Konfig der Windows-Gäste gelangt man am einfachsten, wenn man in der virsh

edit <Name der virtuellen Maschine>

eingibt. Man landet dann mit einem vi in der Konfig und wenn man den vi beendet, wird die Konfig auch gleich richtig gespeichert.

Die Datei sollte nach den Änderungen etwa wie folgt aussehen:

<domain type='kvm'>
  <name>WKSNUE01</name>
  <uuid>cce892d2-8fee-3add-f25d-6a46b1f14268</uuid>
  <memory unit='KiB'>4194304</memory>
  <currentMemory unit='KiB'>4194304</currentMemory>
  <vcpu placement='static'>1</vcpu>
  <os>
    <type arch='x86_64' machine='pc-1.0'>hvm</type>
    <boot dev='hd'/>
  </os>
  <features>
    <acpi/>
    <apic/>
    <pae/>
    <hyperv>
      <relaxed state='on'/>
      <vapic state='on'/>
    </hyperv>
  </features>
  <clock offset='localtime'/>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>restart</on_crash>
  <devices>
    <emulator>/usr/bin/kvm</emulator>
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <source file='/daten/images/WKSNUE01.img'/>
      <target dev='hda' bus='ide'/>
      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
    </disk>
    <controller type='ide' index='0'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
    </controller>
    <controller type='usb' index='0'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
    </controller>
    <controller type='pci' index='0' model='pci-root'/>
    <interface type='network'>
      <mac address='52:54:00:14:8c:a5'/>
      <source network='default'/>
      <model type='rtl8139'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>
    <serial type='pty'>
      <target port='0'/>
    </serial>
    <console type='pty'>
      <target type='serial' port='0'/>
    </console>
    <input type='tablet' bus='usb'/>
    <input type='mouse' bus='ps2'/>
    <input type='keyboard' bus='ps2'/>
    <graphics type='vnc' port='-1' autoport='yes'/>
    <sound model='ich6'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
    </sound>
    <video>
      <model type='vga' vram='9216' heads='1'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
    </video>
    <memballoon model='virtio'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
    </memballoon>
  </devices>
</domain>

Anpassung von Grub

In der Datei „/etc/default/grub“ sollten für den Linux-Kernel „Headline scheduler“, and „transparent hugepages“ eingeschaltet werden. Dies macht macht man in der Variable „GRUB_CMDLINE_LINUX_DEFAULT“. Die Zeile mit der Variable sollte dazu wie folgt aussehen.

GRUB_CMDLINE_LINUX_DEFAULT="elevator=deadline transparent_hugepage=always"

Damit die Anpassung aktiv wird muss man noch den folgenden Befehl eingeben.

update-grub

Einträge für die Datei /etc/sysctl.conf

kernel.sched_min_granularity_ns=10000000
kernel.sched_wakeup_granularity_ns=15000000
vm.dirty_ratio=10
vm.dirty_background_ratio=5
vm.swappiness=10