Posted in

Apache web and proxy server (Advanced)

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>

Leave a Reply

Your email address will not be published. Required fields are marked *