Difference between revisions of "Apache 2 - Redirection (mod rewrite)"

 
(One intermediate revision by the same user not shown)
Line 2: Line 2:
  
  
=Redirections=
 
  
 
+
=Principle=
==Principle==
 
  
 
Just a little reminder...
 
Just a little reminder...
Line 28: Line 26:
  
  
==Enable redirections==
+
=Enable redirections (mod_rewrite)=
  
 
Module "rewrite" allows you to redirect source URL to another one.
 
Module "rewrite" allows you to redirect source URL to another one.
Line 36: Line 34:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 +
 +
 +
 +
=Redirection from here to there=
  
  
Line 95: Line 97:
  
 
==Virtual host: Alias redirection==
 
==Virtual host: Alias redirection==
 +
 +
Instead of redirecting all to HTTPS you can redirect just 1 service.
 +
  
 
The following example will redirect a "/phpsecinfo" from HTTP to HTTPS.
 
The following example will redirect a "/phpsecinfo" from HTTP to HTTPS.
Line 107: Line 112:
 
RewriteRule ^/phpsecinfo(/.*|$)    https://%{HTTP_HOST}/phpsecinfo$1 [L,R]
 
RewriteRule ^/phpsecinfo(/.*|$)    https://%{HTTP_HOST}/phpsecinfo$1 [L,R]
 
<Location /phpsecinfo>
 
<Location /phpsecinfo>
order deny,allow
+
 
deny from all
+
                #### Apache < 2.4
                # Only allow specific IP@
+
#order deny,allow
                 # allow from 127.0.0.1 192.168.1.0/24
+
                 #allow from 127.0.0.1 192.168.1.0/24
                 allow from all
+
       
 +
                 #### Apache 2.4
 +
                Require local
 +
                Require ip 192.168.1
 
</Location>
 
</Location>
 
...
 
...
Line 120: Line 128:
 
Alias /phpsecinfo /var/www/phpsecinfo
 
Alias /phpsecinfo /var/www/phpsecinfo
 
<Location /phpsecinfo>
 
<Location /phpsecinfo>
order deny,allow
+
                #### Apache < 2.4
deny from all
+
#order deny,allow
                 # Only allow specific IP@
+
                #allow from all
                # allow from 127.0.0.1 192.168.1.0/24
+
       
                 allow from all
+
                 #### Apache 2.4
 +
                 Require all granted
 
         </Location>
 
         </Location>
 
...
 
...
Line 139: Line 148:
  
  
==Apache 2 Module configuration==
+
=Redirections as security filter=
  
 
This configuration will apply to all virtual-hosts.
 
This configuration will apply to all virtual-hosts.

Latest revision as of 08:36, 11 August 2014



Principle

Just a little reminder...

Apache2 mod_rewrite principle


  • Redirections are not transparent
  • Redirections are performed by the client. The server only serves the new URL to use
  • Redirections can also be used as a security tool to filter HTTP requests and only allow some of them.


As you can see on the previous picture, redirection can be declared:

  • As Apache 2 module configuration. This will apply to all virtual hosts and web-sites
  • In a Virtual Host configuration
    • Default setting - ex: HTTP to HTTPS
    • For a specific alias |or| directory
  • In a web page
  • In a .htaccess to protect a specific directory



Enable redirections (mod_rewrite)

Module "rewrite" allows you to redirect source URL to another one.

a2enmod rewrite



Redirection from here to there

Virtual host: redirect all HTTP to HTTPS

The safer way to redirect HTTP to HTTPS is use to adjust the virtual host configuration.

<VirtualHost *:80>
	ServerName dev.daxiongmao.eu
	ServerAlias www.dev.daxiongmao.eu *.dev.daxiongmao.eu
	ServerAdmin guillaume@qin-diaz.com

	### LOG ###
	LogLevel warn
	ErrorLog ${APACHE_LOG_DIR}/dev.daxiongmao.eu/error.log
	CustomLog ${APACHE_LOG_DIR}/dev.daxiongmao.eu/access.log combined
	

	############################################
	## Redirect all traffic to HTTPS website
        ############################################
        RewriteEngine On
        # This checks to make sure the connection is not already HTTPS
        RewriteCond %{HTTPS} off        
        # This rule will redirect users from their original location, to the same location but using HTTPS.
        RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} 
	# Alternate (fail-over) solution 
	redirect permanent / https://myServer/


        ########
	# No need of a document root anymore as everything is redirect to HTTPS
        ########
	
</VirtualHost>


-Note-

As you can see you don't need a DocumentRoot anymore for the *:80 virtual host.



Take changes into account

You have to restart the server to use this settings

service apache2 restart

Test your configuration


Virtual host: Alias redirection

Instead of redirecting all to HTTPS you can redirect just 1 service.


The following example will redirect a "/phpsecinfo" from HTTP to HTTPS.


Edit your virtual-host configuration and use that example to redirect to another server too by adjusting the rewrite rule.

<VirtualHost *:80>
...
        # PHPSecInfo
	RewriteRule ^/phpsecinfo(/.*|$)    https://%{HTTP_HOST}/phpsecinfo$1 [L,R]
	<Location /phpsecinfo>

                #### Apache < 2.4
		#order deny,allow
                #allow from 127.0.0.1 192.168.1.0/24	
         
                #### Apache 2.4
                Require local
                Require ip 192.168.1
	</Location>
...
</VirtualHost>
<VirtualHost *:443>
...
	# PHPSecInfo
	Alias 	/phpsecinfo /var/www/phpsecinfo
	<Location /phpsecinfo>
                #### Apache < 2.4
		#order deny,allow
                #allow from all
         
                #### Apache 2.4
                Require all granted
        </Location>
...
</VirtualHost>


Reload your configuration

/etc/init.d/apache2 reload


Redirections as security filter

This configuration will apply to all virtual-hosts.


Create the module configuration file

vim /etc/apache2/mods-available/rewrite.conf


