Allow access to only login page in directory apache - apache2

I have password protected my webpage in Linux Mint by using mod_auth_form in apache2 with the configuration in /etc/apache2/apache2.conf:
<Directory "/var/www/html">
AuthFormProvider file
AuthType form
AuthName "Reserved Area"
Session On
SessionCookieName session path=/
require valid-user
AuthFormLoginRequiredLocation "http://localhost/login.php"
# This is the login page
ErrorDocument 401 /login.php
# This is the file containing users login data
AuthUserFile /var/www/html/users/users
</Directory>
When an unauthorized user tries to access something on the webpage he will be redirected to the login page "login.php", however he won't have access to this page either so I tried adding:
<Location /var/www/html/login.php>
Order Allow,Deny
Allow from all
</Location>
But the problem remains and it just tries to redirect to the login page infinitely. What would enable a user to access only the login page but not anything else on the site?

I found that if I replaced
<Location /var/www/html/login.php>
Order Allow,Deny
Allow from all
</Location>
with
<Directory /var/www/html/login>
Options Indexes
AllowOverride None
Require all granted
</Directory>
and added a folder /var/www/html/login where I placed everything that had to do with the login page it started working. I never figured out why Location didn't work to give access to the login.php file.
I also removed the line
AuthFormLoginRequiredLocation "http://localhost/login.php
as it wasn't needed.
The line:
ErrorDocument 401 /login.php
was also changed to:
ErrorDocument 401 /login/login.php

Related

Apache2 route to a different folder based on location match

I would like to reroute my apache to a different system folder.
Currently I have this setting
<VirtualHost *:443>
ServerName blaah.com
SSLCertificateFile /etc/ssl/certs/blaah.crt
SSLCertificateKeyFile /etc/ssl/private/blaah.key
SSLCertificateChainFile /etc/ssl/certs/DigiCertCA.crt
DocumentRoot /var/www/blaah
Alias /webalizer /var/www/webalizer
<Directory /var/www/webalizer>
Allow from 192.168.0.0/16
Deny from all
AuthType Basic
AuthName webalizer
AuthUserFile /var/www/webalizer/.htpasswd
Require valid-user
</Directory>
ProxyPass /gogs http://127.0.0.1:3000
<LocationMatch "^/blaah/blaah/">
Deny from all
</LocationMatch>
<LocationMatch "^/maintenance">
Allow from IP
Deny from all
</LocationMatch>
</VirtualHost>
So basically when going to servername blaah.com you get directed to a service.
Now I want to do a maintenance on that service, that means I have to reroute them.
But I want to test out that endpoint, so when you write blaah.com/maintenance (the last Location Match should cover that) you get directed to /var/www/maintenance. That folder holds a single index.html that tells you that an maintenance is underway. How can I accomplish that?
In nginx I would do multiple locations and then change document root and tryfiles.
Figured it out.
Used
Alias /maintenance /var/www/maintenance
<Directory /var/www/maintenance">
Allow from IP
</Directory>

Apache2 WebDAV writable directory in readonly server

To serve files, I set up a readonly WebDAV with Apache2 serving from davs://dav.example.com/. However, I want a subdirectory (davs://dav.example.com/uploads/) that is writable by the logged in user.
To make my site readonly, I used the following:
...
<Directory /var/www/dav>
Options +Indexes
DAV On
Order allow,deny
AuthType Basic
AuthName "Not for public access! Login only"
AuthUserFile /var/www/htpasswd
<Limit GET OPTIONS PROPFIND>
Require valid-user
Deny from all
</Limit>
<Limit PUT POST DELETE PROPPATCH MKCOL COPY MOVE LOCK UNLOCK>
Require host dav.example.com
Deny from all
</Limit>
Satisfy Any
</Directory>
...
I've tried making <Directory /var/www/dav/upload>, copying the <Limit PUT... with Require valid-user in it, but that didn't work. When creating a file in the /upload/ dir, the server responded with a 500 error.
Is this possible? I have access to the site.conf file.
Make a <Directory /var/www/dav/upload> block with this in it:
<LimitExcept GET OPTIONS PROPFIND PUT POST DELETE PROPPATCH MKCOL COPY MOVE LOCK UNLOCK>
Require valid-user
Deny from all
</LimitExcept>
This also works in .htaccess files, if needed.

How to use OIDCUnAuthAction pass in mod_auth_openidc correctly?

I want to use mod_auth_openidc for authentication only, by using what is set in REMOTE_USER.
Currently, I have this:
<Location />
# reverse proxy to app
# authorization not controlled by web server, but by app
Require all granted
</Location>
The user accesses an url hosted by the app that logs them in. When logged in, there's additional info on every page, and access is allowed to some urls that otherwise return 401.
Now I want to add OIDC to this, so I tried adding the following:
OIDCRedirectURI https://<hostname>/oidc/redirect_uri
<Location /oidc>
ProxyPass "!"
AuthType openid-connect
Require valid-user
</Location>
Accessing "/oidc" successfully redirects to the provider, then redirects back to /oidc, which doesn't exist in the app, so apache goes 404.
If I go anywhere else, no REMOTE_USER is set and so the user is not authenticated. (I have a debug-page that dumps headers and environment variables and other sundry for this.)
I found this question: Optional or anonymous authentication with mod_auth_openidc, which mentions OIDCUnAuthAction, but it is unclear how to use it.
If I change the first location-block to:
<Location />
# reverse proxy to app
# authorization not controlled by web server, but by app
Require all granted
OIDCUnAuthAction pass
</Location>
.. then the user is no longer redirected.
If I in addition add OIDCUnAuthAction auth to the second Location-block, the redirect is back and the user is back to being redirected to /oidc and not being authenticated anywhere else.
<Location /oidc>
ProxyPass "!"
AuthType openid-connect
Require valid-user
OIDCUnAuthAction auth
</Location>
If I keep the last version of the /oidc-block and change the first block to
<Location />
# reverse proxy to app
# authorization not controlled by web server, but by app
AuthType openid-connect
Require valid-user
OIDCUnAuthAction pass
</Location>
.. that doesn't change anything.
If I do force login everywhere, with
<Location />
# reverse proxy to app
# authorization not controlled by web server, but by app
AuthType openid-connect
Require valid-user
</Location>
then accessing any page redirects me to the provider, which redirects me to where I came from. On the debug-page I see that there are lots of claims headers, but REMOTE_USER is either not set, or set in such a way that it cannot be dumped (it's not visible to the app), so the user is not authenticated.
If I use OIDCAuthNHeader Foo it turns up together with the other http headers, prefixed with HTTP_, but then the app can't find it since it isn't named REMOTE_USER...
I'm at my wits end. How is this supposed to work? Can it work at all?

mod_auth_openidc error 400 Bad Request - too many cookies (?)

I have a container mapped by Nginx on example.org/portia/test, structured as follow:
Container exposes only port 9001, where an Apache instance as proxy is listening.
A Django server is running on 8000, all traffic for /api and /server_capabilities is sent to him.
Another Django server is running on 9002, which handles websockets on /ws path.
a scheme of my network
I'm trying to add OpenIdConnect authentication using the mod_auth_openidc plugin for Apache, I want to protect the entire virtual host.
So far I reach the correct login page on auth-example.org, I login with my credentials and the auth server redirects me with the correct URI. Ngnix answers me with a 400 error.
request sent with a lot of cookies
The auth server is used by several application inside mydomain.org, so I guess something is wrong with my Apache configuration file.
For clarity's sake, I can't touch Nginx or the auth server confs.
apache_site.conf
<VirtualHost *:9001>
ServerAdmin webmaster#localhost
DocumentRoot /app/portiaui/dist
ServerName www.example.org
ServerAlias example.org
#ProxyRequests On
Alias /static /app/portiaui/dist
OIDCProviderMetadataURL https://www.auth-example.org/auth/realms/master/.wel$
OIDCRedirectURI https://example.org/portia/test/callback
OIDCCryptoPassphrase <much secret>
OIDCClientID portia
OIDCClientSecret <much private>
OIDCCookiePath example.org/portia/test/
OIDCCookieDomain example.org
<Location /static>
Require all granted
</Location>
<Location /api>
Require all granted
ProxyPass http://127.0.0.1:8000/api
ProxyPassReverse http://127.0.0.1:8000/api
ProxyPreserveHost On
</Location>
<Location /server_capabilities>
Require all granted
ProxyPass http://127.0.0.1:8000/server_capabilities
ProxyPassReverse http://127.0.0.1:8000/server_capabilities
ProxyPreserveHost On
</Location>
<Location /ws> # mod_proxy_wstunnel is enabled
RequestHeader set Host "127.0.0.1:9002"
ProxyPreserveHost On
ProxyPass http://127.0.0.1:9002/ws
ProxyPassReverse http://127.0.0.1:9002/ws
</Location>
<Location />
AuthType openid-connect
Require valid-user
</Location>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
The cookie path setting in OIDCCookiePath only needs to contain the actual path, not the host. In fact I'd start without using any of OIDCCookiePath or OIDCCookieDomain.
The answer of Hans Z. suggests me to change also OIDCRedirectURI in a relative path.
Setting OIDCRedirectURI /callbacksolved the issue: my Apache instance doesn't receives the entire URL www.example.org/portia/test/callback but only the last part of the path. This is due to the front side Nginx instance.

How to hide/protect Angular application (equivalent htpasswd)

I tried to protect my application (the test environment) to hide it from curious with a htpasswd. Here is my architecture:
[AngularJS] -> [Apache Proxy] -> [Service]
The aim is to block people who has no password.
I tried first to add a htpasswd on my Apache Proxy at the highest level:
<Location "/">
AuthUserFile /etc/apache2/passwords
AuthName "Forbidden"
AuthType Basic
require valid-user
</Location>
Problem: the prompt was fired at each time a request was made (don't know why).
I tried after to reduce the scope:
<Location "/modules/user/">
AuthUserFile /etc/apache2/passwords
AuthName "Forbidden"
AuthType Basic
require valid-user
</Location>
It works because the call to this route is made at each request. Fine.
But now I created a new route : /modules/user/account. I fell in the first problem I have but worse: a prompt is always displayed, and never accepted. Apache in the logs says:
[Mon Nov 23 11:51:55.510434 2015] [authz_core:debug] [pid 3043:tid 139650316363520] mod_authz_core.c(809): [client 164.177.43.41:55888] AH01626: authorization result of Require valid-user : denied (no authenticated user yet), referer: https://test.mysite.com/
htpasswd is maybe the wrong way to protect my application, what should I do?
Thanks

Resources