How can I password protect a VHost for external viewers? - apache

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

Related

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

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.

Refreshing an Added Alias Directory to Apache's HTTPD

I'm exposing files using Apache's httpd <Directory> as below
Alias /getfiles "/web/playbooks/tmpfiles"
<Directory "/web/playbooks/tmpfiles">
Options Indexes MultiViews
AllowOverride None
Require all granted
</Directory>
With this I'm able to access all files/folder inside /web/playbooks/tmpfiles through web browser URL like the below.
http://<server>:<port>/getfiles/<anyfile.txt>
Is it possible to refresh the above URL so I could see latest changes to files/folder inside /web/playbooks/tmpfiles periodically?
Any solution would be great.
You could try to make the client autorefresh by itself through instructions in the html itself instead of trying to do something weird which is not probably in the http spec. (I might be wrong).
For example, according to your directory entry, load module_autoindex module and then use this config:
<Directory /web/playbooks/tmpfiles>
Options Indexes MultiViews
IndexOptions FancyIndexing
IndexHeadInsert "<meta http-equiv=\"refresh\" content=\"10\">"
AllowOverride None
Require all granted
</Directory>
This way Apache httpd will add that tag in the html and the client will know it has to autorefresh the page each 10 seconds. Generally it is not recommended to set this too low, so perhaps 10 seconds and above is alright for you.

https works after comment out deny from all, but will there be any security problem?

I'm now working on installing certification of our website to https. I've tried for few days until I found one forum which to take note on deny from all which will block the access . So I comment out deny from all and now it works, but will there be any issue on security side? Below are the configuration used, are there any website that I can refer to for related command?
<Directory "${INSTALL_DIR}/www/abc">
SSLOptions +StdEnvVars
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order Deny,Allow
Deny from all
Allow from 127.0.0.1 localhost ::1
</Directory>
The Deny from all directive does exactly what it says it does: it blocks all requests, regardless of their origin. Ironically, the next line permits access if and only if the request originated from the same IP address, so this might be the safest configuration you can have, provided you don't mind having the most useless server of all time.
You only want to use the Deny from all to prevent access to the filesystem, otherwise it blocks all incoming requests, as you noticed. Then you specifically allow access only to the directories where you plan on serving files from, like so:
# Make the server filesystem completely off-limits
<Directory "/">
# Do not permit .htaccess files to override this setting
AllowOverride None
# Deny all requests
Require all denied
</Directory>
<Directory "${INSTALL_DIR}/www/abc">
# If you want directories to be allowed to override settings
AllowOverride All
# Let people actually access the server content
Require all granted
</Directory>
<Files ".ht*">
# Make sure .htaccess file (which contain server configurations and
# settings) are completely off-limits to anyone accessing the server,
# even if they are in a directory that is otherwise accessible.
Require all denied
</Files>
As far as the security of the server is concerned, the best advice I would give you is just make sure sensitive files and passwords are not stored in a directory accessible by the server. Even passwords in php files are not safe, because if a malignant actor is able to disable the php engine somehow, the file will be served in plain-text, with all of the sensitive information right there.
The best method of circumventing this is to create a configuration file outside the server root directory and using a SetEnv directive to define the variable.
SetEnv DATABASE_USERNAME "KobeBryantIsBetterThanJordan24"
SetEnv DATABASE_PASSWORD "LebronJamesIsAlsoPrettyGood107"
Then you can use something like this to get the variables into your php scripts without every exposing the information in plaintext.
$username = filter_input(INPUT_SERVER, 'DATABASE_USERNAME', FILTER_SANITIZE_STRING);
$password = filter_input(INPUT_SERVER, 'DATABASE_PASSWORD', FILTER_SANITIZE_STRING);
define('DATABASE_USERNAME', $username);
define('DATABASE_PASSWORD', $password);
Last but not least, make sure you add phpinfo to the disable_functions setting in your php.ini file, as that would immediately expose the password.

Configuring website to be private and a page public

I'm using Apache in my web server which resides in a public IP. I wan to be able to limit access of this whole site to the local network except for one file.
For example:
<Directory "/var/www/mysite">
Options Indexes MultiViews FollowSymLinks
AllowOverride None
Order Deny,Allow
Deny from all
Allow from 192.168.1.1/24
</Directory>
would limit access to my website only to the people in that IP range. However, the file myfile.html also resides in that directory, and I want it to be visible publicly. Maybe:
<File "/var/www/mysite/myfile.html">
Options Indexes MultiViews FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
</File>
So my questions are: Does the <File> tag go inside the <Directory> tag or somewhere else? Will myfile.html be visible publicly even though it resides in a Directory that is only visible to a range of IPs? Do the configurations above look right? (I'm an apache noob) Is there a better way to this (maybe the firewall)?
Your input is appreciated.

How to protect part of a cakephp website for a stage deployment?

I have a cakephp project consisting of website URLs and a URL for an API, say:
http://myproject.com/controller1/someaction
http://myproject.com/controller2/someotheraction
http://myproject.com/api/controller1/someapiaction
For production deployment, the websites and API both handle authentication & authorization using cakephp's methods.
I would like to deploy the whole project on a staging server. There, the websites should be HTTP Auth protected, whilst the API should be unprotected (because I don't want to add auth to the API consumers). I do not want to change the project's sources or configuration and instead solve it via Apache configuration.
I tried several vhost configurations, basically following this scheme:
<LocationMatch "/api/.*">
Order allow,deny
Allow from all
Satisfy any
</LocationMatch>
<Location />
Order allow,deny
Allow from all
AllowOverride all
AuthType Basic
AuthName "myproject"
AuthUserFile /path/to/.htpasswd
AuthGroupFile /path/to/.htgroup
Require group mytesters
</Location>
I also tried mixing Location & Directory directives, using Location or LocationMatch for both sections, negated regex for LocationMatch, separate vhosts for both sections, ... - none of this worked: Either the whole site was protected, or nothing.
Am I getting something really wrong, or is it just not possible (due to Apache or the the way cakephp handles rewrites)?
Try the following configuration:
<Directory /path/to/your/htdocs>
AuthType Basic
AuthName "myproject"
AuthUserFile /path/to/.htpasswd
AuthGroupFile /path/to/.htgroup
Require valid-user
AllowOverride AuthConfig
</Directory>
<Location "/api">
Satisfy any
</Location>