Spring Sale! Save 30% on all books w/ code: PLANET24
Web Dev + WordPress + Security

HTAccess Password-Protection Tricks

Recently a reader asked about how to password-protect a directory for every specified IP while allowing open access to everyone else. In my article, Stupid htaccess Tricks, I show how to password-protect a directory for every IP except the one specified, but not for the reverse case. In this article, I will demonstrate this technique along with a wide variety of other useful password-protection tricks, including a few from my Stupid htaccess Tricks article. Before getting into the juicy stuff, we’ll review a few basics of HTAccess password protection.

HTAccess password protection works in cascading fashion

Before we begin, there are few things you need to know about Apache’s various password-protection directives. First, these password-protection tricks apply to the directory in which they are placed. For example, to password-protect your entire site, you would place one of these tricks in the web-accessible root HTAccess file for your site. HTAccess directives are applied down the directory structure, in cascading fashion, such that all subdirectories are also protected.

You need two files for password protection: htaccess and htpasswd

The second thing you need to know is that, in most cases, there are two parts to any password-protection implementation: the .htaccess file and the .htpasswd file. The .htaccess file will contain any of the sweet tricks provided in this article, while the .htpasswd file will contain the required username and an encrypted version of your password.

There are several ways to generate your .htpasswd file. If you are comfortable with Unix, you can simply run the “htpasswd” command. For example, entering the following command will create a working password file in the /home/path/ directory:

htpasswd -bc /home/path/.htpasswd username password

Placing the password file above the web-accessible root directory is a good security measure. If you examine the file after it has been created, the only thing it will contain is a line that looks similar to this:

username:Mx1lbGn.nkP8

Instead of running a Unix command, you may prefer to use one of the 200,000 online services providing an online password generator.

Regardless of how or where you decide to create your .htpasswd file, keep its location in mind for use in its associated HTAccess file(s). And yes, you may use one .htpasswd file for multiple HTAccess files placed in multiple directories.

Know which version of Apache you are using

In each of the examples below, the directives are enclosed within an <IfModule> container. This is to prevent your server from crashing if the required Apache modules are not available or not installed. Generally, the required modules will be present, but the <IfModule> check is a good precautionary measure.

When implementing any of the password-protection methods in this article, make sure you double-check which version of Apache you are using before you begin. The examples in this article assume you are using either Apache 1.3 or 2.0, as the <IfModule> containers are checking for the presence of the mod_auth module. Thus, if you are running Apache 2.2 (or better), you will want to replace the current <IfModule> containers with the following:

<IfModule mod_authn_file.c></IfModule>

If in doubt, ask your host, install the ShowIP Firefox extension, or dig around in your server’s control panel. And, if you just don’t know, don’t care, or can’t figure it out, just remove the opening and closing <IfModule> tags from the method you would like to use and call it good. Without them, if your server is not equipped the required module, it will simply return a 500 error message, which is easily resolved by removing the password directives.

You can customize the dialogue on the password prompt

The last thing that you should know before diving into some sweet tricks is that you may customize the message shown on the password prompt by editing the following line in each of the examples in this article:

AuthName "Username and password required"

By changing the text inside of the quotes, you may use any language you wish for the password prompt.

So now at this point in our adventure, we’re ready to dive into some juicy HTAccess password-protection tricks..

Basic password protection

To password protect your site or any directory, place this code in the associated HTAccess file:

# basic password protection
<IfModule mod_auth.c>
 AuthUserFile /home/path/.htpasswd
 AuthName "Username and password required"
 AuthType Basic
 <Limit GET POST>
  Require valid-user
 </Limit>
</IfModule>

That’s about as basic as it gets. Remember to create your password file and specify its directory in the first line. Let’s move on to something more interesting.

Open-access for one IP, password-protect everyone else

This method is great during project development, where you want open access with the ability to give others access via password:

# password protect excluding specific ip
<IfModule mod_auth.c>
 AuthName "Username and password required"
 AuthUserFile /home/path/.htpasswd
 AuthType Basic
 Require valid-user
 Order Deny,Allow
 Deny from all
 Allow from 111.222.333.444
 Satisfy Any
</IfModule>

By placing that code into the HTAccess file of the directory that you would like to protect, only the specified IP will be allowed open access; everyone else will need to enter the proper username and password.

Open access multiple IPs, password-protect everyone else

The above code may be modified easily to provide multiple IPs open access while denying everyone else:

# password protect excluding specific ips
<IfModule mod_auth.c>
 AuthName "Username and password required"
 AuthUserFile /home/path/.htpasswd
 AuthType Basic
 Require valid-user
 Order Deny,Allow
 Deny from all
 Allow from localhost
 Allow from 111.222.333.444
 Allow from 555.666.777.888
 Satisfy Any
</IfModule>

You may add as many IPs as needed. This method is great during project development, where the following conditions will apply:

  • Project development remains private for regular visitors
  • Access may be granted to clients (or anyone) by providing the password
  • Members of the development team have open access on their respective machines

In addition to providing unrestricted access to your team, you may also want to keep certain web services in mind by including the following directives (insert above the Satisfy Any directive):

