Score:0

Apache: Allow Certain Users only from specified subnet

us flag

I have a requirement to change some Apache 2.4 authentication so that most users can access the website from anywhere, but certain users (who can be identified in a number of ways, but an LDAP group would be the easiest) can only be permitted access from a certain IP address subnet. (Authentication is via OIDC module plus ldap groups.)

(A simplified version of what) the current Apache config is

<RequireAll>
    <RequireAny>
        Require valid-user
        Require claim aud:apache123.company.com
    </RequireAny>
    Require ldap-attribute companyMemberOf="ALL_USERS_OF_THIS_TOOL"
</RequireAll>

I'm not sure how best to implement this negative clause for a certain group.

I had to use the workaround discussed here with a dummy Require all granted clause to avoid the RequireAll directive contains only negative authorization directives error.

I think adding this would do it but I'd appreciate the feedback. Because with this kind of thing I can easily imagine somebody writing "you'd think that would work but it doesn't because...", or "yes that works, but it's really not the right way to do it because..."

    <RequireAny>
        <RequireAll>
            RequireNone ldap-attribute companyMemberOf="RESTRICTED_GROUP"
            # Just to keep Apache happy
            Require all granted
         </RequireAll>
        RequireIp 10.10.0.0/22
    </RequireAny>
Score:0
es flag

Let's follow the boolean logic of the rules as they would stand:

<RequireAll>
### First, and foremost, users need to be Apache users.
    Require ldap-attribute companyMemberOf="ALL_APACHE_USERS"

### AND
    <RequireAny>
##### Users need to be either valid
        Require valid-user
##### Or have the appropiate claim.
        Require claim aud:apache123.company.com
    </RequireAny>

### AND
    <RequireAny>
##### Finally, users need to NOT have the companyMemberOf="RESTRICTED_GROUP" attribute
        Require not ldap-attribute companyMemberOf="RESTRICTED_GROUP"
##### Or be accessing from the 10.10.0.0/22 subnet.
        Require ip 10.10.0.0/22
    </RequireAny>
</RequireAll>

Logic dictates that the last block would evaluate to true (and therefore granting access) only if:

  • a). Users ARE coming from the subnet,
  • or b). Users ARE NOT restricted.

So, I believe the rules should satisfy your needs.

Note, however, the space between "Require" and "ip" and using "not" instead of "None"; the directive is used to enclose a set of directives, analogically to or .

Mort avatar
us flag
Thanks. I just updated my problem after some testing and with some new information from https://serverfault.com/questions/984997/apache-2-4-require-exclude-ip-range . There is some funny syntax associated with negatives.
es flag
I did think that this approach was somehow "reverseward", LOL, but couldn't think a "forward" way to do it, in order to keep it cleaner, clearer and easier to maintain.
es flag
Also, have you tried with "Require not" instead of "RequireNone"?. The way I wrote it, shouldn't throw AH01624 (since "require ip" is not negative).
Mort avatar
us flag
"negative Require directive has no effect in <RequireAny> directive"
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.