Apache Web and Proxy server
Introduction to Apache HTTP Server
Apache HTTP Server, developed by the Apache Software Foundation, is an open-source and free web server that supports a multitude of features and can run on various operating systems, including Unix/Linux, Windows, and macOS. Its popularity stems from its flexibility, extensibility, and the rich set of features it offers, such as SSL/TLS support, URL redirection, and authentication mechanisms.
The Apache HTTP Server is a powerful and flexible web server that can be configured to meet a wide range of needs, from serving simple static websites to acting as a reverse proxy or load balancer for complex web applications. This guide provides a comprehensive overview of the key features and configuration options available in Apache, allowing you to get started with setting up and managing your own Apache web server.
By understanding and utilizing the various configuration options, modules, and best practices outlined in this guide, you can effectively deploy and manage a secure, high-performance web server tailored to your specific requirements. Whether you are hosting a single site, multiple sites, or using Apache for proxying and load balancing, this guide offers the foundational knowledge necessary to achieve your goals.
Installing Apache HTTP Server
On Linux (Ubuntu/Debian)
To install Apache on a Debian-based system, you can use the apt package manager. Open a terminal and execute the following commands:
sudo apt update sudo apt install apache2
On Linux (CentOS/RHEL)
For Red Hat-based systems, you can use yum:
sudo yum install httpd sudo systemctl start httpd sudo systemctl enable httpd
On Windows
Download the Apache HTTP Server binaries from the official website.
Extract the contents to a directory, e.g., C:\Apache24.
Open a Command Prompt with administrative privileges.
Navigate to the bin directory inside the Apache installation folder.
Install Apache as a service using:
httpd.exe -k install
Basic Configuration
The main configuration file for Apache is httpd.conf, which is typically located in /etc/httpd/conf/ on Red Hat-based systems or /etc/apache2/ on Debian-based systems.
Key Directives
ServerRoot: Specifies the directory where the server’s configuration, error, and log files are kept.
ServerRoot “/etc/httpd”
Listen: Defines the IP address and port on which the server listens for incoming requests.
Listen 80
DocumentRoot: Specifies the directory out of which the server will serve the requested files.
DocumentRoot “/var/www/html”
ServerName: Sets the request scheme, hostname, and port that the server uses to identify itself.
ServerName www.example.com:80
Directory: Used to apply directives to a specific directory.
<Directory "/var/www/html"> Options Indexes FollowSymLinks AllowOverride None Require all granted </Directory>
Serving a Single Website
To serve a single website, the configuration can be fairly straightforward. Below is a basic example of how to configure Apache to serve a single site.
Configuration Example
Create a directory for your website content:
sudo mkdir -p /var/www/example.com/html sudo chown -R $USER:$USER /var/www/example.com/html
Create a simple HTML file as a placeholder:
echo "<html><body><h1>Welcome to example.com!</h1></body></html>" > /var/www/example.com/html/index.html
Create a new virtual host configuration file:
sudo nano /etc/apache2/sites-available/example.com.conf
Add the following configuration to the file:
<VirtualHost *:80> ServerAdmin webmaster@example.com ServerName example.com ServerAlias www.example.com DocumentRoot /var/www/example.com/html ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost>
Enable the new virtual host:
sudo a2ensite example.com.conf sudo systemctl reload apache2
Your website should now be accessible at http://example.com.
Serving Multiple Websites
Serving multiple websites on a single Apache server involves setting up multiple virtual hosts. Each virtual host can have its own configuration and serve different content based on the domain name requested by the client.
Configuration Example
Create directories for your websites:
sudo mkdir -p /var/www/site1.com/html sudo mkdir -p /var/www/site2.com/html sudo chown -R $USER:$USER /var/www/site1.com/html sudo chown -R $USER:$USER /var/www/site2.com/html
Create simple HTML files for each site:
echo "<html><body><h1>Welcome to site1.com!</h1></body></html>" > /var/www/site1.com/html/index.html echo "<html><body><h1>Welcome to site2.com!</h1></body></html>" > /var/www/site2.com/html/index.html
Create virtual host configuration files for each site:
Site1 Configuration:
sudo nano /etc/apache2/sites-available/site1.com.conf
<VirtualHost *:80> ServerAdmin webmaster@site1.com ServerName site1.com ServerAlias www.site1.com DocumentRoot /var/www/site1.com/html ErrorLog ${APACHE_LOG_DIR}/site1_error.log CustomLog ${APACHE_LOG_DIR}/site1_access.log combined </VirtualHost>
Site2 Configuration:
sudo nano /etc/apache2/sites-available/site2.com.conf
<VirtualHost *:80> ServerAdmin webmaster@site2.com ServerName site2.com ServerAlias www.site2.com DocumentRoot /var/www/site2.com/html ErrorLog ${APACHE_LOG_DIR}/site2_error.log CustomLog ${APACHE_LOG_DIR}/site2_access.log combined </VirtualHost>
Enable the new virtual hosts:
sudo a2ensite site1.com.conf sudo a2ensite site2.com.conf sudo systemctl reload apache2
Your websites should now be accessible at http://site1.com and http://site2.com.
Configuring Reverse Proxy
A reverse proxy sits in front of web servers and forwards client requests to the appropriate backend server. Apache can be configured as a reverse proxy using the mod_proxy module.
Enabling mod_proxy
First, ensure that the necessary modules are enabled:
sudo a2enmod proxy sudo a2enmod proxy_http sudo systemctl restart apache2
Reverse Proxy Configuration Example
Create a virtual host configuration for the reverse proxy:
sudo nano /etc/apache2/sites-available/reverse-proxy.conf
Add the following configuration:
<VirtualHost *:80> ServerAdmin webmaster@proxy.com ServerName proxy.com ProxyRequests Off ProxyPass / http://backendserver.com/ ProxyPassReverse / http://backendserver.com/ ErrorLog ${APACHE_LOG_DIR}/proxy_error.log CustomLog ${APACHE_LOG_DIR}/proxy_access.log combined </VirtualHost>
Enable the new virtual host:
sudo a2ensite reverse-proxy.conf sudo systemctl reload apache2
In this example, requests to http://proxy.com will be forwarded to http://backendserver.com.
Configuring Forward Proxy
A forward proxy is used to forward client requests to the Internet. This is commonly used to filter or log client requests.
Enabling mod_proxy
Ensure the necessary modules are enabled:
sudo a2enmod proxy sudo a2enmod proxy_http sudo systemctl restart apache2
Forward Proxy Configuration Example
Edit the main configuration file to set up the forward proxy:
sudo nano /etc/apache2/mods-enabled/proxy.conf
Add the following configuration:
<IfModule mod_proxy.c> ProxyRequests On <Proxy "*"> Order deny,allow Deny from all Allow from Clients 192.168.1.0/24 </Proxy> ProxyVia On ErrorLog ${APACHE_LOG_DIR}/proxy_error.log CustomLog ${APACHE_LOG_DIR}/proxy_access.log combined </IfModule> ```
Restart Apache to apply the changes:
sudo systemctl restart apache2
In this configuration, the forward proxy will only accept requests from the local network 192.168.1.0/24.
Advanced Configuration Options
Enabling SSL/TLS
SSL/TLS can be enabled to secure your website with HTTPS. Here’s how to configure SSL/TLS for a virtual host.
Enable the SSL module:
sudo a2enmod ssl sudo systemctl restart apache2
Create a directory for your SSL certificates:
sudo mkdir /etc/apache2/ssl
Obtain SSL certificates or generate self-signed certificates:
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/apache2/ssl/apache-selfsigned.key -out /etc/apache2/ssl/apache-selfsigned.crt
Configure your virtual host to use SSL:
sudo nano /etc/apache2/sites-available/example.com-ssl.conf
Add the following configuration:
<VirtualHost *:443> ServerAdmin webmaster@example.com ServerName example.com ServerAlias www.example.com DocumentRoot /var/www/example.com/html SSLEngine on SSLCertificateFile /etc/apache2/ssl/apache-selfsigned.crt SSLCertificateKeyFile /etc/apache2/ssl/apache-selfsigned.key ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost>
Enable the new virtual host:
sudo a2ensite example.com-ssl.conf sudo systemctl reload apache2
Your website should now be accessible via https://example.com.
URL rewriting
URL rewriting with the mod_rewrite module in Apache allows you to manipulate URLs for various purposes such as improving site navigation, SEO, and user-friendliness. Here’s a detailed breakdown of the process and additional examples.
Enabling mod_rewrite
To enable mod_rewrite, you need to run the following commands:
sudo a2enmod rewrite sudo systemctl restart apache2
Add rewrite rules in your virtual host configuration
Update your virtual host configuration file, usually located in /etc/apache2/sites-available/000-default.conf or a similar location. Here is an example configuration:
<VirtualHost *:80> ServerAdmin webmaster@example.com ServerName example.com DocumentRoot /var/www/example.com/html <Directory /var/www/example.com/html> Options Indexes FollowSymLinks AllowOverride All Require all granted </Directory> ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php?q=$1 [L,QSA] </VirtualHost>
RewriteEngine On: This directive enables the runtime rewriting engine.
RewriteCond %{REQUEST_FILENAME} !-f: This condition checks if the requested filename is not a file.
RewriteCond %{REQUEST_FILENAME} !-d: This condition checks if the requested filename is not a directory.
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]: This rule rewrites any URL to index.php?q=$1, where $1 is the captured group from the original URL. The [L,QSA] flags mean:
L: Last rule, stop processing other rules if this one matches.
QSA: Query String Append, append the original query string to the rewritten URL.
Creating a .htaccess File
If you want to manage rewrites per directory, create a .htaccess file in your document root:
nano /var/www/example.com/html/.htaccess
Add the following rules to the .htaccess file:
RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
Example 1: Redirecting from Non-WWW to WWW
To ensure users are always redirected from the non-www version of your site to the www version, you can add the following rule:
RewriteEngine On RewriteCond %{HTTP_HOST} !^www\. RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
RewriteCond %{HTTP_HOST} !^www\.: Checks if the hostname does not start with www.
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]: Redirects to the www version of the hostname with a 301 status code (permanent redirect).
Example 2: Redirecting to HTTPS
To ensure all traffic is redirected to HTTPS, use the following rules:
RewriteEngine On RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{HTTPS} off: Checks if the connection is not HTTPS.
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]: Redirects to the same URL but with HTTPS, using a 301 status code.
Example 3: Custom Error Pages
To serve custom error pages, you can use the following rules:
RewriteEngine On ErrorDocument 404 /custom_404.html ErrorDocument 500 /custom_500.html
ErrorDocument 404 /custom_404.html: When a 404 error occurs, serve custom_404.html.
ErrorDocument 500 /custom_500.html: When a 500 error occurs, serve custom_500.html.
Enable mod_rewrite: Use sudo a2enmod rewrite and restart Apache.
Add rules: In your virtual host configuration or .htaccess file, enable RewriteEngine and add your rewrite rules.
Rewrite conditions and rules: Use conditions (RewriteCond) to check specific criteria and rules (RewriteRule) to perform the URL rewrites.
Load Balancing
Apache can be configured to distribute incoming requests across multiple backend servers, enhancing availability and performance.
Enable the necessary modules:
sudo a2enmod proxy_balancer sudo a2enmod lbmethod_byrequests sudo systemctl restart apache2
Configure a load balancer virtual host:
sudo nano /etc/apache2/sites-available/loadbalancer.conf
Add the following configuration:
<Proxy "balancer://mycluster"> BalancerMember http://backend1.example.com BalancerMember http://backend2.example.com ProxySet lbmethod=byrequests </Proxy> <VirtualHost *:80> ServerAdmin webmaster@loadbalancer.com ServerName loadbalancer.com ProxyPass / balancer://mycluster/ ProxyPassReverse / balancer://mycluster/ ErrorLog ${APACHE_LOG_DIR}/loadbalancer_error.log CustomLog ${APACHE_LOG_DIR}/loadbalancer_access.log combined </VirtualHost>
Enable the new virtual host:
sudo a2ensite loadbalancer.conf
sudo systemctl reload apache2
Security Considerations
Basic Security Measures
Regularly update Apache to the latest version to ensure you have the latest security patches.
sudo apt update sudo apt upgrade apache2
Disable Unnecessary Modules: Only enable the modules you need to minimize the attack surface.
Use Proper Permissions: Ensure that files and directories have appropriate permissions.
Using .htaccess for Security
Restrict Access by IP:
<FilesMatch ".*"> Order Deny,Allow Deny from all Allow from 192.168.1.0/24 </FilesMatch>
Password Protection:
htpasswd -c /etc/apache2/.htpasswd username
<Directory "/var/www/secure"> AuthType Basic AuthName "Restricted Content" AuthUserFile /etc/apache2/.htpasswd Require valid-user </Directory>
SSL/TLS Best Practices
Use Strong Cipher Suites: Configure Apache to use strong cipher suites.
SSLCipherSuite HIGH:!aNULL:!MD5
SSLProtocol All -SSLv2 -SSLv3
Redirect HTTP to HTTPS:
<VirtualHost *:80> ServerName example.com Redirect "/" "https://example.com/" </VirtualHost>
HSTS (HTTP Strict Transport Security):
Header always set Strict-Transport-Security “max-age=31536000; includeSubDomains”
Performance Tuning
Enable Compression
Enable the mod_deflate module:
sudo a2enmod deflate sudo systemctl restart apache2
Add the following configuration to compress text-based resources:
<IfModule mod_deflate.c> AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css application/javascript application/json </IfModule>
Caching Static Content
Enable the mod_expires and mod_headers modules:
sudo a2enmod expires sudo a2enmod headers sudo systemctl restart apache2
Configure caching:
<IfModule mod_expires.c> ExpiresActive On ExpiresByType image/jpg "access plus 1 year" ExpiresByType image/png "access plus 1 year" ExpiresByType image/gif "access plus 1 year" ExpiresByType text/css "access plus 1 month" ExpiresByType application/pdf "access plus 1 month" ExpiresByType text/javascript "access plus 1 month" ExpiresByType application/javascript "access plus 1 month" ExpiresByType application/x-javascript "access plus 1 month" ExpiresByType application/x-shockwave-flash "access plus 1 month" ExpiresByType image/x-icon "access plus 1 year" ExpiresDefault "access plus 1 month" </IfModule>
<IfModule mod_headers.c> <FilesMatch "\.(js|css|xml|gz)$"> Header append Vary: Accept-Encoding </FilesMatch> </IfModule>
MPM (Multi-Processing Modules)
Apache supports different MPMs, which control how it handles incoming requests. The two most commonly used MPMs are prefork and worker.
Prefork MPM: Suitable for compatibility with non-thread-safe libraries.
<IfModule mpm_prefork_module> StartServers 5 MinSpareServers 5 MaxSpareServers 10 MaxRequestWorkers 150 MaxConnectionsPerChild 3000 </IfModule>
Worker MPM: Suitable for high-traffic sites.
<IfModule mpm_worker_module> StartServers 2 MinSpareThreads 25 MaxSpareThreads 75 ThreadLimit 64 ThreadsPerChild 25 MaxRequestWorkers 150 MaxConnectionsPerChild 0 </IfModule>