Allow from validator.w3.org
Allow from jigsaw.w3.org
Allow from google.com

Open access for everyone with password-protect for specific IPs

This method is useful for a variety of situations, including cases where you would like to block a list of malicious IPs.

# password protect only for specified ips
<IfModule mod_auth.c>
 AuthName "Username and password required"
 AuthUserFile /home/path/.htpasswd
 AuthType Basic
 Require valid-user
 Order Allow,Deny
 Allow from all
 Deny from 111.222.333.444
 Deny from 555.666.777.888
 Satisfy Any
</IfModule>

You may list as many IP addresses as necessary. You may also deny from entire IP blocks by truncating the address accordingly. For example, to block everyone coming from an IP address beginning with “999.888”, we would add the following directive:

Deny from 999.888

For more information on how this works, see this section of my Stupid htaccess Tricks article.

Open access for everyone with password-protect for specific CIDR number

Similar to the previous method, here is a technique for requiring a password only from a select CIDR number. This method is useful for blocking mega-spammers such as RIPE, Optinet, and others. If, for example, you find yourself adding line after line of Apache Deny directives for addresses beginning with the same first few numbers, choose one of them and try a whois lookup. Listed within the whois results will be the CIDR value representing every IP address associated with that particular network. Thus, blocking via CIDR is an effective way to eloquently prevent all IP instances of the offender from accessing your site. Here is a generalized example for blocking by CIDR:

# password protect only for specified CIDR
<IfModule mod_auth.c>
 AuthName "Username and password required"
 AuthUserFile /home/path/.htpasswd
 AuthType Basic
 Require valid-user
 Order Allow,Deny
 Allow from all
 Deny from 10.1.0.0/16
 Deny from 80.0.0/8
 Satisfy Any
</IfModule>

Password protect a single file

I have used this technique countless times. To password-protect a single file, simply add this to your HTAccess file:

# password protect single file
<IfModule mod_auth.c>
 <Files "protected.html">
  AuthName "Username and password required"
  AuthUserFile /home/path/.htpasswd
  Require valid-user
  AuthType Basic
 </Files>
</IfModule>

Here we are protecting a file named “protected.html” from access. The file will only be available after submission of the proper username and password.

Password protect multiple files

To protect multiple files, the method is very similar, only this time we are using Apache’s FilesMatch directive. This allows us to list as many files as needed:

# password protect mulitple files
<IfModule mod_auth.c>
 <FilesMatch "(protected\.html)|(passwords\.txt)">
  AuthName "Username and password required"
  AuthUserFile /home/path/.htpasswd
  Require valid-user
  AuthType Basic
 </FilesMatch>
</IfModule>

In this example, we are password protecting two files, “protected.html” and “passwords.txt”. To add more, simply include more instances of “|(filename\.ext)” in the list of files.

Password protect multiple file types

With this method, we are using Apache’s FilesMatch directive to password-protect multiple file types. Here is an example:

# password protect mulitple file types
<IfModule mod_auth.c>
 <FilesMatch "\.(inc|txt|log|dat|zip|rar)$">
  AuthName "Username and password required"
  AuthUserFile /home/path/.htpasswd
  Require valid-user
  AuthType Basic
 </FilesMatch>
</IfModule>

Once in place, this code will require a password for access to the following file types: .inc, .txt, .log, .dat, .zip, and .rar. Customize to suit your needs.

Password protection for everything except a single file

Thanks to Brett Batie for this powerful technique for allowing access to a single file while password-protecting everything else:

# password protect everything except a single file
<IfModule mod_auth.c>
 AuthName "Username and password required"
 AuthUserFile /home/path/.htpasswd
 Require valid-user
 AuthType Basic
 <Files "open-access.html">
  Order Deny,Allow
  Deny from all
  Allow from 123.456.789
  Satisfy any
 </Files>
</IfModule>

When placed in the root directory or any parent directory, this code will password-protect everything except the file named “open-access.html”, which itself may be located in any subsequent directory or subdirectory.

To protect everything while allowing access to multiple files, we may use Apache’s FilesMatch directive instead. Here is an example allowing access to “open-access-1.html”, “open-access-2.html”, and “open-access-3.html”:

# password protect everything except specified files
<IfModule mod_auth.c>
 AuthName "Username and password required"
 AuthUserFile /home/path/.htpasswd
 Require valid-user
 AuthType Basic
 <FilesMatch "(open-access-1.html)|(open-access-2.html)|(open-access-3.html)">
  Order Deny,Allow
  Deny from all
  Allow from 123.456.789
  Satisfy any
 </FilesMatch>
</IfModule>

Note that we may consolidate the file list as follows:

<FilesMatch "open-access-[1-3]\.html">

An alternative approach to allowing open access to any file or group of files is to locate them in their own directory with the following directives added to its HTAccess file:

Allow from all
satisfy any

Wrap it up then

As you can see, Apache’ mod_auth functionality makes it possible to configure just about password-protection setup you may need. From preventing access from specific IP addresses and domains to allowing access only for specific files and directories, Apache makes it possible to protect your files easily and securely. And we haven’t even gotten into the many possibilities available for configuring specific user and group authorizations. I think I’ll save that for another article. In the meantime, for more information on Apache’s powerful mod_auth, check out the Official Documentation.

