apache2 : how to allow access from a file - apache

I would like to restrict access to a folder according to some IPs.
I already know how to do that by
<Directory "/path/to/my/directory/">
Order Deny,Allow
Deny from all
Allow from 123.123.123.1 # IP 1
Allow from 123.123.123.2 # IP 2
Allow from 127
</Directory>
As I would like to manage the list of allowed IP differently, I would prefer allow them from a text file where the IPs could be notes like that :
123.123.123.1
123.123.123.2
Does anybody know how to do that ? If that's not possible is there another way to do such thing ?
P.S.: To make everything clear, my final purpose is to grab IPs connected to a local VPN (OpenVPN), complete a file with the IP if not already include and restart apache2 so that it can take account of them. It's a little bit strange but on the same server i have html contents that I wanna be accessed only by vpn users. But even if I pass through the vpn, apache2 see the remote IP address not the endpoint one...

You can't include extra files in the apache config like what you want to do, but you could use mod_rewrite's RewriteMap directive to use a mapping file, or run a script.
For example, you can create the map:
RewriteMap allow_ips txt:/path/to/ipfile.txt
And in the /path/to/ipfile.txt you'd have
123.123.123.1 1
123.123.123.2 1
123.123.123.4 1
123.123.123.10 1
Then in your directory container:
RewriteEngine On
RewriteCond ${allow_ips:%{REMOTE_ADDR}|0} 0
RewriteRule ^ - [L,F]
The mapping is being used in the condition: ${allow_ips:%{REMOTE_ADDR}|0}. if the remote address is in the /path/to/ipfile.txt, then the mapping will return "1", otherwise it returns "0" which would satisfy the condition and the rule will deny access.
Problem with this kind of mapping is that you need to have something other than a "0" at the end of each IP (in order to form a map).
The other option is to write a script and use the prg map type. The script would look up the IP in a different file and return the appropirate "1" or "0". This is a little less lightweight since the script would be run each time as opposed to a cached map file.

Related

use Apache Alias instead of RewriteRule to serve HTML page

A simple Alias in Apache configuration not working -
Alias /url/path/some-deleted-page.html /url/path-modified/new-avatar-of-some-deleted-page.html
It gives "page not found".
However RewriteRule works as expected but it sends redirect status to browser. I want browser/user not to be aware of the redirect. Hence, I want to use Alias instead of RewriteRule. I want to confirm if mod_alias can be used to map individual URL.
I use ProxyPassMatch also which executes all html pages as PHP script. Also adding ProxyPass makes no diffrence.
ProxyPass /url/path/some-deleted-page.html !
Please help so that I can map individual URL (a bunch of them) with Alias instead of RewriteRule.
The purpose of mod_alias is to map requested URLs with a directory on the system running your httpd instance. It does not return anything to the browser (i.e. no redirection code, nothing). It is all done internally. Hence your client does not even know it is there.
Request: http://www.example.com/someurl/index.html
Configuration
[...]
DocumentRoot "/opt/apache/htdocs"
Alias "/someurl/" "/opt/other_path/someurl_files/"
[...]
In this scenario, users asking for any URL besides /someurl/ would receive files from /opt/apache/htdocs.
If a user asks for /someurl/, files from /opt/other_path/someurl_files/ will be used.
Still missing in this example is a <Directory> definition for securing the Alias directory.
You should read: https://httpd.apache.org/docs/2.4/mod/mod_alias.html
Alias will cover the case where you need to point a certain URL to a particular directory on the file system.
If you need to modify the filename (i.e. the client asks for file A, and you send back page B), you should use RewriteRule. And to hide the fact you changed the filename, use the [P] flag.
This directive allows you to use regex, yet still use a proxy mechanism. So your client does know what went on, as the address in his address bar does not change.

Apache 2.4.x ip blacklist

