I'm trying to figure out how exactly v2.0 should be parsing configuration files. The most annoying part is if it should always just "use whatever comes first in config" or try some kind of a "use most specific rule". The "most specific" kind of makes more sense initially, but then you start wondering how to handle e.g.: 1) User logs in to imap from 192.168.0.1. What is foo's value? protocol imap { remote_ip 192.168.0.0/16 { foo = foo } } remote_ip 192.168.0.0/24 { foo = bar } 2) User logs in from 192.168.0.1 to 10.1.2.3. What is foo's value? local_ip 192.168.0.1 { remote_ip 10.1.2.0/24 { foo = foo } } remote_ip 10.1.2.3 { local_ip 192.168.0.0/24 { foo = bar } } Any thoughts? -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 197 bytes Desc: This is a digitally signed message part URL: <http://dovecot.org/pipermail/dovecot/attachments/20090810/9b48afbf/attachment-0002.bin>
Timo Sirainen wrote:> I'm trying to figure out how exactly v2.0 should be parsing > configuration files. The most annoying part is if it should always just > "use whatever comes first in config" or try some kind of a "use most > specific rule". The "most specific" kind of makes more sense initially, > but then you start wondering how to handle e.g.: > > 1) User logs in to imap from 192.168.0.1. What is foo's value? > > protocol imap { > remote_ip 192.168.0.0/16 { > foo = foo > } > } > remote_ip 192.168.0.0/24 { > foo = bar > } > > 2) User logs in from 192.168.0.1 to 10.1.2.3. What is foo's value? > > local_ip 192.168.0.1 { > remote_ip 10.1.2.0/24 { > foo = foo > } > } > remote_ip 10.1.2.3 { > local_ip 192.168.0.0/24 { > foo = bar > } > } > > Any thoughts?I think the easiest scheme to keep in my brain would be to evaluate the blocks, in order, as if they were branches in code. Fooling around with an arbitrary order of evaluation/specificity would be a recipe for disaster (see, for example, any CSS engine). So, something like, protocol imap { remote_ip 192.168.0.0/16 { foo = foo } } would translate to, if (protocol == imap) { if (remote_ip matches 192.168.0.0/16) { foo = foo } } and then later, remote_ip 192.168.0.0/24 { foo = bar } would set the value of 'foo' to 'bar', since it would evaluate in a similar fashion, and comes later in the config file. It's easy to explain, easy to implement, and easy to debug. Ultimately, the users are going to have to understand how it works in order to configure Dovecot properly. "Put the most general rules first, and then override them" is a practice with which most of us are already familiar.
Hi Timo, What's your thought on the 'precedence order' (hope it make sense), on protocol, remote_ip, local_ip? From your sample 1, it would read equals (to most technical people) to protocol imap { remote_ip 192.168.0.0/16 { foo = foo } } protocol ALL { remote_ip 192.168.0.0/24 { foo = bar } } If follow this syntax, sample 1's answer would be foo = foo, assuming specific rules overwrite general rules, and assuming protocol is the first order. Sample 2 is tough, that's why I asked what's your thought on precedence order. Restricting syntax to only remote before local (or vice versa) should resolve it. Joseph On 10-Aug-09, at 1:57 PM, Timo Sirainen wrote:> I'm trying to figure out how exactly v2.0 should be parsing > configuration files. The most annoying part is if it should always > just > "use whatever comes first in config" or try some kind of a "use most > specific rule". The "most specific" kind of makes more sense > initially, > but then you start wondering how to handle e.g.: > > 1) User logs in to imap from 192.168.0.1. What is foo's value? > > protocol imap { > remote_ip 192.168.0.0/16 { > foo = foo > } > } > remote_ip 192.168.0.0/24 { > foo = bar > } > > 2) User logs in from 192.168.0.1 to 10.1.2.3. What is foo's value? > > local_ip 192.168.0.1 { > remote_ip 10.1.2.0/24 { > foo = foo > } > } > remote_ip 10.1.2.3 { > local_ip 192.168.0.0/24 { > foo = bar > } > } > > Any thoughts?
On Aug 10, 2009, at 11:57 AM, Timo Sirainen wrote:> I'm trying to figure out how exactly v2.0 should be parsing > configuration files. The most annoying part is if it should always > just > "use whatever comes first in config" or try some kind of a "use most > specific rule". The "most specific" kind of makes more sense > initially, > but then you start wondering how to handle e.g.: > > 1) User logs in to imap from 192.168.0.1. What is foo's value? > > protocol imap { > remote_ip 192.168.0.0/16 { > foo = foo > } > } > remote_ip 192.168.0.0/24 { > foo = bar > } > > 2) User logs in from 192.168.0.1 to 10.1.2.3. What is foo's value? > > local_ip 192.168.0.1 { > remote_ip 10.1.2.0/24 { > foo = foo > } > } > remote_ip 10.1.2.3 { > local_ip 192.168.0.0/24 { > foo = bar > } > } > > Any thoughts?Figure out that they intersect and return an error! Aria Stewart aredridel at nbtsc.org
Timo Sirainen wrote:> I'm trying to figure out how exactly v2.0 should be parsing > configuration files. The most annoying part is if it should always just > "use whatever comes first in config" or try some kind of a "use most > specific rule". The "most specific" kind of makes more sense initially, > but then you start wondering how to handle e.g.: > > 1) User logs in to imap from 192.168.0.1. What is foo's value? > > protocol imap { > remote_ip 192.168.0.0/16 { > foo = foo > } > } > remote_ip 192.168.0.0/24 { > foo = bar > } >make it protocols { imap { remote_ip x/16 { foo = foo } } all { remote_ip x/24 { foo = bar } } }> 2) User logs in from 192.168.0.1 to 10.1.2.3. What is foo's value? > > local_ip 192.168.0.1 { > remote_ip 10.1.2.0/24 { > foo = foo > } > } > remote_ip 10.1.2.3 { > local_ip 192.168.0.0/24 { > foo = bar > } > } >I'd strongly suggest to use the same approach as firewalls (or exim): first match wins. I love exim because I can configure it much like my firewalls & routers, and the "fall through until something matches" syntax that most firewalls/ACLs use is well-understood & flexible. Kind regards, Felix -- Felix Sch?ren Head of Network ----------------------------------------------------------------------- Host Europe GmbH - http://www.hosteurope.de Welserstra?e 14 - 51149 K?ln - Germany Telefon: 0800 467 8387 - Fax: +49 180 5 66 3233 (*) HRB 28495 Amtsgericht K?ln - USt-IdNr.: DE187370678 Gesch?ftsf?hrer: Uwe Braun - Alex Collins - Mark Joseph - Patrick Pulverm?ller (*) 0,14 EUR/Min. aus dem dt. Festnetz, Mobilfunkpreise ggf. abweichend
Timo Sirainen wrote:> I'm trying to figure out how exactly v2.0 should be parsing > configuration files. The most annoying part is if it should always just > "use whatever comes first in config" or try some kind of a "use most > specific rule". The "most specific" kind of makes more sense initially, > but then you start wondering how to handle e.g.: > > 1) User logs in to imap from 192.168.0.1. What is foo's value? > > protocol imap { > remote_ip 192.168.0.0/16 { > foo = foo > } > } > remote_ip 192.168.0.0/24 { > foo = bar > } >make it protocols { imap { remote_ip x/16 { foo = foo } } all { remote_ip x/24 { foo = bar } } }> 2) User logs in from 192.168.0.1 to 10.1.2.3. What is foo's value? > > local_ip 192.168.0.1 { > remote_ip 10.1.2.0/24 { > foo = foo > } > } > remote_ip 10.1.2.3 { > local_ip 192.168.0.0/24 { > foo = bar > } > } >I'd strongly suggest to use the same approach as firewalls (or exim): first match wins. I love exim because I can configure it much like my firewalls & routers, and the "fall through until something matches" syntax that most firewalls/ACLs use is well-understood & flexible. Kind regards, Felix -- Felix Sch?ren Head of Network ----------------------------------------------------------------------- Host Europe GmbH - http://www.hosteurope.de Welserstra?e 14 - 51149 K?ln - Germany Telefon: 0800 467 8387 - Fax: +49 180 5 66 3233 (*) HRB 28495 Amtsgericht K?ln - USt-IdNr.: DE187370678 Gesch?ftsf?hrer: Uwe Braun - Alex Collins - Mark Joseph - Patrick Pulverm?ller (*) 0,14 EUR/Min. aus dem dt. Festnetz, Mobilfunkpreise ggf. abweichend
On Mon, 2009-08-10 at 13:57 -0400, Timo Sirainen wrote:> I'm trying to figure out how exactly v2.0 should be parsing > configuration files. The most annoying part is if it should always just > "use whatever comes first in config" or try some kind of a "use most > specific rule".I think it's possible to do both: Use the most specific rule, but if it's also not the first rule, it's a broken configuration and it'll fail. If there are ambiguity in specificity, it's also an error. (I'm also wondering about if it should be the first rule. Somehow to me it comes more naturally that last settings always override previous settings. If we really want to make first settings come first, then the default settings must be at the bottom of dovecot.conf, or they'd need some exception.) Require the nesting to be in order: local_ip { remote_ip { protocol {} } } Any of the levels could be dropped out, but the ordering couldn't be switched. Then we'll basically require that more specific blocks need to be before less specific blocks, or the configuration reading will fail. (Or vice versa? It somehow seems more natural to me..) The block specificity is determined by the nesting order. 1) Simple example: # allow plaintext auth from intranet, except from .123.1 remote_ip 192.168.123.1 { disable_plaintext_auth = yes } remote_ip 192.168.0.0/16 { disable_plaintext_auth = no } disable_plaintext_auth = yes If the remote_ip blocks were switched, it would give an error. 2) More complex example: Client connecting 192.168.0.1 -> 10.1.2.3. # this first match is used local_ip 192.168.0.1/31 { remote_ip 10.1.2.0/24 { foo = foo } } # ok, exact match (handle the same as duplicate settings in root, # maybe optionally give a warning about them) local_ip 192.168.0.1/31 { remote_ip 10.1.2.0/24 { foo = foo2 } } # error, local_ip more specific local_ip 192.168.0.1 { foo = xx } # ok, local_ip less specific, remote_ip less specific local_ip 192.168.0.0/16 { remote_ip 10.1.2.0/23 { foo = bar } } # error, remote_ip more or equal specific local_ip 192.168.0.0/16 { remote_ip 10.1.2.3 { foo = baz1 } remote_ip 10.1.2.0/24 { foo = baz2 } } # error, protocol more specific local_ip 192.168.0.0/16 { protocol imap { foo = x } } -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 197 bytes Desc: This is a digitally signed message part URL: <http://dovecot.org/pipermail/dovecot/attachments/20090810/3cc610bb/attachment-0002.bin>
On Mon, 2009-08-10 at 17:59 -0400, Timo Sirainen wrote:> > (I'm also wondering about if it should be the first rule. Somehow to meI think first rule match is best approach, as someone else pointed out, its how many things that most people here would work with daily work, be it a server daemon configuration, iptables, or Cisco routers. The only exceptions that I can think of immediately is Apache, ircu, and DNews where last (entered in order) matching rule wins. Noel
On Monday 10 August 2009 19:57:53 Timo Sirainen wrote:> I'm trying to figure out how exactly v2.0 should be parsing > configuration files. The most annoying part is if it should always just > "use whatever comes first in config" or try some kind of a "use most > specific rule".I generally prefer the "most specific rule wins". If that is not the case, it should not be possible to specify the same configuration within containers of different scope. It is not intuitive to have a value in a restricted scope and in a more general scope, and there are situations when the general value is used even though the specifiv scope> The "most specific" kind of makes more sense initially, > but then you start wondering how to handle e.g.: > > 1) User logs in to imap from 192.168.0.1. What is foo's value? > > protocol imap { > remote_ip 192.168.0.0/16 { > foo = foo > } > } > remote_ip 192.168.0.0/24 { > foo = bar > }This one is easy. It should be foo in any case :-) Protocol sections that are more specific are an existing and coarse-granular concept, and AFAIk now it doesn't matter whether the protocol section is before or after the general setting. This concept should in any case be retained.> 2) User logs in from 192.168.0.1 to 10.1.2.3. What is foo's value? > > local_ip 192.168.0.1 { > remote_ip 10.1.2.0/24 { > foo = foo > } > } > remote_ip 10.1.2.3 { > local_ip 192.168.0.0/24 { > foo = bar > } > } > > Any thoughts?Perhaps this should be invalid. Rainer
On 8/10/2009, Timo Sirainen (tss at iki.fi) wrote:> (I'm also wondering about if it should be the first rule. Somehow to > me it comes more naturally that last settings always override > previous settings.For config files, I agree.> If we really want to make first settings come first, then the default > settings must be at the bottom of dovecot.conf, or they'd need some > exception.)Or just have the default settings there as an example, but commented out. Have an explanation at the top of the config file that if you only need the default settings, they do not need to be uncommented, and that the last setting wins (or will cause a warning or error, or whatever you decide). I like that I can use postconf -d (show default settings - and this is why I'd like to have a doveconf -d, as well as doveconf -n), to see if I have specifically set any defaults, and if I did, delete/comment them. This limits the settings returned by postconf -n, which makes it easier to read. I'd like dovecot to have the same capability. When I did this, I cut the ouput down from 80 lines to less than 40. -- Best regards, Charles
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Mon, 10 Aug 2009, Timo Sirainen wrote:> I'm trying to figure out how exactly v2.0 should be parsingIMO, "most specific" won't work as you pointed out several times, because Dovecot cannot know, which precendence the zillion configuration options and conditionals have in the particular setup. In my view, "first match" is good, if one needs quick processing time and can cut, once the match is found. E.g. in firewalls and routers. Or when the options are not _conditionally_ assigned, e.g. in sendmail cf, you do not have no way to have a config option _not_ apply. Most conf files/system I know, that split between common (or default) setting and specific overrides work in last match. They bundle the default settings on top and specify the overrides below, just like a program, as already pointed out. Moreover, because most programs parse the config file til its end anyway. It is more work to debug problems, but in my eyes the conf files look cleaner. There are a few, where you can "fix" a setting, so it cannot be overwritten later, but mostly because first the system conf file is parsed and should be able to fix some settings against user override. Maybe a dovecot debug mode can issue the line number when a setting is assigned. Bye, - -- Steffen Kaiser -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) iQEVAwUBSoGFynWSIuGy1ktrAQJY3Qf/Tv96bzBg4yd4fOuY/rplpf7ap3DJv//K geDA8WWHuzU4J505DmBi0AxvmfZ6ZHFnII0xGnatK9qxaaWDTceqdRJlZWdf25XL Hf52ff4xVOgQXpoqvh0zT8VxM4q9Qe7mH2g4VTz0eKbvVP0qFaHBAv66qa1czgGP 9Xj27YrmE3FKiurCkVCwVzGFQM4akTs+qD3VvBy3sTyoLB3XenzS6e4EXjsbQAQe McaUUL/nJKtKwXyN7aH3lKZaFe3ECsb1SZWtTxQ4GAEuwPeawWIrK3r1S1ykfYUV ZQERdMVWgc1FsG5IdTTYcq5DgHSWEotRcN92Aw7v9i20yaTw1wKSEg==b+sT -----END PGP SIGNATURE-----
I would suppose that partly overlapping rules are most often a sign of a configuration error. So how about 1) most specific rule wins (or last rule wins, forcing more specific rules to appear further down the file) 2) partly overlapping flag an error, except for 3) using != (or whatever) instead of = surpresses the error and makes the last rule win.
On Mon, 2009-08-10 at 13:57 -0400, Timo Sirainen wrote:> I'm trying to figure out how exactly v2.0 should be parsing > configuration files. The most annoying part is if it should always just > "use whatever comes first in config" or try some kind of a "use most > specific rule".I've now implemented the "use most specific rule".> The "most specific" kind of makes more sense initially, > but then you start wondering how to handle e.g.: > > 1) User logs in to imap from 192.168.0.1. What is foo's value? > > protocol imap { > remote_ip 192.168.0.0/16 { > foo = foo > } > } > remote_ip 192.168.0.0/24 { > foo = bar > }Error in configuration file /usr/local/etc/dovecot/dovecot.conf line 2: remote_ip must not be under protocol Switching around protocol and remote_ip makes it work, I think it's pretty clear then what should happen (foo=bar always with 192.168.0.*): remote_ip 192.168.0.0/16 { protocol imap { foo = foo } } remote_ip 192.168.0.0/24 { foo = bar }> 2) User logs in from 192.168.0.1 to 10.1.2.3. What is foo's value? > > local_ip 192.168.0.1 { > remote_ip 10.1.2.0/24 { > foo = foo > } > } > remote_ip 10.1.2.3 { > local_ip 192.168.0.0/24 { > foo = bar > } > }Error in configuration file /usr/local/etc/dovecot/dovecot.conf line 7: local_ip must not be under remote_ip Then if you switch around the remote_ip and local_ip it'll start up normally. But when you log in from 192.168.0.1 -> 10.1.2.3 it'll log an error and fail: Conflict in setting foo found from filter at /usr/local/etc/dovecot/dovecot.conf:7 So this is a runtime error. It would be possible to test out all the different combinations at startup, but with complex configs that might start taking forever.. Currently it doesn't tell where the other side of the conflict came from. It probably wouldn't be too difficult to add, but I think I'll just leave it for future until it actually becomes a problem for someone. :) It's also possible to test these per-IP configurations with doveconf: ./doveconf -n -f lip=192.168.0.1 -f rip=10.1.2.3 -f service=imap -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 197 bytes Desc: This is a digitally signed message part URL: <http://dovecot.org/pipermail/dovecot/attachments/20090903/2f204de9/attachment-0002.bin>
Reasonably Related Threads
- Multiple SSL certs question
- how to config dovecot for multiple domains, multiple SSL certs, and conditional IP access -- with passwd-file passdb?
- VPN address of the remote host
- BUG: passdb checkpassword {} and lastauth file
- Metric label values truncated when using OpenMetrics endpoint