htaccess

Allow, Satisfy and related directives have been deprecated, and they only still work for backwards compatibility as part of the module mod_access_compat

The new way is using the module mod_authz_host and the Require directives.

ricorca che talvolta .htaccess è disabilitato, per abilitalo nel virtualHost :

    AllowOverride All
    Order deny,allow
    Deny from all
    Allow from 192.168.0.
    Allow from 87.30.7.191 #ip specifico
 
    <FilesMatch \.(inc|conf)>
        order allow, deny
        deny from all
    </FilesMatch>
 
    <DirectoryMatch "^/.*/(\.svn|CVS)/">
        Order deny,allow
        Deny from all
    </DirectoryMatch>
 
    <Directory ~ "\.svn">
        Order allow,deny
        Deny from all
    </Directory>
 
 
    # Deny access to certain directories
    <FilesMatch "(etc|tmp)$">
        Order allow,deny
        Deny from all
    </FilesMatch>
 
    # Set the default documents
    DirectoryIndex index.php index.html
 
    # Disallow directory browsing
    Options Indexes +FollowSymLinks

IP Whitelist / Banlist

consentire l'accesso a una classe di IP

    <Directory /APP_PATH>
        Order deny,allow
        Deny from all
        Allow from 160.120.25.65
        Allow from 127.0.0.0/8
    </Directory>
    # https://httpd.apache.org/docs/2.4/mod/mod_authz_host.html
    # dir available only from localhost or IP
    <Directory /var/www/html/>
        Require host localhost
        Require ip 127.0.0.1
        Require ip 192.168
        Require ip 10
    </Directory>

more sophisticated IP expressions

    # IPv4
    Allow from 127.0.0.0/8     # IPv4 Loopback Addresses
    Allow from 169.254.0.0/16  # IPv4 Link-local Addresses
    Allow from 10.0.0.0/8      # IPv4 Normal LAN Address Space
    Allow from 172.16.0.0/12   # IPv4 Normal LAN Address Space
    Allow from 192.168.0.0/16  # IPv4 Normal LAN Address Space
 
    # IPv6  For Apache 2.4 and up only
    <IfVersion >= 2.4>
        Allow from ::1/128    # IPv6 Loopback Addresses
        Allow from fe80::/10  # IPv6 Link-local Addresses
        Allow from fc00::/7   # IPv6 Unique Local Addresses (LAN Space)
    </IfVersion>

docs: mod_authz_host

impedire l'accesso a una classe di IP

  order allow,deny
  allow from all
  deny from 65.19.146.2 220.248.0.0/14

impedire l'accesso a tutto il server web, ad esempio permettendo solo l'uso locale:

    nano /etc/apache2/ports.conf
    Listen 127.0.0.1:80
    # apache2 reaload

restrizione per IP a un singolo script Require ip 111.222.99.0/20 Require ip 91.92.93.0/22

Auth Password

permettere l'accesso della rete locale ma richiedere la password a tutti gli altri

    AuthUserFile /etc/apache2/.htpasswd
    AuthType Basic
    AuthName MySite
    Require valid-user
    Allow from 192.168.0
    Satisfy Any

per costruire .htpasswd

deve essere leggibile a www-data

    htpasswd -c /etc/apache2/.htpasswd <username>
    chmod 644 /etc/apache2/.htpasswd
    AuthType Basic
    AuthUserFile "/etc/apache2/.htpasswd"
    AuthName "Enter valid username and password!"
    require valid-user
 
    # require user aaaa bbbb #per permettere i soli username aaaa bbbb
    # proteggere un singolo file
    #<Files my-secret-file.html>
    #require valid-user
    #</Files>

basic php auth