I'm looking for an easy way to blacklist IP addresses in Apache 2.4.x. My web site logs ip addresses that tried illegal operations into a text file. I would like to use this text file within Apache to deny all access to all vhosts to this ip list. What would be the best way (easiest and least resource consuming way) ?
Found this but this is only for 2.2.. Not sure how this applies to 2.4..
Cheers.
edit: this is a windows x64 box running apache x64
#vastlysuperiorman called it right, csf/lfd is the best at this. Unfortunately, they only run on linux.
This free utility promises to provide the same functionality: dynamically monitor access attempts and auto-block IP addresses. You can unblock with a command, in case of false positives. Certainly worth a short.
An alternative could be to create a VM (if your platform supports virtualization) deploy a very small spec linux box, and use that as a proxy. This should be easy to implement. BTW, why not just use linux? .. :-)
(this should have been a comment on #vastlysuperiorman's post, but I don't have enough SO reps to comment on the post of others)
Edited to suggest a possible apache 2.4 based solution:
To translate ACL directives between the 2.2 and 2.4 in apache
2.2 Syntax
order Deny,Allow
include conf/IPList.conf
Allow from all
2.4 Syntax
DocumentRoot /some/local/dir
<Directory /some/local/dir/>
<RequireAll>
Require all granted
Include conf/IPList.conf
</RequireAll>
</Directory>
#this will also work
<Location />
<RequireAll>
Require all granted
Include conf/IPList.conf
</RequireAll>
</Directory>
# conf/IPLIst.com is actually in /etc/apache2/conf/IPList.conf
# (ie, paths are relative to where apache is installed.
# I guess you can also use the full path to the list.
And inside conf/IPList.conf, you will have individual lines with entries like the following
Require not ip 10.10.1.23
Require not ip 192.168.22.199
Require not ip 10.20.70.100
Using mod-rewrite and a list of IPs for banning
For a redirect-to-another-page to work, you need to keep the RewriteRule outside the base URL you are guarding.
For instance, the redirect would not work under a Directory directive on DocumentRoot or a Location directive on '/', because the ban affects the status page we want to display.
So, best to keep this outside a Directory or Location directive, or link to a status page on another unprotected web server.
#Required set of rewrite rules
RewriteEngine on
RewriteMap hosts-deny txt:/etc/apache/banned-hosts
RewriteCond ${hosts-deny:%{REMOTE_ADDR}|NOT-FOUND} !=NOT-FOUND [OR]
RewriteCond ${hosts-deny:%{REMOTE_HOST}|NOT-FOUND} !=NOT-FOUND
RewriteRule ^ /why-am-i-banned.html
## inside our banned hosts file, we have:
## /etc/apache2/banned-hosts (maintain the format .. its not just a plain text file)
##
193.102.180.41 -
192.168.111.45 -
www.example.com -
www.sumwia.net -
# inside our status page, could be html as below or a plain text file with '.txt' extension
#/var/www/html/why-am-i-banned.html
#
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Why is my IP banned?</title>
</head>
<body>
<h2>Why is my IP address banned?</h2>
<p>
To manage spammers and for other security needs, our server automatically blocks
suspicious IP address. If however you reckon your IP address has been blocked
wrongfully, please contact us.
</p>
</body>
</html>
And of course, you can parse your log files and populate conf/IPList.conf or /etc/apache2/banned-hosts as appropriate ..
As a short term solution
An alternative that will allow you to use the 2.2 syntax, is to install mod_access_compat module and continue using your deprecated 2.2 style 'Deny,Allow' directives. But this is only advisable as a short-term solution since that module is just there to aid transition, and would probably go away in future versions of apache 2.4
I too have not seen a good alternative for blocking access dynamically from within Apache itself. There are "hacky" ways: you could set an environment variable to contain a list of IPs and then use the module with ${REMOTE_ADDR} and the env function, but that's a stretch. Details on the Expression Parser
However, I have used several light weight modules that are helpful in protecting your Apache server.
ConfigServer Firewall (CSF/LFD) is a great solution for linux systems. It provides a simple method for managing iptables, and can be set up to do brute force detection and blocking. Info here
EDIT:
Add the following line to /etc/csf/csf.deny to include your custom IP block list:
Include /var/www/example.deny
Alternately, update your script to append IP addresses to csf.deny either directly:
echo $badIP >> /etc/csf/csf.deny
or using the CSF command line option (preferred):
csf -d 10.20.30.40
CSF readme here
mod_security is one of my favorite Apache/nginx modules. It detects dangerous GET and POST requests and blocks access accordingly. When set up properly, it will trigger CSF to block the IP addresses that frequently violate rules. Details here

Apache server directory browsing while there is a website running

Is it possible to browse a directory on an Apache server with a running website?
Example: I have myserver/mydirectory with an index.html and 'test.txt`. Can I list somehow those files assuming browsing is enabled?
there are a couple of things you can try:
in httpd.conf find the line that begins with "DirectoryIndex" and replace it with "DirectoryIndex disabled" this way apache will not server default files like index.html and just list files. however you can explicitly request it if you want.
if default document setting is important to you, you can also configure apache to listen to another port and setup a virtual host on that port and do the same thing with "DirectoryIndex" for virtual host, this way you have two ports , one that serves default documents and one that only list files.
if you want to use only one port for this , you can try no. 2 option and then set a proxy that sends all requests that begin for example with /list/ to the other virtual host, this way you work on one port and if you want list of files instead of writing "/myserver/mydirectory" you request "/list/myserver/mydirectory"
hope it helps.
The DirectoryIndex directive in the Apache configuration tells Apache which index files to look for. Default settings includes index.html, so if you have such a file in your directory, this is the file that Apache will serve if you enter the site without specifying a specific file (this you properly already know, but included for completeness).
To enable directory listing in Apache, have a look at the Options Indexes option. For example in your case (assuming your website is located in /var/www/website:
<Directory /var/www/website/mydirectory>
Options Indexes FollowSymLinks
</Directory>
This will, however, only enable listing of files if Apache do not find an index file. A solution is therefore either to delete (or rename index.html), or to use a website scripting language like PHP to enable directory listing (For this, Google is your friend :-)

Blocking IPs with htaccess and log bloat

I set a 'deny from' in my htaccess to block certain spam bots from parsing my site. While using the code below, I noticed in my log file that I'm getting a lot of 'client denied by server configuration' and it's cluttering up the log files when the bot starts its scan. Any thoughts?
Thanks,
Steve
<Files *>
order allow,deny
allow from all
deny from 123.45.67.8
</Files>
I ended up going with the following:
RewriteCond %{REMOTE_ADDR} 123.4.3.4.5
RewriteRule (.*) - [F,L]
Take a look at the conditional logging here - I think that will provide everything you need:
http://httpd.apache.org/docs/2.2/logs.html
Also - if you can identify that the various bots are always coming from a specific IP address, you can block them in your hosts.allow/deny files VIA IP address or automatically using something like blockhosts or possibly mod_evasive, that way apache will never see the requests to log them.
-sean
UPDATE:
Are you identifying the ip addresses manually then adding them to your htaccess? that sounds painful. If you really want to do it that way I would suggest you block the ip addresses at the firewall with a drop rule OR as above in hosts allow/deny.
SPURIOUS BROKEN RECORD UPDATE:
Take a look at blockhosts, it can block ip addresses based on their 'behavior' & will eliminate the need for you to manually prune them out every day.
You can get the log file to be sent to a program (aka a script).
Perhaps implement a script than just gives a periodic summary?). The rest to log file?

Apache block an ip address from accessing the website

someone trying to access pages like
//mysqladmin//scripts/setup.php
Is it some hack attempt or .. ?
If yes then how i can block its ip from accessing mine website ?
Via htaccess or something else ?
As an update to this old question for those who still land here:
Order Allow Deny are deprecated as of Apache 2.4 and Require should be used.
<RequireAll>
Require all granted
Require not ip 1.2.3.4
</RequireAll>
Ranges, netmasks, etc. can also be specified.
https://httpd.apache.org/docs/2.4/mod/mod_access_compat.html (Deprecated)
https://httpd.apache.org/docs/2.4/mod/mod_authz_core.html#require
To block special IP addresses you can put the following in a .htaccess file located in your directory, you like to restrict:
order allow,deny
deny from 1.2.3.4
allow from all
Where 1.2.3.4 is the IP you like to block.
But note that IP adresses change users and also attackers change IP adresses.
So this will not secure your application and potentially block leagal visitors.
The better solution will be to make sure your script does not accept malicious paths.
Append a base path to the path you get from the user
Make sure the path you get from the user does not contain '../'