Acces Control only works inside <Location> directive, Apache/2.4.6 (CentOS) - apache2.4

There's a server with several instances of Apache running. One instance needs access from anywhere, but only for authorized users. Instance is started up by a systemctl script with the -f option pointing to a config file in /opt/.
Config includes directives from another file in the same folder under /opt/. The relevant part of the included directives looks like the following at the present moment:
"
[...]
<Location "/subfolder">
<RequireAll>
Require all granted
Require valid-user
</RequireAll>
LimitRequestBody <someNumber>
</Location>
[...]
DavLockDB /somepath/webdav/DavLock
Alias /subfolder /mainfolder/subfolder
<Directory /mainfolder/subfolder>
Dav on
AuthType Basic
AuthName "Restricted Files"
AuthUserFile /somepath/webdav/.htpasswd
<RequireAll>
Require all granted
Require valid-user
</RequireAll>
AllowOverride All
SSLRequireSSL
Options FollowSymLinks Indexes
</Directory>
[...]
"
This works so far, it only permits access to folder if you enter your username and password.
Problem is, if I comment out the <Location directive to comply with security recommendations, then access is flat-out denied. There is no way to enter a username and a password, and if I supply them on the command line, they are ignored, while they previously worked with the <Location block intact.
The <RequireAll> block inside the <Directory> directive is completely ineffectual. In fact, if I comment it out there, it changes nothing whatsoever in the behaviour of the httpd instance. It works only when it is placed inside the <Location block. The rest of the <Directory> block on the other hand seems to be working.
Does someone have any tips as to what I may be missing here? Thanks in advance!

H/T to Apache Basic Auth not working in .htaccess or Directory blocks; works fine in Location blocks
The problem was that the configuration file the Apache instance is started up with included one of the system-wide configs in /etc/ with a default location block inside, similar to the following:
<Location />
Require all denied
[...]
</Location>
When I commented out the line Require all denied from here, the access control directives in the <Directory> block started to work as expected.
The explanation of the above is that, unlike "normal" <Location> directives, which "operate completely outside the filesystem", <Location /> refers to the entire server (see the Apache documentation: https://httpd.apache.org/docs/2.4/mod/core.html#location ), so it means pretty much the same as <Directory /> (at least when it comes to its scope), except that it can only be overridden by another <Location> directive.

Related

Apache: how to protect mod_info output

I use Apache's mod_info to display detailed information about my server setup.
httpd-vhosts.conf
# Set path below to be handled by mod_info. It will show server info.
# For this to work, this module must be loaded (uncommented in httpd.conf)
<Location /special/path>
SetHandler server-info
Order allow,deny
Allow from 127.0.0.1
</Location>
Allow from is set to the local machine because this is on my dev machine.
This module allows me to see a tremendous amount of information by navigating to /special/path. I'd like to get the same benefit on my production server, so I can see the output remotely. This means I need to make the path publicly accessible but of course keep that info away from prying eyes.
What's the most practical way to protect that output? I'm ok with a static password challenge so long as the password is not stored in the clear (hashed is ok) and definitely not stored in a publicly accessible location.
Apache 2.4.16
To solve my problem, I used this configuration:
# All paths beginning with /admin will be password protected with
# credentials from /path/admin.htpasswd
<Location /admin>
AuthType Basic
AuthName "Administrators"
AuthBasicProvider file
AuthUserFile "/path/admin.htpasswd"
Require valid-user
</Location>
<IfModule info_module>
<Location /admin/server-info>
SetHandler server-info
</Location>
</IfModule>
The .htpasswd file contains one {username}:{hashed password} per line. Eg:
linda:$apr1$hq20V6OX$uKFyONT91I1BhCae0YJ7B1
eric:$apr1$h4XrUUNS$Hi61JTs1nQOgI/ehMnC0X0
I used the password hash generator from htaccesstools.com

Why does "Require all denied" in apache2.conf apply to all sub-directories?

I'd like to understand this behaviour which does not make sense to me.
apache2.conf has the default configuration at the bottom.
As you can see, it has "Require all denied" for / and "Require all granted" for /var/www/
I have a website under /var/www/HM/
After using URL rewriting, Apache is asked to send the result of for example /var/www/HM/subdir/
Instead of correctly returning the content of index.php located in subdir, it denies access. I found out that the / "Require all denied" config in apache2.conf is to blame, but this does not make sense to me especially as "Require all granted" is given to /var/www/
I have managed to set "Require all granted" for /var/www/HM/ and it seems to work then. But still I'd like to understand why the / directive in apache2.conf applies to everything below and that the /var/www/ directive does not!
Also if the directive for /var/www/ does not apply to sub-directories, I wonder if my directive for /var/www/HM/ will apply to its own sub-directories...
Thanks for your help!
# Sets the default security model of the Apache2 HTTPD server. It does
# not allow access to the root filesystem outside of /usr/share and /var/www.
# The former is used by web applications packaged in Debian,
# the latter may be used for local directories served by the web server. If
# your system is serving content from a sub-directory in /srv you must allow
# access here, or in any related virtual host.
<Directory />
Options FollowSymLinks
AllowOverride All
Require all denied
</Directory>
<Directory /usr/share>
AllowOverride All
Require all granted
</Directory>
<Directory /var/www/>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
The documentation states that the Directory directive includes sub-directories:
Enclose a group of directives that apply only to the named file-system
directory, sub-directories, and their contents.
I skimmed a bit through the apache-httpd code and couldn't find any special handling of the root directory or any other directory. (okay okay, root is special: it's always first in the directory list)
Also: experience tells me that you probably had another Directory directive in another config file that messed up the directory permissions, or a .htaccess in the subdirectory with Deny from all specified.

