Apache 2
Contents
Requirements
Before going through this tutorial, I recommend you to setup:
Installation
Apache 2
This will install web server + PHP + Perl + all required libraries.
Apache2 core
apt-get install apache2 apache2-mpm-prefork apache2-utils ssl-cert
Additional libraries
apt-get install libapache2-mod-fcgid libruby
Doc
apt-get install apache2-doc
Perl
apt-get install libapache2-mod-perl2 libapache2-mod-perl2-doc
SNMP
Sometimes you might encounter some SNMP errors on latest Debian based distributions.
In that case you have to install a new package and run it.
apt-get install snmp-mibs-downloader
download-mibs
source: http://www.podciborski.co.uk/miscellaneous/snmp-cannot-find-module/
PHP 5
Core
apt-get install libapache2-mod-php5 php5 php5-common
Modules PHP5
apt-get install php5-curl php5-dev php5-gd php-pear php5-imagick php5-imap php5-mcrypt
apt-get install php5-memcache php5-mhash php5-mysql php5-snmp php5-xmlrpc php5-xcache php5-curl php5-xsl
Additional libs
apt-get install php5-cli php5-cgi php-pear php-auth php5-mcrypt mcrypt
Image Magick
apt-get install php5-imagick imagemagick
Configuration
Edit PHP config file:
vim /etc/php5/apache2/php.ini
Add / uncomment the following lines in Dynamic extensions area (~ line 865)
- extension=mysql.so
- extension=gd.so
!! Note this is NOT required on Ubuntu 14.04 because these modules are enabled by default !!
Firewall
You have to open the following ports:
- Port 80 = HTTP
- Port 443 = HTTPS
$IPTABLES -A INPUT -p tcp -m state -i eth0 --dport 80 -j ACCEPT
$IPTABLES -A INPUT -p tcp -m state -i eth0 --dport 443 -j ACCEPT
Restart the firewall
/etc/init.d/firewall restart
Test your installation
Restart the Apache2 server
service apache2 restart
You can now test your installation by going to 'http://localhost' or 'http://myServer'. You should see the default page.
HTTP Virtual host
Preparation
Initialize configuration
cd /etc/apache2/sites-available/
Create target directory
mkdir -p /var/www/myServer
Prepare the log files
mkdir -p /var/log/apache2/myServer
touch /var/log/apache2/myServer/access.log
touch /var/log/apache2/myServer/error.log
chmod -R 660 /var/log/apache2/myServer/*
chown -R www-data:www-data /var/log/apache2/myServer/*
Copy default index file
cp /var/www/html/index.html /var/www/myServer
chown -R www-data:www-data /var/log/apache2/myServer/*
Configuration
Init configuration
cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/myServer.conf
Edit configuration
vim /etc/apache2/sites-available/myServer
To begin the virtual host, write the following lines:
- Adjust the settings to your own configuration
<VirtualHost 192.168.0.100:80> → Choose the best options for your needs
<VirtualHost *:80>
#############################
# Server main properties
#############################
ServerName myServer
ServerAlias www.myServer *.myServer
ServerAdmin webmaster@domain
# Logs settings
LogLevel Warn
CustomLog ${APACHE_LOG_DIR}/myServer/access.log combined
ErrorLog ${APACHE_LOG_DIR}/myServer/error.log
#############################
# Root folder properties
#############################
DocumentRoot /var/www/myServer
# Restrict access to server root
<Directory />
Options FollowSymLinks
AllowOverride None
Order allow,deny
deny from all
</Directory>
# SECURITY: forbid access to .htaccess so no outsider can ever change it
<Files ~ "^\.ht">
Order allow,deny
Deny from all
</Files>
# Virtual host root directory
<Directory /var/www/myServer>
Require all granted
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
#############################
# Other configuration
# Alias, proxy redirections, CGI scripts, Directory, etc.
#############################
</VirtualHost>
Enable / disable virtual host(s)
Virtual Host desactivation
If you're listening on *:80 then you should probably disable the default virtual host before enabling yours!
a2dissite 000-default
Virtual Host activation
To activate a Virtual Host, just type
a2ensite myServer
Then, restart your web server
/etc/init.d/apache2 restart
Check your server! You should see your "index.html" page.
HTTPS (SSL) Virtual host
Create SSL certificate
First of all, you need to create a server certificate. Cf. SSL dedicated document → Create a new server certificate
>> see SSL server
Enable SSL module
You have to either copy or create symlinks for server certificate.
To avoid rights collision I'm using a copy operation. However I know from past experience that symLinks work very well if you set the correct rights.
-Note-
You MUST use the NON-ENCRYPTED private key if you want to start Apache2 automatically on each reboot.
Copy certificates
cp /srv/ssl/certs/myServer.cert.pem /etc/apache2/webServer.pem
cp /srv/ssl/private/myServer.nopass.key /etc/apache2/webServer.key
Alternative: Symlinks to /srv/ssl/
ln -s /srv/ssl/certs/myServer.cert.pem /etc/apache2/webServer.pem
ln -s /srv/ssl/private/myServer.nopass.key /etc/apache2/webServer.key
Activate the SSL module
a2enmod ssl
Prepare virtual host (optional)
Create virtual host folder
mkdir -p /var/www/myServer-ssl
cp /var/www/index.html /var/www/myServer-ssl
chown -R www-data:www-data /var/www/myServer-ssl
Prepare the log files (optional)
# That should already exists from before
mkdir -p /var/log/apache2/myServer
# Create *-ssl.log
touch /var/log/apache2/myServer/error-ssl.log
touch /var/log/apache2/myServer/access-ssl.log
chmod -R 660 /var/log/apache2/myServer/*
chown -R www-data:www-data /var/log/apache2/myServer/*
Create a default "/var/www/myServer-ssl/index.html" to check your virtual host.
If you'd like you can use this ultra-simple file [1]
cd /var/www/myServer-ssl/
wget http://daxiongmao.eu/wiki_upload_files/apache2/index.html
chown www-data:www-data index.html
Virtual host declaration
You have 2 possibilities:
- Update your current virtual host (recommended)
- Create a new one, only for the SSL virtual host
Update non-ssl V.Host configuration
vim /etc/apache2/sites-available/myServer
!! Adjust the settings to your own configuration !!
# Secure web server
<VirtualHost _default_:443>
<VirtualHost 192.168.0.100:443> → Choose the best options for your needs
<VirtualHost *:443>
#############################
# Server main properties
#############################
ServerName myServer
ServerAlias www.myServer *.myServer
ServerAdmin webmaster@domain
# Logs settings
LogLevel Warn
CustomLog ${APACHE_LOG_DIR}/myServer/access-ssl.log combined
ErrorLog ${APACHE_LOG_DIR}/myServer/error-ssl.log
# Enable SSL
SSLEngine On
SSLCertificateFile /etc/apache2/webServer.pem
SSLCertificateKeyFile /etc/apache2/webServer.key
#############################
# Root folder properties
#############################
DocumentRoot /var/www/myServer-ssl
# Restrict access to server root
<Directory />
Options FollowSymLinks
AllowOverride None
Order allow,deny
deny from all
</Directory>
# SECURITY: forbid access to .htaccess so no outsider can ever change it
<Files ~ "^\.ht">
Order allow,deny
Deny from all
</Files>
# Virtual host root directory
<Directory /var/www/myServer-ssl>
Require all granted
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
#############################
# Other configuration
# Alias, proxy redirections, CGI scripts, Directory, etc.
#############################
</VirtualHost>
Restart the web server
service apache2 restart
Now you can test your server https://myServer
If you've use a self-signed certificate you might see some alert. Just discarded it and process anyway!
Redirections
Principle
Just a little reminder...
- Redirections are not transparent
- Redirections are performed by the client. The server only serves the new URL to use
- Redirections can also be used as a security tool to filter HTTP requests and only allow some of them.
As you can see on the previous picture, redirection can be declared:
- As Apache 2 module configuration. This will apply to all virtual hosts and web-sites
- In a Virtual Host configuration
- Default setting - ex: HTTP to HTTPS
- For a specific alias |or| directory
- In a web page
- In a .htaccess to protect a specific directory
Enable redirections
Module "rewrite" allows you to redirect source URL to another one.
a2enmod rewrite
Virtual host: redirect all HTTP to HTTPS
The safer way to redirect HTTP to HTTPS is use to adjust the virtual host configuration.
<VirtualHost *:80>
ServerName dev.daxiongmao.eu
ServerAlias www.dev.daxiongmao.eu *.dev.daxiongmao.eu
ServerAdmin guillaume@qin-diaz.com
### LOG ###
LogLevel warn
ErrorLog ${APACHE_LOG_DIR}/dev.daxiongmao.eu/error.log
CustomLog ${APACHE_LOG_DIR}/dev.daxiongmao.eu/access.log combined
############################################
## Redirect all traffic to HTTPS website
############################################
RewriteEngine On
# This checks to make sure the connection is not already HTTPS
RewriteCond %{HTTPS} off
# This rule will redirect users from their original location, to the same location but using HTTPS.
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
# Alternate (fail-over) solution
redirect permanent / https://myServer/
########
# No need of a document root anymore as everything is redirect to HTTPS
########
</VirtualHost>
-Note-
As you can see you don't need a DocumentRoot anymore for the *:80 virtual host.
Take changes into account
You have to restart the server to use this settings
service apache2 restart
Test your configuration
Virtual host: Alias redirection
The following example will redirect a "/phpsecinfo" from HTTP to HTTPS.
Edit your virtual-host configuration and use that example to redirect to another server too by adjusting the rewrite rule.
<VirtualHost *:80>
...
# PHPSecInfo
RewriteRule ^/phpsecinfo(/.*|$) https://%{HTTP_HOST}/phpsecinfo$1 [L,R]
<Location /phpsecinfo>
order deny,allow
deny from all
# Only allow specific IP@
# allow from 127.0.0.1 192.168.1.0/24
allow from all
</Location>
...
</VirtualHost>
<VirtualHost *:443>
...
# PHPSecInfo
Alias /phpsecinfo /var/www/phpsecinfo
<Location /phpsecinfo>
order deny,allow
deny from all
# Only allow specific IP@
# allow from 127.0.0.1 192.168.1.0/24
allow from all
</Location>
...
</VirtualHost>
Reload your configuration
/etc/init.d/apache2 reload
Apache 2 Module configuration
This configuration will apply to all virtual-hosts.
Create the module configuration file
vim /etc/apache2/mods-available/rewrite.conf
Copy / paste this configuration (adjust to your own settings!)
RewriteEngine On
# --------------------- SECURITY RULES (JOOMLA) ------------------------ #
## End of deny access to extension xml files
RewriteCond %{QUERY_STRING} mosConfig_[a-zA-Z_]{1,21}(=|\%3D) [OR]
# Block out any script trying to base64_encode crap to send via URL
RewriteCond %{QUERY_STRING} base64_encode.*\(.*\) [OR]
# Block out any script that includes a <script> tag in URL
RewriteCond %{QUERY_STRING} (\<|%3C).*script.*(\>|%3E) [NC,OR]
# Block out any script trying to set a PHP GLOBALS variable via URL
RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]
# Block out any script trying to modify a _REQUEST variable via URL
RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2})
# Send all blocked request to homepage with 403 Forbidden error!
RewriteRule ^(.*)$ index.php [F,L]
# --------------------- SECURITY RULES (PERSONAL) ------------------------ #
## DENY REQUEST BASED ON REQUEST METHOD ###
RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK|OPTIONS|HEAD)$ [NC]
RewriteCond %{REQUEST_METHOD} (GET|POST) [NC]
RewriteRule ^.*$ - [F]
# Avoid common security flows
RewriteCond %{QUERY_STRING} ^(.*)http(\:|\%3A)(.*)$
RewriteCond %{QUERY_STRING} mosConfig_ [NC,OR]
RewriteCond %{QUERY_STRING} ^(.*)(%3C|<)/?script(.*)$ [NC,OR]
RewriteCond %{QUERY_STRING} ^(.*)(%3D|=)?javascript(%3A|:)(.*)$ [NC,OR]
RewriteCond %{QUERY_STRING} ^(.*)document\.location\.href(.*)$ [NC,OR]
RewriteCond %{QUERY_STRING} ^(.*)base64_encode(.*)$ [NC,OR]
RewriteCond %{QUERY_STRING} ^(.*)GLOBALS(=|[|%[0-9A-Z]{0,2})(.*)$ [NC,OR]
RewriteCond %{QUERY_STRING} ^(.*)_REQUEST(=|[|%[0-9A-Z]{0,2})(.*)$ [NC,OR]
RewriteCond %{QUERY_STRING} ^(.*)(SELECT|INSERT|DELETE|CHAR\(|UPDATE|REPLACE|LIMIT)(.*)$
# Avoid common security mistakes
RewriteCond %{QUERY_STRING} \.\.\/ [NC,OR]
RewriteCond %{QUERY_STRING} boot\.ini [NC,OR]
RewriteCond %{QUERY_STRING} tag\= [NC,OR]
RewriteCond %{QUERY_STRING} ftp\: [NC,OR]
RewriteCond %{QUERY_STRING} http\: [NC,OR]
RewriteCond %{QUERY_STRING} https\: [NC,OR]
RewriteCond %{QUERY_STRING} mosConfig [NC,OR]
RewriteCond %{QUERY_STRING} ^.*(\(|\)|<|>|'|"|\?|\*).* [NC,OR]
RewriteCond %{QUERY_STRING} ^.*(%22|%27|%3C|%3D|%3E|%7B|%7C).* [NC,OR]
RewriteCond %{QUERY_STRING} ^.*(%0|%A|%B|%C|%D|%F|127\.0).* [NC,OR]
RewriteCond %{QUERY_STRING} ^.*(globals|encode|localhost|loopback).* [NC,OR]
RewriteCond %{QUERY_STRING} ^.*(select|insert|union|declare|drop).* [NC]
RewriteRule ^(.*)$ - [F,L]
# Ban Typical Vulnerability Scanners and others
# Kick out Script Kiddies
RewriteCond %{HTTP_USER_AGENT} ^(java|curl|wget).* [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^.*(libwww-perl|curl|wget|python|nikto|wkito|pikto|scan|acunetix).* [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^.*(winhttp|HTTrack|clshttp|archiver|loader|email|harvest|extract|grab|miner).* [NC,OR]
# Avoid zombies software
RewriteCond %{HTTP_USER_AGENT} ^Anarchie [OR]
RewriteCond %{HTTP_USER_AGENT} ^ASPSeek [OR]
RewriteCond %{HTTP_USER_AGENT} ^attach [OR]
RewriteCond %{HTTP_USER_AGENT} ^autoemailspider [OR]
RewriteCond %{HTTP_USER_AGENT} ^Xaldon\ WebSpider [OR]
RewriteCond %{HTTP_USER_AGENT} ^Xenu [OR]
RewriteCond %{HTTP_USER_AGENT} ^Zeus.*Webster [OR]
RewriteCond %{HTTP_USER_AGENT} ^Zeus
RewriteRule ^.* - [F,L]
# Allow the robots to reference our website
RewriteCond %{HTTP_USER_AGENT} !^Googlebot [NC]
RewriteCond %{HTTP_USER_AGENT} !^Googlebot-Image [NC]
RewriteCond %{HTTP_USER_AGENT} !^Googlebot-Mobile [NC]
RewriteCond %{HTTP_USER_AGENT} !^Msnbot [NC]
RewriteCond %{HTTP_USER_AGENT} !^Mediapartners-Google [NC]
# Keep request without referer
RewriteCond %{HTTP_REFERER} !^$
# To allow your pictures to be displayed on Google
RewriteCond %{HTTP_REFERER} !^http://.*google\.(comŠ(co\.)?[a-z]{2})/
# To forbid the copy of your pictures to anyone else : display an other image !
RewriteRule .*\.(jpe?g|gif|bmp|png)$ /images/hotlinkis.jpg [L]
Update your Apache2 configuration:
a2enmod rewrite
Restart your server:
service apache2 restart
Proxy
Special thanks to Julien Rialland for his insight regarding this part!
Principle
The proxy module allow you to expose a resource that is not directly accessible.
For instance it can redirect remote user to a specific server that can be host on a different machine or port through a simple URL.
Proxy VS redirection
Header text | Proxy | Redirection |
---|---|---|
Main usage |
|
Signal a change or redirect to the HTTPS web-site |
Action | Hidden to the user.
|
Explicit
|
Internet limits: why do we need a proxy?
Some application are not available from outside…
- For security reasons [default URL is not allowed]
- Due to network issues
How does Apache2 mod_proxy work?
The Apache2 proxy module allow you to provide access through transparent redirection.
It relies on:
- Already open port (80 or 443)
- Redirection rule
- Each service URL must be unique
- The target service must be reachable by the web server
As you can see on the previous example, the services will be accessible using some dedicated URL.
Remote “http://myServer/myService” will redirect to “http://localhost:8081”
→ The mod_proxy is none intrusive.
You don’t have to change anything in the original service configuration. Apache2 will handle all the transformations.
Proxy / redirect / rewrite - HTTP request processing
When Apache2 receive a request it will be process in the following order:
The evaluation order is:
- Mod_proxy
- Mod_rewrite
- Other modules
- Serve requested resources if no rule should apply
So, even if you enable a full redirection to HTTPS you can still use some HTTP service through mod_proxy (because mod_proxy is the 1st to be evaluate).
Installation
Enable proxy module
a2enmod proxy proxy_http proxy_ajp
Configure proxy redirections
You can configure the redirections in 2 ways:
- Through your virtual host configuration
- Through the module configuration file
Module configuration file
You have to edit / create the configuration file.
vim /etc/apache2/mods-enabled/proxy.conf
Virtual host
Just edit again your previous V.Host:
vim /etc/apache2/sites-available/myServer.conf
V.Host proxy declaration
Adjust your V.Host configuration to:
<VirtualHost *:80>
ServerName dev.daxiongmao.eu
ServerAlias www.dev.daxiongmao.eu *.dev.daxiongmao.eu
ServerAdmin guillaume@qin-diaz.com
### LOG
LogLevel warn
ErrorLog ${APACHE_LOG_DIR}/dev.daxiongmao.eu/error.log
CustomLog ${APACHE_LOG_DIR}/dev.daxiongmao.eu/access.log combined
### Redirect all traffic to HTTPS website
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
redirect permanent / https://myServer/
### No proxy here because I only want to use HTTPS
</VirtualHost>
<VirtualHost *:443>
...
#############################
# Proxy configuration
#############################
ProxyVia On
ProxyPreserveHost On
<Proxy *>
AddDefaultCharset off
Order deny,allow
Allow from all
Satisfy Any
</Proxy>
########################
# Standard Web application - No proxy required
########################
#### Direct access without further configuration
ProxyPass /maintenance !
ProxyPass /menu !
ProxyPass /ssl !
#### URL filter example
# PhpMyAdmin
<Location /phpmyadmin>
Order allow,deny
Allow from 127.0.0.1 192.168.1.0/24
Require all granted
ProxyPass !
</Location>
########################
# Proxy redirections
########################
# Proxy to a Java application running over Tomcat
ProxyPass /webdav ajp://localhost:8009/webdav/
ProxyPassReverse /webdav ajp://localhost:8009/webdav
# Proxy to a Java application running over Tomcat, with IP filter
<Location /manager>
Order allow,deny
Allow from 127.0.0.1 192.168.1.0/24 193.12.118.196
ProxyPass ajp://localhost:8009/manager/
ProxyPassReverse ajp://localhost:8009/manager/
</Location>
# Proxy to another server
ProxyPass /jira http://192.168.1.12:8080/jira
ProxyPassReverse /jira http://192.168.1.12:8080/jira
</VirtualHost>
Some notes:
- Do NOT put a / after the target URL
- Do NOT use / as ProxyPass source, use the previous redirect permanent instead
Apply changes and test result
service apache2 restart
For example, Navigate to http://myServer/jira
Related topics
Distribute and install the certificates
Some guides to setup specific application and features: