Drupal Apache VirtualHost
Jump to navigation
Jump to search
The main Directory block of our Apache VirtualHost for Drupal sites contains:
<Directory /home/example/sites/default>
Options -Indexes +SymlinksIfOwnerMatch -MultiViews -IncludesNOEXEC -ExecCGI
DirectoryIndex index.php index.html index.htm wsh.shtml
AllowOverride AuthConfig FileInfo Indexes Limit Options=ExecCGI,IncludesNOEXEC,Indexes,MultiViews,SymLinksIfOwnerMatch Nonfatal=Override
<IfModule mod_version.c>
<IfVersion < 2.4>
Order Allow,Deny
Allow from all
</IfVersion>
<IfVersion >= 2.4>
Require all granted
</IfVersion>
</IfModule>
<IfModule !mod_version.c>
<IfModule !mod_authz_core.c>
Order Allow,Deny
Allow from all
</IfModule>
<IfModule mod_authz_core.c>
Require all granted
</IfModule>
</IfModule>
<IfModule mod_php7.c>
php_admin_value doc_root /home/example/sites/default
php_admin_value open_basedir /home/example/:/tmp/:/usr/share/php/
php_admin_value upload_tmp_dir /home/example/tmp
php_admin_value uploadprogress.file.contents_template /home/example/tmp/upload_contents_%s
php_admin_value uploadprogress.file.filename_template /home/example/tmp/upt_%s.txt
php_admin_value session.save_path /home/example/tmp
php_admin_value soap.wsdl_cache_dir /home/example/tmp
php_flag magic_quotes_gpc off
php_flag magic_quotes_sybase off
php_flag register_globals off
php_flag session.auto_start off
php_value mbstring.http_input pass
php_value mbstring.http_output pass
php_flag mbstring.encoding_translation off
<FilesMatch ".+\.ph(p[345]?|t|tml)$">
SetHandler application/x-httpd-php
</FilesMatch>
<FilesMatch ".+\.phps$">
SetHandler application/x-httpd-php-source
# Deny access to raw php sources by default
# To re-enable it's recommended to enable access to the files
# only in specific virtual host or directory
Require all denied
</FilesMatch>
# Deny access to files without filename (e.g. '.php')
<FilesMatch "^\.ph(p[345]?|t|tml|ps)$">
Require all denied
</FilesMatch>
<FilesMatch "\.(cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
</FilesMatch>
<FilesMatch "\.(engine|inc|info|install|make|module|profile|test|po|sh|.*sql|theme|tpl(\.php)?|xtmpl)(~|\.sw[op]|\.bak|\.orig|\.save)?$|^(\..*|Entries.*|Repository|Root|Tag|Template)$|^#.*#$|\.php(~|\.sw[op]|\.bak|\.orig\.save)$">
<IfModule mod_version.c>
<IfVersion < 2.4>
Order Deny,Allow
Deny from all
</IfVersion>
<IfVersion >= 2.4>
Require all denied
</IfVersion>
</IfModule>
<IfModule !mod_version.c>
<IfModule !mod_authz_core.c>
Order Deny,Allow
Deny from all
</IfModule>
<IfModule mod_authz_core.c>
Require all denied
</IfModule>
</IfModule>
</FilesMatch>
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault A1209600
<FilesMatch \.php$>
ExpiresActive Off
</FilesMatch>
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
RewriteRule "(^|/)\." - [F]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^ index.php [L]
<IfModule mod_headers.c>
RewriteCond %{HTTP:Accept-encoding} gzip
RewriteCond %{REQUEST_FILENAME}\.gz -s
RewriteRule ^(.*)\.css $1\.css\.gz [QSA]
RewriteCond %{HTTP:Accept-encoding} gzip
RewriteCond %{REQUEST_FILENAME}\.gz -s
RewriteRule ^(.*)\.js $1\.js\.gz [QSA]
RewriteRule \.css\.gz$ - [T=text/css,E=no-gzip:1]
RewriteRule \.js\.gz$ - [T=text/javascript,E=no-gzip:1]
<FilesMatch "(\.js\.gz|\.css\.gz)$">
Header set Content-Encoding gzip
Header append Vary Accept-Encoding
</FilesMatch>
</IfModule>
</IfModule>
</IfModule>
</Directory>
We also prevent PHP being run from the uploads directory:
<Directory /home/example/sites/default/sites/default/files>
Options None +SymLinksifOwnerMatch
SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006
<Files *>
SetHandler Drupal_Security_Do_Not_Remove_See_SA_2013_003
</Files>
<IfModule mod_php7.c>
php_flag engine off
</IfModule>
AddType text/plain .php .phtml .cgi .pl
</Directory>