Securing your Web server

Unix Insider –

This month's offering is the first in a series of three columns devoted to securing your Web site. We start with a look at server-wide security, procede to directory-level issues in July, and conclude in August with the gory details of password-protected documents.

Security basics

When you bring your server online and start soliciting visitors, you instantly increase the chances of your server being penetrated by some hacker. Why? Because your site is now well-known, promiscuously offering content to the world. Of the millions of machines on the Net, a very small percentage are actually Web servers. Since hackers tend to focus on machines where they may find something useful, any Web server is a better target than an anonymous machine sitting on someone's desk somewhere.

This means that you must not only secure your Web server and documents, you must also secure your machine against all other sorts of hacks and queries. Fortunately, Unix Insider Online's very own Peter Galvin has done an excellent job covering the basics of server security, starting with his April column and concluding in May. Follow his advice and your machine will be well on its way to being impervious to most network-based security attacks. In particular, make sure you install tcp_wrapper and carefully configure external access to your machine.

The httpd security model

Now you're ready to configure the security features of your Web server. In order to do that, you need to understand how httpd and its derivatives, including NCSA's httpd and the Apache server handle server security.

Each time a user connects to your site, the client passes to the server the numeric IP address of the client machine. In some cases, this may be the IP address of a proxy server, requesting the document on behalf of some other machine. The http protocol also allows the client to provide the name of the user making the request, but this rarely happens. As a result, the only bit of data the server has to validate the request is the IP address of the client machine.

The first thing the server does is reverse this numeric address in an effort to get the textual domain name of the machine. This is the name that is human-readable, like www.sun.com. The reversing process involves contacting a domain name server, presenting it with the numeric IP address, and getting the domain name in return.

Surprisingly, many machines on the Net are not correctly configured to have their IP addresses reversed. This is not the fault of the machine, per se, but of the domain name server responsible for that machine's domain. Many network administrators get the forward maps (mapping the name to the IP address) correct but fail to configure the reverse maps (which perform the opposite mapping). As a result, this attempt to reverse the IP address may fail. Undaunted, the server forges ahead anyway.

Once the server has the client's IP address, and possibly its domain name in hand, it begins applying sets of rules to determine if this client can access the document in question. This IP-based rule model is at the heart of Web server security, enhanced only by password protection (which we'll cover in August).

Configuring the access.conf file

At the server level, document access is controlled by entries you put in your server's access.conf file, usually located in the conf directory at the top level of your server's installation directory. Within this directory, you can specify access rules for any directory within your server's document directory.

For each directory you want to control, you need to put a

<font face="Courier"><directory></font>
tag into the access.conf file. Within the
<font face="Courier"><directory></font>
tag you'll use a
<font face="Courier"><limit></font>
tag with its
<font face="Courier">allow</font>
,
<font face="Courier">deny</font>
, and
<font face="Courier">order</font>
parameters to control access to the directory.

Let's start with a simple example: Opening up your server so that the whole world can access files in your top-level document directory.

<font face="Courier">     <directory /usr/local/http/docs>
        <limit> 
           order allow,deny
           allow from all
        </limit>
     </directory>
</font>

The

<font face="Courier">order</font>
directive tells the server to process all
<font face="Courier">allow</font>
directives before any
<font face="Courier">deny</font>
directives. Astute readers will note that we don't have any
<font face="Courier">deny</font>
directives, but bear with me, it becomes useful later. More importantly, the
<font face="Courier">allow</font>
directive tells the server to allow access from any client address.

Suppose you're implementing one of those nifty new intranet things that are suddenly all the rage (I guess "private WAN" or "local area network" didn't sound cool enough to catch on years ago), and you need to restrict access to just the folks in your company. Now, you'll need a

<font face="Courier">deny</font>
directive:

<font face="Courier">     <directory /usr/local/http/docs>
        <limit> 
           order deny,allow
           deny from all
           allow from .mycompany.com
        </limit>
     </directory>
</font>

The

<font face="Courier">order</font>
directive suddenly becomes important. First, the
<font face="Courier">deny</font>
directive restricts access to everyone. Then, the
<font face="Courier">allow</font>
directive allows anyone whose machine name is part of the
<font face="Courier">mycompany.com</font>
domain. All other machines are denied access.

IP address reversal is now critical to gain access to your server. If the IP address cannot be reversed, the server cannot decide if a machine is part of your domain. It errs on the conservative side and denies access to the client. If someone in your company has a misconfigured domain name server, they'll soon be on the phone complaining that they can't reach your pages, and it's all your fault.

