1<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd"> 2<html> 3<head> 4<title>Postfix MongoDB Howto</title> 5<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 6</head> 7<body> 8<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix MongoDB Howto</h1> 9<hr> 10 11<h2>MongoDB Support in Postfix</h2> 12 13<p> Postfix can use MongoDB as a source for any of its lookups: 14aliases(5), virtual(5), canonical(5), etc. This allows you to keep 15information for your mail service in a replicated noSQL database 16with fine-grained access controls. By not storing it locally on the 17mail server, the administrators can maintain it from anywhere, and 18the users can control whatever bits of it you think appropriate. 19You can have multiple mail servers using the same information, 20without the hassle and delay of having to copy it to each. </p> 21 22<p> Topics covered in this document:</p> 23 24<ul> 25<li><a href="#build">Building Postfix with MongoDB support</a> 26<li><a href="#config">Configuring MongoDB lookups</a> 27<li><a href="#example_virtual">Example: virtual alias maps</a> 28<li><a href="#example_mailing_list">Example: Mailing lists</a> 29<li><a href="#example_projections">Example: MongoDB projections</a> 30<li><a href="#feedback">Feedback</a> 31<li><a href="#credits">Credits</a> 32</ul> 33 34<h2><a name="build">Building Postfix with MongoDB support</a></h2> 35 36<p>These instructions assume that you build Postfix from source 37code as described in the INSTALL document. Some modification may 38be required if you build Postfix from a vendor-specific source 39package. </p> 40 41<p>The Postfix MongoDB client requires the <b>mongo-c-driver</b> 42library. This can be built from source code from <a 43href="https://github.com/mongodb/mongo-c-driver/releases">the 44mongod-c project</a>, or this can be installed as a binary package 45from your OS distribution, typically named <b>mongo-c-driver</b>, 46<b>mongo-c-driver-devel</b> or <b>libmongoc-dev</b>. 47Installing the mongo-c-driver library may also install <b>libbson</b> 48as a dependency. </p> 49 50<p> To build Postfix with mongodb map support, add to the CCARGS 51environment variable the options -DHAS_MONGODB and -I for the 52directory containing the mongodb headers, and specify the AUXLIBS_MONGODB 53with the libmongoc and libbson libraries, for example:</p> 54 55<blockquote> 56<pre> 57% make tidy 58% make -f Makefile.init makefiles \ 59 CCARGS="$CCARGS -DHAS_MONGODB -I/usr/include/libmongoc-1.0 \ 60 -I/usr/include/libbson-1.0" \ 61 AUXLIBS_MONGODB="-lmongoc-1.0 -lbson-1.0" 62</pre> 63</blockquote> 64 65<p>The 'make tidy' command is needed only if you have previously 66built Postfix without MongoDB support. </p> 67 68<p>If your MongoDB shared library is in a directory that the RUN-TIME 69linker does not know about, add a "-Wl,-R,/path/to/directory" option 70after "-lbson-1.0". Then, just run 'make'.</p> 71 72<h2><a name="config">Configuring MongoDB lookups</a></h2> 73 74<p> In order to use MongoDB lookups, define a MongoDB source as a 75table lookup in main.cf, for example: </p> 76 77<blockquote> 78<pre> 79alias_maps = hash:/etc/aliases, proxy:mongodb:/etc/postfix/mongo-aliases.cf 80</pre> 81</blockquote> 82 83<p> The file /etc/postfix/mongo-aliases.cf can specify a number of 84parameters. For a complete description, see the mongodb_table(5) 85manual page. </p> 86 87<h2><a name="example_virtual">Example: virtual(5) alias maps</a></h2> 88 89<p> Here's a basic example for using MongoDB to look up virtual(5) 90aliases. Assume that in main.cf, you have: </p> 91 92<blockquote> 93<pre> 94virtual_alias_maps = hash:/etc/postfix/virtual_aliases, 95 proxy:mongodb:/etc/postfix/mongo-virtual-aliases.cf 96</pre> 97</blockquote> 98 99<p> and in mongodb:/etc/postfix/mongo-virtual-aliases.cf you have: </p> 100 101<blockquote> 102<pre> 103uri = mongodb+srv://user_name:password@some_server 104dbname = mail 105collection = mailbox 106query_filter = {"$or": [{"username":"%s"}, {"alias.address": "%s"}], "active": 1} 107result_attribute = username 108</pre> 109</blockquote> 110 111<p>This example assumes mailbox names are stored in a MongoDB backend, 112in a format like:</p> 113 114<blockquote> 115<pre> 116{ "username": "user@example.com", 117 "alias": [ 118 {"address": "admin@example.com"}, 119 {"address": "abuse@example.com"} 120 ], 121 "active": 1 122} 123</pre> 124</blockquote> 125 126<p>Upon receiving mail for "admin@example.com" that isn't found in the 127/etc/postfix/virtual_aliases database, Postfix will search the 128MongoDB server/cluster listening at port 27017 on some_server. It 129will connect using the provided credentials, and search for any 130entries whose username is, or alias field has "admin@example.com". 131It will return the username attribute of those found, and build a 132list of their email addresses. </p> 133 134<p> Notes: </p> 135 136<ul> 137 138<li><p> As with <b>projection</b> (see below), the Postfix mongodb 139client automatically removes the top-level '_id' field from a 140result_attribute result. </p> </li> 141 142<li><p> The Postfix mongodb client will only parse result fields 143with data types UTF8, INT32, INT64 and ARRAY. Other fields will be 144ignored, with a warning in the logs. </p> </li> 145 146</ul> 147 148<h2><a name="example_mailing_list">Example: Mailing lists</a></h2> 149 150<p>When it comes to mailing lists, one way of implementing one would 151be as below:</p> 152 153<blockquote> 154<pre> 155{ "name": "dev@example.com", "active": 1, "address": 156 [ "hamid@example.com", "wietse@example.com", "viktor@example.com" ] } 157</pre> 158</blockquote> 159 160<p>using the filter below, will result in a comma separated string 161with all email addresses in this list. </p> 162 163<blockquote> 164<pre> 165query_filter = {"name": "%s", "active": 1} 166result_attribute = address 167</pre> 168</blockquote> 169 170<p> Notes: </p> 171 172<ul> 173 174<li><p> As with <b>projection</b> (see below), the Postfix mongodb 175client automatically removes the top-level '_id' field from a 176result_attribute result. </p> </li> 177 178<li><p> The Postfix mongodb client will only parse result fields 179with data types UTF8, INT32, INT64 and ARRAY. Other fields will be 180ignored, with a warning in the logs. </p> </li> 181 182</ul> 183 184<h2><a name="example_projections">Example: advanced projections</a></h2> 185 186<p>This module also supports the use of more complex MongoDB 187projections. There may be some use cases where operations such as 188concatenation are necessary to be performed on the data retrieved 189from the database. Although it is encouraged to keep the database 190design simple enough so this is not necessary, postfix supports the 191use of MongoDB projections to achieve the goal. </p> 192 193<p>Consider the example below:</p> 194 195<blockquote> 196<pre> 197{ "username": "user@example.com", 198 "local_part": "user", 199 "domain": "example.com", 200 "alias": [ 201 {"address": "admin@example.com"}, 202 {"address": "abuse@example.com"} 203 ], 204 "active": 1 205} 206</pre> 207</blockquote> 208 209<p>virtual_mailbox_maps can be created using below parameters in a 210mongodb:/etc/postfix/mongo-virtual-mailboxes.cf file:</p> 211 212<blockquote> 213<pre> 214uri = mongodb+srv://user_name:password@some_server 215dbname = mail 216collection = mailbox 217query_filter = {"$or": [{"username":"%s"}, {"alias.address": "%s"}], "active": 1} 218projection = { "mail_path": {"$concat": ["$domain", "/", "$local_part"]} } 219</pre> 220</blockquote> 221 222<p>This will return 'example.com/user' path built from the database fields. </p> 223 224<p>A couple of considerations when using projections:</p> 225 226<ul> 227 228<li><p>As with <b>result_attribute</b>, the Postfix mongodb client 229automatically removes the top-level '_id' field from a projection 230result. </p></li> 231 232<li><p> The Postfix mongodb client will only parse fields with data 233types UTF8, INT32, INT64 and ARRAY. Other fields will be ignored, 234with a warning in the logs. It is suggested to exclude any unnecessary 235fields when using a projection. </p></li> 236 237</ul> 238 239<h2><a name="feedback">Feedback</a></h2> 240 241<p> If you have questions, send them to postfix-users@postfix.org. 242Please include relevant information about your Postfix setup: 243MongoDB-related output from postconf, which libraries you built 244with, and such. If your question involves your database contents, 245please include the applicable bits of some database entries. </p> 246 247<h2><a name="credits">Credits</a></h2> 248 249<ul> 250 251<li> Stephan Ferraro (Aionda GmbH) implemented an early version of the 252Postfix MongoDB client. 253 254<li> Hamid Maadani (Dextrous Technologies, LLC) added support for 255projections and %<i>letter</i> interpolation, and added documentation. 256 257<li> Wietse Venema adopted and restructured the code and documentation. 258 259</ul> 260 261</body> 262 263</html> 264