Sammelleidenschaft
Gerade kurz vor den Klausuren sucht man sich ja immer mal wieder gerne Beschäftigungen um sich vom Lernen abzuhalten. So ist das auch bei mir. Meine Sammelleidenschaft wurde wieder neu entfacht. Und das für meine treue Kindheitskonsole: das Super Nintendo. Bis heute hat es keine einzige Konsole geschafft mich so zu fesseln wie das SNES zu seiner Zeit. Auf keiner Konsole gab es so viele faszinierende Rollenspiele wie auf dem Super Nintendo. Höchste Zeit die Konsole mal wieder auszupacken und die Spielesammlung etwas zu erweitern. Insbesondere mit Spieleperlen wie Star Ocean, Tales of Phantasia, Secret of Mana 2, ... kurzum mit Spielen, die es nie nach Europa bzw. in die USA geschafft haben und die durch Fanübersetzungen für mich erst spielbar wurden. Da am Emulator kein so richtiges Flair aufkommen will, muss ein anderer Weg her diese Spiele auf dem SNES zu spielen. Das Stichwort heißt Cartmodding und damit verbunden auch andere Hardware-Hacks an der Konsole. Mehr zu diesen Themen bald hier auf dem Blog, bzw. auf einer gesonderten Projektseite.
Neue Universität, alter Stress
Man sollte meinen andere Hochschulen seien besser organisiert als die Berufsakademie Stuttgart, doch weit gefehlt! Wenn ich einen Vergleich ziehe, dann ist die BA Stuttgart die bestorganisierte Hochschule, die ich kenne (allerdings kenne ich nur 2 Hochschulen). Sekretärinnen haben keine Sprechstunden, man hat definitive Ansprechpartner, Probleme können schnell, unkompliziert und unbürokratisch gelöst werden, ...
Ganz anders hier. Mit meiner Zulassung zum Masterstudiengang waren Zulassungsauflagen verbunden. Ich will hier nicht pauschal behaupten, dass man BA-Studenten damit einen Stein in den Weg legen will, z.B. weil man sie an regulären Hochschulen nicht oder nur sehr ungern aufnehmen will, aber der Eindruck kann schnell entstehen. Natürlich gab ich mich mit den Zulassungsauflagen nicht zufrieden, da ich alle Leistungen, die ich nachholen sollte schon an der BA Stuttgart erfolgreich erbracht habe. Also hieß es: Bescheinigungen an der BA einholen, Anträge schreiben, begründen, Gegenüberstellungstabellen ausfüllen, etc etc. Der Antrag ging letzte Woche dann endlich durch den Prüfungsausschuss und siehe da: er wurde in allen Punkten bewilligt. Mein (naheliegender) Schluss ist nun, dass einem wirklich jemand Steine in den Weg legen will oder dass Zulassungsanträge nicht individuell bearbeitet werden, sondern sobald ein gewisses Stichwort gefunden wurde (wie z.B. Berfusakademie) pauschal (nicht gerechtfertigte) Auflagen erteilt werden.
Mein Tipp für alle, denen es ähnlich geht: Wenn ihr euch ungerecht behandelt fühlt, wehrt euch! Und wehrt euch früh, denn wenn man es erst kurz vor Semesterende macht, wie z.B. ich, dann ist der Stundenplan schon versaut und man kommt nicht auf seine XX ECTS-Punkte, die man in einem Semester sammeln soll, damit man das Studium in der Regelstudienzeit abschließen kann. Der Prüfungsausschuss ist gerne bereit sein "Urteil" zu revidieren, wenn man nachvollziehbar darlegt, dass man geforderte Leistungen schon erbracht hat.
P.S.: Meine Auflagen waren das Nachholen von Theoretischer Informatik, Mathematik 3 (z.B. Gleichungen mehrerer Veränderlicher, Integralrechnung), sowie Algorithmen. Also nicht gerade wenig Auflagen und auch nicht gerade wenig anspruchsvoll. Und vor allem völlig unnötig, wenn man die Leistungen schon erbracht hat...
Der neue Server: Teil X Sonstiges
Der Entwurf zu diesem Beitrag ist schon fast ein Jahr alt. Ich will ihn nun endlich mal veröffentlichen in der Hoffnung, dass er einigen Leuten hilft und ihnen Arbeit abnimmt.
------------------
In diesem Beitrag sind alle Dinge zusammengefasst, die thematisch nicht direkt zusammenpassen oder nicht direkt in einen einzigen Beitrag passen, da sie mehrere Themen streifen.
ssl-Zertifikat erstellen
Jetzt erstellen wir ein ssl-Zertifikat, welches wir bei cacert.org signieren lassen. Dies bietet einige Vorteile gegenüber dem Selbst-Signieren (self-signing). Leider ist das cacert.org Root-Zertifikat noch nicht in Firefox aufgenommen und somit erhält man immer diese lästige Warnung, wenn man eine cacert-zertifizierte Webseite aufruft, bis man deren Root-Zertifikat in Firefox importiert.
Am Besten geht man nach dieser Anleitung vor zum Erstellen eines Zertifikats: http://wiki.cacert.org/wiki/CSRGenerator. Danach verschiebt man den Private-Key nach "/etc/ssl/private" und den Public-Key nach "/etc/ssl/certs". Nun kann man das Zertifikat z.B. in Apache verwenden, aber auch für den Mailserver, IMAP-/POP-Server, svn, ... Sollte eine Applikation nicht auf den Private-Key zugreifen können, benötigt aber Zugriff darauf, so muss man den Benutzer unter der die Applikation läuft in die Gruppe "ssl-cert" aufnehmen (ACHTUNG: Dies könnte ein Sicherheitsrisiko darstellen!).
Diffie-Hellman-Code erzeugen
Dies wird z.B. für postfix gebraucht, aber auch für einige IMAP-Server, deshalb erzeugen wir hier diesen Code und speichern ihn unter "/etc/ssl/private/":
openssl gendh -out /etc/ssl/private/dh_1024.pem -2 -rand /dev/urandom 1024 openssl gendh -out /etc/ssl/private/dh_512.pem -2 -rand /dev/urandom 512
SSL-vHost in apache erstellen
Um in apache einen SSL-vHost erstellen kann, muss man die Datei ports.conf unter "/etc/apache2" ändern und die folgende Zeilen hinzufügen/ergänzen:
<IfModule mod_ssl.c> # SSL name based virtual hosts are not yet supported, therefore no # NameVirtualHost statement here NameVirtualHost *:443 Listen 443 </IfModule>
Danach können wie gehabt vHosts erstellt werden, mit dem Unterschied, dass die Zeile "
SSLEngine on
SSLCertificateFile /etc/ssl/certs/server.pem
SSLCertificateKeyFile /etc/ssl/private/privatekey.pem
SSLCipherSuite HIGH
SSLProtocol all -SSLv2Weiter unten stelle ich ein Skript vor, mit welchem man bequem vHosts (sowohl mit und ohne SSL) erstellen kann und automatisch von Port 80 auf Port 443 weiterleiten, wenn der vHost SSL unterstützt.
Quellen:
http://wiki.cacert.org/wiki/CSRGenerator
http://cacert.org/
sftp-Gastzugang
Oft möchte man Leuten einen Zuganz zu seinem Server verschaffen, damit man etwas in ein bestimmtes Verzeichnis hochladen, bzw. daraus herunterladen darf, aber nicht aus diesem Verzeichnis herausnavigieren darf und evtl. Schaden anrichten kann. Dies kann man mit openSSH 5.0 sehr einfach lösen, da es eingebaute chroot-Mechanismen hat. So kann man z.B. eine ganze Gruppe auf ihr Home-Laufwerk oder einen anderen Ordner beschränken oder aber auch nur einen einzigen Benutzer. Im Folgenden legen wir eine Gruppe "chrooted" an, welche auf ihr Home-Laufwerk beschränkt sein wird. Alle Home-Laufwerke dieser Gruppe werden standardmäßig unter "/home/chrooted" liegen. Für unseren Gastbenutzer legen wir darunter ein Verzeichnis "upload" an und ändern die Rechte entsprechend:
mkdir upload chown <uploaduser>:users /home/chrooted/upload chmod 775 /home/chrooted/upload
Will man Ordner außerhalb des Home-Laufwerks zugänglich machen, kann man diese mit "mount -o bind" temporär einbinden, bzw. über die "/etc/fstab" dauerhaft:
/pfad/zum/quellverzeichnis /pfad/zum/zielverzeichnis none rw,bind 0 0
Gruppe "chrooted" anlegen:
addgroup --system chrootedUm einen Benutzer in die Gruppe "chrooted" aufzunehmen, führt man folgenden Befehl aus:
adduser <uploaduser> chrooted
Danach muss man die sshd_config anpassen, bzw. erweitern:
#Subsystem sftp /usr/lib/openssh/sftp-server Subsystem sftp internal-sftp Match group chrooted # chroot all users of these group to their homes # %h will be substituted by the user's home # %u will be substituted with the user's user name ChrootDirectory %h AllowTcpForwarding no ForceCommand internal-sftp
Wichtig ist, dass das Home-Verzeichnis des Benutzers root gehören muss ("chown root: /pfad/zu/home"). Die Unterordner sollten dann wieder dem Benutzer gehören, damit das ganze auch Sinn macht und er Dateien hoch-/runterladen kann. In unserem Beispiel bedeutet das, dass "/home/chrooted" root gehören muss und "/home/chrooted/upload" dem
Zusätzlich kann man nun noch unter "/etc/passwd" die Standardkonsole des
<uploaduser>:x:1666:1666:Guest upload-account,,,:/home/chrooted:/bin/false
Quellen:
http://binblog.wordpress.com/2008/04/06/openssh-chrooted-sftp-eg-for-webhosting/
http://www.debian-administration.org/articles/590
Tauschverzeichnis anlegen
Da alle Konsolenbenutzer auch Mitglied in der Gruppe "users" sind, ist es ein leichtes ein Tausch-Verzeichnis unter "/home/shared" anzulegen. Darunter legen wir - der Benutzerfreundlichkeit zuliebe - einen Symlink nach "/home/chrooted/upload" an (siehe vorheriges Kapitel):
mkdir /home/shared chown root:users /home/shared chmod 775 /home/shared ln -s /home/chrooted/upload upload
Nun können sich alle Konsolenbenutzer über dieses Verzeichnis austauschen und auf die Dateien des Gast-Accounts zugreifen, welche für ihn bereitstellen bzw. je nach Rechten auch welche löschen.
vHosts-Skript
Um einem die Arbeit etwas zu erleichtern habe ich schnell ein kleines bash-Skript runtergehackt, mit welchem man bequem vHosts unter apache2 anlegen kann. Ist man nach Der neue Server: Teil 4 apache vorgegangen, so müssen im Skript normalerweise keine Änderungen vorgenommen werden, anderfalls braucht das Skript evtl. ein paar Anpassungen.
Hier das Skript:
createVhost.sh:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | #!/bin/bash # createVhost.sh - Creates an Apache2 vHost configuration # # Copyright (C) 2009 johker # # This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License v2 as published by the Free Software Foundation # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License v2 for more details. ### CHANGE ME! ### WWW_ROOT="/var/www" SITES_ROOT="/etc/apache2/sites-available" CHANGE_PHP_INI="no" EXAMPLE_ROOT="$WWW_ROOT/example" SITES_EXAMPLE="$SITES_ROOT/example" SITES_EXAMPLE_SSL="$SITES_EXAMPLE-ssl" SSL_PRIV_DEFAULT="/etc/ssl/private/privatekey.pem" SSL_PUB_DEFAULT="/etc/ssl/certs/publickey.pem" PHP_INI_TEMPLATE="/etc/php5/cgi/php.ini" ### END CHANGE ME! ### ############################################################# ########## DO NOT CHANGE ANYTHING BELOW THIS LINE! ########## ############################################################# # Make sure only root can run our script if [ "$(id -u)" != "0" ]; then echo "ERROR: This script must be run as root!" 1>&2 exit 1 fi # Query the user for some details read -p "Domain name: " SRV_NAME read -p "Domain aliases (leave blank if no aliases available, separated by blank): " SRV_ALIAS read -p "Admin e-mail address: " SRV_ADMIN read -p "vHost owner (system user): " USER read -p "Use SSL (yes/no)[no]: " SSL if [ -z $SSL ]; then # set default value SSL="no" fi if [ $SSL == "yes" ]; then read -p "SSL private key[$SSL_PRIV_DEFAULT]: " CERT_PRIV read -p "SSL public key[$SSL_PUB_DEFAULT]: " CERT_PUB if [ -z $CERT_PRIV ]; then # set default value CERT_PRIV=$SSL_PRIV_DEFAULT fi if [ -z $CERT_PUB ]; then # set default value CERT_PUB=$SSL_PUB_DEFAULT fi fi VHOST_ROOT="$WWW_ROOT/$SRV_NAME" DOC_ROOT="$VHOST_ROOT/docs" CONF_ROOT="$VHOST_ROOT/conf" LOG_ROOT="$VHOST_ROOT/logs" TMP_ROOT="$VHOST_ROOT/tmp" PHP_FCGI="$CONF_ROOT/php-fcgi.conf" PHP_INI="$CONF_ROOT/php.ini" VHOST_CONF="$SITES_ROOT/$SRV_NAME" # GROUP equals USER GROUP=$USER function changeFcgiConfig { # adjust fcgi config sed "s!{SRV_NAME}!$SRV_NAME!g" -i $PHP_FCGI # ... php.ini if [ $CHANGE_PHP_INI == "yes" ]; then sed "s!;upload_tmp_dir =!upload_tmp_dir = $TMP_ROOT!g" -i $PHP_INI sed "s!;open_basedir =!open_basedir = $DOC_ROOT:$TMP_ROOT!g" -i $PHP_INI sed "s!;session.save_path = /var/lib/php5!session.save_path = $TMP_ROOT!g" -i $PHP_INI fi } function createDirs { # create the directory structure cp -R $EXAMPLE_ROOT $VHOST_ROOT if [ $CHANGE_PHP_INI == "yes" ]; then # don't put a symlink to php.ini in $CONF_ROOT, but copy it there rm $CONF_ROOT/php.ini cp $PHP_INI_TEMPLATE $CONF_ROOT fi changeFcgiConfig chown $USER:$GROUP -R $VHOST_ROOT chattr +i $CONF_ROOT/php-fcgi.conf # as $CONF_ROOT/php.ini is just a symlink most of the time, chattr will usually fail chattr +i $CONF_ROOT/php.ini 2> /dev/null } function createApacheConfig { # now let's adjust the apache vHost-configuration if [ $SSL == "yes" ]; then cp $SITES_EXAMPLE_SSL $VHOST_CONF else cp $SITES_EXAMPLE $VHOST_CONF fi # now do sed operations on $VHOST_CONF sed "s!{SRV_NAME}!$SRV_NAME!g" -i $VHOST_CONF if [ -z "$SRV_ALIAS" ]; then sed "s!{SRV_ALIAS}!!g" -i $VHOST_CONF else sed "s!{SRV_ALIAS}!$SRV_ALIAS!g" -i $VHOST_CONF sed "s!# ServerAlias! ServerAlias!g" -i $VHOST_CONF fi sed "s!{SRV_ADMIN}!$SRV_ADMIN!g" -i $VHOST_CONF sed "s!{USER}!$USER!g" -i $VHOST_CONF sed "s!{GROUP}!$GROUP!g" -i $VHOST_CONF sed "s!{DOC_ROOT}!$DOC_ROOT!g" -i $VHOST_CONF sed "s!{CONF_ROOT}!$CONF_ROOT!g" -i $VHOST_CONF sed "s!{LOG_ROOT}!$LOG_ROOT!g" -i $VHOST_CONF if [ $SSL == "yes" ]; then sed "s!{CERT_PUB}!$CERT_PUB!g" -i $VHOST_CONF sed "s!{CERT_PRIV}!$CERT_PRIV!g" -i $VHOST_CONF fi } createDirs createApacheConfig exit 0 |
Die dazugehörenden Ordnerstruktur unter "/var/www/example":
mkdir /var/www/example mkdir /var/www/example/conf mkdir /var/www/example/docs mkdir /var/www/example/tmp mkdir /var/www/example/logs touch /var/www/example/logs/access.log touch /var/www/example/logs/error.log ln -s /etc/php5/cgi/php.ini /var/www/example/conf/php.ini
Hier noch die Datei "php-fcgi.conf", welche nach "/var/www/example/conf/" gehört:
php-fcgi.conf:
#!/bin/sh PHPRC="/var/www/{SRV_NAME}/conf" export PHPRC PHP_FCGI_CHILDREN=3 export PHP_FCGI_CHILDREN exec /usr/bin/php5-cgi
Dazu noch die vHost-configs "example", sowie "example-ssl" unter /etc/apache2/sites-available":
- example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
<VirtualHost *:80> SuExecUserGroup {USER} {GROUP} ServerName {SRV_NAME} # ServerAlias {SRV_ALIAS} ServerAdmin {SRV_ADMIN} DocumentRoot {DOC_ROOT} AddHandler fcgid-script .php <Directory {DOC_ROOT}> FCGIWrapper {CONF_ROOT}/php-fcgi.conf .php Options +SymLinksIfOwnerMatch +MultiViews +ExecCGI -Indexes AllowOverride FileInfo AuthConfig Order allow,deny allow from all </Directory> ErrorLog {LOG_ROOT}/error.log CustomLog {LOG_ROOT}/access.log combined LogLevel warn ServerSignature Off </VirtualHost>
- example-ssl:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
<VirtualHost *:80> ServerName {SRV_NAME} # ServerAlias {SRV_ALIAS} ServerAdmin {SRV_ADMIN} <IfModule mod_ssl.c> RewriteEngine on RewriteCond %{SERVER_PORT} ^80$ RewriteRule ^(.*)$ https://%{SERVER_NAME}$1 [L,R] RewriteLog {LOG_ROOT}/rewrite.log RewriteLogLevel 2 </IfModule> ErrorLog {LOG_ROOT}/error.log CustomLog {LOG_ROOT}/access.log combined LogLevel warn ServerSignature Off </VirtualHost> <VirtualHost *:443> SuExecUserGroup {USER} {GROUP} ServerName {SRV_NAME} # ServerAlias {SRV_ALIAS} ServerAdmin {SRV_ADMIN} SSLEngine on SSLCertificateFile {CERT_PUB} SSLCertificateKeyFile {CERT_PRIV} SSLCipherSuite HIGH SSLProtocol all -SSLv2 DocumentRoot {DOC_ROOT} AddHandler fcgid-script .php <Directory {DOC_ROOT}> FCGIWrapper {CONF_ROOT}/php-fcgi.conf .php Options +SymLinksIfOwnerMatch +MultiViews +ExecCGI -Indexes AllowOverride FileInfo Order allow,deny allow from all </Directory> ErrorLog {LOG_ROOT}/error.log CustomLog {LOG_ROOT}/access.log combined LogLevel warn ServerSignature Off </VirtualHost>
Das Skript kann als Benutzer root ausgeführt werden. Es fragt nach ein paar Parametern (default-Werte stehen in eckigen Klammern und können durch Drücken der Eingabetaste übernommen werden) und erstellt dann den vHost und die dazugehörige Konfiguration. Nach Ausführen des Skripts muss der vHost noch mittels des "a2ensite"-Befehls aktiviert werden und die apache-Konfiguration muss neu eingelesen werden.
AVI Dateien zusammenfügen
Das funktioniert entweder mit mencoder:
1 | mencoder -forceidx -ovc copy -oac copy -o output.avi input1.avi input2.avi ... |
Oder mit avimerge aus dem transcode package:
1 | avimerge -o output.avi -i input1.avi input2.avi ... |
Wordpress Seite mit Passwort schützen
Lange habe ich nach dieser Funktion gesucht und nun habe ich sie endlich gefunden:
Rechts neben der Textbox zum Verfassen eines Beitrags gibts es einen Bereich "Publish". Dort kann man unter "Visibility" festlegen, ob eine Seite öffentlich, passwortgeschützt oder privat sein soll.
Synergy
Ein geniales Tool, wenn man zwei Rechner hat und diese ohne teure Hardware mit der selben Maus/der selben Tastatur verwenden will. Zusätzlich steht auch noch eine gemeinsame Zwischenablage zur Verfügung.
Unter folgendem Link wird sehr einfach erklärt, wie man Synergy einrichtet:
http://gnuski.blogspot.com/2008/02/quicksynergy-quick-howto.html
Funambol Installation
Heute geht's um Funambol - einen Synchronisationsserver für Mobiltelefone, PIM Programme, ... Funambol bietet unter anderem auch Unterstützung für Push-Mail, Kalender-, Aufgaben- und Kontaktsynchronisation für viel Plattformen. Mehr Informationen gibts unter http://www.funambol.com/opensource.
Dieses Howto beschreibt die Installation von Funambol mit postgres als Datenbank-Backend.
Installation
Als Erstes laden wir den JDBC Treiber für postgres herunter: http://jdbc.postgresql.org/download/postgresql-8.3-605.jdbc3.jar
Danach das Funambol Installationspackage: http://funambol.com/opensource/download.php?file_id=funambol-7.1.1.bin&_=d
Danach führen wir das Funambol Paket mit folgendem Befehl aus:
1 | sh funambol-7.1.1.bin |
Wir wählen den Standard-Installationspfad, verneinen aber die Frage, ob wir den Server starten wollen.
Konfiguration
Danach kopieren wir den postgres JDBC-Treiber nach "/opt/Funambol/tools/jre-1.5.0/jre/lib/ext/" und legen einen postgres-Benutzer für Funambol an:
1 2 3 | su - postgres createuser -P createdb funambol |
Bei "createuser" geben wir als Namen "funambol" an und verneinen alle drei Fragen.
Nun müssen die Datenbank-Einstellungen von Funambol geändert werden. Dazu editieren wir "/opt/Funambol/ds-server/install.properties":
1 2 3 4 5 | jdbc.classpath=../tools/jre-1.5.0/jre/lib/ext/postgresql-8.3-605.jdbc3.jar jdbc.driver=org.postgresql.Driver jdbc.url=jdbc:postgresql:funambol jdbc.user=funambol jdbc.password=<PASSWORD> |
Die Datei "com/funambol/server/db/db.xml" wird nach dem gleichen Schema bearbeitet. Danach muss "/opt/Funambol/bin/install" ausgeführt werden (ggf. zuvor die Umgebungsvariable JAVA_HOME setzen). Jetzt kann funambol per "/opt/Funambol/bin/funambol start" gestartet werden.
Funambol in runlevel eintragen
1 2 | cp /opt/Funambol/bin/funambol /etc/ update-rc.d funambol defaults |
Funambol Admin-Tool
Das Funambol Admin-Tool kann von der Funambol-Homepage heruntergeladen werden. Hier kann man das initiale Admin-Passwort ändern.
Des Weiteren muss man im "Server Settings"-Tab die Server URI ändern. Sie sollte dieses Format haben:
1 | http://<SERVER>:<PORT>/funambol/ds |
Testen
Nun kann man sich mit URL, Benutzername und Passwort am Server anmelden und synchronisieren. Da Autoprovisioning aktiviert ist, kann man Benutzername und Passwort frei wählen. Dies sollte jedoch in einem Produktivsystem geändert werden, da sich sonst jeder am Server anmelden kann. Dazu muss man den Officer im "Server Settings"-Tab ändern.
Freien Speicherplatz auf ftp-Server bestimmen
In Zusammenhang mit meinem letzten Beitrag über Server-Backups hier noch ein kleiner Tipp wie man den freien Speicherplatz auf einem ftp-Server bestimmen kann:
1 | echo du -hs . | lftp -u <BENUTZERNAME>,<PASSWORT> <SERVER> |
Sollte das Paket lftp nicht verfügbar sein, kann man es über apt nachinstallieren:
1 | aptitude install lftp |
Falls jemand weiß, ob und wie man den freien Speicherplatz direkt über ncftp erfragen kann, wäre ich über einen kleinen Kommentar dankbar.
Der neue Server: Teil 9 Backup
Der Server ist zwar nicht mehr neu, aber dieser Beitrag ist evtl. dennoch für einige hilfreich. Deshalb: Viel Spaß!
Heute widme ich mich dem Thema Backup. Das habe ich viel zu stark vernachlässigt und will das jetzt nachholen. Das Tool der Wahl ist duplicity mit dem c't Wrapper-Skript ftplicity. Duplicity benutzt unter der Decke rsync zur Erkennung der Deltas. Das Skript wird so konfiguriert, dass es täglich ein inkrementelles Backup macht und monatlich ein volles Backup und dabei die alten Backups löscht. Während des Backup-Prozesses werden auch Backups der MySQL- und postgreSQL-Datenbanken mit den mitgelieferten Tools erstellt (nicht einfach durch Kopieren der Datenbankdateien, da man dabei einen inkonsistenten Zustand erwischen könnte und die Datenbank unbrauchbar ist).
Installation
Zuerst die Installation der benötigten Pakete:
1 2 3 4 5 6 | aptitude install duplicity ncftp wget http://downloads.sourceforge.net/project/ftplicity/ftplicity/1.5.0.2/ftplicity_1.5.0.2.tgz?use_mirror=switch tar xvfz ftplicity_1.5.0.2.tgz mv ftplicity_1.5.0.2/ftplicity /usr/local/bin/ chown root: /usr/local/bin/ftplicity chmod 755 /usr/local/bin/ftplicity |
Konfiguration
Erstellung eines GPG-Schlüssel für Backups
Da ftplicity Backups automatisch verschlüsselt ablegt, ist es nötig einen GPG-Schlüssel zu erstellen:
1 | gpg --gen-key |
root@domain.tld:~# gpg --gen-key
gpg (GnuPG) 1.4.9; Copyright (C) 2008 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
gpg: keyring `/root/.gnupg/secring.gpg' created
Please select what kind of key you want:
(1) DSA and Elgamal (default)
(2) DSA (sign only)
(5) RSA (sign only)
Your selection? <-- ENTER
DSA keypair will have 1024 bits.
ELG-E keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) <-- ENTER
Requested keysize is 2048 bits
Please specify how long the key should be valid.
0 = key does not expire
Key is valid for? (0) <-- ENTER
Key does not expire at all
Is this correct? (y/N) <-- y
You need a user ID to identify your key; the software constructs the user ID
from the Real Name, Comment and Email Address in this form:
"Heinrich Heine (Der Dichter)
Real name: Musterserver Backup
Email address: backup@domain.tld
Comment: Key for System Backups on domain.tld
You selected this USER-ID:
"domain.tld Backup (Key for System Backups on domain.tld)
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? <-- O
You need a Passphrase to protect your secret key.
Enter passphrase: <-- Passwort eingeben
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.+++++++++++++++.+++++++++++++++.++++++++++++++++++++.+++++..+++++++++++++++>++++++++++>.+++++...........<+++++>+++++..<.+++++.....................................................>.+++++.....+++++
gpg: /root/.gnupg/trustdb.gpg: trustdb created
gpg: key 123ABC45 marked as ultimately trusted
public and secret key created and signed.
...
Die achtstellige ID (im Beispiel 123ABC45) bitte merken, da diese später benötigt wird. Ebenso das Passwort.
Danach legen exportieren wir noch unsere Schlüssel (public/private), damit wir diese an einem sicheren Ort speichern können, damit unsere Daten nicht verloren gehen, sollte die Festplatte sich verabschieden:
1 2 | root@domain.tld:~/gpg-key# gpg --output backup_pub.gpg --armor --export 123ABC45 root@domain.tld:~/gpg-key# gpg --output backup_sec.gpg --armor --export-secret-key 123ABC45 |
ftplicity
Nun starten wir ftplicity einmal, damit eine Standardkonfiguration angelegt wird, die wir an unsere Wünsche anpassen können:
1 | ftplicity system create |
Nun editieren wir die Datei "/root/.ftplicity/system/conf":
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | # gpg key data (for symmetric encryption comment out GPG_KEY) GPG_KEY='123ABC45' GPG_PW='PASSWORD' # 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" #GPG_OPTS='' # credentials & server address of the backup target (URL-Format) # syntax is # scheme://user[:password]@host[:port]/[/]path # probably one out of # file:///some_dir # ftp://user[:password]@other.host[:port]/some_dir # hsi://user[:password]@other.host/some_dir # cf+http://container_name # imap://user[:password]@host.com[/from_address_prefix] # imaps://user[:password]@host.com[/from_address_prefix] # rsync://user[:password]@other.host[:port]::/module/some_dir # rsync://user[:password]@other.host[:port]/relative_path # rsync://user[:password]@other.host[:port]//absolute_path # s3://host/bucket_name[/prefix] # s3+http://bucket_name[/prefix] # scp://user[:password]@other.host[:port]/some_dir # ssh://user[:password]@other.host[:port]/some_dir # tahoe://alias/directory # webdav://user[:password]@other.host/some_dir # webdavs://user[:password]@other.host/some_dir ### # TARGET='scheme://user[:password]@host[:port]/[/]path' TARGET='ftp://<USER>:<PASS>@<HOST>/<DIR>' # optionally the password can be defined as extra variable # if password is set already in TARGET, this setting replaces it #TARGET_PW='_backend_password_' # base directory to backup SOURCE='/' # Time frame for old backups to keep, Used for the "purge" command. # see duplicity man page, chapter TIME_FORMATS) # defaults to 1M, if not set #MAX_AGE=1M # Number of full backups to keep. Used for the "purge-full" command. # See duplicity man page, action "remove-all-but-n-full". # defaults to 1, if not set #MAX_FULL_BACKUPS=1 # verbosity of output (5 for gpg errors, 9 for bug fixing) # 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 # 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 _ " # 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, since then default file # naming is compatible and this option is pending depreciation #DUPL_PARAMS="$DUPL_PARAMS --short-filenames " # 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 #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 5MB. # VOLSIZE must be number of MB's to set the volume size to. #VOLSIZE=50 #DUPL_PARAMS="$DUPL_PARAMS --volsize $VOLSIZE " # 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 " |
Und nun noch die Datei "/root/.ftplicity/system/exclude":
1 2 3 4 5 6 7 | /dev /proc /sys /tmp /var/cache /var/tmp /var/run |
Danach erstellen wir unter "/usr/local/sbin/" die Datei db_backup mit Rechten "700":
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | #!/bin/bash # Script to backup MySQL and postgreSQL databases # author: johker ############### CHANGE THESE VARIABLE IF NECESSARY #################### MYSQL_USER="MYSQL_USER" MYSQL_PW="MYSQL_PASSWORD" POSTGRES_USER="POSTGRES_USER" POSTGRES_PW="POSTGRES_PASSWORD" TMP="/tmp/" FINAL_LOC="/var/backups/" ################ DON'T CHANGE ANYTHING BELOW THIS LINE ################ echo "Creating backup of MySQL databases" mysqldump -u$MYSQL_USER -p$MYSQL_PW --all-databases > $FINAL_LOC"mysql.sql" gzip -f $FINAL_LOC"mysql.sql" echo "Creating backup of postgreSQL databases" su -c "cd $TMP && pg_dumpall > $TMP'postgres.out'" $POSTGRES_USER gzip -f $TMP'postgres.out' mv -f $TMP'postgres.out.gz' $FINAL_LOC chmod 640 $FINAL_LOC"mysql.sql.gz" $FINAL_LOC"postgres.out.gz" chown root: $FINAL_LOC"mysql.sql.gz" $FINAL_LOC"postgres.out.gz" exit 0 |
Und in die Datei "/root/.ftplicity/system/pre" fügen wir folgende Zeile ein:
1 2 3 | #!/bin/bash /usr/local/sbin/db_backup |
Testen
Mit folgendem Befehl kann man die ftplicity-Konfiguration testen:
ftplicity system status
Wenn alles o.k. ist, kann man mit folgedem Befehl ein initiales Backup anlegen:
ftplicity system backup
Erstellen eines Cronjobs
Da wir das Backup nicht jedes mal händisch anstoßen wollen, hier einträge für die crontab von root (editierbar per "crontab -e" als Benutzer root):
1 2 3 4 | # run the (incremental) backup each night at 03:23h 23 3 * * * /usr/local/bin/ftplicity system backup # do a full backup once per month & delete old backups at 04:47h 47 4 1 * * /usr/local/bin/ftplicity system purge --force && /usr/local/bin/ftplicity system purge-full --force && /usr/local/bin/ftplicity system full |
Quellen
http://www.howtoforge.com/ftp-backups-with-duplicity-ftplicity-debian-etch
http://maff.ailoo.net/2009/07/backup-virtual-machines-lvm-snapshots-ftplicity-duplicity/
http://robert.penz.name/161/howto-backup-your-dedicated-server-to-a-foreign-ftp-server/
Wordpress Update
Habe gerade eben ein automatisches Upgrade von Version 2.7.1 auf Version 2.8.2 durchgeführt. Hat wunderbar funktioniert. Ich muss mir ganz ehrlich eingestehen, dass ich nicht gedacht hätte, dass das reibungslos funktioniert. Naja, bin ich vielleicht etwas zu sehr an Linux gewöhnt
