Commit | Line | Data |
---|---|---|
e0f3765a PH |
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 |