Require a password for everything except one folder?

I’m trying to deny access to all locations on the server, unless the
user
has a specific IP address or enteres a password. This part is working.
I’m
also trying to add an exception, where any path starting with /Public is
allowed by anyone with no password. I’ve tried to override it in a
location
block, but this doesn’t seem to have any effect.

server {

satisfy any;
allow xx.xxx.xxx.xxx;
deny all;
auth_basic “Restricted”;
auth_basic_user_file /x/y/z;

location ~* ^/Public {
satisfy any;
allow all;
}

location / {
try_files fake.html @apache;
}

}

I’ve also tried nesting like:

location / {
location ~* ^/Public {
satisfy any;
allow all;
}
try_files fake.html @apache;
}

But it always requires a password, even on Public. How can I override
security on just the one folder?

Posted at Nginx Forum:

Am 06.11.2014 02:46 schrieb nrahl:

I’m
also trying to add an exception, where any path starting with /Public
is
allowed by anyone with no password.

location ~* ^/Public {
satisfy any;
allow all;
}

location /Public { auth_basic off; }

location /Public { auth_basic off; }

This prevents the password prompt from appearing on /Public, but results
in
an immediate 403 Forbidden error on that location.

I’ve also tried:

location /Public { auth_basic off; allow all; }

But adding “allow all” causes the password prompt to appear on that
location
again.

Posted at Nginx Forum:

Are you sure that the test url that you are requesting matches this
location?

There may be more useful information in the debug log regarding what
is going wrong for you.

With debug logging on, I ahve confirmed it is matching the correct
location.

With:

location ^~ /Public {
satisfy any;
allow all;
auth_basic off;
try_files fake.html @apache;
}

It matched the /Public location and I get: “no user/password was
provided
for basic authentication” durring the access phase.

With:

location ^~ /Public {
auth_basic off;
try_files fake.html @apache;
}

It matches the Public location, and produces:
access phase: 9
post access phase: 10
access forbidden by rule, client: xxx.xxx.xxx.xxx, server:
www.myserver.com,
request: “GET /Public/ HTTP/1.1”, host: “www.myserver.com”.

Then it returns a 403 without a basic auth prompt. So It looks like the
rule
is ovverriding the basic auth prompt, but not the deny rule?

Posted at Nginx Forum:

On Thu, Nov 06, 2014 at 09:51:12AM -0500, nrahl wrote:

Hi there,

I’ve also tried:

location /Public { auth_basic off; allow all; }

But adding “allow all” causes the password prompt to appear on that location
again.

location ^~ /public {
auth_basic off;
allow all;
}

seems to work for me.

Are you sure that the test url that you are requesting matches this
location?

There may be more useful information in the debug log regarding what is
going wrong for you.

f

Francis D. [email protected]

On Thu, Nov 06, 2014 at 04:47:28PM -0500, nrahl wrote:

Hi there,

With debug logging on, I ahve confirmed it is matching the correct location.

Do you also see the subrequest that accesses a different location that
has its own configration?

for basic authentication" durring the access phase.
Is that only if the file fake.html does not exist, so there is a new
request to the location @apache which does require authentication?

Or do you get unexpected output when the request is only handled in
this location?

With:

location ^~ /Public {
auth_basic off;
try_files fake.html @apache;
}

access forbidden by rule, client: xxx.xxx.xxx.xxx, server: www.myserver.com,
request: “GET /Public/ HTTP/1.1”, host: “www.myserver.com”.

You have denied access by ip address here, so 403 is the expected
response, no?

You may have more success if you can describe what response you expect,
and provide a complete (small) server{} configuration that demonstrates
the unwanted behaviour that you see.

f

Francis D. [email protected]

You have denied access by ip address here, so 403 is the expected
response, no?

You may have more success if you can describe what response you
expect,
and provide a complete (small) server{} configuration that
demonstrates
the unwanted behaviour that you see.

The expected response is a password prompt on all locations, unless the
IP
matches, in which case allow, or the path starts with /Public, in which
case
allow.

Here’s the whole config, it’s not that long:

server {
listen 443 ssl;

root /path/to/www;
index index.html index.php;
server_name www.myserver.com myserver.com;

error_log /var/log/nginx/debug.log debug;

Password Protect Everything

satisfy any;
allow xxx.xxx.xxx.xxx; # Our IP
deny all;
auth_basic “Restricted”;
auth_basic_user_file /path/to/pw/file;

… ssl_certificate …

error_page 404 /Errors/404.html;

If request is for the homepage, skip all rules and just serve it.

location = / {
try_files /cache/index.html @apache;
}

location ~* ^/(blog|about)/(.).(css|js|gif|jpe?g|png|pdf|htm?l)$ {
rewrite ^/(blog|about)/(.
).(css|js|gif|jpe?g|png|pdf|htm?l)$
/wordpress/$2.$3 last;
}

Static CSS, JS and Image Files

location ~* .(css|js|gif|jpe?g|png|pdf|htm?l)$ {
expires 168h;
add_header Pragma public;
add_header Cache-Control “public, must-revalidate,
proxy-revalidate”;
try_files $uri $uri/ =404;
}

location ^~ /Public { # Disable access restriction on this location
auth_basic off;
try_files fake.html @apache;
}

location / { # All other requests get proxy passed to apache.
try_files fake.html @apache;
}

Proxy Pass

location @apache {
proxy_max_temp_file_size 0;
proxy_buffering off;
proxy_set_header X-Forwarded-Protocol $scheme;
proxy_intercept_errors on;
proxy_read_timeout 500;
proxy_connect_timeout 500;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8080;
}
}

Posted at Nginx Forum:

On Thu, Nov 06, 2014 at 05:35:09PM -0500, nrahl wrote:

Hi there,

The expected response is a password prompt on all locations, unless the IP
matches, in which case allow, or the path starts with /Public, in which case
allow.

nginx config is based on “one request is handled in one location”;
but one http request is not necessarily just one nginx request.

I suspect that if you put the configuration that you want, in the
location
that you want, things will Just Work. Trying to have one location both
require and not require a password, is probably the root of the issue.

location ^~ /Public { # Disable access restriction on this location
auth_basic off;

(You will want to disable “deny all” or “satisfy any” here too.)

  try_files fake.html @apache;

Instead of that try_files, can you just “proxy_pass” directly?

Either copy-paste the config ending with

   proxy_pass http://127.0.0.1:8080;

or do “include the-proxy-pass-file;”?

}

location / { # All other requests get proxy passed to apache.
try_files fake.html @apache;

Same there, but that one is not directly influenced by the “satisfy
any” thing.

Good luck with it,

f

Francis D. [email protected]

Thanks, I got it working. My goal was to avoid repeating both the proxy
config and the password blocks, but I was able to make them inlcudes to
avoid a bunch of duplicate lines.

Thanks again!

Posted at Nginx Forum: