Restrictive htaccess

I’d like to take a restrictive approach with my htaccess file in that I’d like to block everyone by default except IP subnets that I explicitly determine to be permitted to access my website using only POST or GET access methods. I understand the visitor risks inherent to taking this approach but given how dirty and malicious the internet has become, I view this as being merited, especially since it prioritizes security over permitting visitor access. Security over access.

With that in mind, I have 2 questions:

1.) I initially tried to implement this approach using thousands of “allow from XXX.XXX.XXX.XXX/NN” allow from CIDR entries and judging from the tests I’ve conducted, I’m able to have 115,282 individual lines of these CIDR rules. Anything that increases the htaccess file size by even just 1 KB more results in the htaccess file not working. This gives me an idea of just how many rule lines I can have… Is it safe to assume that this amount restriction is due to server resources (i.e. - CPU, RAM, etc.?), or could it be an Apache configuration in the shared environment I’m testing from? I know I can simplify the rules I’ve been testing with by major margins but for the sake of these tests, I’d like to have a clearer idea about where the breakage is occurring from. What ways exist to pinpoint it? Logs?

2.) Do any boilerplate htaccess templates exist that provide a good starting point for this type of restrictive approach? I’m over in the United States and would like to start with ranges found in both the States and Australia.

Feedback is appreciated and thanks in advance.

Have you considered a simple .htaccess file and using PHP validation and a Mysqli database table containing the permitted URLs. I believe this approach would remove the .htaccess restrictions that is currently being experienced.

John -

Could you elaborate on that? The overall goal I had in mind was to prevent access to my site by IP addresses or ranges I considered traditionally malicious or spammy…

The ,htaccess file could redirect every page to index.php

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]

The first couple of lines of the index.php would first find the $_SERVER['REQUEST_URL'] then search a database and see if the URL is blocked. If blocked then redirect to some other site otherwise continue rendering the index.php web page.

Hmmm… That might work if I can figure out one thing:

I have the following web directory structure:

– .htaccess
– myfoobarsite_live
– myfoobarsite_test

Inside my htaccess file, I need a means of routing domain-specific requests to appropriate sub-directories as follows:

(So if someone visits “”, they get taken to production and if “”, the sub-domain test website that I use for testing and development purposes.)

Currently, my /public_html/.htaccess file contains the following that I’ve used to handle this up to this point:

RewriteEngine on

RewriteCond %{HTTP_HOST} ^www\.myfoobarsite\.com$ [NC]
RewriteRule ^$ myfoobarsite_live/index.php [L]

RewriteCond %{HTTP_HOST} ^www\.myfoobarsite\.com$ [NC]
RewriteCond %{DOCUMENT_ROOT}/myfoobarsite_live%{REQUEST_URI} -f
RewriteRule .* myfoobarsite_live/$0 [L]

RewriteCond %{HTTP_HOST} ^www\.myfoobarsite\.com$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* myfoobarsite_live/index.php?q=$0 [QSA]

# Add "www." to all "" requests and force HTTPS, thereby forcing visitors to default to live and use SSL...
RewriteCond %{HTTP_HOST} ^myfoobarsite\.com$
RewriteRule ^(.*)$$1 [R=301]

With your suggestion in mind, how would I force all requests through an index.php file prior to sending them onward to the respective directory?

(Note that this configuration is done on a shared hosting platform that allows use of C-PANEL. I don’t have any .htaccess sub-domain routines in my .htaccess file as it’s easier to use sub-domains created by C-PANEL as their routing is somewhat automatically handled without needing .htaccess rewrites. The only rewrites I need are those for my production sites.)

My knowledge of .htaccess rules is very limited but it looks as though all requests are already being rewritten to index.php.

I would perhaps write an include file which is included at the start of index.php and any other web pages. The file would contain a function which returns true or false and used to either redirect or continue.

Search for “PHP header(…)” for the manual on redirection.

Have you access to the Apache logs?

Here’s the thing: those requests get rewritten to an index in a sub-directory. I’d prefer to filter the requests (first) into the .htaccess found in /public_html/ before the request is allowed to access either /public_html/myfoobarsite_live/index.php or /public_html/myfoobarsite_test/index.php. In other words, I’d like to have incoming requests for either production or test be routed through the /public_html/.htaccess before being routed into either of the sub-directories after they’re vetted by the PHP that checks the requesting IP address. So with that in mind, would your “return true or false” idea still work?

And yes, I do have access to some logs. I can look at a PHP error log and I can view an access log, too. I’m thinking I might try to set up a sub-directory somewhere, plop an .htaccess file in there using this setup, and in the same sub-directory put a couple test directories in there with “Hello World” PHP files to test all this out.

Long story short, it sounds like (if everything can be configured correctly), I’d consolidate every request through the first layer’s .htaccess file which would force requests through the PHP layer to verify permission to progress onward into one of the main sub-directories for either production or test. I’ll have to fiddle with the request piece to make sure I can use that “return true or false” piece because I’ve never done anything like that before–but it’s a good idea. :slight_smile:

I was curious and created a web-page that validates the IP Address, adds to a database table and renders three states/modes:

    $tmp = (bool) count($_GET);    
        $mode = 'BYPASS';    

        $lBefore = $db->getPdo((string) 'find', $uri);
            $mode = 'BANNED';
            $iBan = $db->getPdo('insert', $uri);
            $mode = 'INSERT';

Each state/mode was fed to a switch/case statement and rendered the relevant output.

That’s the first rung of the ladder completed, now have to associate a country flag and possibly a Google Map.

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.