Weby běžící pod vlastním uživatelem – Apache a peruser MPM
Provozovat webserver pro více aplikací s různými majiteli bez rozdělení vlastnických práv k souborům a běžícím procesům je docela hazard. Spustit každý web pod samostatným uživatelem můžete různými způsoby, já si vybral u Apache webserveru MPM peruser.
Na serverech využíváme primárně OS Linux – distribuci CentOS. Součástí CentOSu peruser MPM není, je tedy třeba si ho přeložit ze zdrojového kódu. Zdrojový kód k peruser MPM lze stáhnout na domácí stránce projektu – www.peruser.org.
Překlad Apache ze zdrojového kódu řešíme “rebuildem” RPM. Stáhl jsem si originální src.rpm, upravil spec soubor a přidal do něj patch peruser MPM 0.4.0 MPM beta 2.
Upravený httpd.spec, zdrojový balíček připravený pro překlad a přeložené binárky přikládám ke stažení.
Po nainstalování apache z výše odkazovaných balíčků je nutné změnit používanou binárku a tím i MPM z httpd.worker na httpd.peruser v souboru /etc/sysconfig/httpd. Změna se provede nastavením proměnné “HTTPD=/usr/sbin/httpd.peruser”.
Do konfiguračního soubouru apache /etc/httpd/conf/httpd.conf je nutné dopsat základní konfiguraci peruser MPM:
<IfModule peruser.c> # Multiplexer pool MinMultiplexers 3 MaxMultiplexers 10 ProcessorWaitTimeout 2 20 # Fork limits ServerLimit 256 MaxClients 256 MaxRequestsPerChild 400 # Processor defaults MinProcessors 4 MinSpareProcessors 4 MaxProcessors 128 # Timeouts IdleTimeout 180 ExpireTimeout 3600 </IfModule>
Popis jednotlivých voleb je k nalezení v dokumentaci http://www.peruser.org/trac/peruser/wiki/PeruserDocumentation
Pro každého virtualhosta, kterého vytvoříte, je nutné specifikovat pod jakým uživatelem poběží.
<VirtualHost webserver:80> ServerName zdenda.com RewriteEngine On RewriteOptions Inherit DocumentRoot /var/www/zdenda.com/public_html <Directory /var/www/zdenda.com/public_html> AllowOverride All </Directory> Processor zdenda.com zdenda.com ServerEnvironment zdenda.com zdenda.com MaxProcessors 128 </VirtualHost> <VirtualHost webserver:80> ServerName zdenda.com ServerAlias *.zdenda.com RewriteEngine On RewriteOptions Inherit DocumentRoot /var/www/zdenda.com VirtualDocumentRoot /var/www/zdenda.com/subdomains/%1 <Directory /var/www/zdenda.com/subdomains/*> AllowOverride All </Directory> Processor zdenda.com zdenda.com ServerEnvironment zdenda.com zdenda.com MaxProcessors 128 </VirtualHost>
Virtualhosta mám dvakrát, protože první virtualhost je pro zdenda.com a druhý pro *.zdenda.com.
Výpis procesů apache (ps axfu) ukazuje jak jak apache forkuje potomky s různými vlastníky (Passenger potomek apache nám zajišťuje běh Redmine):
root 13462 0.0 0.0 399320 22480 ? Ss Aug21 0:01 /usr/sbin/httpd.peruser root 13700 0.0 0.0 212444 1340 ? Ssl Aug21 0:00 \_ PassengerWatchdog root 13703 0.0 0.0 813956 2100 ? Sl Aug21 0:19 | \_ PassengerHelperAgent root 13705 0.0 0.0 53888 10468 ? Sl Aug21 0:14 | | \_ Passenger spawn server 10000 27651 2.6 0.4 262016 112468 ? S 10:22 0:08 | | \_ Passenger ApplicationSpawner: /var/www/domain.tld/subdomain/redmine nobody 13710 0.0 0.0 146476 2300 ? Sl Aug21 0:00 | \_ PassengerLoggingAgent apache 13716 0.0 0.0 399456 11776 ? S Aug21 0:00 \_ /usr/sbin/httpd.peruser apache 13758 0.0 0.0 399456 11776 ? S Aug21 0:00 \_ /usr/sbin/httpd.peruser apache 13777 0.0 0.0 399456 11776 ? S Aug21 0:00 \_ /usr/sbin/httpd.peruser apache 13794 0.0 0.0 399592 11968 ? S Aug21 0:00 \_ /usr/sbin/httpd.peruser 10002 14261 0.0 0.0 399456 12332 ? S 00:59 0:00 \_ /usr/sbin/httpd.peruser 10002 14262 0.0 0.0 399456 11476 ? S 00:59 0:00 \_ /usr/sbin/httpd.peruser 10002 14263 0.0 0.0 399456 11476 ? S 00:59 0:00 \_ /usr/sbin/httpd.peruser 10002 14264 0.0 0.0 399456 11476 ? S 00:59 0:00 \_ /usr/sbin/httpd.peruser 10014 24408 0.0 0.1 413296 28588 ? S 08:02 0:00 \_ /usr/sbin/httpd.peruser 10011 26760 0.0 0.0 399456 12384 ? S 09:42 0:00 \_ /usr/sbin/httpd.peruser 10011 27079 0.0 0.0 399456 12384 ? S 09:56 0:00 \_ /usr/sbin/httpd.peruser 10014 27320 0.0 0.1 412884 28040 ? S 10:07 0:00 \_ /usr/sbin/httpd.peruser 10000 27336 0.0 0.0 400124 14136 ? S 10:08 0:00 \_ /usr/sbin/httpd.peruser 10014 27366 0.0 0.0 399456 11504 ? S 10:09 0:00 \_ /usr/sbin/httpd.peruser 10014 27367 0.0 0.1 412852 27964 ? S 10:09 0:00 \_ /usr/sbin/httpd.peruser 10008 27485 0.0 0.1 424332 39348 ? S 10:14 0:00 \_ /usr/sbin/httpd.peruser
Pro založení virtualhosta je tedy třeba provést:
- založit uživatele a skupinu v OS, uživateli dát shell rssh aby mohl nahrát data na web
- vytvořit domácí adresář a nastavit správně oprávnění
- vytvořit konfigurační soubor virtualhosta (každého vhosta dáváme do samostatného konf. souboru)
Pokud budete mít na serveru více virtualhostů, je vhodné si usnadnit jejich zakládání např. pomocí skriptu:
#!/bin/bash ORIGDIR=$(pwd) cd ${0%/*} VHOSTDIR=/etc/httpd/vhosts.d/ VHOSTTEMPLATE=/etc/httpd/vhost.tpl if [ -f "${0##*/}.conf" ]; then . "${0##*/}.conf" fi cd "$ORIGDIR" usage() { cat >&2 <<EOF Usage: ${0##*/} [switches] --domain domain.tld --help print help --domain domain.tld domain EOF [ $# -ge 1 ] && exit $1 } params=$( getopt -n "${0##*/}" -o "" -l help,domain: -- "$@" ) [ $? != 0 ] && usage 1 eval set -- "$params" unset params while : do case "$1" in --help) usage 0;; --domain) DOMAIN="${2}";; --) shift; break;; esac shift done for i in DOMAIN VHOSTDIR VHOSTTEMPLATE; do if [ -z "${!i}" ]; then echo "Hodnota $i neni definovana." >&2 exit 1 fi done if ! egrep -q -i '^([[:alnum:]]|-)+\.([[:alpha:]][[:alpha:]]+)$' <<< ${DOMAIN} ; then echo "Parametr --domain zrejme neobsahuje domenu 2. radu" >&2 exit 1 fi if find $VHOSTDIR -type f | xargs -- egrep -l "\ $DOMAIN\$" ; then echo "Virtualhost pro domenu $DOMAIN je jiz v systemu" >&2 exit 1 fi if getent passwd $DOMAIN > /dev/null; then echo "Uzivatel nebo skupina $DOMAIN jiz v systemu existuje, zalozte noveho virtualhosta rucne." >&2 exit 1 else if ! useradd -c "Web $DOMAIN" -d "/home/web/$DOMAIN" -s /usr/bin/rssh -m -k /home/web/.skeleton -U "$DOMAIN"; then echo "Nepodarilo se zalozit uzivatele $DOMAIN:$DOMAIN, ktery je nutny pro beh webu." >&2 echo "Virtualhost nebyl vytvoren." >&2 exit 1 fi fi if ! $(cat $VHOSTTEMPLATE | sed -e "s%__DOMAIN__%$DOMAIN%g" > $VHOSTDIR/$DOMAIN.conf); then userdel -r "$DOMAIN" echo "Pri vytvareni konfiguracniho souboru $VHOSTDIR/$DOMAIN.conf nastala chyba." >&2 echo "Systemovy uzivatel $DOMAIN:$DOMAIN byl odstranen." >&2 echo "Opravte chybu a zkuste vytvorit noveho virtualhosta." >&2 exit 1 fi if ! service httpd configtest 2>/dev/null; then echo "V konfiguraci apache je nekde chyba :-(" >&2 service httpd configtest echo "Odstrante chybu a provedte reload konfigurace." >&2 exit 1 else cat << __EOF__ ========================================== Virtualhost pro domenu $DOMAIN byl zalozen. Web pobezi v systemu pod uzivatelem $DOMAIN:$DOMAIN Domaci adresar uzivatele je v /var/www/$DOMAIN Apache bude hledat data pro pristup na web v adresarich /var/www/$DOMAIN/public_html pro domenu $DOMAIN (dom. 2. radu) a v adresari /var/www/$DOMAIN/subdomains/XXX pro domeny XXX.$DOMAIN Uzivatel $DOMAIN ma do systemu prisup pres SSH pouze pro SCP/SFTP. Plny pristup uzivatele do systemu je mozne povolit zmenou shellu na /bin/bash prikazem "usermod -s /bin/bash $DOMAIN" Odstraneni uzivatele, dat a vhosta ze systemu je mozne pomoci prikazu "usermod -r $DOMAIN" a smazanim souboru /etc/httpd/vhosts.d/$DOMAIN.conf Pro nasmerovani domeny na server pouzijte IP adresu `getent hosts neon| awk '{print $1}'` ========================================== Provedte reload apache: "service httpd reload" ========================================== __EOF__ exit 0 fi
Šablona virtualhosta:
# cat /etc/httpd/vhost.tpl <VirtualHost webserver:80> ServerName __DOMAIN__ RewriteEngine On RewriteOptions Inherit DocumentRoot /var/www/__DOMAIN__/public_html <Directory /var/www/__DOMAIN__/public_html> AllowOverride All </Directory> Processor __DOMAIN__ __DOMAIN__ ServerEnvironment __DOMAIN__ __DOMAIN__ MaxProcessors 128 </VirtualHost> <VirtualHost webserver:80> ServerName __DOMAIN__ ServerAlias *.__DOMAIN__ RewriteEngine On RewriteOptions Inherit DocumentRoot /var/www/__DOMAIN__ VirtualDocumentRoot /var/www/__DOMAIN__/subdomains/%1 <Directory /var/www/__DOMAIN__/subdomains/*> AllowOverride All </Directory> Processor __DOMAIN__ __DOMAIN__ ServerEnvironment __DOMAIN__ __DOMAIN__ MaxProcessors 128 </VirtualHost>
Použití skriptu je snadné, jako root stačí spustit “add_vhost.sh –domain domena.tld” a skript vytvoří potřebnou konfiguraci.