.htaccess: combine IP block and basic auth - apache

What I want to achieve:
one .htaccess file for production and staging
basic auth protection for staging environment (based on hostname)
block specific IP on both enviroments
What I tried so far:
SetEnvIfNoCase Host development\.foobar\.tld authRequired
<RequireAny>
<RequireAll>
Require all granted
Require not ip 1.2.3.4
</RequireAll>
<RequireAny>
<RequireAll>
Require all granted
Require not env authRequired
</RequireAll>
AuthType Basic
AuthName "Development"
AuthUserFile /path/to/.htpasswd
Require valid-user
</RequireAny>
</RequireAny>
My problem now is that the IP block is ignored. I've no idea how to properly nest the Require directives.

I have similar setup, but I'm not using password based authentication for it. However, I think that this approach should work for you too.
What you need to do is to store the result of the IP check in a variable for later use.
The code below is untested but I think it will work:
SetEnvIf X-Forwarded-For "^1\.2\.3\.4" reject-access
<If "%{HTTP_HOST} =~ /development\.foobar\.tld$/">
AuthType Basic
AuthName "Development"
AuthUserFile /path/to/.htpasswd
<RequireAll>
Require not env reject-access
Require valid-user
</RequireAll>
</If>
<Else>
<RequireAll>
Require not env reject-access
</RequireAll>
</Else>

Related

Apache 2.4 require password on subdomain not seems to be working

My final foal is to as password on every sub domain but not www and local.
I followed the https://httpd.apache.org/docs/trunk/howto/auth.html guide. "Visitors coming from that address will not be able to see the content covered by this directive. If, instead, you have a machine name, rather than an IP address, you can use that."
AuthType Basic
AuthName "Password Required"
<If "req('Host') == 'dev.domain.ee'">
AuthUserFile /path/dev/.htpasswd
</If>
<If "req('Host') == 'test.domain.ee'">
AuthUserFile /path/test/.htpasswd
</If>
<If "req('Host') == 'prelive.domain.ee'">
AuthUserFile /path/prelive/.htpasswd
</If>
<RequireAll>
Require all granted
Require not host dev.domain.ee test.domain.ee prelive.domain.ee
</RequireAll>
Still it does not work by not asking password on dev.domain.ee
I found a solution for my own problem.
<RequireAny>
Require host www.domain.ee
Require local
Require valid-user
</RequireAny>
That telles to require valid user for all other cases except localhost and www.domain.ee

Apache 2.4 mod_authz - RequireAny/All and Require valid-user

