Re: How to configure tri-state Allow/Deny-from + HTTP Basic Auth combo?

Yehuda Katz <[email protected]> Tue, 16 Dec 2025 10:29:26 -0500
Newsgroups gmane.comp.apache.user
Message-ID <CAGBAQ47cSx04a+WLioxoUzDr2VAaagrKOVgOq6hkHEsR30FHaw@mail.gmail.com>
--000000000000ba3e1f0646136549
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

This is doable with the new auth syntax.

For example:

<RequireAll>
    # Clients in these IP ranges are blocked
    Require not ip 10.83.2.0/24
    Require not ip 10.83.3.0/24
    <RequireAny>
        <RequireAny>
            # Clients in these IP ranges are allowed
             Require ip 127.0.0.1
            Require ip 10.83.0.0/24
        </RequireAny>

        # All others must authenticate
       <RequireAll>
            Require valid-user
            AuthType Basic
            AuthName Login
            AuthBasicProvider file
            AuthUserFile "/var/www/private/.htpasswd"
        </RequireAll>
    </RequireAny>
</RequireAll>

Tested on my computer.

- Y

On Tue, Dec 16, 2025 at 5:32=E2=80=AFAM Nutchanon Wetchasit <xwindows@xwind=
ows.in.th>
wrote:

> Hello folks,
>
> I'm using shared hosting based on Apache 2.4, and I have been using
> the old-school `mod_access_compat` access-control directives
> `Allow from` and `Deny from` for some years now; they work okay
> and are straighforward to read and understand.
>
> However, I found that when I used these in combination with
> HTTP Basic Authentication, even under the control of `Satisfy` directive,
> only allowed a 2 states of entry allowance in `Satisfy` configuration:
>
> - `Satisfy any`:  let in if allowed, authenticate if denied
> - `Satisfy both`: authenticate if allowed, reject if denied
>
> I'm currently using the latter style in some part of my site
> (with `Order Allow,Deny` precedence); but it is not ideal,
> because I actually would like to *also* let requests
> from whitelisted locations to also bypass the "authentication" [1]
> entirely,
> which would make the check tri-state:
>
> A. If `Allow from` (or its newer equivalent) matches the request,
>    bypass the HTTP Basic authentication and allow the request in.
>
> B. If `Deny from` (or its newer equivalent) matches the request,
>    fail the request with 403 response, *without* ever allowing it
>    to authenicate to bypass this restriction.
>
> C. If neither matched, then present a 401 response requesting credential
>    for HTTP Basic authentication.
>
> I have read relevant parts of 2.4's `mod_access_compat` documentation [2]
> several times, and I couldn't find a way to configure tri-state
> access control in the manner I described above.
>
> So I would like to ask: how to configure Apache HTTPd 2.4
> to do this kind of tri-state access control based on remote IP address
> and HTTP Basic Authentication (using old-style `Allow from`/`Deny from`
> or newer `Require` notwithstanding)?
>
> Or is this being impossible and I'd have to resort to roll-my-own
> last-ditch option in order to do so? [3]
>
> Thanks in advance,
> Nutchanon Wetchasit
>
>
> [1] I'm scare-quoting "authentication", because I'm (ab)using this for
> non-authentication uses where things entered were not secret:
> it is rather for gauging user's ability to understand what's on the page
> and take unusual action based on what he understood.
>
> ^ There is a specific all-caps C-word term that describe this technique,
>   but I'm intentionally not writing it here to prevent this email
>   from becoming searchable to unsavory people aiming to circumvent this.
>
> (And the reason that HTTP Basic Authentication is used for this is exactl=
y
> because it is *not* intended for this task; and also because it could be
> set up solely via server configuration directives without having to
> write additional CGI programs or install third-party software,
> nor having to maintain session cookie)
>
> [2]
> https://httpd.apache.org/docs/2.4/mod/mod_access_compat.html
>
> [3]
> While it is possible to implement this less-usual kind of tri-state ACL
> using CGI program that produces internal-forwarding `Location: `
> response line; I would prefer to relegate that as a last-resort measure,
> since it involves reinventing many wheels (partially re-parsing
> the `.htaccess` file), as well as the clash with complex `mod_rewrite`
> rules
> I additionally use (many of them depend on $REDIRECT_STATUS
> internal environment variable-- which CGI-issued redirections would
> bungle).
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
>
>

--000000000000ba3e1f0646136549
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">This is doable with the new auth syntax.<div><br></div><di=
v>For example:</div><div><br></div><div>&lt;RequireAll&gt;<br>=C2=A0 =C2=A0=
 # Clients in these IP ranges are blocked<br>=C2=A0 =C2=A0 Require not ip <=
a href=3D"http://10.83.2.0/24">10.83.2.0/24</a><br>=C2=A0 =C2=A0 Require no=
t ip <a href=3D"http://10.83.3.0/24">10.83.3.0/24</a><br>=C2=A0 =C2=A0 &lt;=
RequireAny&gt;</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 &lt;RequireAny&gt;<br>=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 # Clients in these IP ranges are =
allowed=C2=A0</div><div>=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Req=
uire ip 127.0.0.1<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Require ip <=
a href=3D"http://10.83.0.0/24">10.83.0.0/24</a></div><div>=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 &lt;/RequireAny&gt;<br><br></div><div>=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 # All others must authenticate<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0&lt;Requir=
eAll&gt;<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Require valid-user<br=
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 AuthType Basic</div><div>=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 AuthName Login<br>=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 AuthBasicProvider file<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 AuthUserFile &quot;/var/www/private/.htpasswd&quot;<br>=C2=A0=
 =C2=A0 =C2=A0 =C2=A0 &lt;/RequireAll&gt;<br>=C2=A0 =C2=A0 &lt;/RequireAny&=