apache basic auth across multiple virtualhosts

I have a few staging sites as virtual hosts on a server, plus a couple of public-facing virtual host sites. The stating sites are all under a single directory (e.g., /var/www/staging-sites/[site-document-root]).
Up to now I've been configuring HTTP Basic Auth for each virtual host, but it seems like there should be a way to do it once for all of them.
The question "apache global basic auth" indicates that I could place Basic Auth directives in a <Directory /var/www/staging-sites> container in the main apache config file, but doing so doesn't cause the browser to prompt for credentials.
Here's the output of tail -n 7 /etc/apache2/apache2.conf:
<Directory "/var/www/staging-sites/">
AuthType Basic
AuthName "Authentication Required"
AuthBasicProvider file
AuthUserFile /var/www/staging-sites/.htpasswd
Require valid-user
</Directory>
I've verified that /var/www/staging-sites/.htpasswd exists, and that the site foo.mydomain.com uses the Document Root /var/www/staging-sites/foo.
I've restarted apache to ensure the new config gets loaded.
However, when I open http://foo.mydomain.com, the site is displayed without prompting for Basic Auth credentials.
What am I doing wrong?
Solved. The problem was this section in the virtualhost configuration itself:
<Directory /var/www/staging-sites/foo>
Require all granted
</Directory>
Apparently all the virtualhosts were created with an equivalent configuration. As might be expected, Require all granted in the virtualhost config outdoes Require valid-user in the global config.
Removing that line allows the Basic Auth, as configured above, to work properly.
You can also leave Require all granted but add Satisfy all

Apache 2.2 WebDav Anonymous access

I sorta have a HTTP config working for Apache 2.2 that allows WebDav. At least I can use the WinSCP client to attach with the DAV account listed below.
But I also have much older clunkier clients that may only work for anonymous access. And they are not working.
Windows 7 (Map drive), it pops up the credentials but does not log in.
FalconView (probably only understands anonymous login
Any idea what I am doing wrong here with the anon access? I am a novice at HTTPD.conf
(the environment variable ${EGPL_JobsPath} resolves to a windows path:
E.g. F:\Jobs
Alias /jobs ${EGPL_JobsPath}
<IfModule dav_lock_module>
DavLockDB "${EGPL_JobsPath}"
</IfModule>
<Directory "${EGPL_JobsPath}">
Header set Access-Control-Allow-Origin "*"
Dav On
Require valid-user
Options Indexes FollowSymLinks
Order allow,deny
Allow from all
<LimitExcept GET PROPFIND OPTIONS REPORT>
Require user me
</LimitExcept>
AuthType Basic
AuthName DAV
AuthUserFile conf/users.passwords
</Directory>
The only way I could get this to work, is to turn off all Authentication and leave the webdav folder open to the world. I would still like to hear from people with better ideas:
Alias /jobs ${EGPL_JobsPath}
<IfModule dav_lock_module>
DavLockDB "${EGPL_LibrarianPath}"
</IfModule>
<Directory "${EGPL_JobsPath}">
Header set Access-Control-Allow-Origin "*"
Dav On
</Directory>

How can I password protect a VHost for external viewers?

I have been struggling with this problem for some time now. Let me break it down:
We have an apache2 server which hosts most of our company's websites. Each website is a separate vhost. One of this vhosts is used by our internal UI Designer to present his latest drafts and projects to both internal users and 3rd party clients. At the moment, this VHost is password protected from the Vhost configuration file using this directive:
<Directory /var/www/>
Options Indexes FollowSymLinks MultiViews
AllowOverride all
Order allow,deny
Allow from all
AuthUserFile /home/secure/passwords
AuthName "Username and password required"
AuthType Basic
Require valid-user
</Directory>
What I need is to make this website available (so NO password prompt) to our internal users meaning a specific IP range. I have tried to use the Allow from 192.168.xxx.xxx option in the above instruction set. However this is not letting the internal IP through (still asking for a password). So I tried to use our company's external IP address (which you can find on any "what's my IP website"). No luck with that either.
So for my last attempt, I have created a second vhost which obviously uses a different ServerName. Also, in order not to have any conflicts in the configuration file, I have created a symlink to /var/www and called it www2. Therefore, the Directory directive in the second vhost file looks like this:
<Directory /var/www2/>
Options Indexes FollowSymLinks MultiViews
AllowOverride none
Order allow,deny
Allow from all
</Directory>
However the configuration files are clearly conflicting because with the current configuration I get password protection on both hosts. If I disable this in the first Vhost, I lose it on both.
There is no .htaccess file in any of the directories, so there is nothing there to overwrite the configuration. The apache2.conf file has nothing defined related to Auth.
I'm not sure if you require more details, but feel free to ask me anything.
I appreciate the help!
----edit----
I just want to specify that I can't say 100% that my method of doing it is the correct one. Maybe setting up 2 VHosts isn't the solution to my problem. If anyone thinks of a better way of doing it, I'm open to suggestions. Bottom line is that I need one website to be available to internal users and password protected for anyone else.
Cheers!
have you tried to solve this using Satisfy Directive of Apache?
For example:
<Directory /var/www/>
Options Indexes FollowSymLinks MultiViews
AllowOverride all
Order allow,deny
Allow from all
AuthUserFile /home/secure/passwords
AuthName "Username and password required"
AuthType Basic
Require valid-user
Allow from 192.168.1
Satisfy Any
</Directory>
More information can be found here