Sendmail über externen Mailserver (anderer Port) senden lassen

Wenn man das im letzten Beitrag beschriebene Problem mit Mails hat (Port 25 geblockt) und bereits einen externen Mailserver wie dort beschrieben eingerichtet hat, muss man nun noch den Weitertransport über diesen Server organisieren.

Dazu geht man bei dem hinter der Firewall befindlichen Server mit der MTA sendmail (habe ich wegen der Einfachheit gewählt) wie folgt vor:

Zuerst stoppen wir sendmail

service sendmail stop

und editieren /etc/mail/sendmail.mc

define(`SMART_HOST',`smtp.myisp.net')dnl
define(`RELAY_MAILER_ARGS', `TCP $h 587')
define(`ESMTP_MAILER_ARGS', `TCP $h 587')
FEATURE(`authinfo',`Hash -o /etc/mail/authinfo.db')dnl

Mit dem Befehl

m4 /etc/mail/sendmail.mc > /etc/mail/sendmail.cf

wird die Config geprüft und in einem für sendmail lesbaren Format gespeichert.

Danach wird die Datei /etc/mail/authinfo mit folgendem Inhalt angelegt:

AuthInfo:ispdomain.net "U:my_username" "P:my_password" "M:PLAIN"
AuthInfo: "U:my_username" "P:my_password" "M:PLAIN"

Statt PLAIN kann auch ein anderer vom Relayserver unterstützter Authentifizierungsmechanismus gewählt werden.

makemap hash /etc/mail/authinfo < /etc/mail/authinfo

schreibt die Auth-Daten in eine von sendmail lesbare Hashfile (authinfo.db).

Jetzt kann sendmail wieder gestartet werden

service sendmail start

und sollte Mails nun über Port 587 an den Relay-Server weiterleiten, der sie schließlich ausliefert.

Postfix auf mehreren Ports „horchen“ lassen

Viele Netzwerke verbieten den Zugriff auf Port 25, um zu verhindern, dass Spam von ihrem Netzwerk aus gesendet wird (wenn auch nicht über ihren eigenen Mailserver). Muss man trotzdem öfter Mails aus einem solchen Netzwerk verschicken, bietet es sich an, Postfix auf dem Mailserver einen zweiten Port zuzuweisen.

Das ginge zwar auch in der master.cf, eventuell müssten dann aber noch einige andere Sachen geändert werden. Einfacher geht es, indem man iptables anweist, vom zweiten Port aus an 25 umzuleiten:

1
iptables -t nat -A PREROUTING -p tcp --dport 587 -j REDIRECT --to-ports 25

Mit

1
iptables-save

wird die Änderung auch nach dem Serverneustart direkt wieder übernommen.

Root-Partition online vergrößern

Die Root-Partition vergrößern – das klingt schon mal scary. Aber dann auch noch online – das heißt ohne Live-CD, während des Betriebs? Warum um alles in der Welt sollte man sowas machen wollen? Ganz einfach, man stelle sich einen Server vor, bei dem die Root-Partition vergrößert werden soll und zu dem man keinen physischen Zugang hat. Voilà, das Szenario.

HINWEIS: Diese Methode funktioniert nur, wenn der zusätzliche Speicherplatz direkt an die zu vergrößernde Partition anschließt!

HINWEIS: Die hier vorgestellte Methode wurde von mir auf einem CentOS-Server live und erfolgreich angewendet, trotzdem gibt’s wie immer keine Garantie – und man sollte ein Backup in der Hinterhand haben.

Während viele Websites sagen, dass es nicht möglich wäre, die Partition ohne Live-CD oder Rettungssystem zu vergrößern, habe ich auf dem Blog von RaftaMan eine Anleitung gefunden, die genau das ermöglicht. Um einen Neustart des Systems kommt man zwar nicht herum (der Kernel muss die neue Partitionsgröße einlesen bevor man das Filesystem daran anpassen kann), aber es geht alles ohne von CD zu booten.

Also, los geht’s:

1
fdisk -l

zeigt uns die Devices und darauf enthaltenen Partitionen an. Um eine Partition zu bearbeiten müssen wir zunächst in fdisk das Device aufrufen:

1
fdisk /dev/sda

würde jetzt für die erste Festplatte stehen. Auf der Befehlszeile drücken wir nun „p“ und „Enter“, worauf uns noch einmal (zur Sicherheit) die Partitionen angezeigt werden:

1
2
3
4
5
6
7
Command (m for help): p
Disk /dev/sda: 5218 MB, 5218304000 bytes
255 heads, 63 sectors/track, 634 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
 
    Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1         634     5092573+  83  Linux

Den Anfangssektor unbedingt merken oder aufschreiben, wird er falsch gesetzt kann das alle Daten unbrauchbar machen! Diese Partition müssen wir jetzt löschen (oh ja, richtig gehört), aber keine Angst es gehen dabei keine Daten verloren solange der Anfangssektor gleich und die Partition nachher größer als vorher ist. Also geben wir jetzt ein „d“ und „Enter“ ein, worauf wir nach der Nummer der Partition gefragt werden. Da die Zählung bei 1 beginnt also in unserem Fall eine 1. Und noch mal „Enter“.

Als nächstes erstellt man eine neue Partition mit „n“ und „Enter“. Dabei nutzt man den gleichen Partitionstyp und den gleichen Startsektor wie bei der Ausgangspartition. Der Endsektor kann innerhalb der angezeigten Grenzen beliebig gewählt werden, sollte aber größer sein als der Ursprüngliche, damit die Partition keine Daten verliert.

1
2
3
4
5
6
7
8
9
Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-934, default 1):
Using default value 1
Last cylinder or +size or +sizeM or +sizeK (1-934, default 934): 850

Falls die Ausgangspartition das „boot“-Flag gesetzt hatte, müssen wir das auch hier wieder setzen:

1
2
Command (m for help): a
Partition number (1-4): 1

Schlussendlich schreiben wir die Änderungen mit „w“ und „Enter“ in die Partitionstabelle. Die Bestätigung sollte fast sofort erscheinen und uns darauf hinweisen, dass ein Neustart erforderlich ist.

1
2
3
4
5
6
7
8
9
Command (m for help): w
The partition table has been altered!
 
Calling ioctl() to re-read partition table.
 
WARNING: Re-reading the partition table failed with error 16: Device or resource busy.
The kernel still uses the old table.
The new table will be used at the next reboot.
Syncing disks.

Nach dem Neustart, den wir direkt durchführen, kann das Filesystem problemlos live an die neue Partitionsgröße angepasst werden:

1
2
3
4
5
resize2fs /dev/sda1
resize2fs 1.39 (29-May-2006)
Filesystem at /dev/sda1 is mounted on /; on-line resizing required
Performing an on-line resize of /dev/sda1 to 1522150 (4k) blocks.
The filesystem on /dev/sda1 is now 1522150 blocks long.

Und fertig. Der neue Speicherplatz steht vollständig zur Verfügung.

phpmyadmin sicher(er) zur Verfügung stellen

Möchte man phpmyadmin mehreren Domains zur Verfügung stellen, so bietet sich dafür das Debian-Paket „phpmyadmin“ an:

1
apt-get install phpmyadmin

Danach kann man unter /etc/phpmyadmin/apache.conf eine config finden, die man per

1
ln -s /etc/phpmyadmin/apache.conf /etc/apache2/conf.d/phpmyadmin.conf

in das Apache-Verzeichnis einbindet.

Jetzt muss an hier aber noch ein wenig gefeilt werden, denn so stellt man phpmyadmin grundsätzlich auch über HTTP – also unverschlüsselt – zur Verfügung. Administriert jetzt jemand über ein öffentliches Netzwerk seine Datenbank (immer an den DAU denken, auch wenn es sich erst mal vollkommen an den Haaren herbeigezogen anhört), hat man ruck-zuck ein Problem.

Deshalb leite ich grundsätzlich alle HTTP-Anfragen an phpmyadmin einfach nach HTTPS weiter. Dazu öffnet man die /etc/phpmyadmin/apache.conf und fügt ganz oben folgenden Text ein:

1
2
3
4
5
6
7
8
9
<IfModule mod_rewrite.c>
        <IfModule mod_ssl.c>
                <Location ~ "/phpmyadmin(/|$)">
                        RewriteEngine on
                        RewriteCond %{HTTPS} off
                        RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI}
                </Location>
        </IfModule>
</IfModule>

Jetzt wird jeder Besucher von http://domain.de/phpmyadmin zu https://domain.de/phpmyadmin umgeleitet, was phpmyadmin ein ganzes Stück sicherer macht. Trotzdem ist zu überlegen, ob man die Software nicht lieber zusätzlich mit einem .htaccess-Schutz versieht. Wie das geht, erfährt man unter anderem bei SELFHTML.

Nodejs-Server via Apache-Reverse-Proxy und Monit

Um einen Nodejs-Server aufzusetzen braucht es nicht viel. Eigentlich nur die Binaries und eine JS-Datei mit dem eigentlichen Server. Doch wenn man den Server dauerhaft und bequem zugreifbar betreiben möchte, sind ein paar mehr Schritte notwendig.

Zunächst wird Nodejs und der Paketmanager npm installiert:

1
apt-get install nodejs npm

Danach richten wir den Proxy ein, sonst wäre ein Aufruf nur über einen Nicht-Standard-Port (80 ist ja schon vom Apachen belegt) möglich. In der Regel verwendet Nodejs hier Port 3000, aber das ist je nach Script unterschiedlich. Wir aktiviren also zunächst den Passthrough-Modus:

1
2
a2enmod proxy
a2enmod proxy_http

Für die eigentliche Einrichtung kann jetzt ein eigener VHost (z.B. eine Subdomain) angelegt werden, oder – wie in meinem Beispiel – ein Unterverzeichnis hergenommen werden.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<VirtualHost ip:80>
	ServerName   myhost.com:80
	ServerAlias  www.myhost.com
	UseCanonicalName Off
	DocumentRoot /var/www/vhosts/myhost/httpdocs
	ErrorLog  /var/www/vhosts/myhost/statistics/logs/error_log
 
	...
 
	<Directory /var/www/vhosts/myhost/httpdocs>
		Options -Includes +ExecCGI
	</Directory>
 
	<Proxy *>
  		Order deny,allow
  		Allow from all
	</Proxy>
 
	<Location /mynodejspath>
  		ProxyPass http://localhost:3000
  		ProxyPassReverse http://localhost:3000
	</Location>
</VirtualHost>

Würde man nun nodejs manuell starten, könnte man schon per http://myhost.com/mynodejspath darauf zugreifen. Da Nodejs aber noch ein wenig fehleranfällig ist und dann gern mal sang- und klanglos abtritt, benutze ich monit zur Überwachung und ggf. zum Neustart des Servers (der Nodejs-App).

1
apt-get install monit

Als Startscript verwende ich ein Standard-init.d-Script, sodass ich auch beim Systemstart problemlos den Nodejs-Server mitstarten lassen kann. Dabei ist zu beachten, dass ich auf Benutzer „root“ prüfe und den Nodejs-Server ggf. über einen extra User starte. Andere Nutzer starten die Nodejs-App mit diesem Script als sie selbst.

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
#!/bin/bash
DIR=/var/www/vhosts/myhost/httpdocs/mynodejspath
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
NODE_PATH=/usr/lib/node_modules
NODE=/usr/bin/node
 
test -x $NODE || exit 0
 
function start_app {
  if [ $(whoami) = "root" ]
  then
    NODE_ENV=production nohup sudo -u nodejsusername "$NODE" "$DIR/app.js" 1>>"$DIR/logs/node.log" 2>&1 &
    echo $! > "$DIR/pids/node.pid"
  else
    NODE_ENV=production nohup "$NODE" "$DIR/app.js" 1>>"$DIR/logs/node.log" 2>&1 &
    echo $! > "$DIR/pids/node.pid"
  fi
}
 
function stop_app {
  kill `cat $DIR/pids/node.pid`
}
 
case $1 in
   start)
      start_app ;;
    stop)
      stop_app ;;
    restart)
      stop_app
      start_app
      ;;
    *)
      echo "usage: myapp {start|stop|restart}" ;;
