1

I'm trying to provide hundreds of users on our Apache httpd site the ability to restrict access to their web pages by different users and groups in our AD server through .htaccess. Apache lets me do that easily with mod_ldap and mod_authnz_ldap, and I understand how that works. I can restrict users with various 'require user' and 'require ldap-group' directives. The problem comes with sharing that privilege with the user community.

The first problem is that because I'm using AD with LDAP, I need to have a bind username/password which is provided in .htaccess via AuthLDAPBindDN and AuthLDAPBindPassword. I don't really want the users using their own username and password in their .htaccess as a bind user because that wouldn't be very secure. At the same time, I don't know how secure it is to publish a generic bind user/password. Maybe that's not a problem? After all, the bind user can't login to any system, and our AD server isn't available from outside the department, and every user can already do anything the generic bind user can do. That being said, if there's a way to do this without sharing the bind user and password, I'm sure that it's ultimately better.

Ideally, Apache httpd would let me set a DEFAULT for AuthLDAPBindDN and AuthLDAPBindPassword which would automatically be used if not overridden by the user in all cases. As far as I can tell, it does not do that.

The alternate way is to use aliases. There's a different syntax for authentication aliases (AuthProviderAlias) for users and authorization aliases for groups (AuthzProviderAlias ldap-group).

For user authentication I can set a default nicely with:

<AuthnProviderAlias my-ldap>
 AuthLDAPURL ...
 AuthLDAPBindDN ...
 AuthLDAPBindPassword ...
</AuthnProviderAlias>

Now when the users use in their .htaccess: AuthBasicProvider my-ldap, those values get inherited. This is terrific. They can restrict access to users.

But then for the authorization part by groups, things break down.

First, I have many different groups, and I want users to have the flexibility to use any of those groups to allow restricted access to their pages. From what I can tell, there's no syntax for one AuthzProviderAlias that would apply to each group on the system. I need to define for each and every group something like this:

<AuthzProviderAlias ldap-group mygroup  ....>
  AuthLDAPURL
  AuthLDAPBindDN
  AuthLDAPBindPassword ...
  Require ldap-group cn=mygroup,...
</AuthzProviderAlias>

Okay - if necessary, I can write a script that will generate the file of aliases to match all the groups on our system. It doesn't feel right though.

Now, in the users .htaccess they can "Require mygroup". However, what if they want to require group1 or group2? The Satisfy directive doesn't apply across multiple require directives.

Now it seems I need to provide group aliases combining different groups - group A and group B, group A and group C -- the possibilities are endless. This doesn't feel right

So I guess my question is this .. if I share a generic bind username and password and post it to a page that Google indexes and the world can see, is this so bad? Is this what people do who want all their users to be able to use LDAP auth via Apache httpd? That bind user can't login to any system, and our AD server isn't available from outside the department. I don't think this gives the user the ability to do anything they couldn't already do anyway.

Jason K
  • 13
  • 3

2 Answers2

1

I think your <AuthzProviderAlias> solution will work. It's almost exactly the same as the example at Creating Authorization Provider Aliases. It will require you to create a separate alias for each LDAP group, but you can at least automate most of the boilerplate of that with mod_macro:

<Macro LdapGroupAlias $name $dn>
  <AuthzProviderAlias ldap-group $name $dn>
    AuthLDAPURL ...
    AuthLDAPBindDN ...
    AuthLDAPBindPassword ...
  </AuthzProviderAlias>
</Macro>
Use LdapGroupAlias group1 cn=group1,...
Use LdapGroupAlias group2 cn=group2,...
...

Then your users can combine the groups as they like, for example:

Require group1
Require group2

and so on, including <RequireAny>, <RequireAll>, and <RequireNone> to combine the groups in arbitrary ways. So you don't need a new alias for every combination of groups - just one for each group.

Andrew Schulman
  • 8,811
  • 21
  • 32
  • 47
  • Unfortunately, from what I can tell, it does not work that way by design. You use the AuthnProviderAlias by specifying: "AuthBasicProvider my-ldap". The Require ldap-group don't see the previously configured bindDN and password which is why you need to redefine it for each one. I tried just now just to be completely convinced that it wouldn't work, and as I suspected, it unfortunately did not work. – Jason K Oct 30 '20 at 13:46
  • Thanks. Overhauled my answer after taking another look through the docs. – Andrew Schulman Oct 30 '20 at 15:47
  • Thanks, Andrew! I appreciate you trying again. I enabled mod_macro, and tried your example, and that does indeed work. Really, the only minor thing missing would be if I could find a way to do it without having to predefine each group. Using LdapGroupAlias is better, but it still has to be predefined. If the groups never changed, that would be a non-issue, but they do from time to time. If only there was a way to make it so that "Require group-NAME" would automatically call Use LdapGroupALias NAME cn=NAME,... but this is already 99.99% of the way there. – Jason K Oct 30 '20 at 19:08
  • Yeah. Agree. It's not what we'd like it to be. I've experimented with it today looking for a fully automated solution, but I didn't find anything better than the above. – Andrew Schulman Oct 30 '20 at 19:50
0

Does it work if you set the following in your global config?

<Location />
  AuthLDAPURL ...
  AuthLDAPBindDN ...
  AuthLDAPBindPassword ...
</Location>

I'm wondering if those directives are inherited by the rest of the config. That'd be a simple solution.

Andrew Schulman
  • 8,811
  • 21
  • 32
  • 47
  • Andrew - you're a genius! I am positive I tried that before, and it didn't work, but it certainly worked now. I have to do more experimentation, but if this is true, this means I can forget about aliases and macros, put the bind user and pass in "location /" and everything will just work the way I wanted it to work from the very beginning! I can't thank you enough. – Jason K Oct 30 '20 at 23:11
  • @JasonK lol yay! Yeah, it's sure simpler. – Andrew Schulman Oct 30 '20 at 23:53