August 10th, 2008 | .htaccess files - Ultimate .htaccess Tutorial
« PreviousNotes from Apache HTTPD Source Code »
.htaccess file is the configuration file for the Apache Web Server that provides a number of directives for configuring Apache and Apache Modules
If you look around the site you’ll notice .htaccess tricks that nobody else has, .htaccess tricks that push the limits. This isn’t an introduction to .htaccess, this is the evolution of .htaccess files for your website.
.htaccess files are similar to httpd.conf the main server configuration file, but htaccess is allowed anywhere and is used to control the directory (recursively) they are placed in. Many web hosts allow .htaccess (DreamHost, Powweb, MediaTemple) files for their webhosting customers but don’t make them a selling point or explain how to use the .htaccess file since so few people have heard of it.
Intended Audience: Elite: Web developers, Server administrators, hosting provider techs, students, and anyone else curious about .htaccess: the best subject to learn for a website owner.
Originally this page was known as the “Ultimate .htaccess Guide” but I’ve been regularly adding new .htaccess tricks and .htaccess examples for several years. I also add my favorite .htacess tutorials, .htaccess tricks published elsewhere, results from some my .htaccess experiments and basically try to continually improve this article! The reason is because various Web Hosting companies Support Staff send customers here, Higher-Education Institutions/Profs bring students here, but the main reason to create the best .htaccess resource on the Net is because I’m sorta obsessed with finding the coolest htaccess tricks, and I’ve got some cool ones I promise you that!
The .htaccess file is an incredibly useful powerful tool that WILL make your life so much easier if you learn to use it. I learn about .htaccess by reading the Apache HTTP Server Source Code, including all the various module source (like mod_rewrite) and then doing my own hacking/research which I sometimes publish. I chose the name AskApache because of that very reason, and from respect for the ASF Contributors and Developers, well-known world-wide for their superior programming skills and inexhaustible dedication to keeping it all free… Here’s what they say (minus the bold, mine):
Note: The .htaccess example code included on this page is just a small taste of the article they reference.
ErrorDocument 403 http://www.yahoo.com/ Order deny,allow Deny from all Allow from 208.113.134.190
This lets google crawl the page, lets me access without a password, and lets my client access the page WITH a password. It also allows for XHTML and CSS validation! (w3.org)
AuthName "Under Development" AuthUserFile /home/sitename.com/.htpasswd AuthType basic Require valid-user Order deny,allow Deny from all Allow from 208.113.134.190 w3.org htmlhelp.com googlebot.com Satisfy Any
Redirect non-https requests to https server and ensure that .htpasswd authorization can only be entered across HTTPS
SSLOptions +StrictRequire
SSLRequireSSL
SSLRequire %{HTTP_HOST} eq "askapache.com"
ErrorDocument 403 https://askapache.com
SetEnv TZ America/Indianapolis
SetEnv SERVER_ADMIN webmaster@google.com
ServerSignature for ErrorDocumentServerSignature off | on | email
Article: Setting Charset in htaccess, and article by Richard Ishida
AddDefaultCharset UTF-8 DefaultLanguage en-US
Options -ExecCGI AddHandler cgi-script .php .pl .py .jsp .asp .htm .shtml .sh .cgi
RewriteCond %{REQUEST_METHOD} !^(GET|HEAD|OPTIONS|POST|PUT)
RewriteRule .* - [F]
AddType application/octet-stream .avi .mpg .mov .pdf .xls .mp4
RemoveHandler cgi-script .pl .py .cgi AddType text/plain .pl .py .cgi
Undocumented techniques and methods will allow you to utilize mod_rewrite at an “expert level” by showing you how to unlock its secrets.
RewriteCond %{REQUEST_URI} !^/(robots\.txt|favicon\.ico|sitemap\.xml)$
RewriteCond %{HTTP_HOST} !^www\.askapache\.com$ [NC]
RewriteRule ^(.*)$ http://www.askapache.com/$1 [R=301,L]
RewriteCond %{REQUEST_URI} !^/robots\.txt$ [NC]
RewriteCond %{HTTP_HOST} !^www\.[a-z-]+\.[a-z]{2,6} [NC]
RewriteCond %{HTTP_HOST} ([a-z-]+\.[a-z]{2,6})$ [NC]
RewriteRule ^/(.*)$ http://%1/$1 [R=301,L]
Apache HTTP Project FAQ Why is mod_rewrite so difficult to learn and seems so complicated?
Hmmm… there are a lot of reasons. First, mod_rewrite itself is a powerful module which can help you in really all aspects of URL rewriting, so it can be no trivial module per definition. To accomplish its hard job it uses software leverage and makes use of a powerful regular expression library by Henry Spencer which is an integral part of Apache since its version 1.2. And regular expressions itself can be difficult to newbies, while providing the most flexible power to the advanced hacker.
Redirect 301 /old/file.html http://www.askapache.com/new/file.html
RedirectMatch 301 /blog(.*) http://www.askapache.com/$1
If you have a php.cgi or php.ini file in your /cgi-bin/ directory or other pub directory, try requesting them from your web browser. If your php.ini shows up or worse you are able to execute your php cgi, you’ll need to secure it ASAP. This shows several ways to secure these files, and other interpreters like perl, fastCGI, bash, csh, etc.
<FilesMatch "^php5?\.(ini|cgi)$"> Order Deny,Allow Deny from All Allow from env=REDIRECT_STATUS </FilesMatch>
Fresh .htaccess code for you! Check out the Cookie Manipulation and environment variable usage with mod_rewrite! I also included a couple Mod_Security .htaccess examples. Enjoy!
This code sends the Set-Cookie header to create a cookie on the client with the value of a matching item in 2nd parantheses.
RewriteEngine On RewriteBase / RewriteRule ^(.*)(de|es|fr|it|ja|ru|en)/$ - [co=lang:$2:.askapache.com:7200:/]
Header set Set-Cookie "language=%{lang}e; path=/;" env=lang
# year <FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|swf|mp3|mp4)$"> Header set Cache-Control "public" Header set Expires "Thu, 15 Apr 2010 20:00:00 GMT" Header unset Last-Modified </FilesMatch> #2 hours <FilesMatch "\.(html|htm|xml|txt|xsl)$"> Header set Cache-Control "max-age=7200, must-revalidate" </FilesMatch> <FilesMatch "\.(js|css)$"> SetOutputFilter DEFLATE Header set Expires "Thu, 15 Apr 2010 20:00:00 GMT" </FilesMatch>
<Files login.php> AuthName "Prompt" AuthType Basic AuthUserFile /home/askapache.com/.htpasswd Require valid-user </Files>
<FilesMatch "^(private|phpinfo)\.*$"> AuthName "Development" AuthUserFile /.htpasswd AuthType basic Require valid-user </FilesMatch>
Header set P3P "policyref=\"http://www.askapache.com/w3c/p3p.xml\"" Header set X-Pingback "http://www.askapache.com/xmlrpc.php" Header set Content-Language "en-US" Header set Vary "Accept-Encoding"
Want to block a bad robot or web scraper using .htaccess files? Here are 2 methods that illustrate blocking 436 various user-agents. You can block them using either SetEnvIf methods, or by using Rewrite Blocks.
SetEnvIfNoCase ^User-Agent$ .*(craftbot|download|extract|stripper|sucker|ninja|clshttp|webspider|leacher|collector|grabber|webpictures) HTTP_SAFE_BADBOT SetEnvIfNoCase ^User-Agent$ .*(libwww-perl|aesop_com_spiderman) HTTP_SAFE_BADBOT Deny from env=HTTP_SAFE_BADBOT
RewriteCond %{HTTP_USER_AGENT} ^.*(craftbot|download|extract|stripper|sucker|ninja|clshttp|webspider|leacher|collector|grabber|webpictures).*$ [NC]
RewriteRule . - [F,L]
By using some cool .htaccess tricks we can control PHP to be run as a cgi or a module. If php is run as a cgi then we need to compile it ourselves or use .htaccess to force php to use a local php.ini file. If it is running as a module then we can use various directives supplied by that modules in .htaccess
SetEnv PHPRC /location/todir/containing/phpinifile
AddHandler php-cgi .php .htm Action php-cgi /cgi-bin/php5.cgi
#!/bin/sh export PHP_FCGI_CHILDREN=3 exec php5.cgi -c /abs/php5/php.ini
This is freaking sweet if you use SSL I promise you! Basically instead of having to check for HTTPS using a RewriteCond %{HTTPS} =on for every redirect that can be either HTTP or HTTPS, I set an environment variable once with the value “http” or “https” if HTTP or HTTPS is being used for that request, and use that env variable in the RewriteRule.
SetEnvIfNoCase ^If-Modified-Since$ "(.+)" HTTP_IF_MODIFIED_SINCE=$1 SetEnvIfNoCase ^If-None-Match$ "(.+)" HTTP_IF_NONE_MATCH=$1 SetEnvIfNoCase ^Cache-Control$ "(.+)" HTTP_CACHE_CONTROL=$1 SetEnvIfNoCase ^Connection$ "(.+)" HTTP_CONNECTION=$1 SetEnvIfNoCase ^Keep-Alive$ "(.+)" HTTP_KEEP_ALIVE=$1 SetEnvIfNoCase ^Authorization$ "(.+)" HTTP_AUTHORIZATION=$1 SetEnvIfNoCase ^Cookie$ "(.+)" HTTP_MY_COOKIE=$1
chmod .htpasswd files 640, chmod .htaccess 644, php files 600, and chmod files that you really dont want people to see as 400. (NEVER chmod 777, try 766)
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www\.)?askapache.com/.*$ [NC]
RewriteRule \.(gif|jpg|swf|flv|png)$ http://www.askapache.com/feed.gif [R=302,L]
See all 57 .htaccess ErrorDocuments
ErrorDocument 400 /htaccess/400_BAD_REQUEST.html ErrorDocument 401 /htaccess/401_UNAUTHORIZED.html ErrorDocument 403 /htaccess/403_FORBIDDEN.html ErrorDocument 404 /htccess/index.php?error=404 ErrorDocument 502 /htaccess/502_BAD_GATEWAY.html ErrorDocument 503 /htaccess/503_SERVICE_UNAVAILABLE.html
SecFilterSelective REMOTE_ADDR "208\.113\.183\.103" "nolog,noauditlog,pass"
SecFilterSelective REMOTE_ADDR “!^208\.113\.183\.103″ “nolog,noauditlog,pass”
SecFilterSelective REMOTE_ADDR “208\.113\.183\.103″ “log,auditlog,pass”
Here’s how to find the directives available in the core of apache httpd that you can use in your .htaccess file. You can find out what your httpd allows if you can access the httpd binary from a shell by typing the following command from a shell.
./httpd -L|grep -B 2 "htaccess"|grep -v '-'
FilesLimitLimitExceptIfModuleIfDefineFilesMatchAuthTypeAuthNameRequireSatisfyAddDefaultCharsetAcceptPathInfoErrorDocumentOptionsDefaultTypeFileETagServerSignatureContentDigestLimitRequestBodyLimitXMLRequestBodyForceTypeSetHandlerSetOutputFilterSetInputFilterAddOutputFilterByTypeHere are just a few of the modules that come with Apache. Each one can have new commands for use in .htaccess file scopes.
mod_actions.c, mod_alias.c, mod_asis.c, mod_auth_basic.c, mod_auth_digest.c, mod_authn_anon.c, mod_authn_dbd.c, mod_authn_dbm.c, mod_authn_default.c, mod_authn_file.c, mod_authz_dbm.c, mod_authz_default.c, mod_authz_groupfile.c, mod_authz_host.c, mod_authz_owner.c, mod_authz_user.c, mod_autoindex.c, mod_cache.c, mod_cern_meta.c, mod_cgi.c, mod_dav.c, mod_dav_fs.c, mod_dbd.c, mod_deflate.c, mod_dir.c, mod_disk_cache.c, mod_dumpio.c, mod_env.c, mod_expires.c, mod_ext_filter.c, mod_file_cache.c, mod_filter.c, mod_headers.c, mod_ident.c, mod_imagemap.c, mod_include.c, mod_info.c, mod_log_config.c, mod_log_forensic.c, mod_logio.c, mod_mem_cache.c, mod_mime.c, mod_mime_magic.c, mod_negotiation.c, mod_proxy.c, mod_proxy_ajp.c, mod_proxy_balancer.c, mod_proxy_connect.c, mod_proxy_ftp.c, mod_proxy_http.c, mod_rewrite.c, mod_setenvif.c, mod_speling.c, mod_ssl.c, mod_status.c, mod_substitute.c, mod_unique_id.c, mod_userdir.c, mod_usertrack.c, mod_version.c, mod_vhost_alias.c
<Directory<DirectoryMatch<Files<FilesMatch<IfDefine<IfVersion<IfModule<Limit<LimitExcept<Location<LocationMatch<Proxy<ProxyMatch<VirtualHostAcceptMutexAcceptPathInfoAccessFileNameActionAddCharsetAddDefaultCharsetAddDescriptionAddEncodingAddHandlerAddInputFilterAddLanguageAddOutputFilterAddOutputFilterByTypeAddTypeAliasAliasMatchAllowCONNECTAllowOverrideAnonymousAnonymous_AuthoritativeAnonymous_LogEmailAnonymous_MustGiveEmailAnonymous_NoUserIdAnonymous_VerifyEmailAuthAuthoritativeAuthDBMAuthoritativeAuthDBMGroupFileAuthDBMTypeAuthDBMUserFileAuthDigestAlgorithmAuthDigestDomainAuthDigestFileAuthDigestGroupFileAuthDigestNcCheckAuthDigestNonceFormatAuthDigestNonceLifetimeAuthDigestQopAuthDigestShmemSizeAuthGroupFileAuthNameAuthTypeAuthUserFileBS2000AccountBrowserMatchBrowserMatchNoCaseCacheNegotiatedDocsCharsetDefaultCharsetOptionsCharsetSourceEncCheckSpellingContentDigestCookieDomainCookieExpiresCookieNameCookieStyleCookieTrackingCoreDumpDirectoryDAVDAVDepthInfinityDAVMinTimeoutDefaultIconDefaultLanguageDefaultTypeDocumentRootErrorDocumentErrorLogExtFilterDefineExtFilterOptionsFancyIndexingFileETagForceLanguagePriorityForceTypeGprofDirHeaderHeaderNameHostnameLookupsIdentityCheckImapBaseImapDefaultImapMenuIncludeIndexIgnoreLanguagePriorityLimitRequestBodyLimitRequestFieldsLimitRequestFieldsizeLimitRequestLineLimitXMLRequestBodyLockFileLogLevelMaxRequestsPerChildMultiviewsMatchNameVirtualHostNoProxyOptionsPassEnvPidFilePortProxyBlockProxyDomainProxyErrorOverrideProxyIOBufferSizeProxyMaxForwardsProxyPassProxyPassReverseProxyPreserveHostProxyReceiveBufferSizeProxyRemoteProxyRemoteMatchProxyRequestsProxyTimeoutProxyViaRLimitCPURLimitMEMRLimitNPROCReadmeNameRedirectRedirectMatchRedirectPermanentRedirectTempRemoveCharsetRemoveEncodingRemoveHandlerRemoveInputFilterRemoveLanguageRemoveOutputFilterRemoveTypeRequestHeaderRequireRewriteCondRewriteRuleSSIEndTagSSIErrorMsgSSIStartTagSSITimeFormatSSIUndefinedEchoSatisfyScoreBoardFileScriptScriptAliasScriptAliasMatchScriptInterpreterSourceServerAdminServerAliasServerNameServerPathServerRootServerSignatureServerTokensSetEnvSetEnvIfSetEnvIfNoCaseSetHandlerSetInputFilterSetOutputFilterTimeoutTypesConfigUnsetEnvUseCanonicalNameXBitHackallowdenyorderCGIMapExtensionEnableMMAPISAPIAppendLogToErrorsISAPIAppendLogToQueryISAPICacheFileISAPIFakeAsyncISAPILogNotSupportedISAPIReadAheadBufferSSLLogSSLLogLevelMaxMemFreeModMimeUsePathInfoEnableSendfileProxyBadHeaderAllowEncodedSlashesLimitInternalRecursionEnableExceptionHookTraceEnableProxyFtpDirCharsetAuthBasicAuthoritativeAuthBasicProviderAuthDefaultAuthoritativeAuthDigestProviderAuthLDAPAuthzEnabledAuthLDAPBindDNAuthLDAPBindPasswordAuthLDAPCharsetConfigAuthLDAPCompareDNOnServerAuthLDAPDereferenceAliasesAuthLDAPGroupAttributeAuthLDAPGroupAttributeIsDNAuthLDAPRemoteUserIsDNAuthLDAPURLAuthzDBMAuthoritativeAuthzDBMTypeAuthzDefaultAuthoritativeAuthzGroupFileAuthoritativeAuthzLDAPAuthoritativeAuthzOwnerAuthoritativeAuthzUserAuthoritativeBalancerMemberDAVGenericLockDBFilterChainFilterDeclareFilterProtocolFilterProviderFilterTraceIdentityCheckTimeoutIndexStyleSheetProxyPassReverseCookieDomainProxyPassReverseCookiePathProxySetProxyStatusThreadStackSizeAcceptFilterProtocolAuthDBDUserPWQueryAuthDBDUserRealmQueryUseCanonicalPhysicalPortCheckCaseOnlyAuthLDAPRemoteUserAttributeProxyPassMatchSSIAccessEnableSubstituteProxyPassInterpolateEnvThese are just some of my favorite .htaccess resources. I’m really into doing your own hacking to get the knowledge and these links are all great resources if you are like me. I’m really interested in new or unusual solutions or hacks that use .htaccess, so let me know if you find one.
Here’s a great article form 2001 that goes into detail about some of the rarer uses for .htaccess files. Anyone interested in security should read all 3 articles.
Stupid .htaccess tricks is probably the best explanation online for many of the best .htaccess solutions, including many from this page. Unlike me they are fantastic writers, even for technical stuff they are very readable, so its a good blog to kick back on and read.
Here’s a resource that I consider to have some of the most creative and ingenious ideas for .htaccess files, although the author is somewhat of a character ;) Its a trip trying to navigate around the site, a fun trip. Its like nothing I’ve ever seen. There are only a few articles on the site, but the htaccess articles are very original and well-worth a look. See: htaccess tricks and tips and more .htaccess tricks
Mostly a site for… blog security (which is really any web-app security) this blog has a few really impressive articles full of solid information for Hardening WordPress with .htaccess among more advanced topics that can be challenging but effective. This is a good site to subscribe to their feed, they publish plugin exploits and wordpress core vulnerabilities quite a bit.
Oldschool security/unix dude with some incredibly detailed mod_rewrite tutorials, helped me the most when I first got into this, and a great guy too. See: Basic Mod_Rewrite Guide, and Advanced Mod_Rewrite Tutorial
Alot of .htaccess tutorials and code. See: Hardening Wordpress with Mod Rewrite and htaccess
jdMorgan is the Moderator of the Apache Forum at WebmasterWorld, a great place for answers. In my experience he can answer any tough question pertaining to advanced .htaccess usage, haven’t seen him stumped yet.
Apache Documentation: 1.3 | 2.0 | 2.2 | Current
Apache HTTP Server Project
Apache Software exists to provide robust and commercial-grade reference implementations of many types of software. It must remain a platform upon which individuals and institutions can build reliable systems, both for experimental purposes and for mission-critical purposes. We believe that the tools of online publishing should be in the hands of everyone, and that software companies should make their money by providing value-added services such as specialized modules and support, amongst other things. We realize that it is often seen as an economic advantage for one company to “own” a market - in the software industry, that means to control tightly a particular conduit such that all others must pay for its use. This is typically done by “owning” the protocols through which companies conduct business, at the expense of all those other companies. To the extent that the protocols of the World Wide Web remain “unowned” by a single company, the Web will remain a level playing field for companies large and small. Thus, “ownership” of the protocols must be prevented. To this end, the existence of robust reference implementations of various protocols and application programming interfaces, available free to all companies and individuals, is a tremendously good thing.
Furthermore, the Apache Software Foundation is an organic entity; those who benefit from this software by using it, often contribute back to it by providing feature enhancements, bug fixes, and support for others in public lists and newsgroups. The effort expended by any particular individual is usually fairly light, but the resulting product is made very strong. These kinds of communities can only happen with freely available software — when someone has paid for software, they usually aren’t willing to fix its bugs for free. One can argue, then, that Apache’s strength comes from the fact that it’s free, and if it were made “not free” it would suffer tremendously, even if that money were spent on a real development team.
« Elite Log File Scrolling with Color SyntaxNotes from Apache HTTPD Source Code »
The power of the Web is in its universality. Access by everyone regardless of disability is an essential aspect. Tim Berners-Lee
November 12, 2008 | 6 dicas de segurança para o seu blog Wordpress | Kerkeberos.net - Tecnologia e Informação
November 6, 2008 | .htaccess Plugin Blocks Spam, Hackers, and Password Protects Blog
October 20, 2008 | .htaccess trick shows Development CSS file only to Developer
December 13, 2007 | Modified WP-Cache for Huge Speed Increase
February 7, 2007 | adam taylor; eightfourseven2
Except where otherwise noted, content on this site is licensed under a Creative Commons Attribution 3.0 License, which lets you use/modify/re-post this content provided you follow the attribution guidelines.
I am unsure if I am doing somethign wrong. I am hosted with Godaddy but when the checking script runs it displays some errors and I am unsure as to how to resolve them:
Error 1
.htaccess Capabilities
.htaccess files allowed [200] errors out and gives me:
The others items in this list also turn yellow ( not red like the first one but also give the same error )
Second Error:
Is this critically needed?
Third error:
all three same error as above:
What am I missing?
ww.example.com/customer file.htm?_vti_bin/but it didn't haveshtml.exeinstead i found.htaccessfile. I'm not very familiar about htaccess much. Can you please help me how did htaccess directed toshtml.exe.Options +FollowSymLinks RewriteEngine On RewriteBase / RewriteCond %{HTTP_HOST} !^www\.yourdomain\.com$ [NC] RewriteRule ^(.*)$ http://www.yourdomain.com/$1 [R=301,L]It work fine for the folowing url typesite.com/restaurant.htmlIf I have to redirect the following non www url to www urlsite.com/cms/restaurant.htmlWhen I hit this url I get the following response Please let me know what code to add? Thanks, Johndomain.tld/index.php?option=com_content&task=view&id=16Itemid=32 to -> http//domain.tld/content/And:domain.tld/index.php?option=com_content&task=view&id=30&Itemid=63 to -> http://domain.tld/content/careersThanks