esac
exit 0

Die Verzeichnisse „pids“ und „logs“ müssen unter dem App-Pfad noch angelegt werden. Danach kommt das Monit-Script nach /etc/monit/noderc:

1
2
3
4
5
6
7
8
9
10
#!monit
set logfile /var/log/monit.log
 
check process nodejs with pidfile "/var/www/vhosts/myhost/httpdocs/mynodejspath/pids/node.pid"
    start program = "/etc/init.d/myapp start"
    stop program  = "/etc/init.d/myapp stop"
    if failed port 3000 protocol HTTP
        request /
        with timeout 10 seconds
        then restart

… und ein Starter-init.d Script nach /etc/init.d/monit:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/bash
 
case $1 in
   start)
      monit -d 60 -c /etc/monit/noderc
      ;;
    stop)
      killall monit
      ;;
    restart)
      stop_app
      start_app
      ;;
    *)
      echo "usage: monit {start|stop|restart}" ;;
esac
exit 0

Ein Symlink nach rc2.d komplettiert die Automatisierung:

1
2
cd /etc/rc2.d/
ln -s ../init.d/monit S99monit

 

Somit haben wir viele Probleme gelöst:

  • Nodejs startet mit dem Server
  • Es wird überwacht und falls notwendig neu gestartet
  • Der Jeweilige Besitzer (und root) können es manuell neu starten
  • Es läuft mit eingeschränkten Userrechten
  • Es ist über Port 80 zugreifbar
  • und wir haben wieder etwas gelernt 😉

