Setup a status page on a Apache 2 server
Apache 2, PHP-FPM, APC, and other tools have usage statistics in Web pages. The data provided by these statistics are critical. It is important to secure the access to them. This howto setup a secure sub-domain dedicated to the display of HTTP server statuses.
This howto is tested on :
- Debian 6.0 Squeeze
- Debian 7.0 Wheezy
Prerequisite
This howto needs:
- a Apache 2 HTTP server with the a2tools script available in Install and setup Apache 2 on Debian.
Parameters
Provide the domain name where will be available the statuses (adjust the bold value to your setup) :
DOMAIN="status.domain.com"
Provide the SSL certificate name used to secure the site with HTTPS (created by following Create a SSL / TLS certificate on Debian) (optionnal, recommanded) :
SSL_KEY_NAME="${DOMAIN}"
Security parameters
If your Internet Service Provider allocates a fixed IP address, provide it :
USER_FIXED_IP="xx.xx.xx.xx"
You can find your current Internet access IP address by browsing monip.org.
Provide a user login name to be used when you are not at home/work :
USER_NAME="username"
Installation
Compute the install path :
INSTALL_PATH="/opt/apache2/${DOMAIN}"
Create the folder where will be store the statuses pages :
command mkdir --parents "${INSTALL_PATH}"
Add an index file listing available statuses :
echo "<html><head><title>$(command hostname --fqdn) servers status</title></head><body>
<h1>$(command hostname --fqdn) server status:</h1>
<ul>
</ul>
</body></html>" > "/opt/apache2/${DOMAIN}/index.html"
HTTP server configuration
Install the needed software :
command apt-get install apg apache2-utils
Detect the security settings used:
command test "${USER_NAME}" = "username" && USER_NAME=""
command test "${USER_FIXED_IP}" = "xx.xx.xx.xx" && USER_FIXED_IP=""
Generate a random password for the user :
command test -n "${USER_NAME}" && USER_PASSWORD="$(command apg -q -a 0 -n 1 -M NCL)"
Create the password files folder :
command test -n "${USER_NAME}" && command mkdir --parents '/etc/apache2/passwords'
Create the password file for the domain :
command test -n "${USER_NAME}" && command htpasswd -cb "/etc/apache2/passwords/${DOMAIN}.pwd" "${USER_NAME}" "${USER_PASSWORD}"
Create the HTTP security configuration according to provided parameters:
if [ -n "${USER_NAME}" ]; then
SECURITY="
# Protect default access
Order deny,allow
Deny from all
# Auth configuration
# Allow auth either by user, or by IP
Satisfy any
# We enable password authentication
AuthType Basic
AuthName \"${DOMAIN} Apache 2 status pages\"
AuthUserFile /etc/apache2/passwords/${DOMAIN}.pwd
Require valid-user
# Allow access from user main Internet connexion
#Allow from ${USER_FIXED_IP}/32"
else
if [ -n "${USER_FIXED_IP}" ]; then
SECURITY="
# Protect default access
Order deny,allow
Deny from all
# Allow access from user main Internet connexion
#Allow from ${USER_FIXED_IP}/32"
else
SECURITY="
# No protection on access
Order deny,allow
Allow from all"
fi
fi
Detect the SSL option:
SSL_OPTION=""
if [ -e "/etc/ssl/private/${SSL_KEY_NAME}.key" ]; then
SSL_OPTION="--ssl=${SSL_KEY_NAME}"
fi
Create Apache 2 configuration file for the domain :
command a2tools --template="custom" ${SSL_OPTION} "${DOMAIN}" "
DocumentRoot ${INSTALL_PATH}
<Location />
${SECURITY}
</Location>
#########################################################
### STATUS PAGES CONFIGURATION START (do not remove). ###
### STATUS PAGES CONFIGURATION END (do not remove). ###
#########################################################
"
Setup a HTTP to HTTPS redirection if needed :
if [ -e "/etc/ssl/private/${SSL_KEY_NAME}.key" ]; then
command a2tools --template="redirect" "${DOMAIN}" "https://${DOMAIN}/"
fi
Detect the configuration file of the status VHost :
STATUS_VHOST="$(command grep -rl \
"STATUS PAGES CONFIGURATION END" \
'/etc/apache2/sites-available')"
Allow the provided IP address access (if needed) :
if [ -n "${USER_FIXED_IP}" ]; then
command sed -i -e "s/#Allow from ${USER_FIXED_IP}/Allow from ${USER_FIXED_IP}/" \
"${STATUS_VHOST}"
fi
Check the new Apache 2 setup :
command apache2ctl -t
Reload Apache 2 configuration :
/etc/init.d/apache2 reload
This command list the access parameters to the statuses :
echo "URL: https://${DOMAIN}/
Identifiant : ${USER_NAME}
Mot de passe : ${USER_PASSWORD}"
Access from a subfolder
If you want the statuses to be available from a sub-folder of the domain, provide the sub-folder location :
SUB_FOLDER="/status/$(command hostname --fqdn)"
Detect the statuses virtual host configuration file :
STATUS_VHOST="$(command grep --max-count=1 -rl \
"STATUS PAGES CONFIGURATION END" \
'/etc/apache2/sites-available')"
Apply the setup :
if [ -n "${SUB_FOLDER}" ]; then
command sed -i -e "/DocumentRoot/a\\
Alias ${SUB_FOLDER} ${INSTALL_PATH}\\
RewriteCond %{REQUEST_URI} \!^(/php5.fastcgi)*/php-fpm-ping\\
RewriteCond %{REQUEST_URI} \!^(/php5.fastcgi)*/php-fpm-status\\
RewriteCond %{REQUEST_URI} \!^(/php5.fastcgi)*${SUB_FOLDER}\\
RewriteRule ^/(.*) ${SUB_FOLDER}/\$1 [R=301,L]" \
${STATUS_VHOST}
fi
Check the new Apache 2 setup :
command apache2ctl -t
Reload the configuration :
/etc/init.d/apache2 reload
Addition of status pages
PhpMyAdmin
If PHPMyAdmin is installed, you can add this web-application to the status pages in order to secure its access.
Detect the status VHost configuration file :
STATUS_VHOST="$(command grep -rl \
"STATUS PAGES CONFIGURATION END" \
'/etc/apache2/sites-available')"
Detect the installation path :
if [ -n "${STATUS_VHOST}" ]; then
INSTALL_PATH=$(command grep "DocumentRoot" "${STATUS_VHOST}" \
| command sed -e 's/^[ \t]*//;s/[ \t]*$//' -e 's/[ \t]*[ \t]/ /g' \
| command cut --delimiter=" " --field=2)
fi
Detect the used subfolder:
SUB_FOLDER=""
if [ -n "${STATUS_VHOST}" -a -n "$(command grep '^[ ]*Alias ' "${STATUS_VHOST}")" ]; then
SUB_FOLDER="$(command grep '^[ ]*Alias ' "${STATUS_VHOST}" \
| command sed -e 's/^[ \t]*//;s/[ \t]*$//' -e 's/[ \t]*[ \t]/ /g' \
| command cut --delimiter=" " --field=2)"
fi
Add PHPMyAdmin configuration to the virtual host :
if [ -n "${STATUS_VHOST}" -a -e "/etc/phpmyadmin/apache.conf" ]; then
command sed -i -e "/STATUS PAGES CONFIGURATION END/i\\
# PHPMyAdmin configuration.\\
Include '/etc/phpmyadmin/apache.conf'\\
" "${STATUS_VHOST}"
fi
Add the subfolder settings to the virtual host:
if [ -n "${SUB_FOLDER}" -a -e "/etc/phpmyadmin/apache.conf" ]; then
command sed -i -e "/DocumentRoot/i\\
# PHPMyAdmin subfolder access.\\
Alias ${SUB_FOLDER}/phpmyadmin /usr/share/phpmyadmin\\
" "${STATUS_VHOST}"
fi
Check Apache 2 setup for errors :
command apache2ctl -t
Reload the configuration :
/etc/init.d/apache2 reload
Add the corresponding link to the domain index page :
if [ -e "/etc/phpmyadmin/apache.conf" ]; then
command sed -i -e '/<\/ul>/i\
<li><a href="./phpmyadmin">PHPMyAdmin</a></li>' \
"${INSTALL_PATH}/index.html"
fi
You can now access to PHPMyAdmin.
System status
phpSysInfo is a Web application displaying system data. It needs a HTTP server with PHP.
Install the PHP5 XSL extension:
command apt-get install php5-xsl
Detect the statuses virtual host configuration file :
STATUS_VHOST="$(command grep -rl \
"STATUS PAGES CONFIGURATION END" \
'/etc/apache2/sites-available')"
Detect the installation path used :
if [ -n "${STATUS_VHOST}" ]; then
INSTALL_PATH=$(command grep "DocumentRoot" "${STATUS_VHOST}" \
| command sed -e 's/^[ \t]*//;s/[ \t]*$//' -e 's/[ \t]*[ \t]/ /g' \
| command cut --delimiter=" " --field=2)
fi
Download the sources of the software last version with sf-downloader :
if [ -n "${INSTALL_PATH}" -a -e "/etc/php5" ]; then
command wget 'https://raw.github.com/biapy/howto.biapy.com/master/various/sf-downloader' \
--quiet --no-check-certificate --output-document='/tmp/sf-downloader'
command chmod +x '/tmp/sf-downloader'
SOURCE="$(/tmp/sf-downloader --strip-components=1 --output-directory="${INSTALL_PATH}/phpsysinfo" \
--tgz 'phpsysinfo' 'phpsysinfo-VERSION.tar.gz')"
fi
Adjust file permissions :
if [ -d "${INSTALL_PATH}/phpsysinfo" ]; then
command chown -R root:root "${INSTALL_PATH}/phpsysinfo"
command chmod -R go-w "${INSTALL_PATH}/phpsysinfo"
fi
Create the configuration file :
if [ -d "${INSTALL_PATH}/phpsysinfo" ]; then
command cp "${INSTALL_PATH}/phpsysinfo/phpsysinfo.ini.new" "${INSTALL_PATH}/phpsysinfo/phpsysinfo.ini"
fi
Adjust the settings (default language, plugins, etc...) :
if [ -d "${INSTALL_PATH}/phpsysinfo" ]; then
command sed -i \
-e 's/\(PLUGINS=\).*$/\1"PS,PSStatus,SMART"/' \
"${INSTALL_PATH}/phpsysinfo/phpsysinfo.ini"
fi
Add the corresponding link to the domain index page :
if [ -d "${INSTALL_PATH}/phpsysinfo" ]; then
command sed -i -e '/<\/ul>/i\
<li><a href="./phpsysinfo">System status</a></li>' \
"${INSTALL_PATH}/index.html"
fi
You can now view system status.
Statut d'Apache 2
Activez le module status:
command a2enmod status
Detect the statuses virtual host configuration file :
STATUS_VHOST="$(command grep -rl \
"STATUS PAGES CONFIGURATION END" \
'/etc/apache2/sites-available')"
Detect the installation path used :
if [ -n "${STATUS_VHOST}" ]; then
INSTALL_PATH=$(command grep "DocumentRoot" "${STATUS_VHOST}" \
| command sed -e 's/^[ \t]*//;s/[ \t]*$//' -e 's/[ \t]*[ \t]/ /g' \
| command cut --delimiter=" " --field=2)
fi
Detect the statuses sub-folder :
SUB_FOLDER=""
if [ -n "${STATUS_VHOST}" -a -n "$(command grep '^[ ]*Alias ' "${STATUS_VHOST}")" ]; then
SUB_FOLDER="$(command grep '^[ ]*Alias ' "${STATUS_VHOST}" \
| command sed -e 's/^[ \t]*//;s/[ \t]*$//' -e 's/[ \t]*[ \t]/ /g' \
| command cut --delimiter=" " --field=2)"
fi
Add the needed setup to virtual host :
if [ -n "${STATUS_VHOST}" ]; then
command sed -i -e "/STATUS PAGES CONFIGURATION END/i\\
# Apache 2 status page.\\
<Location ${SUB_FOLDER}/apache2>\\
SetHandler server-status\\
</Location>\\
" "${STATUS_VHOST}"
fi
Add the corresponding link to the domain index page :
if [ -e "${INSTALL_PATH}/index.html" ]; then
command sed -i -e '/<\/ul>/i\
<li><a href="./apache2">Apache 2 status</a> (<a href="./apache2?refresh=5">with 5s auto-refresh rate</a>)</li>' \
"${INSTALL_PATH}/index.html"
fi
Check Apache 2 setup for errors :
command apache2ctl -t
Reload the configuration :
/etc/init.d/apache2 reload
You can now view Apache 2 statuses in real time. Here are some knowledge about the provided data :
- A heavy CPU usage can be caused by a script run by a module such à mod_php.
- It is OK to have a bunch of task in "keep-alive" (noted by a "K"). If the vast majority of listed task are in "keep-alive" state, you may want to lower the value of KeepAliveTimeout setting.
- If you have very little inactive tasks (noted by a "."), you may want to raise "MaxClients". Having a sufficient number of inactive tasks to manage new connections can lower server response time. Make sure to have sufficient available memory before changing this value.
PHPinfo
If PHP is available on the server, you can display data on the setup (function phpinfo()).
Detect the statuses virtual host configuration file :
STATUS_VHOST="$(command grep -rl \
"STATUS PAGES CONFIGURATION END" \
'/etc/apache2/sites-available')"
Detect the installation path used :
if [ -n "${STATUS_VHOST}" ]; then
INSTALL_PATH=$(command grep "DocumentRoot" "${STATUS_VHOST}" \
| command sed -e 's/^[ \t]*//;s/[ \t]*$//' -e 's/[ \t]*[ \t]/ /g' \
| command cut --delimiter=" " --field=2)
fi
Create the PHPinfo file :
if [ -e '/etc/php5' ]; then
command echo "<?php phpinfo() ?>" > "${INSTALL_PATH}/phpinfo.php"
fi
Add the corresponding link to the domain index page :
if [ -e "${INSTALL_PATH}/phpinfo.php" ]; then
command sed -i -e '/<\/ul>/i\
<li><a href="./phpinfo.php">PHP info</a></li>' \
"${INSTALL_PATH}/index.html"
fi
You can now view PHPinfo.
APC (Alternative PHP Cache) status
If APC is present on the server (see Install the PHP extension APC on Debian), you can dispose of usage statistics.
Install GD to generate cache usage graphics :
if [ -e '/etc/php5/conf.d/apc.ini' ]; then
command apt-get install php5-gd
fi
Reload the configuration by restarting HTTP server or PHP-FPM :
if [ -e '/etc/php5/conf.d/apc.ini' ]; then
test -x /etc/init.d/apache2 && /etc/init.d/apache2 force-reload
test -x /etc/init.d/php5-fpm && /etc/init.d/php5-fpm restart
fi
Detect the statuses virtual host configuration file :
STATUS_VHOST="$(command grep -rl \
"STATUS PAGES CONFIGURATION END" \
'/etc/apache2/sites-available')"
Detect the installation path used :
if [ -n "${STATUS_VHOST}" ]; then
INSTALL_PATH=$(command grep "DocumentRoot" "${STATUS_VHOST}" \
| command sed -e 's/^[ \t]*//;s/[ \t]*$//' -e 's/[ \t]*[ \t]/ /g' \
| command cut --delimiter=" " --field=2)
fi
Install APC statistics tool :
if [ -e '/usr/share/doc/php-apc/apc.php.gz' -a -d "${INSTALL_PATH}" ]; then
command gunzip --uncompress --to-stdout '/usr/share/doc/php-apc/apc.php.gz' > "${INSTALL_PATH}/apc.php"
elif [ -e '/etc/php5/conf.d/apc.ini' ]; then
# If APC is installed from DotDeb repository.
command wget "http://svn.php.net/viewvc/pecl/apc/trunk/apc.php?view=co" \
--quiet --output-document="${INSTALL_PATH}/apc.php"
fi
Add the corresponding link to the domain index page :
if [ -e "${INSTALL_PATH}/index.html" -a -e "${INSTALL_PATH}/apc.php" ]; then
command sed -i -e '/<\/ul>/i\
<li><a href="./apc.php">Alternative PHP cache status</a></li>' \
"${INSTALL_PATH}/index.html"
fi
You can now view real time APC status.
PHP FPM (FastCGI Process Manager) status
If PHP FPM is present on the server (see Install PHP-FPM on Debian), you can have access to usage statistics.
Detect the statuses virtual host configuration file :
STATUS_VHOST="$(command grep -rl \
"STATUS PAGES CONFIGURATION END" \
'/etc/apache2/sites-available')"
Detect the installation path used :
if [ -n "${STATUS_VHOST}" ]; then
INSTALL_PATH=$(command grep "DocumentRoot" "${STATUS_VHOST}" \
| command sed -e 's/^[ \t]*//;s/[ \t]*$//' -e 's/[ \t]*[ \t]/ /g' \
| command cut --delimiter=" " --field=2)
fi
Detect the statuses sub-folder :
SUB_FOLDER=""
if [ -n "${STATUS_VHOST}" -a -n "$(command grep '^[ ]*Alias ' "${STATUS_VHOST}")" ]; then
SUB_FOLDER="$(command grep '^[ ]*Alias ' "${STATUS_VHOST}" \
| command sed -e 's/^[ \t]*//;s/[ \t]*$//' -e 's/[ \t]*[ \t]/ /g' \
| command cut --delimiter=" " --field=2)"
fi
Enable Apache mod_proxy if needed :
if [ -n "${SUB_FOLDER}" ]; then
command a2enmod proxy proxy_http
fi
Add the needed setup to virtual host :
if [ -n "${STATUS_VHOST}" -a -n "${SUB_FOLDER}" -a -e '/etc/php5/fpm/pool.d/www.conf' ]; then
command sed -i -e "/STATUS PAGES CONFIGURATION END/i\\
# FPM status page.\\
<IfModule mod_proxy.c>\\
ProxyRequests Off\\
ProxyPreserveHost On\\
SetEnv proxy-nokeepalive 1\\
ProxyPass ${SUB_FOLDER}/php-fpm-status http://localhost/php-fpm-status\\
ProxyPass ${SUB_FOLDER}/php-fpm-ping http://localhost/php-fpm-ping\\
</IfModule>\\
\\
# FPM status page.\\
<Location /php-fpm-status>\\
Allow from all\\
</Location>\\
\\
# FPM ping page.\\
<Location /php-fpm-ping>\\
Allow from all\\
</Location>\\
" "${STATUS_VHOST}"
fi
Check Apache 2 setup for errors :
command apache2ctl -t
Reload the configuration :
/etc/init.d/apache2 force-reload
Add the corresponding link to the domain index page :
if [ -e "${INSTALL_PATH}/index.html" -a -e '/etc/php5/fpm/pool.d/www.conf' ]; then
command sed -i -e '/<\/ul>/i\
<li><a href="./php-fpm-status">PHP FPM status</a></li>\
<li><a href="./php-fpm-ping">PHP FPM ping</a></li> '\
"${INSTALL_PATH}/index.html"
fi
You can now view PHP-FPM real time status.
Google mod_pagespeed status
Si Google mod_pagespeed est installé sur le serveur (voir Installer le module Google PageSpeed pour Apache 2 sur Debian), vous pouvez disposer de statistiques d'utilisation.
Detect the statuses virtual host configuration file :
STATUS_VHOST="$(command grep -rl \
"STATUS PAGES CONFIGURATION END" \
'/etc/apache2/sites-available')"
Detect the installation path used :
if [ -n "${STATUS_VHOST}" ]; then
INSTALL_PATH=$(command grep "DocumentRoot" "${STATUS_VHOST}" \
| command sed -e 's/^[ \t]*//;s/[ \t]*$//' -e 's/[ \t]*[ \t]/ /g' \
| command cut --delimiter=" " --field=2)
fi
Detect the statuses sub-folder :
SUB_FOLDER=""
if [ -n "${STATUS_VHOST}" -a -n "$(command grep '^[ ]*Alias ' "${STATUS_VHOST}")" ]; then
SUB_FOLDER="$(command grep '^[ ]*Alias ' "${STATUS_VHOST}" \
| command sed -e 's/^[ \t]*//;s/[ \t]*$//' -e 's/[ \t]*[ \t]/ /g' \
| command cut --delimiter=" " --field=2)"
fi
Add the needed setup to virtual host :
if [ -n "${STATUS_VHOST}" -a -e '/etc/apache2/mods-enabled/pagespeed.load' ]; then
command sed -i -e "/STATUS PAGES CONFIGURATION END/i\\
# Google mod_pagespeed status page.\\
<Location ${SUB_FOLDER}/mod_pagespeed_statistics>\\
SetHandler mod_pagespeed_statistics\\
</Location>\\
<Location ${SUB_FOLDER}/mod_pagespeed_message>\\
SetHandler mod_pagespeed_message\\
</Location>\\
" "${STATUS_VHOST}"
fi
Check Apache 2 setup for errors :
command apache2ctl -t
Reload the configuration :
/etc/init.d/apache2 reload
Add the corresponding link to the domain index page :
if [ -e "${INSTALL_PATH}/index.html" -a -e '/etc/apache2/mods-enabled/pagespeed.load' ]; then
command sed -i -e '/<\/ul>/i\
<li><a href="./mod_pagespeed_statistics">Google mod_pagespeed statistics</a></li>\
<li><a href="./mod_pagespeed_message">Google mod_pagespeed message</a></li>' \
"${INSTALL_PATH}/index.html"
fi
You can now view Google mod_pagespeed status.
Thanks
- Thanks to Deimos.fr (fr) for Monitorer en temps réel votre Apache (fr).
- Thanks to Slicehost (en) for Enabling and using apache's mod_status on Debian (en).
- Thanks to phpSysInfo (en) developers.