HowTo HowToSetupFastCgiIndividualPermissions ins deutsche übersetzt.
Geplante Ergänzungen: scponlyc und php in chroot
Ziel : von der reinen Konfiguration des Lightys wegzukommen und einen "sicheren" Denkansatz zur Einrichtung eines Webserver bieten.
Sinnvoll zu wissen:
n
*Wie ist der gesamt Speichbedarf anhand der PHP Prozesse für einen User zu ermitteln?
*Wieviele Prozesse brauche ich bei 10 / 30 / 50 / 100 / 200 / 500 gleichzeitigen Usern?
falls ihr Antworten habt bitte melden.
Setup FastCGI und PHP mit individuellen user Rechten
Als erstes: Dieses Howto ist nur, als eine Anregung zu verstehen.
Überprüfe jeden der hier aufgeführten Schritte.
Bevor du andere Menschen um Hilfe bittest versuch dir selbst zu helfen in dem du suchst (Internet/Forensuche).
Attackiere bitte niemand, falls du andere Wege bevorzugst, stell sie zur Diskussion.
Einführung
Ein Websitehostingservice für verschiedene Kunden einzurichten, ist nicht das Ziel dieses HowTo sie soll dir nur einen möglichen Lösungsansatz bieten und ist nicht vollständig.
Grundsätzlich, wird für jedem Nutzer deines Webserver, ein individueller Account angelegt. Die User können dann anschließend PHP Files in ihre eigenes virtual host documen root Verzeichnis hochladen.
Ziel ist es das PHP Skripts mit exakt den den User Rechten ausführt werden, welcheder jeweilige Userbesitzt. Ist dies einmal implementiert, kannst du dir (fast) sicher sein das Skripte anderer User oder Projekte nicht mehr verändert oder abgerufen werden können.
Hier ein Beispiel, welches ihr nur auf eurem eigenen Space ausprobieren solltet, es sei den morgen sollen Polizeibeamte vor eurer Haustür stehen.
Code: Select all
<?php
$filename = "/path_to_other_users_vhost_root/index.php";
$handle = fopen($filename, "rb");
$contents = fread($handle, filesize($filename));
fclose($handle);
echo $contents;
?>Lasst uns anfangen.
PHP.ini Einstellung
Viele Attacken lassen sich durch simpelste Einstellungen innerhalb der php.ini vermeiden, manch andere verlangsamen. An dieser Stelle sei euch der heise security Artikel PHP via CGI ans Herz gelegt - besonders der Abschnitt Sicherheitsrelevante PHP-Optionen mit einer kleinen Beispiel php.ini - http://www.heise.de/security/artikel/96564/1
Installation
Vorraussetzung ist das Lighttpd und PHP mit FastCGI installiert ist.
Log dich nun als root auf der Maschine ein, um die folgende Schritte abarbeiten zu können.
1. Erstelle ein paar Benutzer
(Das brauchst du nur machen, wenn du noch keine anderen Nutzer hast)
Falls du dir die Frage stellst warum man hier jetzt Nutzer erstellen muss (nachdem Motto: Ick bin ja schon root, wat will ick den mehr!), damit du den Zugriff auf anderen Source Code verhindern kannst – brauchst du seperate Userzugriffsrechte und dazu eben auch separate User.
Für dieses Beispiel brauchen wir 3 User (iza, george und ron):
Code: Select all
# useradd iza
# useradd george
# useradd ronDu benötigst für jeden oben hinzugefügten Benutzer eine User Gruppe. Um es einfach zu halten, bennenen wir die user groups analog zu den neuen Usern.
Code: Select all
# groupadd iza
# groupadd george
# groupadd ronDie user groups /etc/group editierst du am einfachsten mit deinem bevorzugten Texteditor.
Die Datei muss so ähnlich wie diese Aussehen (die Gruppennummern können variieren)
Code: Select all
..... [eine Menge Zeug darüber]
iza:x:441:iza,lighttpd
george:x:442:george,lighttpd
ron:x:443:ron,lighttpdLasst uns annehmen alle Dateien, welche ausgeliefert werden sollen befinden sich unter dem Ordner /var/www. (Du kannst auch gerne ein anderen nehmen, aber vergewissere dich bitte das du die passenden Rechte gesetzt hast.)
3.1 Wir die Server root Verzeichnisse
Wir erstellen zwei Verzeichnise: Eins für ein paar start-up scripts, auf welche nur root zugreifen kann und ein anderes für die virtual hosts.
Code: Select all
# cd /var/www
# mkdir fastcgi
# mkdir vhosts
# chown lighttpd:lighttpd *
# chmod 755 *
# ls -l /var/www
drwxr-xr-x 2 lighttpd lighttpd 4096 Feb 15 12:17 fastcgi
drwxr-xr-x 9 lighttpd lighttpd 4096 Feb 15 11:21 vhostsNun werden die Ordner für die einzelnen vhosts im Verzeichnis /var/www/vhosts erstellt und entsprechende Userrechte vergeben.
Code: Select all
# cd /var/www/vhosts
# mkdir iza-weasley.com
# mkdir george-weasley.com
# mkdir ron-weasley.com
# chown iza:iza iza-weasley.com
# chown george:george george-weasley.com
# chown ron:ron ron-weasley.com
# chmod 750 *
# ls -l /var/www/vhosts
drwxr-x--- 7 iza iza 4096 Feb 15 20:18 iza-weasley.com
drwxr-x--- 6 george george 4096 Feb 15 11:02 george-weasley.com
drwxr-x--- 6 ron ron 4096 Feb 15 11:23 ron-weasley.com750 bedeutet: 7= Eigentümer darf lesen(4) schreiben(2) ausführen(1) 5= Mitglieder der Gruppe x dürfen lesen (4) und ausführen (1). 0 = irgendjemand darf nichts. Beachtet die vorangestellten chowns (chown Eigentümer:Gruppe [Verzeichnis und/oder Datei])
3.3 wir erstellen die Verzeichnisse für jeden virtual host
Code: Select all
# cd /var/www/vhosts/iza-weasley.com
# mkdir html
# mkdir includes (optional)
# mkdir logs
# chown iza:iza *
# chown lighttpd:iza logs
# chmod 750 *
# ls -l /var/www/vhosts/iza-weasley.com
drwxr-x--- 14 iza iza 4096 Feb 17 11:55 html
drwxr-x--- 2 iza iza 4096 Feb 15 12:05 includes
drwxr-x--- 2 lighttpd iza 4096 Feb 15 11:11 logs3.4 FastCGI Verzeichnisse für jeden User erstellen
Nachdem das Gerüst fast schon steht - geht’s weiter.
Wir wechseln in das /var/www/fastcgi Verzeichnis in welchem mehrere Verzeichnisse für jeden User erstellt werden. (Wenn du fertig bist, beinhalten diese Ordner - die Sockets für den FastCGI Serverprozess):
Code: Select all
# cd /var/www/fastcgi
# mkdir iza
# mkdir george
# mkdir ron
# chown iza:iza iza
# chown george:george george
# chown ron:ron ron
# chmod 750 *
# ls -l /var/www/fastcgi
drwxr-x--- 7 iza iza 4096 Feb 15 20:18 iza
drwxr-x--- 6 george george 4096 Feb 15 11:02 george
drwxr-x--- 6 ron ron 4096 Feb 15 11:23 ron4. FastCGI start-up script für jeden Nutzer erstellen
nun wird ein Ordner erstellt, welcher all deine FastCGI start-up scripts bereithält:
# cd /var/www/fastcgi
# mkdir startup
# chmod 750 startup
# ls -l /var/www/fastcgi
drwxr-x--- 7 iza iza 4096 Feb 15 20:18 iza
drwxr-x--- 6 george george 4096 Feb 15 11:02 george
drwxr-x--- 6 ron ron 4096 Feb 15 11:23 ron
drwxr-x--- 6 root root 4096 Feb 15 11:23 startup[/code]
Nun ab in das /var/www/fastcgi/startup Verzeichnis und fix ein start-up script für iza erstellt., welches es iza-startup.sh genannt wird. Starte deinen geliebten Texteditor, übertrage den folgenden Quellcode und achte auf die Infos darunter und im File selbst:
Code: Select all
#!/bin/sh
## Absoluter Pfad zur spawn-fcgi binary
SPAWNFCGI="/usr/bin/spawn-fcgi"
## Absoluter Pfad zur PHP binary
FCGIPROGRAM="/usr/bin/php-cgi"
## bind to tcp-port on localhost
FCGISOCKET="/var/www/fastcgi/iza/iza.socket"
## uncomment the PHPRC line, if you want to have an extra php.ini for this user
## store your custom php.ini in /var/www/fastcgi/iza/php.ini
## with an custom php.ini you can improve your security
## just set the open_basedir to the users webfolder
## Example: (add this line in you custom php.ini)
## open_basedir = /var/www/vhosts/iza/html
##
#PHPRC="/var/www/fastcgi/iza/"
## number of PHP childs to spawn in addition to the default. Minimum of 2.
## Actual childs = PHP_FCGI_CHILDREN + 1
PHP_FCGI_CHILDREN=5
## number of request server by a single php-process until is will be restarted
PHP_FCGI_MAX_REQUESTS=1000
## IP adresses where PHP should access server connections from
FCGI_WEB_SERVER_ADDRS="127.0.0.1"
# allowed environment variables sperated by spaces
ALLOWED_ENV="PATH USER"
## if this script is run as root switch to the following user
USERID=iza
GROUPID=iza
################## no config below this line
if test x$PHP_FCGI_CHILDREN = x; then
PHP_FCGI_CHILDREN=5
fi
export PHP_FCGI_MAX_REQUESTS
export FCGI_WEB_SERVER_ADDRS
export PHPRC
ALLOWED_ENV="$ALLOWED_ENV PHP_FCGI_MAX_REQUESTS FCGI_WEB_SERVER_ADDRS PHPRC"
# copy the allowed environment variables
E=
for i in $ALLOWED_ENV; do
E="$E $i=$(eval echo "$$i")"
done
# clean environment and set up a new one
env - $E $SPAWNFCGI -s $FCGISOCKET -f $FCGIPROGRAM -u $USERID -g $GROUPID -C $PHP_FCGI_CHILDREN
chmod 770 $FCGISOCKETIn diesem Beispiel, läuft der php process mit dem darüber erstellten user ('iza'). Das bedeutet das php Schreibrechte auf die html und php files hat. Dies kann natürlich vorteilhaft sein, aber auch ein Sicherheitsrisiko. Alternativ, könnte die USERID auf 'nobody' gesetzt werden, um dem PHP-Prozess die Schreibrechte zu entziehen.
Natürlich musst auch dieser Schritt für jeden User wiederholt werden. (Also file kopieren, PHPRC, FCGISOCKET, USERID und GROUPID anpassen)
Vergiss nicht: das Recht zum ausführen der Dateien zu setzen:
Code: Select all
# cd /var/www/fastcgi/startup
# chmod 750 *wenn du dir unsicher über den Ort deiner php.ini bist kannst du folgendes Kommando absetzen
$ php-cgi -i | grep php.ini oder $ php5-cgi -i | grep php.ini
Bitte überprüf aich ob sich folgende Zeile in deiner php.ini befindet:
Code: Select all
cgi.fix_pathinfo=1Code: Select all
chmod 644 php.ini
chown root:root php.iniNun, Feuer frei – starte die FastCGI Serverprozesse:
Code: Select all
# /var/www/fastcgi/startup/iza-startup.sh
spawn-fcgi.c.170: child spawned successfully: PID: xxxxx
# /var/www/fastcgi/startup/george-startup.sh
spawn-fcgi.c.170: child spawned successfully: PID: xxxxx
# /var/www/fastcgi/startup/ron-startup.sh
spawn-fcgi.c.170: child spawned successfully: PID: xxxxx7. Konfigurieren der virtual hosts -> lighttpd.conf
Editier /etc/lighttpd/lighttpd.conf in deinem bevorzugten Texteditor:
Code: Select all
.....[eine Menge Konfig darüber].....
$HTTP["host"] =~ "(^|.)iza-weasley.com$" {
server.document-root = "/var/www/vhosts/iza-weasley.com/html"
server.errorlog = "/var/www/vhosts/iza-weasley.com/logs/error_log"
accesslog.filename = "/var/www/vhosts/iza-weasley.com/logs/access_log"
fastcgi.server = ( ".php" =>
(
( "socket" => "/var/www/fastcgi/iza/iza.socket",
"broken-scriptfilename" => "enable"
)
)
)
}
$HTTP["host"] =~ "(^|.)george-weasley.com$" {
server.document-root = "/var/www/vhosts/george-weasley.com/html"
server.errorlog = "/var/www/vhosts/george-weasley.com/logs/error_log"
...... (du bist dran)
8. Restart des lighttpd daemons
ganz einfach
Code: Select all
# /etc/init.d/lighttpd restart9. Hallo Individualität
Nun log dich als user iza ein und erstelle ein PHP script mit diesem Inhalt. (Beispielsweise /var/www/vhosts/iza-weasley.com/html/index.php):
Code: Select all
<?php
echo "<h1>Hallo Individualität!</h1>";
echo "<p>Current User ID is: ". posix_getuid();
echo "<p>Current Group ID is: ". posix_getgid();
?>Code: Select all
# chown iza:iza /var/www/vhosts/iza-weasley.com/html/index.php
# chmod 640 /var/www/vhosts/iza-weasley.com/html/index.php
# ls -l /var/www/vhosts/iza-weasley.com/html
-rw-r----- 1 iza iza 116 Jul 25 2004 index.phpFalls alles gut gelaufen ist, wirst du als Ausgabe die User ID des User iza und die dazugehörige Gruppen ID der Gruppe iza sehen. (Die ID's kannst du in dem File /etc/passwd und /etc/group auslesen)
10. Automatischer Start der FastCGI startup Skripte
Falls du möchtest kannst du einen crontab Eintrag verfassen damit die FastCGI startup scripte automatisch gestartet werden, wenn du deinen Server bootet.
Dazu nutzt du:
Code: Select all
# crontab -eCode: Select all
@reboot for i in /var/www/fastcgi/startup/*.sh; do $i; doneGlückwunsch jetzt hast du einen laufenden Server mit individuellen (separaten) User rechten.
Einschränkungen
Bei diesem Model, indem du ein sepearaten Pool von FastCGI Prozessen für jeden User startest, wird der Speicher Cache nicht geteilt. Die Folge dessen ist das du für viele Nutzer wesentlich mehr Speicher benötigst.