Gitlab aufsetzen unter Debian/Ubuntu mit Apache

github.com ist ein großartiges Tool für Open Source Projekte auf der ganzen Welt. Es stellt einfachen Zugriff auf das git-Versionierungssystem zur Verfügung, ohne dass man sich um die Befehle für das Erstellen und Warten eines solchen Repos Gedanken machen müsste.

Das ist toll, allerdings hat github einen Nachteil: für private Repositories – also solche, bei denen der Code nicht der ganzen Welt zur Verfügung steht – werden (relativ hohe) Gebühren fällig. Somit ist dieses Tool für kommerzielle Zwecke nur bedingt geeignet, falls man nicht die „Plans“ (github: Plans & Pricing) in Anspruch nehmen möchte.

Lange Zeit gab es keine Softwarelösung, die man sich auf dem eigenen Server installieren konnte, und die ähnlichen Komfort wie github zu bieten hatte. Doch seit einiger Zeit etabliert sich eine solche Lösung: Gitlab. Das Tool steht github kaum noch in etwas nach und kann kostenfrei auf (fast) jedem Rootserver betrieben werden:

  • Ubuntu Linux
  • Debian/GNU Linux
  • Fedora
  • CentOs
  • RedHat.

Zur Installation reichen je nach Komplexität der Installation einige wenige Schritte aus, mehr Komfort gibt es – wie immer – mit mehr Schritten. Doch zunächst das Basis-Setup:

