30 of 38
added 25 characters in body
pa4080
  • 29.9k
  • 10
  • 89
  • 162

Here are over-viewed few ways, involved into a complete mechanism, how to increase Apache2 security within Ubuntu 16.04.

Table of content:

  • Security Assistant Script (SAS) ► Iptables
  • Iptables – Basic Configuration – Save and Restore
  • ModEvasive for Apache2
  • ModEvasive ► SAS ► Iptables
  • ModSecurity 2.9 for Apache2
  • ModSecurity OWASP Core Rule Set 3.x
  • ModSecurity Rules ► SAS ► Iptables
  • ModSecurity Rules Whitelisting
  • ModSecurity [and Apache] Log Files
  • ModSecurity Log Files ► Fail2Ban ► Iptables
  • ModSecurity GuardianLog ► HTTPD-Guardian ► SAS ► Iptables
  • ModSecurity GuardianLog ► Custom Automated Analyse ► SAS ► Iptables
  • HTTPS Connection (See also: Common Apache's Security Tips)

#Security Assistant Script (SAS) ► Iptables

Here is presented the script security-assistant.bash. It could help you with the handling of the malicious IP addresses. The script has two modes.

  • Automatic mode - when an external program, as mod_evasive or mod_security, etc., provides a malicious IP address. In this case, the syntax that invokes the script, should be:

      security-assistant.bash <ip-address> Guardian
      security-assistant.bash <ip-address> ModSecurity
      security-assistant.bash <ip-address> ModEvasive
    

In this mode the script provides two action stages and for every action it will send an email to the administrator(s).

  • First stage: for the first few 'transgressions' the source $IP will be banned for a period of time equal to the value of $BAN_TIME. This mode uses the command at.

  • Second stage: when the number of the transgressions from certain $IP becomes equal to the value of $LIMIT, this IP address will be banned permanently.

  • Manual mode - it has three options:

  • security-assistant.bash <ip-address> --DROP "notes" - creates an entry into the file /var/www-security/iptables-DROP.list and generates a rule as:

         iptables -A GUARDIAN -s <ip-address> -j DROP
    
  • security-assistant.bash <ip-address> --ACCEPT "notes" - creates only an entry into the file /var/www-security/iptables-ACCEPT.list.

  • security-assistant.bash <ip-address> --ACCEPT-CHAIN "notes" - creates an entry into the file /var/www-security/iptables-ACCEPT.list and generates a rule as:

         iptables -A GUARDIAN -s <ip-address> -j ACCEPT
    

The script uses iptables-save.sh and the iptables chain GUARDIAN, explained into the next section. It will create and maintain few files within the $WORK_DIR:

  • security-assistant.history - contains the data for the previous IP's transgressions.
  • security-assistant.mail - the content of the last email sent by the script.
  • iptables-ACCEPT.list and iptables-DROP.list.

###Installation

  • Create work directory, let's call it /var/www-security:

      sudo mkdir /var/www-security
    
  • Download security-assistant.bash and make it executable:

      curl https://pastebin.com/raw/wvV9B1nf | sed -e 's/\r$//' | sudo tee /var/www-security/security-assistant.bash 
      sudo chmod +x /var/www-security/security-assistant.bash
    

    Note about the downloads from PasteBin!

  • Make security-assistant.bash available as custom command:

      sudo ln -s /var/www-security/security-assistant.bash /usr/local/bin/
    
  • Tweak security-assistant.bash. Change at least the value of the variable $EMAIL_TO.

###Dependencies

###Check-up

  • Represent yourself as $AGENT and check whether the Automatic MODE works properly:

      /var/www-security/security-assistant.bash 192.168.1.177 Guardian
    

    Then check your e-mail, type iptables -L GUARDIAN -n, review the files security-assistant.history and security-assistant.mail. Run the above command 5 times and review the files iptables-DROP.list and iptables-CURRENT.conf.

  • Check whether the Manual MODE works properly - add your localhost to the White List:

      security-assistant.bash 127.0.0.1 --ACCEPT "Server's localhost IP"
    

    Then check the file iptables-ACCEPT.list.

###References


#Iptables – Basic Configuration – Save and Restore

###Basic configuration

sudo iptables -P INPUT DROP
sudo iptables -I INPUT 1 -i lo -j ACCEPT
sudo iptables -I INPUT 2 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

###Save and Restore

This could be achieved via custom scripts, that will save and restore the iptables config during system's stop-start (or reboot) process. (If we using UFW to setup Iptables rules this step is not needed.)

printf '#!/bin/sh\n/sbin/iptables-save > /var/www-security/iptables-CURRENT.conf\nexit 0\n' | sudo tee /var/www-security/iptables-save.sh
printf '#!/bin/sh\n/sbin/iptables-restore < /var/www-security/iptables-CURRENT.conf\nexit 0\n' | sudo tee /var/www-security/iptables-restore.sh
sudo chmod +x /var/www-security/iptables-restore.sh /var/www-security/iptables-save.sh
sudo ln -s /var/www-security/iptables-save.sh /etc/network/if-post-down.d/iptables-save
sudo ln -s /var/www-security/iptables-restore.sh /etc/network/if-pre-up.d/iptables-restore

###Create new chain

Create new chain, called GUARDIAN and insert it as number 3 into the INPUT chain:

sudo iptables -N GUARDIAN
sudo iptables -I INPUT 3 -j GUARDIAN

Reboot the system and check the configuration. Please note we must use sudo systemctl reboot. Don't use the force option reboot -f. When the system is back online we can check if the newly created chain exists by a command as: sudo iptables -L GUARDIAN -n.

###References


#ModEvasive for Apache2

ModEvasive is an evasive maneuvers module for Apache to provide evasive action in the event of an HTTP DoS or DDoS attack or brute force attack. It is also designed to be a detection tool, and can be easily configured to talk to ipchains, firewalls, routers, and etcetera. Read more...

###Installation

  • Install and enable the module:

      sudo apt install libapache2-mod-evasive
      sudo a2enmod evasive
    
  • Create Log Directory and make it accessible for www-data:

      sudo mkdir -p /var/log/apache2/mod_evasive
      sudo chown www-data /var/log/apache2/mod_evasive
    
  • Adjust the basic configuration – uncomment and edit certain directives in the file:

      /etc/apache2/mods-enabled/evasive.conf
    
  • Restart Apache: sudo systemctl restart apache2.service.

###Check-up

  • Open a web page from your server and refresh the browser window few times intensively (usually F5 can be used) - you must get 403 Forbidden error message (that will remains several seconds) and also, into the log directory, will be generated a new file.

###References


#ModEvasive ► SAS ► Iptables

Here we will configure mod_evasive to talk to iptables through the security-assistant.bash, created in the above section.

  • Grant permission to www-data to run security-assistant.bash without password via sudo. Use sudo visudo to edit safely /etc/sudoers and add next line under the section # User privilege specification:

      www-data ALL=(ALL) NOPASSWD: /var/www-security/security-assistant.bash
    
  • Edit /etc/apache2/mods-available/evasive.conf in this way:

      <IfModule mod_evasive20.c>
          DOSHashTableSize    3097
          DOSPageCount        7
          DOSSiteCount        50
          DOSPageInterval     2
          DOSSiteInterval     2
          DOSBlockingPeriod   10
          DOSWhitelist        127.0.0.1
    
          #DOSEmailNotify     [email protected]
          DOSLogDir           "/var/log/apache2/mod_evasive"
          DOSSystemCommand    "sudo /var/www-security/security-assistant.bash %s 'ModEvasive' >> /var/www-security/security-assistant-exec.log 2>&1"
      </IfModule>
    
  • Create log file and Restart the Apache server:

      sudo touch /var/www-security/security-assistant.bash-exec.log && sudo chown www-data /var/www-security/security-assistant.bash-exec.log
      sudo systemctl restart apache2.service
    

To test this configuration we can simulate DDOS attack via the F5 method, mentioned above, or we can use a commands as ab, hping3, etc.

Attention: Be careful because the rule iptables -D INPUT -s $BAD_IP -j DROP, used in the above script, will DROP all new connections from the source IP immediately, including yours SSH connection. So you need a backup way to connect to the server, during the tests. Or you can change this rule.


#ModSecurity 2.9 for Apache2

ModSecurity is a web application firewall engine that provides very little protection on its own. In order to become useful, ModSecurity must be configured with rules. In order to enable users to take full advantage of ModSecurity out of the box, Trustwave's Spider Labs is providing a free certified rule set for ModSecurity™ Core Rules provide generic protection. Read more...

###Installation

  • Install and enable the module:

      sudo apt install libapache2-mod-security2
      sudo a2enmod security2
    
  • Create configuration file:

      sudo cp /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf
    
  • Edit the configuration file and add or change at least directives:

      SecRuleEngine On
      SecAuditLog ${APACHE_LOG_DIR}/mod_security2/modsec_audit.log
      SecGuardianLog ${APACHE_LOG_DIR}/mod_security2/modsec_guardian.log
    
  • Apply the Apache's configuration. The file /etc/apache2/mods-enabled/security2.conf involves mod_security configuration files into Apache's configuration. It shall looks as this:

      <IfModule security2_module>
          SecDataDir /var/cache/modsecurity
          IncludeOptional /etc/modsecurity/*.conf
      </IfModule>
    
  • Create Log Directory:

      sudo mkdir -p /var/log/apache2/mod_security2
    
  • Setup log rotation:

      sudo cp /etc/logrotate.d/apache2 /etc/logrotate.d/apache2-modsec
    

Then edit the new file in this way:

    /var/log/apache2/mod_security2/*.log { … }
  • Restart Apache: sudo systemctl restart apache2.service.

###Check-up

  • Create custom rule and test if it works. Edit /etc/modsecurity/modsecurity.conf and add these lines at the bottom:

      # Directory traversal attacks
      SecRule REQUEST_URI "../" "t:urlDecodeUni, deny, log, id:109"
    

Note: This is just an example, and it's covered by OWASP CRS.

  • Restart the server: sudo systemctl restart apache2.service. Then open your browser and type https://domain.name/?abc=../ or use one of these terminal commands:

      wget -L https://domain.name/?abc=../
      curl https://domain.name/?abc=../
    

The result will be: 403 Forbidden. Check the logs:

    sudo cat /var/log/apache2/mod_security2/modsec_audit.log
    sudo cat /var/log/apache2/mod_security2/modsec_guardian.log

###References


#ModSecurity OWASP Core Rule Set 3.x In Ubuntu 16 you can install **CSR 2.x**: `apt install modsecurity-crs`. More details about this approach can be fund in [this manual][31]. Here we will install [**CSR 3.x**][32], detailed instructions are provided within the [Installation manual][33]. [Git][34] is required: `sudo apt install git`.

###Installation

  • Clone CSR in the folder /usr/share/modsecurity-crs.3:

      sudo git clone https://github.com/SpiderLabs/owasp-modsecurity-crs /usr/share/modsecurity-crs.3
    
  • Future updating of the definitions:

      cd /usr/share/modsecurity-crs.3
      sudo git pull
    
  • Create configuration files:

      sudo cp /usr/share/modsecurity-crs.3/crs-setup.conf.example /usr/share/modsecurity-crs.3/crs-setup.conf
      sudo cp /usr/share/modsecurity-crs.3/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example /usr/share/modsecurity-crs.3/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf
      sudo cp /usr/share/modsecurity-crs.3/rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example /usr/share/modsecurity-crs.3/rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf
    

    Read and edit these files carefully! Uncomment at least SecGeoLookupDB directive:

      SecGeoLookupDB util/geo-location/GeoIP.dat
    
  • Auto renew the GeoIP database, that is no longer included with the CRS. Instead you are advised to download it regularly. The script util/upgrade.py brings this functionality. You can use it as follows in cron - sudo crontab -e:

      0 2 * * * /usr/share/modsecurity-crs.3/util/upgrade.py --geoip --cron
    
  • Apply the Apache's configuration. Edit /etc/apache2/mods-available/security2.conf in this way:

      <IfModule security2_module>
          SecDataDir /var/cache/modsecurity
          IncludeOptional /etc/modsecurity/*.conf
          IncludeOptional /usr/share/modsecurity-crs.3/crs-setup.conf
          IncludeOptional /usr/share/modsecurity-crs.3/rules/*.conf   
      </IfModule>
    

    Save the file and then restart Apache: sudo systemctl restart apache2.service.


#ModSecurity Rules Whitelisting

Whitelisting of ModSecurity Rules could be done via the ModSec directives:

SecRuleRemoveById, SecRuleRemoveByMsg, SecRuleRemoveByTag
SecRuleUpdateTargetById, SecRuleUpdateTargetByMsg, SecRuleUpdateTargetByTag
SecRuleUpdateActionById

These directives can be used system wide or within virtual host's configuration; also globally, for specific directories or location matches.

  • Disable mod_security2 for phpMyAdmin. Change /etc/phpmyadmin/apache.conf in this way:

      <Directory /usr/share/phpmyadmin>
          <IfModule security2_module>
              SecRuleEngine Off
          </IfModule>
      </Directory>
    
  • Disable specific rules for certain directory:

      <Directory /var/www/html>
          <IfModule security2_module>
              SecRuleRemoveById 973301
          </IfModule>
      </Directory>
    
  • Disable rules globally. For this purpose we must add our directives somewhere in Apache's configuration files. At this stage the bottom of /etc/apache2/mods-available/security2.conf (within the <IfModule> tags) looks as good place.

  • Disable rules within the entire Apache's configuration:

         SecRuleRemoveById 973301 950907
    
  • Whitelist an IP address so it can pass through ModSecurity:

         SecRule REMOTE_ADDR "@ipMatch 192.168.110.1" 
         phase:1,nolog,allow,ctl:ruleEngine=Off,ctl:auditEngine=Off
    
  • Disable rules within Directory match:

         <Directory /var/www/mediawiki/core>
             SecRuleRemoveById 973301 950907
         </Directory>
    
  • Update rule's action by its ID within Location match:

         <LocationMatch "/index.php.*">
             SecRuleUpdateActionById 973301 "pass"
             SecRuleUpdateActionById 950907 "pass"
         </LocationMatch>
    

In the above examples we assume that 973301 and 950907 are rules IDs that obstruct the normal work of our web apps. We can find rules as these by an analyse of the file modsec_audit.log, where at the bottom we will find entries that cantons strings as: [id "973301"] and [id "950907"]:

    cat /var/log/apache2/mod_security2/modsec_audit.log | grep -Ewo 'id \"[0-9]{1,10}' | sed 's/id \"//' | sort -r | uniq 

###References


#ModSecurity Rules ► SAS ► Iptables

Here are given few more examples how to create custom SecRules, also how we can call our Security Assistant Script (SAS) through them.

###Initial Setup

First we must create startup scrip. The reason is that, ModSec's exec action has too simple syntax. So we can't use neither sudo nor we are able to pass any parameters directly.

  • Create script file and - security-assistant-modsec.sh, make it executable for www-data:

      sudo touch /var/www-security/security-assistant-modsec.sh
      sudo chmod a+rx /var/www-security/security-assistant-modsec.sh
    
  • The script content shall be:

      #!/bin/sh
      ATTACK_INFO="Our Server: $SERVER_NAME; Attacking IP: $REMOTE_ADDR; Attack. host: $REMOTE_HOST; Request URI: $REQUEST_URI; Arguments: $ARGS; Unique ID: $UNIQUE_ID"
      sudo /var/www-security/security-assistant.bash $REMOTE_IP ModSecurity "$ATTACK_INFO"
    

$REMOTE_IP, etc. are EnvVars and their values will be filled by ModSec.

###Let's Rule

  • Redirect all wp-admin page requests, but except these from certain IPs (note the chain):

      # Block wp-admin
      SecRule REQUEST_URI "^/wp-admin" "id:108, log, deny, t:lowercase, chain, redirect:https://www.you.."
          SecRule REMOTE_ADDR "!@ipMatch 192.168.1.11,99.77.66.12"
    
  • Update the default action of OWASP CRS 3 Directory traversal attacks rule:

      # Directory traversal attacks
      SecRuleUpdateActionById 930110 \
      "exec:/var/www-security/security-assistant-modsec.sh"
    
  • Create words black list:

      # REQUEST_URI words blacklist (for complete words blacklist: SecRule REQUEST_URI|ARGS|REQUEST_BODY)
      SecRule REQUEST_URI "@pmFromFile /var/www-security/modsecurity-words-black.list" \
      "id:150,\
       deny,log,chain,\
       redirect:https://www.you.."
          SecRule REMOTE_ADDR "!@ipMatchFromFile /var/www-security/modsecurity-ip-white.list" \
          "setenv:REMOTE_HOST=%{REMOTE_HOST},\
           setenv:ARGS=%{ARGS},\
           exec:/var/www-security/security-assistant-modsec.sh"
    

In this example:

  • REQUEST_URI - this variable contains the full URI from the current request.

  • modsecurity-words-black.list - contains list of phrases, where each specific phrase or word is placed into a new line. You can collect interesting words and phrases from the audit.log file.

  • modsecurity-ip-white.list - could contains white-list of IP addresses, separated at new lines. CIDR entries are acceptable.

  • log action will make log entry for this rule with id:150.

  • chain action is equivalent of logical and, in the example with the combination of ! from the next chained rule we can read it as if not.

  • deny action will block the request if it contains a phrase from the black.list (in its URI) and if the REMOTE_ADDR is not listed into the ip-white.list.

  • redirect will redirect the request if the same conditions are met.

  • deny and redirect actions belong to Disruptive group of actions, that means they must be in the beginning of the chain. Also they will be executed only when all chained rules rerun true.

  • exec action will call our external script. This action isn't Disruptive and will be executed when the current rule returns true. If it was it the begging of the chain it will be executed no mater the result of chained rules!

  • setenv action will export certain internal variables =%{...} as env. vars, exported names can be different from the internals. Some variables must be exported manually, some other are exported automatically!?! Also for some vars, the manual export with the same names, for example setenv:REQUEST_URI=%{REQUEST_URI}, will cause a blank value of the exported variable.

###References


#ModSecurity [and Apache] Log Files

The Apache web server can be configured to give the server administrator important information about how it is functioning... The main avenue for providing feedback to the administrator is through the use of log files. Read more...

ModSecurity has powerful logging mechanism. By the directive SecGuardianLog it provides a log feed specially designed to work with external scripts.

Currently the only tool known to work with guardian logging is httpd-guardian, which is part of the Apache httpd tools project. The httpd-guardian tool is designed to defend against denial of service attacks. It uses the blacklist tool to interact with an iptables-based... firewall, dynamically blacklisting the offending IP addresses. Read more...

###References


#ModSecurity Log Files ► Fail2Ban ► Iptables

It is possible to setup Fail2Ban for data parsing of Apache's log files. modsec_audit.log is probably the best choice, but see also the sections where we talk about of SecGuardianLog.

Take care that SecAuditLogRelevantStatus in /etc/modsecurity/modsecurity.conf is commented. Otherwise everyone that receives a 404 error page would be blocked by fail2ban.

SecAuditEngine RelevantOnly
#SecAuditLogRelevantStatus "^(?:5|4(?!04))"

###References


#ModSecGuardianLog ► HTTPD-Guardian ► SAS ► Iptables

httpd-guardian - detect DoS attacks by monitoring requests Apache Security, Copyright (C) 2005 Ivan Ristic - is designed to monitor all web server requests through the piped logging mechanism. It keeps track of the number of requests sent from each IP address... httpd-guardian can either emit a warning or execute a script to block the IP address...

This script can be used with Apache2 logging mechanism, or with ModSecurity (better).

###Installation and Setup within the Current Circumstances

  • Download httpd-guardian and make it executable:

      wget http://apache-tools.cvs.sourceforge.net/viewvc/apache-tools/apache-tools/httpd-guardian?revision=1.6 -O /var/www-security/httpd-guardian.perl
      chmod +x /var/www-security/httpd-guardian.perl
    

Change my $PROTECT_EXEC; as follow to call our SAS script:

    my $PROTECT_EXEC = "exec /var/www-security/security-assistant.bash %s 'Guardian' >> /var/www-security/security-assistant-exec.log 2>&1";
  • Optionally this customised mirrored version can be used:

      curl https://pastebin.com/raw/EGCiY3TR | sed -e 's/\r$//' | sudo tee /var/www-security/httpd-guardian.perl
      chmod +x /var/www-security/httpd-guardian.perl
    
  • Apply the following change within Apache's configuration, then restart it:

      #SecGuardianLog ${APACHE_LOG_DIR}/mod_security2/modsec_guardian.log
      SecGuardianLog "|/var/www-security/httpd-guardian.perl"
    

#ModSecGuardianLog ► Automated Analyse ► SAS ► Iptables

Here is presented a simple script, called apache-log-analyst.bash, that isn't something special but could be a nice example. Its features are described within the script's body.

###Installation and Setup

  • Download apache-log-analyst.bash and make it executable:

      curl https://pastebin.com/raw/k4ejvc81 | sed -e 's/\r$//' | sudo tee /var/www-security/apache-log-analyst.bash
      chmod +x /var/www-security/apache-log-analyst.bash
    
  • Apply the following change within Apache's configuration, then restart it:

      SecGuardianLog "|/var/www-security/apache-log-analyst.bash"
    

#HTTPS Connection

HTTPS is a communications protocol for secure communication over a computer network which is widely used on the Internet. HTTPS consists of communication over HTTP within a connection encrypted by TLS, or its predecessor SSL. Read more...

pa4080
  • 29.9k
  • 10
  • 89
  • 162