I have problem figuring out how create right configuration for apache 2.4 with mod_authz_core specifically with combination of RequireAny/All and Require valid-user.
I need this configuration: web has blocked access from specified countries, but I have list of specific ip address, that have to be whitelisted and have access to web (even from blocked country)
And there is a part of website which require AuthBasic authentication from .htaccess file
First of all, I am trying to migrate old apache configuration from 2.2 to apache 2.4.
Old configuration:
#blocation for specified countries
SetEnvIf GEOIP_COUNTRY_CODE AB BlockCountry
SetEnvIf GEOIP_COUNTRY_CODE AC BlockCountry
SetEnvIf GEOIP_COUNTRY_CODE AD BlockCountry
SetEnvIf GEOIP_COUNTRY_CODE AE BlockCountry
<LocationMatch "/*">
Order deny,allow
deny from .zx
deny from env=BlockCountry
allow from 127.0.0.1
Include "/etc/httpd/conf/permited-xx-ip.include.old"
</LocationMatch>
This work absolutely fine on apache 2.2.
I changed it to this to match new apache 2.4
<LocationMatch "/.*">
<RequireAny>
<RequireAll>
Require all granted
Require not host .xx
Require not env BlockCountry
</RequireAll>
<RequireAny>
Require local
Include "/etc/httpd/conf/permited-xx-ip.include"
</RequireAny>
</RequireAny>
</LocationMatch>
file /etc/httpd/conf/permited-xx-ip.include contains lines:
Require ip x.x.x.x
And this works fine, but problem is when I have directory which has .htaccess with AuthBasic directive, it will not prompt for username/password.
I was checking logs and it seems that the RequireAny/All allow acces without prompting for password.
.htacces file:
AuthName "members"
AuthType Basic
AuthUserFile ./data/.htpasswd
AuthBasicProvider file
Require valid-user
If i comment Require section in apache conf file, it will prompt for user/password.
I also tried old configuration with mod_compat, but the configuration does not work as intended(it will not consider whitelisted ips).
Thanks for reading long post.
Any suggestion ?
I think i figured it out,
The right configuration should look like this:
<Directory /var/www/www-root>
<RequireAny>
<RequireAll>
Require all granted
Require not host .xx
Require not env BlockCountry
</RequireAll>
<RequireAny>
Require local
Include "/etc/httpd/conf/permited-ip.include"
</RequireAny>
</RequireAny>
</Directory>
Plus the configuration for the directory with AuthBasic .htaccess:
<Directory /var/www/www-root/dirwithauthbasic>
<RequireAll>
<RequireAny>
<RequireAll>
Require all granted
Require not host .xx
Require not env BlockCountry
</RequireAll>
<RequireAny>
Require local
Include "/etc/httpd/conf/permited-ip.include"
</RequireAny>
</RequireAny>
Require valid-user
</RequireAll>
</Directory>
sorry for messed format

.htaccess access conditional login based on DOMAIN

I haven't been able to find the right answer for this on StackOverflow, so I figured I would ask and hopefully others are looking for the same:
I am using the same .htacess for local, dev and prod and want to HTTP_AUTH our DEV box. Here is my htaccess:
RewriteEngine On
RewriteBase /
SetEnvIf Host "localenv" SITE_ENV=LOCAL
SetEnvIf Host "devdomain.com" SITE_ENV=DEV
SetEnvIf Host "proddomain.com" SITE_ENV=PROD
Order deny,allow
Satisfy any
Deny from SITE_ENV=DEV
AuthType Basic
AuthName "Access"
AuthUserFile /path/to/.htpasswd
Require valid-user
This works when I'm my local enviornment, but when I switch the Deny from SITE_ENV=DEV to Deny from SITE_ENV=LOCAL I don't get the authentication requirement anymore, which leads me to believe the code isn't working. I also have changed the AuthUserFile path to point to the local .htpasswd - but I figured this would show up in the logs if it couldn't find the .htpasswd file
Any guidance here?
You can use:
SetEnvIf Host "localenv" SITE_ENV=LOCAL
SetEnvIf Host "devdomain.com" SITE_ENV=DEV
SetEnvIf Host "proddomain.com" SITE_ENV=PROD
AuthType Basic
AuthName "Access"
AuthUserFile /path/to/.htpasswd
Require valid-user
Order Allow,Deny
Allow from all
Deny from SITE_ENV=DEV
Satisfy any

Apache 2.4 how to Require valid-user only for specific hosts

I want to tell Apache 2.4.9 to require valid-user if host is dev.example.com or test.example.com. This doesn't work:
AuthType Basic
AuthName "Speak, friend, and enter."
AuthBasicProvider file
AuthUserFile /sites/example/conf/.htpasswd
AuthGroupFile /dev/null
SetEnvIfNoCase Host ^dev\.example\.com$ env_is_protected
SetEnvIfNoCase Host ^test\.example\.com$ env_is_protected
Require valid-user
Require not env env_is_protected
It causes a server error; evidently not env is not valid contrary to the documentation.
In the following examples, the first five lines are always the same as in the first example.
This doesn't work:
SetEnvIfNoCase Host ^dev\.example\.com$ env_is_protected
SetEnvIfNoCase Host ^test\.example\.com$ env_is_protected
<RequireAny>
Require valid-user
<RequireNone>
Require env env_is_protected
</RequireNone>
</RequireAny>
It causes a server error. The documentation explains:
Because negated authorization directives are unable to return a
successful result, they can not significantly influence the result of
<RequireAny> directive. (At most they could cause the directive to
fail in the case where they failed and all other directives returned a
neutral value.) Therefore negated authorization directives are not
permitted within a <RequireAny> directive.
This doesn't work:
SetEnv env_is_unprotected 1
SetEnvIfNoCase Host ^dev\.example\.com$ !env_is_unprotected
SetEnvIfNoCase Host ^test\.example\.com$ !env_is_unprotected
Require valid-user
Require env env_is_unprotected
The documentation explains about SetEnv:
The internal environment variables set by this directive are set after
most early request processing directives are run, such as access
control and URI-to-filename mapping. If the environment variable
you're setting is meant as input into this early phase of processing
such as the RewriteRule directive, you should instead set the
environment variable with SetEnvIf.
This works:
SetEnvIf Host . env_is_unprotected
SetEnvIfNoCase Host ^dev\.example\.com$ !env_is_unprotected
SetEnvIfNoCase Host ^test\.example\.com$ !env_is_unprotected
Require valid-user
Require env env_is_unprotected
This looks like a hack and takes hours to figure out. Have I failed to discover the proper way of accomplishing my very simple purpose? Is there a better way?
This is how I do it.
(Using Cj Case's nice citation as a comment to explain details. :D )
SetEnvIfNoCase HOST ^dev\.example\.com$ env_is_protected
SetEnvIfNoCase HOST ^test\.example\.com$ env_is_protected
<RequireAny>
<RequireAll>
# when the Require directive is negated it can only fail or return a neutral result,
# and therefore may never independently authorize a request
# (reason why we need an additional "all granted" here!)
Require all granted
Require not env env_is_protected
</RequireAll>
AuthType Basic
AuthName "Speak, friend, and enter."
AuthUserFile /sites/example/conf/.htpasswd
Require valid-user
</RequireAny>
You're only able to use the "not" directive on a RequireAll block and not as an authentication directive.
The result of the Require directive may be negated through the use of the not option. As with the other negated authorization directive , when the Require directive is negated it can only fail or return a neutral result, and therefore may never independently authorize a request.
http://httpd.apache.org/docs/2.4/mod/mod_authz_core.html#require
This would probably work:
<Directory /your/protected/directory/>
AuthType Basic
AuthName "Speak, friend, and enter."
AuthBasicProvider file
AuthUserFile /sites/example/conf/.htpasswd
AuthGroupFile /dev/null
SetEnvIfNoCase Host ^dev\.example\.com$ env_is_protected
SetEnvIfNoCase Host ^test\.example\.com$ env_is_protected
<RequireAll>
Require valid-user
Require not env env_is_protected
</RequireAll>
</Directory>

What is apache htaccess configuration to require authentication for all except for these URLs?

What is the htaccess lines/config I would require to ensure that all parts of my site (files & URLs) are protected by authentication, EXCEPT for a given limited set of URLs. For example all except "/api/.*" if this makes sense.
The actually authentication could be like the below, but it's how I wrap this in the directives...
AuthName "Dialog prompt" AuthType
Basic AuthUserFile
/home/site/.htpasswd Require
valid-user
thanks
this seems to work:
AuthUserFile /home/.htpasswd
AuthName "Password Protected"
authtype Basic
Order Deny,Allow
Satisfy any
SetEnvIf request_uri "/api/" allow_all
Deny from all
Require valid-user
Allow from env=allow_all
You could use SetEnvIf and <IfDefine>:
SetEnvIf Request_URI ^/api/ no_auth_req
# If no_auth_req is NOT defined then require authentication
<IfDefine !no_auth_req>
AuthName "Dialog prompt"
AuthType Basic
AuthUserFile /home/site/.htpasswd
Require valid-user
</IfDefine>