Wer ein paar Basis-Programme nicht installiert hat, muss dies zuerst nachholen:

1
sudo apt-get install wget git git-core build-essential libyaml-dev

Als Nächstes laden wir das Installscript von gitlab herunter und installieren es, was uns viel Arbeit erspart. Es ist dabei von Vorteil, noch kein RubyOnRails installiert zu haben (falls Ruby schon installiert ist, muss es zwingend Ruby 1.9.2 oder besser sein). Ansonsten muss das Script angepasst werden, die Befehle sind relativ selbsterklärend. Hier nun die Variante mit Script (Download-Adresse aktualisiert 19.10.2012):

1
2
3
wget https://raw.github.com/gitlabhq/gitlab-recipes/master/install/debian_ubuntu.sh
chmod +x debian_ubuntu.sh
./debian_ubuntu.sh

Alternativ sind Schritte 1-4 dieser Anleitung auszuführen.

Nun setzen wir die Komponenten für den Ruby-Server auf:

1
2
3
4
5
6
7
sudo gem install charlock_holmes
sudo pip install pygments
sudo gem install bundler
cd /home/gitlab
sudo -H -u gitlab git clone git://github.com/gitlabhq/gitlabhq.git gitlab
cd gitlab
sudo -u gitlab cp config/gitlab.yml.example config/gitlab.yml
1
2
3
sudo -u gitlab cp config/database.yml.sqlite config/database.yml
ODER
sudo -u gitlab cp config/database.yml.example config/database.yml

