Macros: convert to tree for speed of lookup
[exim.git] / configs / config.samples / C050
1 From: David Woodhouse <dwmw2@infradead.org> 
2 Date: Thu, 18 Dec 2003 14:25:47 +0000                                          
3
4 Given a domain in DNS of the form...
5
6 $ORIGIN vdns.infradead.org.mailtarget.
7 fish            604800  IN      TXT     dwmw2@infradead.org
8
9 (It doesn't _have_ to be in private namespace; you can put it anywhere but I
10 prefer to have it private)
11
12 The following routers use it to implement a virtual domain. You could of course
13 omit the first and just make sure you have postmaster in all the zones you use
14 this way...
15
16 Rather than hardcoding the DNS domain to use in the router, we can put it into
17 a flat file with the list of domains for which we should be doing this.
18
19 We put this into /etc/exim/dns-virtual-domains:
20
21         vdns.infradead.org: vdns.infradead.org.mailtarget
22
23 In the main section of the configuration file we have:
24
25 domainlist dns_virtual_domains = lsearch;CONFDIR/dns-virtual-domains
26
27 The following routers handle unqualified addresses, multiple TXT records, and
28 entries of the form '@domain'. Also if we're not primary MX for the virtual
29 domain in question we'll fall back to forwarding to a higher-priority MX host
30 if the DNS isn't talking to us....
31
32 virtual_postmaster:
33   driver = redirect
34   domains = +dns_virtual_domains
35   local_parts = postmaster:root:abuse:mailer-daemon
36   data = postmaster@$primary_hostname
37
38   # For virtual domains, look up the target in DNS and rewrite...
39
40 dns_virtual_domains:
41   driver = redirect
42   domains = +dns_virtual_domains
43   check_ancestor
44   repeat_use
45   one_time
46   allow_defer
47   allow_fail
48   forbid_file
49   forbid_pipe
50   retry_use_local_part
51   qualify_preserve_domain
52
53    # Stash the lookup domain root for use in the next router.
54   address_data = ${lookup{$domain}lsearch{CONFDIR/dns-virtual-domains}}
55
56   # The lookup failure won't distinguish between absent record, absent
57   # domain, or other temporary failures. So we make this router just
58   # give up, and sort out the various failure modes later.
59
60   # The ${sg...} bits turn multiple TXT records (which Exim gives us
61   # separated by \n) into a comma-separated list, and also rewrite
62   # any element of that list of the form '@domain' (i.e. without a
63   # local part) to $local_part@domain, using the original local part
64   # from the address being routed, at the newly-provided domain.
65
66   # Addresses containing _only_ a localpart are qualified at the
67   # same domain as is being looked up, by qualify_preserve_domain
68   # above.
69   data = ${sg{\
70             ${sg{\
71                ${lookup dnsdb{txt=$local_part.$address_data}{$value}fail}\
72             }{\n}{,}}\
73          }{(,|^)[ ]*@}{\$1\$local_part@}}
74
75 dns_virtual_failed:
76   driver = redirect
77   domains = +dns_virtual_domains
78   allow_fail
79   allow_defer
80   data = ${lookup dnsdb{ns=$address_data}\
81         # If NS lookup succeeded, the domain exists and we can find it.
82         # Therefore, the above lookup failure meant that the user
83         # just doesn't exist. Fail appropriately:
84         {:fail:Unknown user at virtual domain}\
85         # NS lookup failed. This means there's a DNS problem -- so we
86         # shouldn't fail the delivery; let the following routers handle
87         # it... Note "fail" not "{:fail:}". It means 'pass'. :)
88         fail}
89
90
91   # We have DNS problems. If we're actually _delivering_, then try to
92   # deliver to a higher-priority MX if one exists. Otherwise, we defer and
93   # let it stay on the queue until the problem is fixed.
94   # You may prefer to freeze or bounce in this situation; I don't.
95 dns_virtual_relay:
96   driver = dnslookup
97   domains = +dns_virtual_domains
98   transport = remote_smtp
99   self = defer
100   no_verify
101   no_more
102
103   # On the other hand, if there's a DNS problem and we're only _verifying_,
104   # as we do when accepting incoming mail, then accept it for now and
105   # it'll get queued for when the DNS works again.
106 dns_virtual_verify_fallback:
107   driver = accept
108   domains = +dns_virtual_domains
109   verify_only
110   no_more
111
112 > Now I just need to investigate DDNS and see if it'll let individual
113 > users update the TXT records for their own aliases in the DNS... :)
114
115 This is remarkably simple to set up -- Google is your friend. I'm now
116 able to set up HMAC-MD5 keys to 'own' certain mail domains, and the
117 owners of those virtual mail domains can happily change the TXT records
118 to their hearts content, without bugging me to make changes and roll out
119 new alias files to all the MX hosts.
120
121 A setuid app which is able to read the key file, and which will update
122 the alias only for the user it's invoked by, is also fairly trivial to
123 implement -- inspired by the 'cammail' alias system.
124