Drupal Apache VirtualHost

From WebarchDocs
Jump to: navigation, 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>