Nachdem die Datenbank-Konfiguration kopiert wurde, müssen bei MySQL die Verbindungsparameter angepasst werden. SQLite läuft sofort „out of the box“.

Im folgenden Schritt initialisieren und konfigurieren wir Gitlab für den Ruby-Server, anschließend testen wir die Umgebung:

1
2
3
sudo -u gitlab -H bundle install --without development test --deployment
sudo -u gitlab bundle exec rake gitlab:app:setup RAILS_ENV=production
sudo -u gitlab bundle exec rake gitlab:app:status RAILS_ENV=production
1
2
3
4
5
6
7
8
9
10
11
12
Starting diagnostic
config/database.yml............exists
config/gitlab.yml............exists
/home/git/repositories/............exists
/home/git/repositories/ is writable?............YES
remote: Counting objects: 603, done.
remote: Compressing objects: 100% (466/466), done.
remote: Total 603 (delta 174), reused 0 (delta 0)
Receiving objects: 100% (603/603), 53.29 KiB, done.
Resolving deltas: 100% (174/174), done.
Can clone gitolite-admin?............YES
UMASK for .gitolite.rc is 0007? ............YES

Der Output des Testbefehls sollte keine „failed“- oder „no“- Einträge haben. Falls alle Zeichen auf „grün“ stehen können wir den Server starten.

1
2
sudo -u gitlab bundle exec rails s -e production -d
./resque.sh

Der Server läuft nun und ist über Port 3000 bereits zugreifbar (nicht wundern, der erste Seitenaufruf dauert ziemlich lange). Wem das reicht, der ist bereits fertig.

Ich selbst mag meine Web-Anwendungen alle über HTTP(S) abrufen, so auch gitlab. Dazu nutze ich nicht die vom Tutorial vorgeschlagene Variante nginx + Unicorn sondern Passenger für Apache (weil Apache bei mir für alle Webanwendungen genutzt wird und Unicorn viel zu umständlich für kleine bis mittlere Installationen ist):

1
2
gem install passenger
passenger-install-apache2-module

Bei der Installation einfach den Anweisungen folgen, es sind ja nicht viele. Danach kann ein VirtualHost für gitlab angelegt werden, wichtig dabei: DocumentRoot muss auf das „public“-Verzeichnis von gitlab zeigen! Schon kann man z.B. über http(s)://gitlab.yourdomain.com auf gitlab zugreifen und loslegen.

Wichtig: Passenger ersetzt quasi den Deploy-Prozess von gits bundle exec, d.h. der Server auf dem Port 3000 muss dann nicht mehr laufen. Wenn man die Wartezeit für den ersten Besucher von gitlab nach dem Serverstart verkürzen will kann man den Apache wie folgt konfigurieren:

1
2
3
4
5
6
7
8
9
PassengerPreStart https://git.yourdomain.com/
 
<VirtualHost ip:443 >
        ServerName git.yourdomain.com
        UseCanonicalName Off
        DocumentRoot /home/gitlab/gitlab/public
 
        PassengerMinInstances 1
        ...

Als optionalen Schritt kann man nun noch ein Shell-Script für init.d schreiben, damit man resque nach einem Neustart nicht immer von Hand aufrufen muss:

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
#! /bin/bash
### BEGIN INIT INFO
# Provides:          gitlab
# Required-Start:    $local_fs $remote_fs $network $syslog redis-server
# Required-Stop:     $local_fs $remote_fs $network $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: resque service for gitlab
# Description:       resque service for gitlab
### END INIT INFO
 
NAME=resque
DESC="resque service"
RESQUE_PID=/home/gitlab/gitlab/tmp/pids/resque_worker.pid
 