Copy / paste this configuration (adjust to your own settings!)

   RewriteEngine On
   # --------------------- SECURITY RULES (JOOMLA) ------------------------ #
   ## End of deny access to extension xml files
   RewriteCond %{QUERY_STRING} mosConfig_[a-zA-Z_]{1,21}(=|\%3D) [OR]
   # Block out any script trying to base64_encode crap to send via URL
   RewriteCond %{QUERY_STRING} base64_encode.*\(.*\) [OR]
   # Block out any script that includes a <script> tag in URL
   RewriteCond %{QUERY_STRING} (\<|%3C).*script.*(\>|%3E) [NC,OR]
   # Block out any script trying to set a PHP GLOBALS variable via URL
   RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]
   # Block out any script trying to modify a _REQUEST variable via URL
   RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2})
   # Send all blocked request to homepage with 403 Forbidden error!
   RewriteRule ^(.*)$ index.php [F,L]

   # --------------------- SECURITY RULES (PERSONAL) ------------------------ #
   ## DENY REQUEST BASED ON REQUEST METHOD ###
   RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK|OPTIONS|HEAD)$ [NC]
   RewriteCond %{REQUEST_METHOD} (GET|POST) [NC]
   RewriteRule ^.*$ - [F]
   # Avoid common security flows
   RewriteCond %{QUERY_STRING} ^(.*)http(\:|\%3A)(.*)$
   RewriteCond %{QUERY_STRING} mosConfig_ [NC,OR]
   RewriteCond %{QUERY_STRING} ^(.*)(%3C|<)/?script(.*)$ [NC,OR]
   RewriteCond %{QUERY_STRING} ^(.*)(%3D|=)?javascript(%3A|:)(.*)$ [NC,OR]
   RewriteCond %{QUERY_STRING} ^(.*)document\.location\.href(.*)$ [NC,OR]
   RewriteCond %{QUERY_STRING} ^(.*)base64_encode(.*)$ [NC,OR]
   RewriteCond %{QUERY_STRING} ^(.*)GLOBALS(=|[|%[0-9A-Z]{0,2})(.*)$ [NC,OR]
   RewriteCond %{QUERY_STRING} ^(.*)_REQUEST(=|[|%[0-9A-Z]{0,2})(.*)$ [NC,OR]
   RewriteCond %{QUERY_STRING} ^(.*)(SELECT|INSERT|DELETE|CHAR\(|UPDATE|REPLACE|LIMIT)(.*)$
   # Avoid common security mistakes
   RewriteCond %{QUERY_STRING} \.\.\/    [NC,OR]
   RewriteCond %{QUERY_STRING} boot\.ini [NC,OR]
   RewriteCond %{QUERY_STRING} tag\=     [NC,OR]
   RewriteCond %{QUERY_STRING} ftp\:     [NC,OR]
   RewriteCond %{QUERY_STRING} http\:    [NC,OR]
   RewriteCond %{QUERY_STRING} https\:   [NC,OR]
   RewriteCond %{QUERY_STRING} mosConfig [NC,OR]
   RewriteCond %{QUERY_STRING} ^.*(\(|\)|<|>|'|"|\?|\*).* [NC,OR]
   RewriteCond %{QUERY_STRING} ^.*(%22|%27|%3C|%3D|%3E|%7B|%7C).* [NC,OR]
   RewriteCond %{QUERY_STRING} ^.*(%0|%A|%B|%C|%D|%F|127\.0).* [NC,OR]
   RewriteCond %{QUERY_STRING} ^.*(globals|encode|localhost|loopback).* [NC,OR]
   RewriteCond %{QUERY_STRING} ^.*(select|insert|union|declare|drop).* [NC]
   RewriteRule ^(.*)$ - [F,L]

   # Ban Typical Vulnerability Scanners and others
   # Kick out Script Kiddies
   RewriteCond %{HTTP_USER_AGENT} ^(java|curl|wget).* [NC,OR]
   RewriteCond %{HTTP_USER_AGENT} ^.*(libwww-perl|curl|wget|python|nikto|wkito|pikto|scan|acunetix).* [NC,OR]
   RewriteCond %{HTTP_USER_AGENT} ^.*(winhttp|HTTrack|clshttp|archiver|loader|email|harvest|extract|grab|miner).* [NC,OR]
   # Avoid zombies software
   RewriteCond %{HTTP_USER_AGENT} ^Anarchie [OR]
   RewriteCond %{HTTP_USER_AGENT} ^ASPSeek [OR]
   RewriteCond %{HTTP_USER_AGENT} ^attach [OR]
   RewriteCond %{HTTP_USER_AGENT} ^autoemailspider [OR]
   RewriteCond %{HTTP_USER_AGENT} ^Xaldon\ WebSpider [OR]
   RewriteCond %{HTTP_USER_AGENT} ^Xenu [OR]
   RewriteCond %{HTTP_USER_AGENT} ^Zeus.*Webster [OR]
   RewriteCond %{HTTP_USER_AGENT} ^Zeus
   RewriteRule ^.* - [F,L]

   # Allow the robots to reference our website
   RewriteCond %{HTTP_USER_AGENT} !^Googlebot [NC]
   RewriteCond %{HTTP_USER_AGENT} !^Googlebot-Image [NC]
   RewriteCond %{HTTP_USER_AGENT} !^Googlebot-Mobile [NC]
   RewriteCond %{HTTP_USER_AGENT} !^Msnbot [NC]
   RewriteCond %{HTTP_USER_AGENT} !^Mediapartners-Google [NC]

   # Keep request without referer
   RewriteCond %{HTTP_REFERER} !^$

   # To allow your pictures to be displayed on Google
   RewriteCond %{HTTP_REFERER} !^http://.*google\.(comŠ(co\.)?[a-z]{2})/
   # To forbid the copy of your pictures to anyone else : display an other image !
   RewriteRule .*\.(jpe?g|gif|bmp|png)$ /images/hotlinkis.jpg [L]


Update your Apache2 configuration:

a2enmod rewrite


Restart your server:

service apache2 restart