1<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
2        "http://www.w3.org/TR/html4/loose.dtd">
3
4<html>
5
6<head>
7
8<title>Postfix Per-Client/User/etc. Access Control</title>
9
10<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
11
12</head>
13
14<body>
15
16<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix
17Per-Client/User/etc. Access Control</h1>
18
19<hr>
20
21<h2>Postfix restriction classes</h2>
22
23<p> The Postfix SMTP server supports access restrictions such as
24reject_rbl_client or reject_unknown_client_hostname on the right-hand side
25of SMTP server access(5) tables. This allows you to implement
26different junk mail restrictions for different clients or users.
27</p>
28
29<p> Having to specify lists of access restrictions for every
30recipient becomes tedious quickly. Postfix restriction classes
31allow you to give easy-to-remember names to groups of UCE restrictions
32(such as "permissive", "restrictive", and so on). </p>
33
34<p> The real reason for the existence of Postfix restriction classes
35is more mundane:  you can't specify a lookup table on the right-hand
36side of a Postfix access table. This is because Postfix needs to
37open lookup tables ahead of time, but the reader probably does not
38care about these low-level details. </p>
39
40<p> Example: </p>
41
42<blockquote>
43<pre>
44/etc/postfix/main.cf:
45    smtpd_restriction_classes = restrictive, permissive
46    # With Postfix &lt; 2.3 specify reject_unknown_client.
47    restrictive = reject_unknown_sender_domain reject_unknown_client_hostname ...
48    permissive = permit
49
50    smtpd_recipient_restrictions =
51	permit_mynetworks
52	reject_unauth_destination
53	check_recipient_access hash:/etc/postfix/recipient_access
54
55/etc/postfix/recipient_access:
56    joe@my.domain	permissive
57    jane@my.domain	restrictive
58</pre>
59</blockquote>
60
61<p> With this in place, you can use "restrictive" or "permissive"
62on the right-hand side of your per-client, helo, sender, or recipient
63SMTPD access tables. </p>
64
65<p> The remainder of this document gives examples of how Postfix
66access restriction classes can be used to: </p>
67
68<ul>
69
70<li> <a href="#internal"> Shield an internal mailing list from
71outside posters</a>,
72
73<li> <a href="#external"> Prevent external access by internal
74senders</a>.
75
76</ul>
77
78<p> These questions come up frequently, and the examples hopefully
79make clear that Postfix restriction classes aren't really the right
80solution. They should be used for what they were designed to do,
81different junk mail restrictions for different clients or users.
82</p>
83
84<h2><a name="internal">Protecting internal email distribution
85lists</a></h2>
86
87<blockquote>
88
89<p> We want to implement an internal email distribution list.
90Something like all@our.domain.com, which aliases to all employees.
91My first thought was to use the aliases map, but that would lead
92to "all" being accessible from the "outside", and this is not
93desired...  :-) </p>
94
95</blockquote>
96
97<p> Postfix can implement per-address access controls.  What follows
98is based on the SMTP client IP address, and therefore is subject
99to IP spoofing. </p>
100
101<blockquote>
102<pre>
103/etc/postfix/main.cf:
104    smtpd_recipient_restrictions =
105        check_recipient_access hash:/etc/postfix/access
106        <i>...the usual stuff...</i>
107
108/etc/postfix/access:
109    all@my.domain   permit_mynetworks,reject
110    all@my.hostname permit_mynetworks,reject
111</pre>
112</blockquote>
113
114<p> Specify <b>dbm</b> instead of <b>hash</b> if your system uses
115<b>dbm</b> files instead of <b>db</b> files. To find out what map
116types Postfix supports, use the command <b>postconf -m</b>. </p>
117
118<p> Now, that would be sufficient when your machine receives all
119Internet mail directly from the Internet.  That's unlikely if your
120network is a bit larger than an office. For example, your backup
121MX hosts would "launder" the client IP address of mail from the
122outside so it would appear to come from a trusted machine. </p>
123
124<p> In the general case you need two lookup tables: one table that
125lists destinations that need to be protected, and one table that
126lists domains that are allowed to send to the protected destinations.
127</p>
128
129<p> What follows is based on the sender SMTP envelope address, and
130therefore is subject to SMTP sender spoofing. </p>
131
132<blockquote>
133<pre>
134/etc/postfix/main.cf:
135    smtpd_recipient_restrictions =
136        check_recipient_access hash:/etc/postfix/protected_destinations
137        <i>...the usual stuff...</i>
138
139    smtpd_restriction_classes = insiders_only
140    insiders_only = check_sender_access hash:/etc/postfix/insiders, reject
141
142/etc/postfix/protected_destinations:
143    all@my.domain   insiders_only
144    all@my.hostname insiders_only
145
146/etc/postfix/insiders:
147    my.domain       OK  <i>matches my.domain and subdomains</i>
148    another.domain  OK  <i>matches another.domain and subdomains</i>
149</pre>
150</blockquote>
151
152<p> Getting past this scheme is relatively easy, because all one
153has to do is to spoof the SMTP sender address. </p>
154
155<p> If the internal list is a low-volume one, perhaps it makes more
156sense to make it moderated. </p>
157
158<h2><a name="external">Restricting what users can send mail to
159off-site destinations</a></h2>
160
161<blockquote>
162
163<p> How can I configure Postfix in a way that some users can send
164mail to the internet and other users not. The users with no access
165should receive a generic bounce message. Please don't discuss
166whether such access restrictions are necessary, it was not my
167decision. </p>
168
169</blockquote>
170
171<p> Postfix has support for per-user restrictions.  The restrictions
172are implemented by the SMTP server. Thus, users that violate the
173policy have their mail rejected by the SMTP server.  Like this:
174</p>
175
176<blockquote>
177<pre>
178554 &lt;user@remote&gt;: Access denied
179</pre>
180</blockquote>
181
182<p> The implementation uses two lookup tables. One table defines
183what users are restricted in where they can send mail, and the
184other table defines what destinations are local. It is left as an
185exercise for the reader to change this into a scheme where only
186some users have permission to send mail to off-site destinations,
187and where most users are restricted. </p>
188
189<p> The example assumes DB/DBM files, but this could also be done
190with LDAP or SQL. </p>
191
192<blockquote>
193<pre>
194/etc/postfix/main.cf:
195    smtpd_recipient_restrictions =
196        check_sender_access hash:/etc/postfix/restricted_senders
197        <i>...other stuff...</i>
198
199    smtpd_restriction_classes = local_only
200    local_only =
201        check_recipient_access hash:/etc/postfix/local_domains, reject
202
203/etc/postfix/restricted_senders:
204    foo@domain      local_only
205    bar@domain      local_only
206
207/etc/postfix/local_domains:
208    this.domain     OK      <i>matches this.domain and subdomains</i>
209    that.domain     OK      <i>matches that.domain and subdomains</i>
210</pre>
211</blockquote>
212
213<p> Specify <b>dbm</b> instead of <b>hash</b> if your system uses
214<b>dbm</b> files instead of <b>db</b> files. To find out what map
215types Postfix supports, use the command <b>postconf -m</b>. </p>
216
217<p> Note: this scheme does not authenticate the user, and therefore it can be
218bypassed in several ways: </p>
219
220<ul>
221
222<li> <p> By sending mail via a less restrictive mail
223relay host. </p>
224
225<li> <p> By sending mail as someone else who does have permission
226to send mail to off-site destinations. </p>
227
228</ul>
229
230</body>
231
232</html>
233