case "$1" in
  start)
        CD_TO_APP_DIR="cd /home/gitlab/gitlab"
        START_RESQUE_PROCESS="./resque.sh"
 
        echo -n "Starting $DESC: "
        if [ `whoami` = root ]; then
          sudo -u gitlab sh -l -c "$CD_TO_APP_DIR > /dev/null 2>&1 && $START_RESQUE_PROCESS"
        else
          $CD_TO_APP_DIR > /dev/null 2>&1 && $START_RESQUE_PROCESS
        fi
        echo "$NAME."
        ;;
  stop)
        echo -n "Stopping $DESC: "
        kill -QUIT `cat $RESQUE_PID`
        echo "$NAME."
        ;;
  restart)
        echo -n "Restarting $DESC: "
        kill -USR2 `cat $RESQUE_PID`
        echo "$NAME."
        ;;
  reload)
        echo -n "Reloading $DESC configuration: "
        kill -HUP `cat $RESQUE_PID`
        echo "$NAME."
        ;;
  *)
        echo "Usage: $NAME {start|stop|restart|reload}" >&2
        exit 1
        ;;
esac
 
exit 0

Diese Datei speichern wir unter /etc/init.d/resque und machen es mit

1
sudo chmod +x /etc/init.d/resque

ausführbar. Danach noch einen symbolischen Link nach /etc/rc2.d/ anlegen

1
2
cd /etc/rc2.d
ln -s /etc/init.d/resque S99resque

Fertig.

Achtung: Das von Gitlab angelegte Admin-Passwort ist immer gleich, d.h. es ist zu empfehlen, sich einen eigenen Account mit Administrationsrechten anzulegen und den Admin-Account dann zu blocken, oder das Passwort des Admin-Accounts zu ändern.

Einzelne Datenbank/Tabelle aus MySQL-Dump wiederherstellen

Auf meinem Rootserver läuft jeden Tag ein Backup mit fwbackups, welches meine Dateien und Datenbanken mittels externem Script sichert und, ebenfalls mit Hilfe eines externen Scripts, auf einen FTP-Backupspace lädt. Das ist – einmal eingerichtet – sehr komfortabel. Möchte ich nun aber an die Daten heran und nur eine Datenbank oder Tabelle zurückspielen so müsste ich eigentlich einen zweiten MySQL-Server starten, das Backup einspielen und dann nur das gewünschte exportieren. Das wäre extrem umständlich, daher habe ich nach einem einfacheren Weg gesucht und ihn auch gefunden:

Nur eine Datenbank zurücksichern:

sed -n '/^-- Current Database: `dbname`/,/^-- Current Database: `/p' dumpfile > dbname.sql 2>error

Nur eine Tabelle zurücksichern:

sed -n -e '/CREATE TABLE.*mytable/,/CREATE TABLE/p' mysql.dump > mytable.dump

Hat man mehrere Tabellen, die ähnlich heißen sollte man Backquotes für die Namen verwenden.

 
Danke an uloBasEI von stackoverflow.com und Prabhat Kumar von adminlinux.blogspot.com für diese Tipps.

//Update: Danke an Kai Hessing, der mich per Mail aufmerksam gemacht hat, dass es mit obriger SQL-Anweisung ein Problem gibt, wenn die Tabelle vor der Rücksicherung schon existiert. Also dann entweder die Tabelle erst löschen oder folgendes Kommando benutzen:

sed -n -e '/DROP TABLE.*MYTABLE/,/UNLOCK TABLES/p' $BACKUPDIR/$FILE > $BACKUPDIR/$FILE.mytable

„Can’t connect to X11 window server“-Error

Als ich letztens eine Serverwartungs-GUI über mein VNC lassen wollte bekam ich auf einmal eine komische Fehlermeldung:

Can't connect to X11 window server using ':1.0' as the value of the DISPLAY variable.

Nach etwas googeln hat mir dann stress_junkie vom Forum linuxquestions.org die Erklärung (inklusive Lösung) geliefert:

If the Java program is running under your own account then the problem comes from DISPLAY being incorrectly defined. Try this:

export DISPLAY=“:0.0″

If a different user account is running the program then the user account that „owns“ the console must add permission for others to display on „their“ X display. Try this:

xhost +local:all

If the program is being used on a different computer, say 192.168.3.5 then try this:
Code:

xhost +inet:192.168.3.5

Ich wollte die GUI nämlich über einen anderen User laufen lassen. Nachdem ich bei diesem den Befehl xhost +local:all ausgeführt hatte, konnte ich zurück zum ausführenden User wechseln und das Programm problemlos starten. Denn nun hatte es die Berechtigung, das X11 window des xterm-Besitzers benutzen zu dürfen.

