CGI and Perl

Whos There? Configuring Client IP/Domain Restrictions

After you've configured the access rights on a per-directory basis, using either the global access.conf or directory-specific access control files, you may decide that you want to allow or deny access on a per-site basis, as well. You may, for instance, only wish to allow connections from a particular domain, possibly for specific directories. You can do this additionally within the global access.conf file using additional entries within the <Limit> directive for a particular directory.

It's important to understand how the allow/deny directives are parsed within any given <Limit> statement. You have three options to specify parse order that give you the ability to override previous deny statements with allow statements, using the order statement

order deny, allow

Using this form lets you, for instance, deny from everywhere, then allow only from a specific domain(s) or host(s), perhaps like this:

<Limit GET>
 order deny,allow
 deny from all
 allow from .corp.adobe.com
 </Limit>

Likewise, you can override allow statements with deny statements to allow everyone and then deny a few specific domains or hosts like so:

<Limit GET>
 order allow,deny
 allow from all
 deny from .bozo.com
 </Limit>

You can also treat all connections as denied, unless the host appears in either an allow or deny statement, using the following order option:

 <Limit GET>
 order mutual-failure
 allow from .metronet.com
 allow from 130.248
 deny from .bozo.com
 </Limit>

This option is probably the safest, because it won't allow any connections from anywhere, unless they're specifically allowed.

Running our script again now gives the following:

Userid: nobody
 Group: nogroup
 Administrator is: [email protected]
 Running at port: 80
 Access filename: .privaccess
 User Directory: public_html
 Global Types:   text/html .shtml
 Options for Directory: /usr/local/etc/httpd/cgi-bin
         Options : None
         AllowOverride : None
         Limit:
 Options for Directory: /usr/local/etc/httpd/htdocs/test1
         Options : None
         AllowOverride : None
         Limit: GET POST
                 require = valid-user
 Options for Directory: /usr/local/etc/httpd/htdocs
         PerlHandler : main::handler
         AddType : text/html .shtml
         Options : Indexes SymLinksIfOwnerMatch IncludesNOEXEC
         AllowOverride : AuthConfig FileInfo Indexes Limit
         Limit: GET
                 deny = from .bozo.com
                 order = mutual-failure
                 allow = from .metronet.com

But note our <Limit> directive for DocumentRoot has not limited retrievals in /cgi-bin. Because the cgi-bin directory isn't beneath DocumentRoot, it's not affected by the <Limit> statement. You'll need to explicitly limit anything outside, or above, the directory where you place <Limit> statements if that is the intent.

Another IP Restriction Mechanism: tcpwrapper

Another alternative, when you wish to restrict/verify connections from particular hosts, is to run a site-wide tool like tcpwrapper. (This will work only if you're starting httpd out of inetd.) You can get tcpwrapper from the COAST archive at

ftp://ftp.cs.purdue.edu/pub/tools/tcp_wrappers

along with plenty of other security tools, papers, and packages. Using tcpwrapper, you can configure certain actions based on the connecting site's domain, or hostname, which are vastly more powerful than the options you have with httpd alone. Many sites out on the open Internet use this tool, and it even ships with a couple of operating systems. If your site has an open pipe to the Internet, it may well be worth investigating this tool.