Search code examples
apache2access-control

apache2 allow only user 'x' to open url 'example.com/private/x'


I have a question about access control in Apache 2. I don't think it's relevant, but I'm running it on a Raspberry Pi 2 with Raspbian.

There are multiple users that can use the website. However, there is one folder in which every user has his own folder. Every user should only have access to his own folder, and no other folders.

The problem I have is that it seems that the only way to do this is by adding each folder to the configuration file, which makes it rather time-intensive to add a user. So is there another way?


To clarify:
Lets say there are three users: user x, y and z.
All of them have access to https://example.com/, but no user other than user x should have access to https://example.com/private/x/, no one besides user y should have access to https://example.com/private/y/, and only user z should have access to https://example.com/private/z/.
What I've done and tried so far:
I've denied all access to location /private, in the hope I could then give the different users access to their respective folders.
I have tried to do that by granting access to the location /private/%{REMOTE_USER}/ and /private/%{REMOTE_IDENT}/, which both didn't work.
I've also tried to use an <If> directive to check if the URL matched to /private/%{REMOTE_USER}/, but that didn't work either.

I've tried to find something in the apache documentation that can help me, but I couldn't find anything that could bring me closer to the answer.


To summarize: is it possible to do this without adding all locations to the configuration file, and if so, how is it possible?
Thanks in advance for your input, Desirius


PS: I almost forgot and I'm not sure if it's relevant, but the authentication is done using PAM, in about the following manner:

<IfModule mod_authnz_external.c>
    AddExternalAuth pwauth /usr/sbin/pwauth
    SetExternalAuthMethod pwauth pipe
    AddExternalGroupMethod unixgroup environment
</IfModule>

AuthType Basic
AuthBasicProvider external
AuthExternal pwauth
GroupExternal unixgroup
Require unix-group www-priv


So I was still looking into this and found something!

From 2.4.8 onwards, named groups and backreferences are captured and written to the environment with the corresponding name prefixed with "MATCH_" and in upper case. This allows elements of URLs to be referenced from within expressions and modules like mod_rewrite. In order to prevent confusion, numbered (unnamed) backreferences are ignored. Use named groups instead.

<LocationMatch "^/combined/(?<sitename>[^/]+)">
    require ldap-group cn=%{env:MATCH_SITENAME},ou=combined,o=Example
</LocationMatch>

(Last part of the LocationMatch directive from the apache documentation.)

Now I thought to make use of this in the following manner:

<LocationMatch "^/private/(?<user>[^/]+)">
    Require expr "%{REMOTE_USER} == %{MATCH_USER}"
</LocationMatch>

But Apache now won't restart. It will restart when the Require line is commented out, but not otherwise. The following did not work either:

<LocationMatch "^/private/(?<user>[^/]+)">
    <RequireAll>
        Require valid-user
        Require expr "%{REMOTE_USER} == %{MATCH_USER}"
    <RequireAll>
</LocationMatch>

So I'm still looking to solve this question, but the focus has shifted slightly. If there is an answer to How can I use Require to check if the authenticated user is the user from a variable?, then that would possibly solve the whole question.

As always, thanks in advance for any input!
Desirius

Edit 2:
I found out that also Require expr "true" does not work. I'm suspecting Require expr to create the problems...


Solution

  • Ok, I've found the answer. Just after I edited my question, I found the remark at the Require Directives: Since v2.4.8, expressions are supported within the user require directives..

    So I realized I could just use Require user "%{env:MATCH_USER}" (together with the part from my edit).

    To give a more complete picture, this is what the configuration looks like now:

    <IfModule mod_authnz_external.c>
        AddExternalAuth pwauth /usr/sbin/pwauth
        SetExternalAuthMethod pwauth pipe
        AddExternalGroupMethod unixgroup environment
    </IfModule>
    
    AuthType Basic
    AuthBasicProvider external
    AuthExternal pwauth
    GroupExternal unixgroup
    Require unix-group www-priv
    
    <Location /private>
        Require all denied
    </Location>
    
    <LocationMatch "^/radicale/(?<user>[^/]+)">
        Require user "%{env:MATCH_USER}"
    </LocationMatch>
    

    To everyone who took the time to read my question, I thank you!

    I hope this answer will help someone else one day.