.htaccess basic auth combined with ip restriction - php

I would like to block a path from my site using the .htaccess configuration. The idea is that only a specific set of IP's can access that specific path from the URL after they authenticated using basic auth.
Note: It's a path, not a page or directory. We are trying to shield off a web-service so there will be only post calls to the URL's.
I would like the url example.com/rest to be blocked and everything behind that url based on IP. So example.com/rest/foo and example.com/rest/foo/bar should be blocked.
All other paths from the application should remain functional and without basic auth.
The IP blocking part has been resolved in a previous question I asked.
The basic configuration (the blocking part, there is more in the .htaccess but is not relevant to this question.) you can find below.
SetEnvIf Request_URI "/rest(/.*)?$" rest_uri
# Check on what subdomain we are.
SetEnvIf Host ^local\. None_Prod_Env
# Static
SetEnvIf AH_CLIENT_IP ^123\.123\.123\.123$ Allow_Host
# Range
SetEnvIf AH_CLIENT_IP ^123\.123\.123\. Allow_Host
Order deny,allow
Deny from all
Allow from env=!rest_uri
Allow from env=Allow_Host
Allow from env=None_Prod_Env
So the configuration above blocks all access to /rest/* but not to non rest paths, it allows a user coming from IP X (Allow_Host variable) and we allow none production environments in this case local.
I tried to extend this functionality with basic auth like so:
SetEnvIf Request_URI "/rest(/.*)?$" rest_uri
SetEnvIfNoCase Request_URI "/rest(/.*)?$" require_auth=true
# ... Allow Host stuff and none prod stuff ...
Order deny,allow
Deny from all
Allow from env=!rest_uri
Allow from env=Allow_Host
Allow from env=None_Prod_Env
AuthName "Password Protected"
AuthType Basic
AuthBasicProvider file
AuthUserFile /var/www/html/.htpasswd
Require valid-user
However this resulted in a basic auth on all pages and not only for the /rest/* url. I played a lot with it but couldn't figure it out. Changing SetEnvIfNoCase to SetEnvIf also didn't help.
Note: Our server is running apache 2.2.22.

You can solve this complex problem using a combination of few Apache directives i.e. mod_dir, mod_setenv and mod_auth_basic:
SetEnvIf Request_URI ^/rest(/.*)?$ rest_uri
# Check on what subdomain we are.
SetEnvIf Host ^local None_Prod_Env
# Static
SetEnvIf AH_CLIENT_IP ^123\.123\.123\.123$ Allow_Host
# Range
SetEnvIf AH_CLIENT_IP ^192\.168\. Allow_Host
RewriteEngine On
# block if request is /rest/* and IP is not whitelisted and not localhost
RewriteCond %{ENV:rest_uri} =1
RewriteCond %{ENV:None_Prod_Env} !=1
RewriteCond %{ENV:Allow_Host} !=1
RewriteRule ^ - [F]
# ask auth for /rest/* && NOT localhost && whitelist IP
AuthType Basic
AuthName "Password Protected"
AuthUserFile /var/www/html/.htpasswd
Require valid-user
Order deny,allow
Deny from all
Allow from env=!rest_uri
Allow from env=!Allow_Host
Allow from env=None_Prod_Env
Satisfy any

Try and add satisfy any to your code. Give it a try this way.
SetEnvIf Request_URI "/rest(/.*)?$" rest_uri
SetEnvIf Referer "^http://local\.example\.com/" None_Prod_Env
AuthName "Password Protected"
AuthType Basic
AuthBasicProvider file
AuthUserFile /var/www/html/.htpasswd
Require valid-user
Order deny,allow
Deny from all
Allow from env=!rest_uri
Allow from env=Allow_Host
Allow from env=None_Prod_Env
Satisfy any

Related

How to password protect index.php and /, but allow access to all other files and subdirectories.

My question is very similar to this one:
getting "authentication required" when requesting / instead of /index.php
However, in the question above, the goal is to allow access to only the root URL or index.php and to password protect access to all other files and subdirectories.
An excellent answer was given:
SetEnvIf Request_URI "^/$" allow=yes
SetEnvIf Request_URI "^/index.php$" allow=yes
AuthType Basic
AuthName "Password Required"
AuthUserFile /var/www/webinterface/.htpasswd
Options +FollowSymLinks
Order Deny,Allow
Satisfy any
Deny from All
Require valid-user
Allow from env=allow
My question is the reverse: I only want to password protect the root URL of the directory or the index.php file, and to allow free access to all other files in the directory. When I used <FilesMatch "index.php"> I succeeded in protecting the index file, but the root url allowed access.
I'm sure the answer is basically obvious to those of you who are more familiar with htaccess than I am. How do I password protect only index.php and the root url? Thank you.
Use it like this:
SetEnvIfNoCase Request_URI "^/(index\.php)?$" PROTECT
AuthType Basic
AuthName "Password Required"
AuthUserFile /var/www/webinterface/.htpasswd
Require valid-user
Satisfy any
Order Allow,Deny
Allow from All
Deny from env=PROTECT
Regex pattern ^/(index\.php)?$ will match / or /index.php and it sets env variable PROTECT
Allow from All allows all the URIs
Deny from env=PROTECT denies env variable PROTECT
Not sure if this is what you really want, but what about the options -Indexes, used like this?
<Directory /www/somefolder>
Options -Indexes FollowSymLinks
AllowOverride None
</Directory>

.htaccess to deny directory access

I am trying to restrict access to directories in my root so that others cannot access the files in those dir directly in a browser. Problem I am running into is now the pages in the root for example the index.php is asking for a password and the .htaccess is in the root of the directories and not the root of the domain. This is preventing the index file from accessing include files from those directories.
What is a simple way to lock down those directories from browser access while still allowing the files in the root to access them and vistors being able to access the root pages without being asked for a password. I would like to to be as far as they know they site is viewable but, if someone starts prying around in the sub directories to steal code it will deny them but, allow the pages to access them.
I have tired this in each of the directories I have been wanting to restrict direct browser access to.
AuthType Basic
AuthName "Administrator"
AuthUserFile /home2/mesquiu0/.htpasswds./htpasswd
Require valid-user
Order Deny,Allow
Deny From All
Allow From 127.0.0.1
All you need to do is add the following line with an extra empty line to disable indexing the directories:
Options -Indexes
See Documentation for more info: http://httpd.apache.org/docs/current/mod/core.html#options
In your .htaccess file put the following line
Deny from all
And this if you like to put exceptions.
allow from all
Just allow the scripts that match php, aspx, etc.
apache 2.2
AuthType Basic
AuthName "Administrator"
AuthUserFile /home2/mesquiu0/.htpasswds./htpasswd
Require valid-user
#Forbid access to any files except from localhost, because of Order Deny,Allow, Allow gets applied later.
Order Deny,Allow
Deny from all
Allow from 127.0.0.1
#Allow access to files matching index.php
<Files index.php>
Order Allow,Deny
Allow from all
</Files>
In Apache 2.4 the rules has changed, and the correct syntax is to use Require all denied instead of Deny from all.
This is for apache 2.4
AuthType Basic
AuthName "Administrator"
AuthUserFile /home2/mesquiu0/.htpasswds./htpasswd
Require valid-user
Require host 127.0.0.1
#Allow access to files matching index.php
<Files index.php>
Require all granted
</Files>

.htaccess path only accessible by ip

I would like to block a path from my site using the .htaccess configuration. The idea is that only a specific set of IP's can access that specific path from the URL.
Note: It's a path, not a page or directory. We are trying to shield off a web-service so there will be only post calls to the URL's.
I would like the url example.com/rest to be blocked and everything behind that url based on IP. So example.com/rest/test_service and example.com/rest/test_service/read should be blocked.
All other paths from the application should remain functional.
What I've tried the following but it doesn't seem to work. Not a single page is accessible like this.
SetEnvIf Request_URI "/rest$" rest_uri
<RequireAll>
Require env rest_uri
<RequireAny>
Require ip XXX.XXX.XXX.XXX
</RequireAny>
</RequireAll>
I've tried different things but none of them seem to work. Any help is appreciated.
You can use mod rewrite to allow a spacific ip address
RewriteEngine on
RewriteCond %{REMOTE_ADDR} !YourIP$
RewriteRule ^/?rest - [F]
This will return 403 forbidden error for all other ip addresses if /rest or /rest/foobar is accessed.
You can use directives like this to allow an IP range for certain URL:
# set env variable if URL is /rest or /rest/
SetEnvIf Request_URI "/rest(/.*)?$" rest_uri
Order deny,allow
# first deny all
Deny from all
# then allow if env var is not set
Allow from env=!rest_uri
# also allow your IP range
Allow from 10.1.0.0/16

Deny all IPs except 1 and require login for others

I have a server which I would like only accessible via my IP address AND require authentication (either HTTP or PHP) for any users outside the IP address.
My current .htaccess file looks like this:
order deny,allow
deny from all
allow from 12.345.67.78
Any ideas on how to require some sort of authentication for users outside of home IP?
You can use mod_setenvif in conjunction with mod_auth.
SetEnvIf Remote_Addr ^12\.345\.67\.78$ ALLOWED
AuthType Basic
AuthName "My Protected Area"
AuthUserFile /full/path/to/passwords
Require valid-user
Satisfy any
Order deny,allow
Deny from all
Allow from env=ALLOWED

3 htaccess protection rules on 3 different environments

I need to protect different par of my website depending on the environment I'm working on.
I have three different environments:
localhost : protect nothing
www.test.example.com : protect the whole website (it's a test website so I don't want it to be accessible)
www.example.com : protect only /admin url (the live website, only /admin is protected)
For now, I use different htaccess files.
For test.example.com, I add:
AuthUserFile mypasswordfile
AuthType Basic
AuthName "Enter password"
require valid-user
For example.com, I add:
SetEnvIf Request_URI /admin/? auth=1
AuthUserFile mypasswordfile
AuthType Basic
AuthName "Enter a password"
Order Deny,Allow
Deny from all
Allow from env=!auth
Require valid-user
Satisfy any
Is there a way to use only one htacess with condition to have something like
if(localhost) { do nothing }
if(test.example.com) { require valid user on all domain }
if(example.com) { require valid user only on /admin}
You can use this combined .htaccess:
# require valid user only on /admin
SetEnvIf Request_URI ^/admin(/|$) auth=1
# if(test.example.com) { require valid user on all domain }
SetEnvIf Host ^test\.example\.com$ auth=1
# if(localhost) { do nothing }
SetEnvIf Host ^localhost$ !auth
AuthUserFile mypasswordfile
AuthType Basic
AuthName "Enter a password"
Order Deny,Allow
Deny from all
Allow from env=!auth
Require valid-user
Satisfy any
You could use version control, for example Mercurial (hg) and add those files to ignore list. This way the .htaccess files will not be overwritten when pushing changes.
If you're running Apache 2.4+ it has an <If .. > Directive you can use : http://httpd.apache.org/docs/2.4/mod/core.html#if
So you could read the Apache SERVER_NAME and apply conditions accordingly inside your .htaccess file.
<If "%{SERVER_NAME} =~ /^test\.example\.com/">
** require valid user on entire domain **
</If>
<ElseIf "%{SERVER_NAME} =~ /^example\.com/">
** require valid user only on /admin **
</ElseIf>
You could leave it as that or add in a specific <ElseIf> for 'localhost' with a final <Else> containing 'Deny from all' or similar - just to make sure you don't leave it open if you upload onto another development environment.
Note: you could also use SERVER_ADDR instead of SERVER_NAME and identify the server by IP address - which might be more reliable.

Categories