Harden Apache2 Server
Tags: apache2, aws, django, security
Published: 2021-08-26 20:06:07

### 1. Install Mod_Security2

```bash
sudo apt install libapache2-mod-security2 -y
```

Alternatively install from Github official repository

[https://github.com/SpiderLabs/ModSecurity(https://github.com/SpiderLabs/ModSecurity)

After installing ModSecurity, enable the Apache 2 `headers` module :

```bash
sudo a2enmod headers
```

After installing ModSecurity and enabling the header module,restart the apache2 service :

```bash
    sudo systemctl restart apache2
```

### 2. Get OWASP CRS and Configure it

ModSecurity is a firewall and therefore requires rules to function.

So we add the OWASP's CRS - Core Rule Set to harden our server

1. Remove the default .recommended extension from the ModSecurity configuration file name

```bash
sudo cp /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.con
```

1. With a text editor such as vim, open /etc/modsecurity/modsecurity.conf and change the value for SecRuleEngine to On:

```bash
sudo nano /etc/modsecurity/modsecurity.conf
```

Add this 

```bash
SecRuleEngine On
```

Restart Server

```bash
sudo systemctl restart apache2
```

The OWASP ModSecurity Core Rule Set (CRS) is a set of generic attack detection rules for use with ModSecurity or compatible web application firewalls. The CRS aims to protect web applications from a wide range of attacks, including the OWASP Top Ten, with a minimum of false alerts. The CRS provides protection against many common attack categories, including SQL Injection, Cross Site Scripting, and Local File Inclusion.

To set up the OWASP-CRS, follow the procedures outlined below.

1. First, delete the current rule set that comes prepackaged with ModSecurity by running the following command:

    ```bash
    sudo rm -rf /usr/share/modsecurity-crs
    ```

2. Ensure that git is installed:

    ```bash
    sudo apt install git
    ```

3. Clone the OWASP-CRS GitHub repository into the `/usr/share/modsecurity-crs` directory:

    ```bash
    sudo git clone https://github.com/coreruleset/coreruleset /usr/share/modsecurity-crs
    ```

4. Rename the `crs-setup.conf.example` to `crs-setup.conf`:

    ```bash
    sudo mv /usr/share/modsecurity-crs/crs-setup.conf.example /usr/share/modsecurity-crs/crs-setup.conf
    ```

5. Rename the default request exclusion rule file:

    ```bash
    sudo mv /usr/share/modsecurity-crs/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example /usr/share/modsecurity-crs/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf
    ```

You should now have the OWASP-CRS setup and ready to be used in your Apache configuration.

### 3. Configure your server  to use Mod_security

1.  Edit the /etc/apache2/mods-available/security2.conf file to include the OWASP-CRS 

```bash
cd /etc/apache2/mods-available/security2.conf

<IfModule security2_module>
        SecDataDir /var/cache/modsecurity
        Include /usr/share/modsecurity-crs/crs-setup.conf
        Include /usr/share/modsecurity-crs/rules/*.conf
</IfModule>
```

1. Include the SecRuleEngine directive set to On.

```bash
cd to /etc/apache2/your.website.conf

<VirtualHost *:80>
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        SecRuleEngine On
</VirtualHost>

Or

<IfModule security2_module>
SecRuleEngine On
</IfModule>
```

1. Restart the apache2 service to apply the configuration

```bash
sudo systemctl restart apache2
```

1. Testing ModSecurity

```bash
curl http://<SERVER-IP/DOMAIN>/index.php?exec=/bin/bash

You'll get 404
```

### 4. Enabling HTTP Policy and Paranoia

```bash
cd to /usr/share/modsecurity-crs

$ cd /usr/share/modsecurity-crs
or
$ sudo nano /usr/share/modsecurity-crs/crs-setup.conf
```

**Change Paranoia Level  on Paranoia Level Initialization section.**

Find this section on 
```/usr/share/modsecurity-crs/crs-setup.conf ```
[[ Paranoia Level Initialization ]] 

The Paranoia Level (PL) setting allows you to choose the desired level of rule checks that will add to your anomaly scores.With each paranoia level increase, the CRS enables additional rules giving you a higher level of security. However, higher paranoia levels also increase the possibility of blocking some legitimate traffic due to false alarms (also named false positives or FPs). If you use higher paranoia levels, it is likely that you will need to add some exclusion rules for certain requests and applications receiving complex input.

### A paranoia level of 1 is default. 
In this level, most core rules are enabled. PL1 is advised for beginners, installations covering many different sites and applications, and for setups with standard security requirements.At PL1 you should face FPs rarely. If you encounter FPs, please open an issue on the CRS GitHub site and don't forget to attach your complete Audit Log record for the request with the issue.

### Paranoia level 2 
This level Includes many extra rules, for instance enabling many regexp-based SQL and XSS injection protections, and adding extra keywords checked for code injections. PL2 is advised for moderate to experienced users desiring more complete coverage and for installations with elevated security requirements. PL2 comes with some FPs which you need to handle.

### Paranoia level 3 
It enables more rules and keyword lists, and tweaks limits on special characters used. PL3 is aimed at users experienced at the handling of FPs and at installations with a high security requirement.

### Paranoia level 4 
It further restricts special characters.The highest level is advised for experienced users protecting installations with very high security requirements. Running PL4 will likely produce a very high number of FPs which have to be treated before the site can go productive.

```bash
SecAction \
"id:900000,\
phase:1,\
nolog,\
pass,\
t:none,\
setvar:tx.paranoia_level=1"
```

### 5. HTTP Policy Settings on HTTP Policy Settings Section

```bash
$ sudo nano /usr/share/modsecurity-crs/crs-setup.conf
```

Section on - [[ HTTP Policy Settings ]] 

This section defines your policies for the HTTP protocol, such as: allowed HTTP versions, HTTP methods, allowed request Content-Types forbidden file extensions (e.g. .bak, .sql) and request headers (e.g. Proxy)

**These variables are used in the following rule files:**

REQUEST-911-METHOD-ENFORCEMENT.conf

REQUEST-912-DOS-PROTECTION.conf

REQUEST-920-PROTOCOL-ENFORCEMENT.conf

HTTP methods that a client is allowed to use.

Default: GET HEAD POST OPTIONS

Example: for RESTful APIs, add the following methods: PUT PATCH DELETE

Example: for WebDAV, add the following methods: CHECKOUT COPY DELETE LOCK

MERGE MKACTIVITY MKCOL MOVE PROPFIND PROPPATCH PUT UNLOCK

Uncomment this rule to change the default.

```bash
SecAction \
"id:900200,\
phase:1,\
nolog,\
pass,\
t:none,\
setvar:'tx.allowed_methods=GET HEAD POST OPTIONS PUT PATCH DELETE'"
```