Lukáš Bařinka
© 2021
REV 2.10
mod_userdir modulemod_userdirhttp://server/~usernameUserDir directive Default: UserDir public_htmlenabled | disabledhttp://server/~usernameUserDir Default: UserDir public_htmlenabled | disabledenabled [user_list] List of enabled users (all for empty list)disabled [user_list] List of disabled users (all for empty list)enabled [seznam_uživatelů] seznam uživatelů, pro které bude fungovat (všichni)disabled [seznam_uživatelů] seznam uživatelů, pro které nebude fungovat (všichni)Request to http://www.mycorp.net/~alice/
Požadavek na http://www.mycorp.net/~alice/
UserDir www
<Directory /home/*/www>
Require all granted
</Directory>
⇨ ~alice/www/
UserDir /var/www/users
<Directory /var/www/users>
Require all granted
</Directory>
⇨ /var/www/users/alice/
UserDir http://www.mycorp.net/users
⇨ http://www.mycorp.net/users/alice/
UserDir disabled root sysadm
Enables user directories for all users except root and sysadm
UserDir disabled
UserDir enabled alice bob
Disables user directories for all users but enables them for users alice and bob
The goal is to publish user directories. There are basically two ways how to achieve that. The first one is to place public directories into users directories. The second one is to place public directories as subdirectories into common directory outside users home directories. The access to users home directories for web server is needed in the first case.
Cílem je nakonfigurovat publikování uživatelských adresářů. V zásadě jsou 2 možnosti. Buď má každý uživatel ve svém domovském adresáři adresář s daty pro web, nebo existuje jeden společný adresář, ve kterém má každý uživatel svůj podadresář. V prvním případě je potřeba, aby webový server mohl přistupovat do adresáře každého uživatele.
www subdirectories inside users home directories, so they can use for its public contentalice/var/www/users and create links called www for users in their home directorieswww, kam budou mít možnost ukládat své webové prezentacealice/var/www/users a tento prostor uživatelům zpřístupněte jako podadresář www v jejich domovských adresářích+ Performance
– Complexity issues to write module
– Same identity of processing workers
+ Standard → easy to use
+ Security – processing workers can have different identity
– Performance
+ Rychlost
– Nutnost napsat takový modul
– Identita procesu obsluhujícího požadavek
+ Standard → jednoduché použití
+ Zabezpečení – změna identity obslužného procesu
– Rychlost
SuExec
mod_suexec [apache 2.2+]
wrapper (setUID!)
SuExec
mod_suexec [apache 2.2+]
wrapper (setUID!)
mod_cgi or mod_cgid
mod_cgi nebo mod_cgid
The most of parameters is hard-coded from compilation: ./configure
Většina parametrů se určuje při kompilaci: ./configure
--enable-suexec enables suEXEC compilation and installation--with-suexec-bin=PATH path to wrapper--with-suexec-caller=UID server identity--with-suexec-userdir=DIR UserDir--with-suexec-docroot=DIR DocumentRoot--with-suexec-uidmin=UID--with-suexec-gidmin=GID--with-suexec-logfile=FILE log file pathname--with-suexec-safepath=PATH safe content for PATH variable--enable-suexec povolí kompilaci a instalaci suEXEC--with-suexec-bin=PATH cesta k wrapperu--with-suexec-caller=UID identita webserveru--with-suexec-userdir=DIR UserDir--with-suexec-docroot=DIR DocumentRoot--with-suexec-uidmin=UID--with-suexec-gidmin=GID--with-suexec-logfile=FILE cesta k log souboru--with-suexec-safepath=PATH bezpečná PATHrootapache4710
ls -la suexec
-rws--x--- 1 root apache ... suexec
rootapache4710
ls -la suexec
-rws--x--- 1 root apache ... suexec
# Debian installation
apt install apache2-suexec-pristine
# instalace v Debianu
apt install apache2-suexec-pristine
SuexecUserGroup directive
SuexecUserGroup User Group
error_log
[notice] suEXEC mechanism enabled (wrapper: /path/to/suexec)
SuexecUserGroup
SuexecUserGroup User Group
error_log
[notice] suEXEC mechanism enabled (wrapper: /path/to/suexec)
http://httpd.apache.org/docs/current/suexec.html
⇨ http://localhost/~alice/cgi-bin/whoami.sh
<IfModule userdir_module>
…
<IfModule suexec_module>
<Directory /home/*/public_html/cgi-bin>
Options ExecCGI
SetHandler cgi-script
</Directory>
</IfModule>
…
</IfModule>
⇨ http://www.mycorp.net/cgi-bin/whoami.cgi
<VirtualHost 10.0.234.1:*>
ServerName www.mycorp.net
…
# suEXEC + CGI
<IfModule suexec_module>
# suEXEC identity
SuexecUserGroup mycorp users
<Directory /var/www/vhosts/mycorp/cgi-bin>
Options +ExecCGI
AddHandler cgi-script .cgi
</Directory>
</IfModule>
…
</VirtualHost>
The goal is to configure CGI as usual, but with different identity for different users. One way how to do that is to use user directories configuration. Another way is to configure different identities for different virtualhosts.
Cílem je nakonfigurovat spouštění CGI skriptů pod různými uživateli. Jedním ze způsobů je využit skripty uvnitř uživatelských adresářů. Druhou možností je konfigurace jednotlivých virtuálních hostitelů.
id command displays process identity (user/group)
Příkaz id zobrazí identitu procesu (uživatele/skupinu)
#!/bin/bash
echo "Content-Type: text/plain"
echo
/usr/bin/id
suexec program is in /usr/lib/apache2/suexec-pristine in Debian
V Debianu je suexec uložen v /usr/lib/apache2/suexec-pristine
/usr/lib/apache2/suexec-pristine -V
mycorp, othercorp1, othercorp2, othercorp3, and nocorpmycorp, othercorp1, othercorp2, othercorp3, nocorpphp-fpm (Fast Process Manager)libapache2-mod-php*
apt install php-fpm
apt install libapache2-mod-php
Module mpm_event disabled.
Enabling module mpm_prefork.
apache2_switch_mpm Switch to prefork
apache2_invoke: Enable module php7.3
a2enmod proxy_fcgi setenvif
a2enconf php7.3-fpm
a2enmod php7.3
Server Application Programming Interface
php -i | grep Thread
Thread Safety => disabled
# Load the module first
<IfModule !mod_php7.c>
LoadModule php7_module modules/libphp7.so
</IfModule>
# Set it to handle the files
<IfModule mod_mime.c>
AddHandler application/x-httpd-php .php .php5
AddHandler application/x-httpd-php-source .phps
</IfModule>
DirectoryIndex index.php index.html
Common Gateway Interface
#!/path/to/php-cgi
<?php
…
?>
#!/cesta/k/php-cgi
<?php
…
?>
QUERY_STRING information is a command line argument 1st parameter is pathname to be processed by default, e.g.: www.mycorp.net/cgi-bin/php-cgi?/etc/passwdPATH_INFO information, the server can send document from webspace which is forbidden for client, e.g.: www.mycorp.net/cgi-bin/php-cgi/private/secret.htmlPHP-CGI interpret solves both of those problems
--force-cgi-redirect → use of mod_actionsREDIRECT_STATUS environment variable It will fail when used directly → Internal Server ErrorQUERY_STRING se předává jako parametry příkazové řádky 1. parametr je typicky cesta k souboru, který se má vykonat, např.: www.mycorp.net/cgi-bin/php-cgi?/etc/passwdPATH_INFO lze interpret přinutit odeslat dokument z webspace, na který nemá klient právo, např.: www.mycorp.net/cgi-bin/php-cgi/private/secret.htmlPHP-CGI interpret řeší oba problémy
--force-cgi-redirect → použití mod_actionsREDIRECT_STATUS, Při přímém volání → Internal Server Error
<?php phpinfo(); ?>
<IfModule mod_mime.c>
AddType application/x-httpd-php .php …
</IfModule>
<IfModule actions_module>
<IfModule alias_module>
<IfModule cgi_module>
Action application/x-httpd-php /php/php-cgi
ScriptAlias /php/ /var/www/php/
<Directory /var/www/php>
Require all granted
</Directory>
DirectoryIndex index.php index.html
</IfModule>
</IfModule>
</IfModule>
<VirtualHost …:*>
DocumentRoot /path/to/DocumentRoot
ServerName www.mycorp.net
…
# suEXEC + CGI setup
<IfModule suexec_module>
SuexecUserGroup user group
<Directory /cesta/k/DocumentRoot/cgi-bin>
Options +ExecCGI
AddHandler cgi-script .cgi
</Directory>
# Sets REDIRECT_STATUS - required for security check
Action application/x-httpd-php /cgi-bin/php.cgi
DirectoryIndex index.php index.html
</IfModule>
</VirtualHost>
<VirtualHost …:*>
DocumentRoot /cesta/k/DocumentRoot
ServerName www.mycorp.net
…
# nastaveni suEXEC + CGI
<IfModule suexec_module>
SuexecUserGroup user group
<Directory /cesta/k/DocumentRoot/cgi-bin>
Options +ExecCGI
AddHandler cgi-script .cgi
</Directory>
# zajisti redirect - nutne pro kontrolu prav
Action application/x-httpd-php /cgi-bin/php.cgi
DirectoryIndex index.php index.html
</IfModule>
</VirtualHost>
wrapper=/var/www/vhosts/mycorp/cgi-bin/php.cgi
#!/bin/bash
exec /usr/bin/php-cgi "$@"
chmod 755 $wrapper
chown user:group $wrapper
The goal is to configure PHP interpret using PHP-CGI. So the .php program does not need to be standard CGI script.
Cílem je nakonfigurovat interpretaci PHP skriptů pomocí rozhraní PHP-CGI. Tedy aby nemusel být .php skript volán jako CGI skript.
info.php to print out current PHP settings using phpinfo(); function.php extensioninfo.php requestinfo.php, který vypíše aktuální nastavení PHP pomocí funkce phpinfo();.php
CGI
+ simple
+ language independent
+ architecture independent
+ process isolation
+ standard
- performance
CGI
+ jednoduchost
+ nezávislost na jazyku
+ nezávislost na architektuře
+ izolace procesů
+ standard
- výkon
Module
+ performance
- complex
- hard to scale
- no process isolation
- language dependent
- tied up to server
Modul
+ výkon
- komplexní
- špatně škálovatelné
- bez izolace procesů
- svázanost s jazykem
- svázanost se serverem
FastCGI
// FastCGI Developer's Kit
#include <fcgi_stdio.h>
void main(void)
{
// loop to accept connectioin
while(FCGI_Accept() >= 0) {
printf("Content-type: text/html\r\n");
printf("\r\n");
printf("Hello world!<br>\r\n");
}
// process termination
exit(0);
}
// FastCGI Developer's Kit
#include <fcgi_stdio.h>
void main(void)
{
// prijimaci smycka
while(FCGI_Accept() >= 0) {
printf("Content-type: text/html\r\n");
printf("\r\n");
printf("Hello world!<br>\r\n");
}
// ukonceni
exit(0);
}
FCGI_PARAMS | environment variables |
FCGI_STDIN | standard input |
FCGI_STDOUT | standard output |
FCGI_STDERR | standard error output |
FCGI_END_REQUEST | request process termination |
FCGI_PARAMS | proměnné prostředí |
FCGI_STDIN | standardní vstup |
FCGI_STDOUT | standardní výstup |
FCGI_STDERR | standardní chybový výstup |
FCGI_END_REQUEST | konec obsluhy požadavku |
200 OK, or authorization failed200 OK, jinak autorizace neproběhla s kladným výsledkemFastCGI implementations
mod_fcgid http://httpd.apache.org/mod_fcgid/mod_fastcgi deprecated
LoadModule fcgid_module modules/mod_fcgid.so
<IfModule fcgid_module>
Alias /fcgi /var/www/main/fcgi
<Directory /var/www/main/fcgi>
Options +ExecCGI
AddHandler fcgid-script .fcgi
AddHandler cgi-script .cgi
Require all granted
</Directory>
</IfModule>
# FcgidMaxRequestsPerProcess should be <= PHP_FCGI_MAX_REQUESTS
# The example PHP wrapper script overrides the default PHP setting.
FcgidMaxRequestsPerProcess 10000
Alias /phpapp/ /usr/local/phpapp/
<Location /phpapp/>
AddHandler fcgid-script .php
Options +ExecCGI
FcgidWrapper /usr/local/bin/php-wrapper .php
Require all granted
</Location>
/usr/local/bin/php-wrapper
#!/bin/sh
# Set desired PHP_FCGI_* environment variables.
# Example:
# PHP FastCGI processes exit after 500 requests by default.
PHP_FCGI_MAX_REQUESTS=10000
export PHP_FCGI_MAX_REQUESTS
# Replace with the path to your FastCGI-enabled PHP executable
exec /usr/local/bin/php-cgi