gt;<br>&lt;/RequireAll&gt;<br></div><div><br></div><div>Tested on my comput=
er.</div><div><br></div><div>- Y</div></div><br><div class=3D"gmail_quote g=
mail_quote_container"><div dir=3D"ltr" class=3D"gmail_attr">On Tue, Dec 16,=
 2025 at 5:32=E2=80=AFAM Nutchanon Wetchasit &lt;<a href=3D"mailto:xwindows=
@xwindows.in.th">[email protected]</a>&gt; wrote:<br></div><blockquot=
e class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px s=
olid rgb(204,204,204);padding-left:1ex">Hello folks,<br>
<br>
I&#39;m using shared hosting based on Apache 2.4, and I have been using<br>
the old-school `mod_access_compat` access-control directives<br>
`Allow from` and `Deny from` for some years now; they work okay<br>
and are straighforward to read and understand.<br>
<br>
However, I found that when I used these in combination with<br>
HTTP Basic Authentication, even under the control of `Satisfy` directive,<b=
r>
only allowed a 2 states of entry allowance in `Satisfy` configuration:<br>
<br>
- `Satisfy any`:=C2=A0 let in if allowed, authenticate if denied<br>
- `Satisfy both`: authenticate if allowed, reject if denied<br>
<br>
I&#39;m currently using the latter style in some part of my site<br>
(with `Order Allow,Deny` precedence); but it is not ideal,<br>
because I actually would like to *also* let requests<br>
from whitelisted locations to also bypass the &quot;authentication&quot; [1=
] entirely,<br>
which would make the check tri-state:<br>
<br>
A. If `Allow from` (or its newer equivalent) matches the request,<br>
=C2=A0 =C2=A0bypass the HTTP Basic authentication and allow the request in.=
<br>
<br>
B. If `Deny from` (or its newer equivalent) matches the request,<br>
=C2=A0 =C2=A0fail the request with 403 response, *without* ever allowing it=
<br>
=C2=A0 =C2=A0to authenicate to bypass this restriction.<br>
<br>
C. If neither matched, then present a 401 response requesting credential<br=
>
=C2=A0 =C2=A0for HTTP Basic authentication.<br>
<br>
I have read relevant parts of 2.4&#39;s `mod_access_compat` documentation [=
2]<br>
several times, and I couldn&#39;t find a way to configure tri-state<br>
access control in the manner I described above.<br>
<br>
So I would like to ask: how to configure Apache HTTPd 2.4<br>
to do this kind of tri-state access control based on remote IP address<br>
and HTTP Basic Authentication (using old-style `Allow from`/`Deny from`<br>
or newer `Require` notwithstanding)?<br>
<br>
Or is this being impossible and I&#39;d have to resort to roll-my-own<br>
last-ditch option in order to do so? [3]<br>
<br>
Thanks in advance,<br>
Nutchanon Wetchasit<br>
<br>
<br>
[1] I&#39;m scare-quoting &quot;authentication&quot;, because I&#39;m (ab)u=
sing this for<br>
non-authentication uses where things entered were not secret:<br>
it is rather for gauging user&#39;s ability to understand what&#39;s on the=
 page<br>
and take unusual action based on what he understood.<br>
<br>
^ There is a specific all-caps C-word term that describe this technique,<br=
>
=C2=A0 but I&#39;m intentionally not writing it here to prevent this email<=
br>
=C2=A0 from becoming searchable to unsavory people aiming to circumvent thi=
s.<br>
<br>
(And the reason that HTTP Basic Authentication is used for this is exactly<=
br>
because it is *not* intended for this task; and also because it could be<br=
>
set up solely via server configuration directives without having to<br>
write additional CGI programs or install third-party software,<br>
nor having to maintain session cookie)<br>
<br>
[2]<br>
<a href=3D"https://httpd.apache.org/docs/2.4/mod/mod_access_compat.html" re=
l=3D"noreferrer" target=3D"_blank">https://httpd.apache.org/docs/2.4/mod/mo=
d_access_compat.html</a><br>
<br>
[3]<br>
While it is possible to implement this less-usual kind of tri-state ACL<br>
using CGI program that produces internal-forwarding `Location: `<br>
response line; I would prefer to relegate that as a last-resort measure,<br=
>
since it involves reinventing many wheels (partially re-parsing<br>
the `.htaccess` file), as well as the clash with complex `mod_rewrite` rule=
s<br>
I additionally use (many of them depend on $REDIRECT_STATUS<br>
internal environment variable-- which CGI-issued redirections would bungle)=
.<br>
<br>
---------------------------------------------------------------------<br>
To unsubscribe, e-mail: <a href=3D"mailto:[email protected]=
g" target=3D"_blank">[email protected]</a><br>
For additional commands, e-mail: <a href=3D"mailto:[email protected].=
org" target=3D"_blank">[email protected]</a><br>
<br>
</blockquote></div>

--000000000000ba3e1f0646136549--