Drupal cron.php access control

Hello,

I’m settign an access control for Drupal cron.php that is invoked via
a cron job.

I tried two approaches and both seem to work

  1. Use the Access module and specify the allowed host.

location /cron.php {
deny all;
allow 127.0.0.1;
allow 192.168.1.0/24;
fastcgi_pass 127.0.0.1:9000;
}

  1. Use a conditional.

location /cron.php {
if ($remote_adrr ~* (192.168.1.(1|2)|127.0.0.1)) {
fastcgi_pass 127.0.0.1:9000;
}
return 404;
}

Travelling down the somewhat dubious path of security by obscurity I
find that returning 404 revals less than a 403.

But I’m aware that it’s a pretty scant justification for using a
conditional. In terms of efficiency which approach is preferred?

BTW I tried to use a non-capturing group but if failed. It always
returned the 404. I tried this:

location /cron.php {
if ($remote_adrr ~* (?:192.168.1.(?:1|2)|127.0.0.1)) {
fastcgi_pass 127.0.0.1:9000;
}
return 404;
}

I suppose libpcre3 implements all of PCRE, including non-capturing
groups. Is this a limitation of nginx regex handling? Or I’m I
misundertanding something more fundamental in what nginx conditionals
and regex handling is concerned?

Thank you,
António

Hello!

On Tue, Aug 17, 2010 at 09:08:53PM +0100, António P. P. Almeida wrote:

     deny all;
     allow 127.0.0.1;
     allow 192.168.1.0/24;
     fastcgi_pass 127.0.0.1:9000;               

}

This one will always return 403 due to “deny all” directive listed
first. Order of deny/allow directives is important, first match
wins.

  1. Use a conditional.

location /cron.php {
if ($remote_adrr ~* (192.168.1.(1|2)|127.0.0.1)) {
fastcgi_pass 127.0.0.1:9000;
}
return 404;
}

This one will always return 404 (with s/adrr/addr/ typo fix).
Probably you mean to add “break” inside “if”.

But this isn’t recommended aproach, see here for details:

Travelling down the somewhat dubious path of security by obscurity I
find that returning 404 revals less than a 403.

If you want to return 404 instead of 403 - just use access module
and configure error_page 403 =404 instead. See

http://wiki.nginx.org/NginxHttpCoreModule#error_page

for details.

But I’m aware that it’s a pretty scant justification for using a
conditional. In terms of efficiency which approach is preferred?

Using access module is much better idea from all points of view.

I suppose libpcre3 implements all of PCRE, including non-capturing
groups. Is this a limitation of nginx regex handling? Or I’m I
misundertanding something more fundamental in what nginx conditionals
and regex handling is concerned?

Non-capturing groups work just fine. It’s missed “break” which
causes 404, see above.

Maxim D.

On 18 Ago 2010 00h49 WEST, [email protected] wrote:

Hello Maxim,

Thank you for your reply.

I tried two approaches and both seem to work
This one will always return 403 due to “deny all” directive listed
first. Order of deny/allow directives is important, first match
wins.

It was working because I had created a new git branch and forgot to do
the checkout in the cloned repository in /etc/nginx. My mistake :frowning:

I assumed that nginx would work like Apache minus the order deny,allow
directive. My reasoning was that first I denied access and then nginx
would parse the remaining directives to see if there are any allowed
addresses.

I noticed that at http://wiki.nginx.org/NginxHttpAccessModule

In fact the order is always allow deny all;

But I’m conditioned by the way Apache access directives work and
assumed it was +/- less the same minus the order directive.

I misunderstood the docs in the wiki. I just edited it trying to make
things more explicit. Lowering the probabilty for this type of mistake
to occur to someone else.

http://wiki.nginx.org/NginxHttpAccessModule#Synopsis

Probably you mean to add “break” inside “if”.
Yes it’s a typo. I just wrote instead of cutting & pasting.

But this isn’t recommended aproach, see here for details:

If is Evil… when used in location context | NGINX

Yes I did that. Thank you. Currently:

Restrict cron access to a specific host.

location /cron.php {
allow 127.0.0.1;
allow 192.168.1.0/24;
error_page 403 =404;
fastcgi_pass 127.0.0.1:9000;
deny all;
}

Working fine.

Non-capturing groups work just fine. It’s missed “break” which
causes 404, see above.

Yes I have it in other lcations and it’s working fine. It was the
missing break. Anyway I dropped the if and followed your suggestion of
employing access rules.

Maxim D.

— appa