define('AUTH_USER' 'aa'false);
define('AUTH_PW'   'bb'false);
if (!isset(
$_SERVER['PHP_AUTH_USER'])) {
    
header('WWW-Authenticate: Basic realm="My Realm"');
    
header('HTTP/1.0 401 Unauthorized');
    echo 
'user hit Cancel button: provide a valid user.';
    exit;
} else {
    if( !empty(
$_SERVER['PHP_AUTH_USER'] ) && !empty($_SERVER['PHP_AUTH_PW']  ) ) {
        if(
          
$_SERVER['PHP_AUTH_USER'] == AUTH_USER &&
          
$_SERVER['PHP_AUTH_PW']   == AUTH_PW
        
) {
            
// OK!
        } else {
            
$_SERVER['PHP_AUTH_USER']=null;
            
$_SERVER['PHP_AUTH_PW']  =null;
            die(
'invalid user and pass.');
        }
    } else {
        
$_SERVER['PHP_AUTH_USER']=null;
        
$_SERVER['PHP_AUTH_PW']  =null;
        die(
'invalid user and pass.');
    }
}

Password Protect Your Directories and Files

    #password-protect a file
    <files secure.php="">
      AuthType Basic
      AuthName "Prompt"
      AuthUserFile /home/path/.htpasswd
      Require valid-user
    </files>
    # password-protect a directory resides
    AuthType basic
    AuthName "This directory is protected"
    AuthUserFile /home/path/.htpasswd
    AuthGroupFile /dev/null
    Require valid-user
    # deny access the .htaccess File
    <files .htaccess="">
    order allow,deny
    deny from all
    </files>
 
    # make sure nobody gets the htaccess, README, COPYING or VERSION files
    <Files ~ "^([\._]ht|README$|VERSION$|COPYING$)">
        Order allow,deny
        Deny from all
    </Files>

Enhances Logging

<VirtualHost *:80>
    DocumentRoot /var/www/html/example.com/
    ServerName www.example.com
    DirectoryIndex index.htm index.html index.php
    ServerAlias example.com
    ErrorDocument 404 /404.php
    ErrorLog /var/log/httpd/example.com_error_log
    CustomLog /var/log/httpd/example.com_access_log combined
</VirtualHost>

Disable Directory Browsing Listing

  Options All -Indexes
  # also, disable other non essential features
  Options -FollowSymLinks
  Options -Includes
  Options -ExecCGI
  # small request by default
  LimitRequestBody 512000
  <Directory "/home/httpd/html/mydomain/files_to_hide">
    Options -Indexes
  </Directory>

Disable Server Signature