If you run internal servers for a large company, like I do, you might get ten calls a week from irate customers who can't reach your pages. The right solution is to force these people to contact their DNS administrator and fix the IP reversal problem. The quick and dirty solution is to add raw IP numbers to the access list:

<font face="Courier">     <directory /usr/local/http/docs>
        <limit> 
           order deny,allow
           deny from all
           allow from .mycompany.com 192.153.22
        </limit>
     </directory>
</font>

This minor modification allows accesses from any machine whose name reverses into the

<font face="Courier">mycompany.com</font>
domain, as well as any machine whose IP address starts with
<font face="Courier">192.153.22</font>
.

Some syntax details:

  • You can add any number of domain names or IP addresses to a single
    <font face="Courier">allow</font>
    or
    <font face="Courier">deny</font>
    directive.
  • Domain names must have a leading "." or they are considered to be an absolute machine name, not a subdomain.
  • Numeric addresses may contain one, two, three, or four elements separated by periods, letting you manage class A, B, or C networks, or a specific machine.
  • You can have any number of directives. They are all processed in the order specified by the
    <font face="Courier">order</font>
    directive.

Now that those details are out of the way, here's some advice:

  • Never use raw IP addresses to allow access to your pages. You'll eventually find yourself with dozens of these things in your access list, making maintenance a nightmare. Always require clients to fix their domain name server to reverse their name correctly.
  • Only put one name per directive. This makes it easy to edit the file, since you can comment out any directive by putting a "#" character at the start of the line.
  • Always create an access control list for your top-level document directory, even if you make it world-readable. This makes it easy to update later and forces you to learn how to manage your server's security.
  • Remember that the access rules are only read when the server starts. If you edit the
    <font face="Courier">access.conf</font>
    file after the server has started, your changes will not take effect until the server is stopped. To make life easier, most servers will reread the file when sent a HUP signal. Check your server's documentation for more details.

Managing multiple directories

You'll note that the

<font face="Courier"><directory></font>
directive has a specific directory name attached to it. If you have multiple document directories on your server, you should have a
<font face="Courier"><directory></font>
directive for each one. Further, each directory can have a completely different set of access rules.

For example, to create a world readable top-level directory and a company-private directory within it, you could use:

<font face="Courier">     <directory /usr/local/http/docs>
        <limit> 
           order allow,deny
           allow from all
        </limit>
     </directory>
     <directory /usr/local/http/docs/private>
        <limit> 
           order deny,allow
           deny from all
           allow from .mycompany.com
        </limit>
     </directory>
</font>

The granting of access permissions is managed all the way down the directory tree. A user must have access to all directories above a particular one to gain access to that directory. Security is usually more restrictive as you go down the directory structure; it makes no sense to allow broad access within a subdirectory when the top-level directory has greater restrictions.

Dealing with individual control

Often, you will need to restrict access to a particular machine or classes of machines. Perhaps some malcontent is spamming your server, or you are required by federal law to restrict the dissemination of certain information (companies bound by ITAR restrictions on the export of sensitive technology are an example). Selective use of the

<font face="Courier">deny</font>
directive makes this easy:

<font face="Courier">     <directory /usr/local/http/docs>
        <limit> 
           order allow,deny
           allow from all
           deny from 137.27.1.1 .kp
        </limit>
     </directory>
</font>

This lets everyone in, except some person at 137.27.1.1 and any machine in North Korea (the

<font face="Courier">.kp</font>
domain). Of course, that guy at 137.27.1.1 will move to 137.27.1.2 next door to his office, and the folks in Korea will simply switch to an open proxy server in Europe before hitting your site. If you've got really sensitive stuff you need to restrict, I'll cover better solutions in August.

You can also grant individual access. Suppose you want to allow access to your private pages to some strategic partner. Use appropriate

<font face="Courier">allow</font>
directives:

<font face="Courier">     <directory /usr/local/http/docs/private>
        <limit> 
           order deny,allow
           deny from all
           allow from .mycompany.com
           allow from .partner.com
        </limit>
     </directory>
</font>

The best way to see how this works is to create a few test directories on your server and change their access rules. Once you get the hang of it, make sure you create appropriate rule sets for every directory on your server.

Looking ahead

Next month, we'll look at other ways to control directory-level access, and I'll reveal a few quick URLs guaranteed to expose the dirty laundry hidden away in almost every Web server.

What’s wrong? The new clean desk test
You Might Like
Join the discussion
Be the first to comment on this article. Our Commenting Policies