Hosting absichern: Apache2 mit ITK-MPM

Für Multiuser-Environments wie eine Hosting-Umgebung stellt sich spätestens ab einer gewissen Userzahl die Frage nach der Absicherung bzw. Abschottung der einzelnen User voneinander. Dafür gibt es verschiedene Varianten, die allesamt unterschiedliche Vor- und Nachteile haben.

Stuart Herbert hat sich dankenswerter Weise schon vorher die Mühe gemacht, die 5 gängigsten Varianten (suphp, mpm-peruser, mpm-itk, PHP + FastCGI und suexec + PHP + FastCGI) einem Vergleich zu unterziehen. Zwar sind die durchgeführten Performance-Tests mit Vorsicht zu genießen (sie spiegeln in keiner Weise ein realitätsnahes Szenario wieder und übersteigern die Performanceverluste erheblich), aber die Artikel vermitteln dennoch ein sehr gutes Bild der jeweiligen Verfahren und ihrer Stärken und Schwächen.

Ich habe mich für meinen Server schlussendlich für mpm-itk entschieden, da es sehr flexibel ist, alle Vorteile von mod_php weiterhin genutzt werden können und der zusätzliche Speicher- und CPU-Bedarf nicht ganz so extrem ist wie bei mpm-peruser. Zudem setzt die Sicherung im Gegensatz zu den fcgi-Varianten hier bereits im Apachen – also an der richtigen Stelle – an. Die Performance-Einbußen sind, anders als der Test es vermuten lassen würde, im Praxisbetrieb sehr moderat.

Um Apache2 mit ITK-MPM einzurichten bedarf es – vorausgesetzt Apache2 ist bereits installiert – unter Ubuntu/Debian nur eines kurzen Befehls:

apt-get install apache2-mpm-itk

Ein vermutlich vorhandenes anderes MPM (Multi-Processing Module) (standardmäßig dürfte das apache2-mpm-prefork sein) wird bei der Installation automatisch entfernt. Es kann also immer nur ein MPM gleichzeitig tätig sein, was ja auch logisch ist.

Nach dem automatisch durchgeführten Apache-Neustart ist das Modul sofort einsatzbereit. Um Gebrauch davon zu machen fügt man in den VirtualHost-Eintrag folgendes ein:

<VirtualHost *:80>
  ServerName www.example.com
  ...
 
  <IfModule mpm_itk_module>
    AssignUserId username groupname
    MaxClientsVHost 50
    NiceValue 10
  </IfModule>
</VirtualHost>

Alle Angaben sind optional. Wird kein Username zugewiesen läuft die jeweilige Domain unter dem Standard-User und der Standard-Gruppe (normalerweise www-data). Der MaxClients-Eintrag ermöglicht es (wie der Name schon sagt), die maximale Anzahl Clients für diesen spezifischen VHost festzulegen. Mit dem nice-Parameter kann man schlussendlich die Prozesspriorität pro VHost regeln (negative Werte = Priorität niedriger als normal).

Update: Es ist wichtig, jedem vHost auch wirklich eine User-Id zuzuordnen. Anderenfalls wird die Id von Apache genommen, was idR dann root ist („Note that if you do not assign a user ID, the default one from Apache will be used.“ lautet der lapidare Hinweis auf der Projektwebsite).

Praktische Methode zum „Kopieren mit Ausschluss“ unter Linux

Das Linux-Command cp enthält leider keine „–exclude“-Funktion. Daher kann man, wenn man rekursiv kopieren will, keine Verzeichnisse oder Dateien angeben, die ausgeschlossen werden sollen. In einem Forum habe ich diesen Tipp gelesen (und dann ausprobiert), der wirklich clever ist.

Das Programm tar enthält eine exclude-Funktion. Also nutzen wir doch einfach dieses:

1
tar -cvf - --exclude dir1 --exclude dir2 --exclude file1.ext --exclude file2.ext /path/to/source | (cd /path/to/destination; tar -xvf -)

Danke für diesen Tipp an vsemaska von linuxforums.org.