About the Author
Jeff Starr = Fullstack Developer. Book Author. Teacher. Human Being.
GA Pro: Add Google Analytics to WordPress like a pro.

25 responses to “HTAccess Password-Protection Tricks”

  1. Cool. This is the best usage of htaccess password protection i’ve seen. All of them are basic, but useful a lot. Thank you very much.

  2. Jeff Starr 2009/07/13 9:03 am

    Thanks, Hon. Yes, a few of these methods are pretty basic, but many of the others required quite a bit of testing and research to get working properly. In any case, it’s great to hear that you find them useful. Cheers.

  3. Hi Jeff,

    This is a fantastic post, covering pretty much every scenario you can think of. Truly great stuff. I’m sure I’ll use it in future.

    As it happens, I recently used the Brett Batie “protect everything except a single file” technique myself, as I password protect wp-admin and the Subscribe to Comments plugin uses a CSS file from within wp-admin. Forgive the blatant plug, especially as I see you don’t password protect wp-admin, but if anyone else reading this does, you may want to check out my Subscribe To Comments & Protected Wp-admin Folder post for advice on that particular scenario.

    Anyway, as always, I’ve learned a lot from your post. I found the Brett Batie technique through random searches, but next time I have a .htaccess password protection need, I’m coming right here. A while back, you asked on Twitter what was the point of bookmarking things in Delicious. It’s for articles like this…

  4. Jeff Starr 2009/07/13 9:54 pm

    Hi Stephen, always a pleasure to hear from you. Thanks for the kind words, and I am truly flattered that you find the post worthy of future reference. It really makes the hard work pay off, as I am sure you understand.

    I don’t mind the plug at all, in fact, I should disclose that it was your post that inspired me to take this article from a simple answer to a reader’s question to the multiple-technique reference that it eventually became. Your posts are about as frequent as mine lately, but they are always educational, enjoyable, and highly useful.

    I encourage all of my readers to subscribe to Stephen Cronin’s More than Scratch the Surface. You won’t regret it! :)

  5. Hi Jeff, I’m blushing now! Thanks for the kind words – although I’d say not only are your posts are more frequent than mine, as I’ve said before, your posts are of the standard I’d like mine to be (but I normally fall short of that).

  6. Rick Austin 2009/07/17 8:50 am

    We’re getting pinged by a botnet that’s looking for a particular page (guestbook/admin.php) that doesn’t exist. They hit us from a multitude of IPs so I can’t block them that way. Is there a way to use .htaccess to refuse requests for a specific page such as this one?

  7. Jeff Starr 2009/07/19 9:05 pm

    Hi Rick, absolutely. Try this:

    RedirectMatch 403 specific-page.html

    And you’re good to go :)

  8. Jason Norris 2009/07/21 5:58 am

    Love the tutorials. Works great for the project i’m working on.

    I have my main site password protected via htaccess now. However, I have subfolders that I would like to allow access for only certain users. Is there a way to allow certain usernames (already logged in to the main site) access to the subfolders, but disallow other users (or require a different password)?

    Thanks so much in advance!

  9. Dave Bacon 2009/08/01 11:46 pm

    Great tutorials, thanks. I’m a newbie at setting up sites, and your tutorials have been really helpful.

    Basic question for you about this specific tutorial:

    How do I allow access to a protected directory once a user has logged in thru a php/mysql login form?

    The directory is protected from the general public. The user goes to the access page, logs in thru the php/mysql form, and a session is created.

    At that point, I want the user to be able to freely access the files in that directory. The problem is that the browser will pop up to ask the .htaccess password info. Since the user already logged in thru the php/mysql form, it’s annoying to have to do it again.

    I found the solution to embed the login in the url, but a) it’s totally not secure, and b) i.e. doesn’t support it anyway.

    With my noob skills, I can’t figure out what to do. I’d really appreciate any suggestions!

    Thanks!

  10. Très bon article, très intéressant. Merci pour ces ressources.

  11. Thanks a ton. I’ve been searching all over for how to protect every file but one. You’re a lifesaver!

  12. hello! nice post you have! congratulations! i have a problem protecting a folder. i set the password as mentioned in the post, but even if i enter the username and password correctly, it keeps prompting me for the credentials. any thoughts? would be much appreciated! thank you!

Comments are closed for this post. Something to add? Let me know.
Welcome
Perishable Press is operated by Jeff Starr, a professional web developer and book author with two decades of experience. Here you will find posts about web development, WordPress, security, and more »
Digging Into WordPress: Take your WordPress skills to the next level.
Thoughts
I live right next door to the absolute loudest car in town. And the owner loves to drive it.
8G Firewall now out of beta testing, ready for use on production sites.
It's all about that ad revenue baby.
Note to self: encrypting 500 GB of data on my iMac takes around 8 hours.
Getting back into things after a bit of a break. Currently 7° F outside. Chillz.
2024 is going to make 2020 look like a vacation. Prepare accordingly.
First snow of the year :)
Newsletter
Get news, updates, deals & tips via email.
Email kept private. Easy unsubscribe anytime.