ericrasch
5/22/2013 - 3:21 PM

.00 Solid Base .htaccess.md

# ######################################################################
# # SECURITY                                                           #
# ######################################################################

# ----------------------------------------------------------------------
# | File access                                                        |
# ----------------------------------------------------------------------

# Block access to directories without a default document.
# Usually you should leave this uncommented because you shouldn't allow anyone
# to surf through every directory on your server (which may includes rather
# private places like the CMS's directories).

<IfModule mod_autoindex.c>
    Options -Indexes
</IfModule>

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

# Block access to hidden files and directories.
# This includes directories used by version control systems such as Git and SVN.

<IfModule mod_rewrite.c>
    RewriteCond %{SCRIPT_FILENAME} -d [OR]
    RewriteCond %{SCRIPT_FILENAME} -f
    RewriteRule "(^|/)\." - [F]
</IfModule>

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

# Block access to backup and source files.
# These files may be left by some text editors and can pose a great security
# danger when anyone has access to them.

<FilesMatch "(^#.*#|\.(bak|config|dist|fla|inc|ini|log|psd|sh|sql|sw[op])|~)$">
    Order allow,deny
    Deny from all
    Satisfy All
</FilesMatch>

# Rules to block access to WordPress specific files
<files readme.html>
  Order allow,deny
  Deny from all
</files>
<files readme.txt>
  Order allow,deny
  Deny from all
</files>
<files README.md>
  Order allow,deny
  Deny from all
</files>
<files install.php>
  Order allow,deny
  Deny from all
</files>
<files wp-config.php>
  Order allow,deny
  Deny from all
</files>

# Rules to disable XML-RPC
<files xmlrpc.php>
  Order allow,deny
  Deny from all
</files>

# Deny access to all .htaccess files
<files ~ "^.*\.([Hh][Tt][Aa])">
  order allow,deny
  deny from all
  satisfy all
</files>

<IfModule mod_rewrite.c>
  RewriteEngine On

  # Rules to protect wp-includes
  RewriteRule ^wp-admin/includes/ - [F]
  RewriteRule !^wp-includes/ - [S=3]
  RewriteCond %{SCRIPT_FILENAME} !^(.*)wp-includes/ms-files.php
  RewriteRule ^wp-includes/[^/]+\.php$ - [F]
  RewriteRule ^wp-includes/js/tinymce/langs/.+\.php - [F]
  RewriteRule ^wp-includes/theme-compat/ - [F]

  # Rules to prevent php execution in uploads
  RewriteRule ^(.*)/uploads/(.*).php(.?) - [F]

  # Rules to block unneeded HTTP methods
  RewriteCond %{REQUEST_METHOD} ^(TRACE|DELETE|TRACK) [NC]
  RewriteRule ^(.*)$ - [F]

  # Rules to block foreign characters in URLs
  RewriteCond %{QUERY_STRING} ^.*(%0|%A|%B|%C|%D|%E|%F).* [NC]
  RewriteRule ^(.*)$ - [F]

  # Rules to help reduce spam
  RewriteCond %{REQUEST_METHOD} POST
  RewriteCond %{REQUEST_URI} ^(.*)wp-comments-post\.php*
  RewriteCond %{HTTP_REFERER} !^(.*)CHANGETHENAMEOFYOURWEBSITEHERE.com.*
  RewriteCond %{HTTP_REFERER} !^http://jetpack\.wordpress\.com/jetpack-comment/ [OR]
  RewriteCond %{HTTP_USER_AGENT} ^$
  RewriteRule ^(.*)$ - [F]
</IfModule>


# ######################################################################
# # WEB PERFORMANCE                                                    #
# ######################################################################

# ----------------------------------------------------------------------
# | Compression                                                        |
# ----------------------------------------------------------------------

<IfModule mod_deflate.c>

    # Force compression for mangled `Accept-Encoding` request headers
    # https://developer.yahoo.com/blogs/ydn/pushing-beyond-gzipping-25601.html

    <IfModule mod_setenvif.c>
        <IfModule mod_headers.c>
            SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding
            RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding
        </IfModule>
    </IfModule>

    # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    # Compress all output labeled with one of the following media types.
    #
    # (!) For Apache versions below version 2.3.7 you don't need to
    # enable `mod_filter` and can remove the `<IfModule mod_filter.c>`
    # and `</IfModule>` lines as `AddOutputFilterByType` is still in
    # the core directives.
    #
    # https://httpd.apache.org/docs/current/mod/mod_filter.html#addoutputfilterbytype

    <IfModule mod_filter.c>
        AddOutputFilterByType DEFLATE "application/atom+xml" \
                                      "application/javascript" \
                                      "application/json" \
                                      "application/ld+json" \
                                      "application/manifest+json" \
                                      "application/rdf+xml" \
                                      "application/rss+xml" \
                                      "application/schema+json" \
                                      "application/vnd.geo+json" \
                                      "application/vnd.ms-fontobject" \
                                      "application/x-font-ttf" \
                                      "application/x-javascript" \
                                      "application/x-web-app-manifest+json" \
                                      "application/xhtml+xml" \
                                      "application/xml" \
                                      "font/eot" \
                                      "font/opentype" \
                                      "image/bmp" \
                                      "image/svg+xml" \
                                      "image/vnd.microsoft.icon" \
                                      "image/x-icon" \
                                      "text/cache-manifest" \
                                      "text/css" \
                                      "text/html" \
                                      "text/javascript" \
                                      "text/plain" \
                                      "text/vcard" \
                                      "text/vnd.rim.location.xloc" \
                                      "text/vtt" \
                                      "text/x-component" \
                                      "text/x-cross-domain-policy" \
                                      "text/xml"

    </IfModule>

    # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    # Map the following filename extensions to the specified
    # encoding type in order to make Apache serve the file types
    # with the appropriate `Content-Encoding` response header
    # (do note that this will NOT make Apache compress them!).
    #
    # If these files types would be served without an appropriate
    # `Content-Enable` response header, client applications (e.g.:
    # browsers) wouldn't know that they first need to uncompress
    # the response, and thus, wouldn't be able to understand the
    # content.
    #
    # https://httpd.apache.org/docs/current/mod/mod_mime.html#addencoding

    <IfModule mod_mime.c>
        AddEncoding gzip              svgz
    </IfModule>

