Order directives have long been ones that people have found confusing and counterintuitive. And although they could be combined in various ways, using the
Satisfy directive, they were still rather limiting. Complex combinations of restrictions were often very difficult.
Among the new features on 2.4 are new Require directives and syntaxes that allow very complex combinations of requirements.
mod_access_compat retains the old Allow, Deny, Order, Satisfy syntax, to ease the transition off of it. However, these directives have been removed from all example configurations, and you’re encouraged to stop using them.
The Require works much like it always has, although new options are added to it to replace the Allow/Deny syntax:
Require all granted
- Access is allowed unconditionally.
Require all denied
- Access is denied unconditionally.
Require env env-var [env-var]
- Access is allowed only if one of the given environment variables is
Require method http-method [http-method]
- Access is allowed only for the given HTTP methods.
Require expr expression
- Access is allowed if expression evaluates to true.
Require expr syntax uses the new expression engine, and so allows for very complex requirements.
Additionally, various other modules can augment the
Require syntax with other requirements. For example, mod_authz_host provides access control by IP address:
Require ip 192.168
Other than the
Require expr syntax, much of the above is as before, just stated more clearly. But the other directives I want to talk about here give you ways to combine the requirements that were not possible at all before.
The RequireAll directive allows you to combine several requirements and enforce all of them. RequireAny says that any one of the requirements is similar. And RequireNone says that none of the requirements must be true. What’s really powerful about these is that they are containers, and so can be nested within one another to create arbitrarily complex scenarios.
First, a few simple examples:
In the first example, we require that a client be either on our local network, or that they be authenticated with a username and password. Either one is sufficient. That is, if they’re on our local network, they won’t be asked for a password.
<RequireAny> Require ip 10.2 Require valid-user </RequireAny>
Alternately, we could require both – that they be on our local network and that they provode a password:
<RequireAll> Require ip 10.2 Require valid-user </RequireAll>
Finally, we could require that we won’t permit any access from someone who’s on our local network, or who is logged in.
<RequireNone> Require ip 10.2 Require valid-user </RequireNone>
This gets really interesting when you want to enforce several different kinds of access control in different ways:
<RequireAll> <RequireAny> Require user superadmin <RequireAll> Require group admins Require ldap-group cn=Administrators,o=Airius <RequireAny> Require group sales Require ldap-attribute dept="sales" </RequireAny> </RequireAll> </RequireAny> <RequireNone> Require group temps Require ldap-group cn=Temporary Employees,o=Airius </RequireNone> </RequireAll>
As you can see, we’ve combined several different sets of requirements to ensure that the user is in the sales or admin group, isn’t a temporary employee, and various other combinations.
As with other features that are new in 2.4, you’ll start to see more and more examples of their use as time goes by. We hope that this has given you a taste of what the new syntax makes possible that was difficult, or even impossible, before.