grep ServerSignature /etc/apache2/conf.d/*
sudo nano /etc/apache2/apache2.conf
    ServerSignature Off
    ServerTokens Prod

disabilita header X-Powered-By:PHP

    sudo nano /etc/php5/apache/php.ini
    expose_php Off
Header always unset X-Powered-By

othes signature

    ServerTokens ProductOnly

pecify the default email address for the server's admin.

    ServerSignature EMail
    SetEnv SERVER_ADMIN test@gmail.com

Disable Modules NON USATI

candidati: mod_imap, mod_include, mod_info, mod_userdir, mod_autoindex.

grep LoadModule /etc/httpd/conf/httpd.conf

Mod Security

web application firewall

    apt-get install libapache2-mod-security
    a2enmod mod-security
    /etc/init.d/apache2 force-reload

scaricare di sicurezza OWASP

    cd /etc/httpd/
    wget http://pkgs.fedoraproject.org/repo/pkgs/mod_security_crs/modsecurity-crs_2.2.5.tar.gz/aaeaa1124e8efc39eeb064fb47cfc0aa/modsecurity-crs_2.2.5.tar.gz
    tar xzf modsecurity-crs_2.2.5.tar.gz
    mv modsecurity-crs_2.2.5 modsecurity-crs
    cd modsecurity-crs
    cp modsecurity_crs_10_setup.conf.example modsecurity_crs_10_config.conf

Mod Evasive

detects and blocks DDOS attacks http://www.tecmint.com/protect-apache-using-mod_security-and-mod_evasive-on-rhel-centos-fedora/

    sudo apt-get install libapache2-mod-evasive
    sudo mkdir /var/log/mod_evasive
    sudo chown www-data:www-data /var/log/mod_evasive/
sudo vi /etc/apache2/mods-available/mod-evasive.load
LoadModule evasive20_module modules/mod_evasive20.so
 
<IfModule mod_evasive20.c>
  DOSHashTableSize    3097
  DOSPageCount        5
  DOSSiteCount        100
  DOSPageInterval     1
  DOSSiteInterval     1
  DOSBlockingPeriod   10
  #DOSEmailNotify      test@test.com
  DOSLogDir           "/var/log/mod_evasive"
  #DOSSystemCommand    "su - someuser -c '/sbin/... %s ...'"
  #DOSWhitelist   127.0.0.1
</IfModule>

DosHashTableSize: number of top-level nodes for each apache child process's hash table. Increasing this number will provide faster performance, but consume more memory. You should increase this if you have a busy web server.

DOSPageCount: the number of requests for the same page per page interval.

DOSSiteCount: This is the threshold for the total number of requests for any object by the same client on the same listener per site interval. Once the threshold for that interval has been exceeded, the IP address of the client will be added to the blocking list.

DOSPageInterval: The interval for the page count threshold; defaults to 1 second intervals.

DOSSiteInterval: The interval for the site count threshold; defaults to 1 second intervals.

DOSBlockingPeriod: amount of time (in seconds) that a client will be blocked. all subsequent requests from the client will result in a 403 (Forbidden) and the timer being reset (e.g., another 10 seconds).

DOSEmailNotify: an email will be sent to the address specified whenever an IP address becomes blacklisted. A locking mechanism using /var/lock/mod_evasive prevents continuous emails from being sent.

test script, apre 100 connessioni alla porta 80 e scrive se la connessione è accettata o rifiutata

#!/usr/bin/perl
 
use IO::Socket;
use strict;
 
for(0..100) {
    my($response);
    my($SOCKET) = new IO::Socket::INET( Proto => "tcp", PeerAddr=> "127.0.0.1:80");
 
    if (! defined $SOCKET) { die $!; }
    print $SOCKET "GET /?$_ HTTP/1.0\n\n";
    $response = <$SOCKET>;
    print $response;
    close($SOCKET);
}

Riavviare istanze che non rispondono

cronjob, domenica, ore 1:01

1  1  * * 0 root /etc/init.d/apache2 restart > /dev/null 2>&1
#!/usr/bin/env python
import urllib2
import commands
from subprocess import call
 
ip = '127.0.0.1'
try:
  link = urllib2.urlopen('http://%s' % ip).code
  print link
except urllib2.HTTPError as e:
  print e.code
except urllib2.URLError:
  call('invoke-rc.d apache2 restart', shell=True)

check configuration file for errors, parse "apache2ctl configtest"

#!/usr/bin/env python
import re
from subprocess import check_output, call
 
def is_config_ok():
    if re.findall('OK',check_output('apache2ctl configtest', shell=True)):
        return 1
    else:
        return 0
 
if __name__ == "__main__":
    if is_config_ok():
        call('invoke-rc.d apache2 restart', shell=True)
    else:
        print "error in config"

HTTPS Encryption

With TLS1.0 coming to end, you are advised to disable all protocols lower than TLSv1.1.

to only allow TLSv1.1 and 1.2 with strong Ciphering:

in vhost configuration

SSLEngine On
SSLProtocol all -SSLv2 -SSLv3 -TLSv1
SSLCipherSuite HIGH:!aNULL:!MD5
 
SSLHonorCipherOrder on
SSLCompression      off
SSLSessionTickets   off

- reload apache - run a test on SSLLabs.com

check the following files for duplicated directives, SSLProtocol and SSLCipherSuite, comment them with # /etc/apache2/mods-enabled/ssl.conf /etc/letsencrypt/options-ssl-apache.conf