</IfModule>

# ----------------------------------------------------------------------
# | ETags                                                              |
# ----------------------------------------------------------------------

# Remove `ETags` as resources are sent with far-future expires headers.
#
# https://developer.yahoo.com/performance/rules.html#etags
# https://tools.ietf.org/html/rfc7232#section-2.3

# `FileETag None` doesn't work in all cases.
<IfModule mod_headers.c>
    Header unset ETag
</IfModule>

FileETag None

# ----------------------------------------------------------------------
# | Expires headers                                                    |
# ----------------------------------------------------------------------

# Serve resources with far-future expires headers.
#
# (!) If you don't control versioning with filename-based
# cache busting, you should consider lowering the cache times
# to something like one week.
#
# https://httpd.apache.org/docs/current/mod/mod_expires.html

<IfModule mod_expires.c>

    ExpiresActive on
    ExpiresDefault                                      "access plus 1 month"

  # CSS
    ExpiresByType text/css                              "access plus 1 year"

  # Data interchange
    ExpiresByType application/atom+xml                  "access plus 1 hour"
    ExpiresByType application/rdf+xml                   "access plus 1 hour"
    ExpiresByType application/rss+xml                   "access plus 1 hour"

    ExpiresByType application/json                      "access plus 0 seconds"
    ExpiresByType application/ld+json                   "access plus 0 seconds"
    ExpiresByType application/schema+json               "access plus 0 seconds"
    ExpiresByType application/vnd.geo+json              "access plus 0 seconds"
    ExpiresByType application/xml                       "access plus 0 seconds"
    ExpiresByType text/xml                              "access plus 0 seconds"

  # Favicon (cannot be renamed!) and cursor images
    ExpiresByType image/vnd.microsoft.icon              "access plus 1 year"
    ExpiresByType image/x-icon                          "access plus 1 year"

  # HTML
    ExpiresByType text/html                             "access plus 0 seconds"

  # JavaScript
    ExpiresByType application/javascript                "access plus 1 year"
    ExpiresByType application/x-javascript              "access plus 1 year"
    ExpiresByType text/javascript                       "access plus 1 year"

  # Manifest files
    ExpiresByType application/manifest+json             "access plus 1 year"

    ExpiresByType application/x-web-app-manifest+json   "access plus 0 seconds"
    ExpiresByType text/cache-manifest                   "access plus 0 seconds"

  # Media files
    ExpiresByType audio/ogg                             "access plus 1 month"
    ExpiresByType image/bmp                             "access plus 1 month"
    ExpiresByType image/gif                             "access plus 1 month"
    ExpiresByType image/jpeg                            "access plus 1 month"
    ExpiresByType image/png                             "access plus 1 month"
    ExpiresByType image/svg+xml                         "access plus 1 month"
    ExpiresByType video/mp4                             "access plus 1 month"
    ExpiresByType video/ogg                             "access plus 1 month"
    ExpiresByType video/webm                            "access plus 1 month"

  # Web fonts

    # Embedded OpenType (EOT)
    ExpiresByType application/vnd.ms-fontobject         "access plus 1 year"
    ExpiresByType font/eot                              "access plus 1 year"

    # OpenType
    ExpiresByType font/opentype                         "access plus 1 year"

    # TrueType
    ExpiresByType application/x-font-ttf                "access plus 1 year"

    # Web Open Font Format (WOFF) 1.0
    ExpiresByType application/font-woff                 "access plus 1 year"
    ExpiresByType application/x-font-woff               "access plus 1 year"
    ExpiresByType font/woff                             "access plus 1 year"

    # Web Open Font Format (WOFF) 2.0
    ExpiresByType application/font-woff2                "access plus 1 year"

  # Other
    ExpiresByType text/x-cross-domain-policy            "access plus 1 week"

</IfModule>

Solid Base .htaccess

Creating a solid base for your .htaccess file. Currently includes RewriteBase, Security (against indexes, files, etc.), and Expires Headers (caching, performance).

  • The URL REWRITES would go at the top of the file.
  • The SECURITY and the WEB PERFORMANCE can go towards the bottom... before and WordPress or WP Super Cache items.
  • UPDATE 2013-08-21: Added code for forcing either non-www or www. on URLs. Also added the MultiViews option.
  • UPDATE 2013-08-23: Added specific code for wp-config.php
  • UPDATE 2013-10-04: Increased favicon expire time.
  • UPDATE 2014-02-05: Removed the Force URL rewrites since there's more than one option.
  • UPDATE 2014-12-10: Updated Expires Headers
  • UPDATE 2015-04-10: Updated file security