Hi Krzysztof,

On Wed, Feb 11, 2009 at 05:58:42PM +0100, Krzysztof Oledzki wrote:
> Willy!
> 
> As you are probably aware, recently there was a mail quoted below, asking 
> about the redirect feature. It encouraged me to think a little more about 
> it, so: shouldn't we rather put the feature into use_backend chain instead 
> of "req allow/deny/block"? This would simply allow to do something like:
> 
> --- cut here ---
> use_backend www_php4 if payment
> redirect prefix https://pay.xxx.bg if pay_xxx
> default_backend www_php4
> --- cut here ---
> 
> instead of:
> --- cut here ---
> use_backend www_php4 if payment
> redirect prefix https://pay.xxx.bg if pay_xxx !payment
> default_backend www_php4
> --- cut here ---
> 
> It would also allow to create more complicated rules, without duplicating 
> whole "use_backend xxx if abc" section, which is sometimes *very* 
> complicated, into "req allow if abc".
> 
> What is your opinion?

To be fair, this is how I believed it worked. But I now remember there
were is a specific "redirect rules" list for them, so I believed wrong.

I've just looked at the diagram I have posted yesterday, and use_backend
is separated there. Now that I'm thinking about it, I believe the reason
I wanted use_backend in a different list was because it is not really an
action. I mean, "allow", "deny", "redirect", "tarpit", ... all terminate
processing or rule evaluation. Having "use_backend" stop evaluation is
problematic, as it's not an action, it's a dynamic configuration. In fact,
it's problematic for existing setups mostly, because new setups could be
written by carefully interleaving use_backend statements in the middle of
the allow/redirect/deny rules. And I agree that for the long term, it's
better to remember that rule ordering is what matters than remembering
which one applies before or after which one.

In fact, I think that having use_backend evaluated last makes sense
since it's really how it's supposed to work. But I agree that for the
poor guy writing the rules, it would be easier to be able to put it
before other rules. In fact, there's a solution consisting in using
"allow" to escape the rules, but it requires that the rule is
duplicated for the use_backend one, which is not always very convenient.

Hmmm now I remember why redirect was in another list. I'm pretty sure
the reason was that we wanted to be able to redirect after an allow
(which is not necessarily a strong requirement).

There are other aspects to consider :
  - eventually, tcp will support use_backend/allow/deny/tarpit
  - outgoing processing will obviously ever support use_backend
  - the backend's incoming rules will support use_server (to force
    a server) but not use_backend.

All these elements may easily be solved by a simple rule list and
strict action enforcing to ensure we never have the wrong action
at the wrong place.

I'm still afraid of breaking existing setups. Same problem as for the
"block" keyword after all.

Don't you think we should create a new "set-backend" keyword to merge
it with the whole list, and let "use_backend" slowly die (for instance,
we mark it deprecated in version 1.4 with a big warning) ?

This means we would have :
   block
   allow|deny|redirect|tarpit|set-backend
   use_backend

Another idea would consist in splitting access rules from traffic
management rules. I mean, "allow", "deny", "tarpit" grant or deny
access. Even the tarpit could be considered as an extended deny.
Then we have "use_backend", "redirect", and maybe later things
about QoS, logging, etc... which would make sense in a separate
list.

Since we can't ask the user to remember which keyword works in which
group, the syntax should make it possible to explicitly state where
the processing ought to happen. That's the principle of the "http-req in"
etc...

So we could have two explicit groups for "http-req" : one just for
access (allow/deny/tarpit), and another one for traffic control which
would be the default one, with all traffic management rules. So we
could have something like this :

   http-req in allow if acl(hdr(host) -i www)
   http-req in deny if ANY

   http-req redirect /index.html if acl(url /)
   http-req redirect /index.html if acl(url /)
   http-req use_backend static if acl(url_beg /static)

The more I'm thinking about it, the more I think that the problem
only comes from those rules which do not terminate processing : "allow"
and "use_backend". Users expect to combine them with other rules. There's
even already an exception for allow/deny rules in the processing so that
the first action is granted in case of an allow.

The problem will only get worse once we have QoS settings, header
addition or replacements, etc..., as those will not be terminal rules
anymore. Note that we could have an optional keyword associated to
all of those to indicate if the eval is to be the last one or not
when it matches, but I'm not sure it will make the config any simpler
because some people will still want to run a few rule sets.

I'd want to avoid the principle of the "goto" + rule number as used in
the Alteon for instance, because while it solves the issue, it makes
administration very hard.

A long time ago, I wanted to support rule sets (and IIRC, the keyword
"ruleset" is accepted in the config). Those ones were dedicated to
rules and switching. The idea was to use them approximately the same
way as iptables with jumps between rulesets. It could help a lot, but
seems very complicated for people who just want to do a few things.
The principle of separating processing in small groups (eg: http-req,
etc...) approximately mimmics this behaviour without adding too much
hassle. We could add also other groups after all.

Maybe we should then start by considering that only "allow" and
"use_backend" sometimes need to take immediate action and exit
rules evaluation, and sometimes go on to the end. Then we may
write some variants for them, eg "allow_now, use_backend_now" or
"allow!, use_backend!" to indicate that we want that rule to act
immediately.

I believe we still need some thinking and to collect users' opinions
on those variants. It would be annoying to make something very poor
and having to support it for a long time.

Best regards,
Willy


Reply via email to