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
Related
I've trying to deploy my website on Heroku, the implementation that i used for this it's Model View Controller with PHP. I don't know what happend but when i try to access to the main page (or index) this works perfectly, when i'm trying to access other pages on mi website something occurs like this:
enter image description here
I know one reason which this is happening, i used in my Router the next:
$currentURL = $_SERVER['PATH_INFO'] ?? '/';
//var_dump($_SERVER);
$method = $_SERVER['REQUEST_METHOD'];
if($method === 'GET'){
$fn = $this->routesGET[$currentURL] ?? null;
} else{
$fn = $this->routesPOST[$currentURL] ?? null;
}
So, i displayed global variable of PHP $_SERVER on my website and i noticed $_SERVER['PATH_INFO'] doesn't appear on it. So, i guess that the problem comes from Apache's configuration because i use Apache2 and PHP for this. So, i don't know how configure because it's my first time doing this, if you can help me, i'll really thank to you.
Here is my directory:
enter image description here
And, finally my procfile:
web: vendor/bin/heroku-php-apache2 public/
These are the general appliable steps of configuring an MVC-based web application. Presumed web server version for the settings below: Apache HTTP Server v2.4.
1) Block access to all directories and files:
First of all, in the config file of Apache, the access to all directories and files should be blocked by default:
# Do not allow access to the root filesystem.
<Directory />
Options FollowSymLinks
AllowOverride None
Require all denied
</Directory>
# Prevent .htaccess and .htpasswd files from being viewed by Web clients.
<FilesMatch "^\.ht">
Require all denied
</FilesMatch>
2) Allow access to a default directory:
The access to a default directory (here /var/www/), supposedly used for projects, should then be allowed:
<Directory /var/www/>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
My recommendation: For security reasons, this location should contain only a index.php and a index.html file, each of them displaying a simple "Hello" message. All web projects should be created in other directories and the access to them should be set separately, as described below.
3) Set access to a separate project directory:
Let's suppose that you create your project in another location (like in the directory /path/to/my/sample/mvc/) than the default one (/var/www/). Then, taking into consideration, that only the subfolder public should be accessible from outside, create a web server configuration for it, like this:
ServerName www.my-sample-mvc.com
DocumentRoot "/path/to/my/sample/mvc/public"
<Directory "/path/to/my/sample/mvc/public">
Require all granted
# When Options is set to "off", then the RewriteRule directive is forbidden!
Options FollowSymLinks
# Activate rewriting engine.
RewriteEngine On
# Allow pin-pointing to index.php using RewriteRule.
RewriteBase /
# Rewrite url only if no physical folder name is given in url.
RewriteCond %{REQUEST_FILENAME} !-d
# Rewrite url only if no physical file name is given in url.
RewriteCond %{REQUEST_FILENAME} !-f
# Parse the request through index.php.
RewriteRule ^(.*)$ index.php [QSA,L]
</Directory>
Note that the above settings can be defined either:
in the config file of Apache, or
in a .htaccess file inside the project, or
in a virtual host definition file.
In case a virtual host definition file is used, the settings must be included between the tags <VirtualHost> and </VirtualHost>:
<VirtualHost *:80>
... here come the settings ...
</VirtualHost>
Note: Don't forget to restart the web server after each change of the configuration settings.
Some resources:
What is Options +FollowSymLinks? (1)
What is Options +FollowSymLinks? (2)
RewriteRule Flags
Exposed folders in MVC application
mod_rewrite: what does this RewriteRule do?
I need to direct my domain www.abc.com to www.xyz.com/folder/form/ and pass parameters to the form, but I need to mask the path so that when users go to www.xyz.com that's all they see along with any passed parameters in the url. Is the possible? How can I achieve this?
I do not own both domains. I own www.abc.com and the folder in www.xyz.com, but not the naked domain. The domains are on different servers.
I have tried the solution setting the DNS to *.abc.com and the CNAME to www and www.xyz.com. But, CNAME's do not allow pointing to a path. If I do a 301 or 302 forward the domain is not masked. What else can I do. I've been pouring over this for days.
Few ways to achieve url masking without using DNS setting.
On server level: Setting up reverse proxy.
If you are using apache, you can use the module named mod_proxy.
Once you have enabled the module, Add following to your .htaccess which is in your abc domain root.
ProxyRequests Off
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass / http://www.example.com/folder/form/
ProxyPassReverse / http://www.example.com/folder/form/
Another way to achieve similar result would be, as follows which does pretty much same thing under the hood.
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^(www\.)?abc\.com$ [NC]
RewriteRule ^ http://www.example.com/folder/form/%{REQUEST_URI} [L,P]
On language level: Using a scripting language like php and then pipe the data to and fro via. the second domain using curl. Kinda mix of 'man in the middle attack" and "phishing". But most importantly, it's pretty much possible.
Then we have other run of the mill solutions like using <iframe>. etc.
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
Please can you tell me in Apache2 how I can restrict a url to my IP address when the url is generated as a script. For example:
example.com/?admin
I have tried Location Match but no joy:
<LocationMatch /?admin>
Order Deny,Allow
Allow from [MY IP]
Deny from all
</LocationMatch>
You could use mod_rewrite to match the %{QUERY_STRING} and disallow anything that's not empty, unless it's from your IP. Check the wiki for examples.
How to allow access to file only to users with ip which are in a range of ip addresses?
For example file admin.php. and range from 0.0.0.0 to 1.2.3.4.
I need configure access to only ONE file not to directory.
Just add a FilesMatch or Files directive to limit it to a specific script.
The following would block acces to all scripts ending in "admin.php" :
<FilesMatch "admin\.php$">
Order deny,allow
Deny from all
Allow from 10.0.0.0/24
</FilesMatch>
The following would ONLY block admin.php :
<Files "admin.php">
Order deny,allow
Deny from all
Allow from 10.0.0.0/24
</Files>
For more information refer to the apache docs on Configuration Sections.
check the man page of the Allow Directive
Order Deny,Allow
Deny from all
Allow from 10.1.0.0/255.255.0.0
A partial IP address
Example:
Allow from 10.1
Allow from 10 172.20 192.168.2
The first 1 to 3 bytes of an IP address, for subnet restriction.
A network/netmask pair
Example:
Allow from 10.1.0.0/255.255.0.0
A network a.b.c.d, and a netmask w.x.y.z. For more fine-grained subnet restriction.
A network/nnn CIDR specification
Example:
Allow from 10.1.0.0/16
Similar to the previous case, except the netmask consists of nnn high-order 1 bits.
You cannot match an IP range with allow, but you can emulate it with a CIDR notation:
Order allow,deny
# 0.0.0.0 - 0.255.255.255.255
Allow from 0.0.0.0/8
# 1.0.0.0 - 1.1.255.255
Allow from 1.0.0.0/15
# 1.2.0.0 - 1.2.1.255
Allow from 1.2.0.0/23
# 1.2.2.0 - 1.2.2.255
Allow from 1.2.2.0/24
# 1.2.3.0 - 1.2.3.3
Allow from 1.2.3.0/30
# 1.2.3.4
Allow from 1.2.3.4
Just do this for a single IP:
<Limit GET POST>
order deny,allow
deny from all
allow from 1.2.3.4
</Limit>
If you want to do it for a range like 10.x.x.x, then do this:
<Limit GET POST>
order allow,deny
allow from 10
deny from all
</LIMIT>
If you are using WordPress, then the Best and Simplest method is to install the plugin - LionScripts : WordPress IP Blocker from their website http://www.lionscripts.com/ip-address-blocker
Their Professional version has much more features like country blocking and IP range blocking, bulk csv uploading etc.
if you to provide a wildcard 0.0.255.255
Order allow,deny
# 1.2.0.0 - 1.2.255.255
Allow from 1.2.0.0/16
This will give a range from 1.2.0.1 - 1.2.255.254
you can also check here
I wanted to redirect all but cetain Ip's to a maintenance page - our IPs all on same network - The following worked based on shamitomar's answer above :
# TEMP MAINTENANCE PAGE
# MAINTENANCE-PAGE REDIRECT
<IfModule mod_rewrite.c>
RewriteEngine on
# One address that is on a diffrent network
RewriteCond %{REMOTE_ADDR} !^xxx\.xxx\.xxx\.xxx
#allow all addresses from our network
RewriteCond %{REMOTE_ADDR} !^xx\.xxx
#Stuff to allow so that we can show our maintenance page while we work
RewriteCond %{REQUEST_FILENAME} !(styles|images).+$
RewriteCond %{REQUEST_URI} !maintenance.html$ [NC]
RewriteCond %{REQUEST_URI} !\.(jpe?g?|png|gif|js|css|ttf|woff) [NC]
RewriteRule .* /maintenance.html [R=302,L]
</IfModule>
Order Deny,Allow
Deny from all
Allow from 311.311.311 322.322.322.322
See answer here