<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Yet another web log &#187; Postfix</title>
	<atom:link href="http://blog.philippheckel.com/tag/postfix/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.philippheckel.com</link>
	<description>Life, Linux and other things</description>
	<lastBuildDate>Thu, 17 Mar 2011 10:04:42 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>WP-UN: WordPress version update notification with cron</title>
		<link>http://blog.philippheckel.com/2010/01/29/wp-un-wordpress-version-update-notification-with-cron/</link>
		<comments>http://blog.philippheckel.com/2010/01/29/wp-un-wordpress-version-update-notification-with-cron/#comments</comments>
		<pubDate>Fri, 29 Jan 2010 13:32:30 +0000</pubDate>
		<dc:creator>Philipp C. Heckel</dc:creator>
				<category><![CDATA[Administration]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Cron]]></category>
		<category><![CDATA[Mail]]></category>
		<category><![CDATA[Postfix]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://blog.philippheckel.com/?p=164</guid>
		<description><![CDATA[WordPress is a very popular open-source blog software and is used widely throughout the Internet. However, with great success comes great attack potential: like any other wide spread open-source software, WordPress is target for frequent hacking attacks and spam-bots. All the more important is it to always update the distribution to the latest release. As [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://wordpress.org/">WordPress</a> is a very popular open-source blog software and is used widely throughout the Internet. However, with great success comes great attack potential: like any other wide spread open-source software, WordPress is target for frequent hacking attacks and spam-bots. All the more important is it to always update the distribution to the latest release.</p>
<p>As Debian/Ubuntu user, I am spoiled when it comes to update management: <em>apt-get</em> updates most of my software, and <em>apticron</em> notifies me when updates are available. For WordPress however, the packaged versions of Debian/Ubuntu are really old and less adjustable which unfortunately makes a manual installation inevitable. While there are several automated WordPress update mechanisms out there, I couldn&#8217;t find a simple notify-on-update tool.</p>
<p>This post introduces the <em>WordPress Update Notifier</em> (WP-UN), a simple script that frequently compares the installed WordPress version with the latest available one. If a new version is available, it sends an e-mail to a given address.</p>
<p><span id="more-164"></span></p>
<h3 id="toc-update">Update</h3>
<p><strong>February &#8217;11</strong>: I updated the script so that it now uses the WordPress API. If you want, you can still download the <a href="http://blog.philippheckel.com/uploads/2010/01/wp-un-0.1">old version of WP-UN</a>, but since wordpress.org changed their download mechanisms, it does not work any more. </p>
<h3 id="toc-requirements">Requirements</h3>
<p>WP-UN is compatible with <strong>WordPress 2.5-3.x</strong>. It needs a  <strong>local mail server</strong> such as <a href="http://www.sendmail.org/">Sendmail</a> or <a href="http://www.postfix.org/">Postfix</a> to deliver the notification e-mail. </p>
<h3 id="toc-download-installation">Download &amp; Installation</h3>
<p>Download the script, save it to your preferred location and make it executable:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">wget</span> <span style="color: #660033;">-O</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>wp-un \
          http:<span style="color: #000000; font-weight: bold;">//</span>blog.philippheckel.com<span style="color: #000000; font-weight: bold;">/</span>uploads<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">2010</span><span style="color: #000000; font-weight: bold;">/</span>01<span style="color: #000000; font-weight: bold;">/</span>wp-un
$ <span style="color: #c20cb9; font-weight: bold;">chmod</span> +x <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>wp-un</pre></div></div>

<p>That&#8217;s it for the installation. The script can now be called by simply running <em>wp-un</em>.</p>
<p><strong>Download</strong>: <a href="http://blog.philippheckel.com/uploads/2010/01/wp-un">WP-UN 0.2, February 2011</a><br />
<strong>Old version</strong>: <a href="http://blog.philippheckel.com/uploads/2010/01/wp-un-0.1">WP-UN 0.1, January 2010</a> (broken!)</p>
<h3 id="toc-usage">Usage</h3>
<p>Now you can call the script with the following arguments:</p>
<ul>
<li><strong>&#8211;test</strong>: to test if the notification works, use the <em>&#8211;test</em> parameter (optional).</li>
<li><strong>INSTALL-DIR</strong>: the path to your local WordPress installation, for example /var/www/myblog.</li>
<li><strong>NOTIFY-EMAIL</strong>: the e-mail address of the person to notify if a new WordPress version is available.</li>
</ul>
<p>By default, the script is completely silent so that adding a cronjob doesn&#8217;t require output redirections. If, however, the <em>&#8211;test</em> option is given, it is more verbose and sends the notification e-mail in any case.</p>
<p>If a new WordPress version is available, the output looks something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">$ wp-un --test /var/www/myblog admin@example.com
Checking installed version... WordPress 2.5.1
Checking latest version... WordPress 2.9.1
Update required; Sending notification to admin@example.com... done.</pre></div></div>

<p>If WordPress is up-to-date, WP-UN would normally not send any notification. If, however, the <em>&#8211;test</em> option is enabled, it sends the e-mail no matter what. In this case, the output will look like this:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">$ wp-un --test /var/www/myblog admin@example.com
Checking installed version... WordPress 2.9.1
Checking latest version... WordPress 2.9.1
Update not necessary; WordPress is up-to-date.
TEST-flag enabled: sending notfication to admin@example.com... done.</pre></div></div>

<p>The notification you receive will look like this:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;"> The WordPress installation on host example.com needs an update:
&nbsp;
   Installed Version: WordPress 2.5.1
                  at: /var/www/myblog
&nbsp;
      Latest Version: WordPress 2.9.1
            Download: http://www.wordpress.org/latest.tar.gz</pre></div></div>

<h3 id="toc-as-cronjob">As cronjob</h3>
<p>If you want to be notified as soon as a new version comes out, installing a cronjob is a good idea. Simply run <em>crontab -e</em> and add the following line to the file:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000;">0</span> <span style="color: #000000;">6</span> <span style="color: #000000; font-weight: bold;">*</span> <span style="color: #000000; font-weight: bold;">*</span> <span style="color: #000000; font-weight: bold;">*</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>wp-un <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>www<span style="color: #000000; font-weight: bold;">/</span>myblog admin<span style="color: #000000; font-weight: bold;">@</span>example.com</pre></div></div>

<p>WP-UN will now run every morning at 6am and notify you if a new WordPress version is out there!</p>
<h3 id="toc-conclusion">Conclusion</h3>
<p>WP-UN is just one of many solutions and it&#8217;s only the work of one afternoon. However, it doesn&#8217;t need any additional software and keeps it simple. It serves its purpose and keeps my WordPress installation always up-to-date. If you have any suggestions or questions, feel free to comment below.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.philippheckel.com/2010/01/29/wp-un-wordpress-version-update-notification-with-cron/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to: Postfix as mail relay with greylisting support</title>
		<link>http://blog.philippheckel.com/2010/01/28/how-to-postfix-as-mail-relay-with-greylisting-support/</link>
		<comments>http://blog.philippheckel.com/2010/01/28/how-to-postfix-as-mail-relay-with-greylisting-support/#comments</comments>
		<pubDate>Thu, 28 Jan 2010 20:35:11 +0000</pubDate>
		<dc:creator>Philipp C. Heckel</dc:creator>
				<category><![CDATA[Administration]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Debian]]></category>
		<category><![CDATA[Greylisting]]></category>
		<category><![CDATA[Mail]]></category>
		<category><![CDATA[Postfix]]></category>
		<category><![CDATA[SQLgrey]]></category>

		<guid isPermaLink="false">http://blog.philippheckel.com/?p=30</guid>
		<description><![CDATA[Greylisting is a very efficient technique for fighting spam and can reduce the spam messages in your mailbox by more than 90%. It uses the fact that most spammers only try delivering their spam-mails once, whereas real mail transfer agents (such as the ones regular e-mail service providers are using) try delivering each message up [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.greylisting.org/">Greylisting</a> is a very efficient technique for fighting spam and can reduce the spam messages in your mailbox by more than 90%. It uses the fact that most spammers only try delivering their spam-mails once, whereas real mail transfer agents (such as the ones regular e-mail service providers are using) try delivering each message up to 4-5 days before they give up. </p>
<p>I have always wondered why most ESPs don&#8217;t offer greylisting for their mailboxes, but only rely on less effective and resource-hungry post-retrieval filter methods. Unfortunately, my e-mail provider is one of them so that I get at least a couple of spam mails a day &#8230;</p>
<p>Luckily, it is very easy to set up your own mail relay with greylisting support, i.e. a mail server that simply forwards the mail to your real provider once it passes the greylist-filter. </p>
<p>This little tutorial describes how to set up <a href="http://www.postfix.org">Postfix</a> and <a href="http://sqlgrey.sourceforge.net/">SQLgrey</a> as mail relay.</p>
<p><span id="more-30"></span></p>
<h3 id="toc-1-what-you-need">1. What you need</h3>
<ul>
<li>A dedicated or virtual private server with SSH root access.</li>
<li>Access to the DNS entries of your domain for adjusting the MX record; in this post called <em>example.com</em></li>
</ul>
<h3 id="toc-2-how-it-works">2. How it works</h3>
<p>If you have outsourced all e-mail services to a service provider like I have, the MX record of your domain usually points to your provider&#8217;s mail server. That is, your mails go directly to the mail server of your provider, e.g. <strong>Google&#8217;s mail server → your provider&#8217;s mail server</strong>. That is, your DNS configuration looks something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">$ dig example.com mx
...
example.com.		IN	MX	50 mx0.example.com.
mx0.example.com.	IN	A	(your provider's mail server IP)
...</pre></div></div>

<p>In order to pre-process mails with greylisting and blacklisting, your server will handle mails as intermediary, i.e., mails will always traverse your server first; in the above case something like <strong>Google&#8217;s mail server → your mail server → your provider&#8217;s mail server</strong>. Consequently, the MX record has to be changed to the IP address of your server:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">$ dig example.com mx
...
example.com.		IN	MX	50 mx0.example.com.
mx0.example.com.	IN	A	(your server IP)
...</pre></div></div>

<p><strong>But</strong>, first things first: we need to configure our server before we change the DNS records!</p>
<h3 id="toc-3-installation-configuration">3. Installation &amp; Configuration</h3>
<p>If you have a Debian based system, install Postfix, SQLgrey and MySQL using apt-get:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> postfix sqlgrey mysql-server</pre></div></div>

<p>This will install:</p>
<ul>
<li><strong><a href="http://www.postfix.org/">Postfix</a></strong>: a fully functioning MTA which will be configured as mail relay, i.e., instead of storing arriving mails on the system, it will just greylist them and then forward them to their real destination (your provider&#8217;s mail server).</li>
<li><strong><a href="http://sqlgrey.sourceforge.net/">SQLgrey</a></strong>: a SQL-based greylisting add-on for Postfix. Before accepting mails blindly, Postfix will ask the SQLgrey daemon whether to accept the mail or not. SQLgrey keeps track of mail delivery attempts and only replies with success if the foreign MTA tried delivering the mail at least twice.</li>
<li><strong><a href="http://www.mysql.com/">MySQL</a></strong>: a RDBMS which will be used as back-end for storing Postfix&#8217;s routing tables and SQLgrey&#8217;s caching tables. Both Postfix and SQLgrey also support other back-ends such as <a href="http://www.postgresql.org/">PostgreSQL</a>.</li>
</ul>
<h4 id="toc-3-1-configuring-sqlgrey">3.1. Configuring SQLgrey</h4>
<p>SQLgrey&#8217;s config files reside in <em>/etc/sqlgrey/</em>, the main configuration happens in <em>/etc/sqlgrey/sqlgrey.conf</em>. The file is well documented and offers many possibilities. </p>
<p>The most important options are:</p>
<ul>
<li><strong>inet</strong>: IP address and port to bind the daemon to, default is 127.0.0.1:2501</li>
<li><strong>db_*</strong>: database connection details, i.e., database, user and password</li>
<li><strong>greymethod</strong>: defines which <a href="http://en.wikipedia.org/wiki/Classful_network#Introduction_of_address_classes">IP class</a> to use for greylisting. Especially important for big e-mail service providers since the same mail might be delivered from two different IP addresses (Class C greylisting recommended!).</li>
<li><strong>optmethod</strong>: defines if greylisting is enabled by default (optout), or has to be enabled specifically for each address or domain (optin).</li>
</ul>
<h5 id="toc-3-1-1-config-file-etcsqlgreysqlgrey-conf">3.1.1. Config file /etc/sqlgrey/sqlgrey.conf</h5>
<p>My configuration looks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="properties" style="font-family:monospace;"><span style="color: #000080; font-weight:bold;">inet</span> <span style="color: #000000;">=</span><span style="color: #008000; font-weight:bold;"> 10101 </span><span style="color: #808080; font-style: italic;"># bind to localhost:10101</span>
<span style="color: #000080; font-weight:bold;">reconnect_delay</span> <span style="color: #000000;">=</span><span style="color: #008000; font-weight:bold;"> 5 </span><span style="color: #808080; font-style: italic;"># no reconnect before 5 minutes</span>
<span style="color: #000080; font-weight:bold;">max_connect_age</span> <span style="color: #000000;">=</span><span style="color: #008000; font-weight:bold;"> 24 </span><span style="color: #808080; font-style: italic;"># no reconnect after 24 hours</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># database settings</span>
<span style="color: #000080; font-weight:bold;">db_type</span> <span style="color: #000000;">=</span><span style="color: #008000; font-weight:bold;"> mysql</span>
<span style="color: #000080; font-weight:bold;">db_name</span> <span style="color: #000000;">=</span><span style="color: #008000; font-weight:bold;"> sqlgrey</span>
<span style="color: #000080; font-weight:bold;">db_host</span> <span style="color: #000000;">=</span><span style="color: #008000; font-weight:bold;"> localhost</span>
<span style="color: #000080; font-weight:bold;">db_user</span> <span style="color: #000000;">=</span><span style="color: #008000; font-weight:bold;"> sqlgrey</span>
<span style="color: #000080; font-weight:bold;">db_pass</span> <span style="color: #000000;">=</span><span style="color: #008000; font-weight:bold;"> sqlgreypassword</span>
<span style="color: #000080; font-weight:bold;">db_cleandelay</span> <span style="color: #000000;">=</span><span style="color: #008000; font-weight:bold;"> 1800 </span>
<span style="color: #000080; font-weight:bold;">clean_method</span> <span style="color: #000000;">=</span><span style="color: #008000; font-weight:bold;"> sync </span><span style="color: #808080; font-style: italic;"># 'async' is said to be buggy</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># greylist by class C network. eg: 2.3.4.6 connection</span>
<span style="color: #808080; font-style: italic;"># accepted if 2.3.4.145 did connect earlier</span>
<span style="color: #000080; font-weight:bold;">greymethod</span> <span style="color: #000000;">=</span><span style="color: #008000; font-weight:bold;"> classc</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># one must optin to have its (incoming) messages being greylisted</span>
<span style="color: #000080; font-weight:bold;">optmethod</span> <span style="color: #000000;">=</span><span style="color: #008000; font-weight:bold;"> optin</span></pre></div></div>

<h5 id="toc-3-1-2-database">3.1.2. Database</h5>
<p>SQLgrey has a fixed database structure which is set up automatically when the script is started. All that needs to be done is to create a new database <em>sqlgrey</em> with a corresponding user. You can do this manually, or with a tool like <a href="http://www.phpmyadmin.net/">phpMyAdmin</a>:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">USER</span> <span style="color: #ff0000;">'sqlgrey'</span>@<span style="color: #ff0000;">'localhost'</span> <span style="color: #993333; font-weight: bold;">IDENTIFIED</span> <span style="color: #993333; font-weight: bold;">BY</span> <span style="color: #ff0000;">'sqlgreypassword'</span>;
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">DATABASE</span> <span style="color: #993333; font-weight: bold;">IF</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">EXISTS</span> <span style="color: #ff0000;">`sqlgrey`</span> ;
<span style="color: #993333; font-weight: bold;">GRANT</span> <span style="color: #993333; font-weight: bold;">ALL</span> PRIVILEGES <span style="color: #993333; font-weight: bold;">ON</span> <span style="color: #ff0000;">`sqlgrey`</span> <span style="color: #66cc66;">.</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">TO</span> <span style="color: #ff0000;">'sqlgrey'</span>@<span style="color: #ff0000;">'localhost'</span>;
<span style="color: #993333; font-weight: bold;">FLUSH</span> PRIVILEGES;</pre></div></div>

<h5 id="toc-3-1-3-populating-the-database">3.1.3. Populating the database</h5>
<p>SQLgrey automatically creates the required tables when it starts for the first time. So start the daemon using the provided init.d-script:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>init.d<span style="color: #000000; font-weight: bold;">/</span>sqlgrey start</pre></div></div>

<p>This creates a couple of tables in the <em>sqlgrey</em>-database. For our purpose and configuration, the tables <em>optin_email</em> and <em>optin_domain</em> are most interesting because only domains and e-mail addresses in these tables will be greylisted.</p>
<p>For our example, we will enable greylisting for the whole domain <em>example.com</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> <span style="color: #ff0000;">`sqlgrey`</span><span style="color: #66cc66;">.</span><span style="color: #ff0000;">`optin_domain`</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`domain`</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'example.com'</span><span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>That&#8217;s it for SQLgrey. Once we connect it to Postfix, it&#8217;ll provide us with the greylisting service we want. </p>
<h4 id="toc-3-2-configuring-postfix">3.2. Configuring Postfix</h4>
<p>Postfix is a very flexible and powerful mail transfer agent (MTA) and can be used as final destination, or mail forwarder (mail relay). For this scenario, Postfix will be a <em>mail relay</em> which only forwards an e-mail if</p>
<ul>
<li>its recipient is listed in the database</li>
<li>and it passes the greylisting-filter</li>
</ul>
<p>The configuration files of Postfix reside in <em>/etc/postfix/</em>. The most interesting file for our purpose is <em>/etc/postfix/main.cf</em>.</p>
<p>In order to not be confused by all the more or less useful config parameters, the file shown here is <em>minimal</em>, i.e., you <em>cannot</em> remove any parameter without major consequences. Details to each of them can be found in the <a href="http://www.postfix.org/postconf.5.html">Postfix configuration man-page</a>.</p>
<p>The most important parameters for the configuration as mail relay are:</p>
<ul>
<li><strong><a href="http://www.postfix.org/postconf.5.html#myhostname">myhostname</a></strong>: this defines your hostname, i.e., in this case <em>relay.example.com</em>. Regarding the hostname, two things must be considered very thoroughly:
<ol>
<li>The hostname must resolve to the IP address of your server, i.e., make sure you don&#8217;t state a fake host here. Postfix uses this value as <a href="http://en.wikipedia.org/wiki/Simple_Mail_Transfer_Protocol">HELO/EHLO</a> identification, and some mail servers might <strong>reject</strong> your mails if  this value doesn&#8217;t resolve to your server&#8217;s IP address.</li>
<li>If you use your top level domain here, e.g. example.com, some mail servers might additionally perform a <a href="http://en.wikipedia.org/wiki/MX_record">MX lookup</a> and match your server&#8217;s IP address with the one of the MX record. In case the MX record points to a different IP address than the A record of the TLD, foreign servers might also <strong>reject</strong> all your mails. In my case, this resulted in log entries like this:

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">postfix/smtp: to=&lt;john.doe@example.com&gt;, 
  relay=mx.my-esp.tld:25,  status=bounced 
  (host mx.somedomain.com[1.2.3.4] refused to talk to me: 
  550 Forged HELO: you are not example.com)</pre></div></div>

<p>As you can see, the foreign hosts suspected me of forging the HELO name, and denied relaying my mails.</li>
</ol>
</li>
<li><strong><a href="http://www.postfix.org/postconf.5.html#relay_domains">relay_domains</a></strong>: this option links to the database table <em>relay_domains</em> and defines the domains managed by this mail server. If a recipient-domain is not in this table, Postfix will reject the mail. For this example, the domain <em>example.com</em> must be added to this DB table.</li>
<li><strong><a href="http://www.postfix.org/postconf.5.html#relay_recipient_maps">relay_recipient_maps</a></strong>: this option links to the database table <em>relay_recipients</em> and defines the e-mail addresses managed by this mail server. If a recipient address is not in this table, Postfix will reject the mail. This option is closely linked to <em>relay_domains</em> and will not work without it!
<p>In this case, only one address will be added to this table: <em>john.doe@example.com</em>.</li>
<li><strong><a href="http://www.postfix.org/postconf.5.html#transport_maps">transport_maps</a></strong>: this option links to the database table <em>transport</em> and defines to which mail server incoming mails will be forwarded. Routing can happen address- or domain-based.
<p>In this case, mails for <em>example.com</em> shall be forwarded to our provider&#8217;s mail server, i.e., this table must have an entry of the form <em>example.com</em> → <em>smtp:[mx.my-esp.tld]</em>.</p>
<p>For details on the value format, read the <a href="http://www.postfix.org/transport.5.html">transport man page</a>.</li>
<li><strong><a href="http://www.postfix.org/postconf.5.html#smtpd_recipient_restrictions">smtpd_recipient_restrictions</a></strong>: this is where the actual magic happens. This option checks the RCPT TO field of each incoming mail, i.e., the recipient, and then queries the greylisting service. Its options closely relate to the <em>relay_*</em>-tables from above:
<ul>
<li><strong><a href="http://www.postfix.org/postconf.5.html#permit_mynetworks">permit_mynetworks</a></strong> allows local applications to send e-mails. If you have web sites running on localhost that may use e-mail, do not remove this option.</li>
<li><strong><a href="http://www.postfix.org/postconf.5.html#reject_unauth_destination">reject_unauth_destination</a></strong> queries the <em>relay_domains</em> SQL table, i.e., it checks whether a the incoming recipient domain is relayed by our server.</li>
<li><strong><a href="http://www.postfix.org/postconf.5.html#reject_unlisted_recipient">reject_unlisted_recipient</a></strong> queries the <em>relay_recipients</em> SQL table to find out if the exact address is relayed.</li>
<li><strong><a href="http://www.postfix.org/postconf.5.html#check_policy_service">check_policy_service</a></strong> queries the SQLgrey daemon which in turn either allows or rejects the mail.</li>
</ul>
</li>
</ul>
<h5 id="toc-3-2-1-config-file-etcpostfixmain-cf">3.2.1 Config file /etc/postfix/main.cf</h5>
<p>Here&#8217;s the minimal <em>main.cf</em> config file to make Postfix a mail relay with greylisting support:</p>

<div class="wp_syntax"><div class="code"><pre class="properties" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># This is a minimal main.cf config file. Make sure to read the above </span>
<span style="color: #808080; font-style: italic;"># comments so you understand what each option means.</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># server name; must resolve to your server's IP address</span>
<span style="color: #000080; font-weight:bold;">myhostname</span> <span style="color: #000000;">=</span><span style="color: #008000; font-weight:bold;"> relay.example.com</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># avoid warning message 'dict_nis_init: NIS ...'</span>
<span style="color: #000080; font-weight:bold;">alias_maps</span> <span style="color: #000000;">=</span> 
&nbsp;
<span style="color: #000080; font-weight:bold;">relay_domains</span> <span style="color: #000000;">=</span><span style="color: #008000; font-weight:bold;"> mysql:/etc/postfix/mysql_relay_domains.cf</span>
<span style="color: #000080; font-weight:bold;">relay_recipient_maps</span> <span style="color: #000000;">=</span><span style="color: #008000; font-weight:bold;"> mysql:/etc/postfix/mysql_relay_recipient_maps.cf</span>
<span style="color: #000080; font-weight:bold;">transport_maps</span> <span style="color: #000000;">=</span><span style="color: #008000; font-weight:bold;"> mysql:/etc/postfix/mysql_transport_maps.cf</span>
&nbsp;
<span style="color: #000080; font-weight:bold;">smtpd_recipient_restrictions</span> <span style="color: #000000;">=</span>
        permit_mynetworks,
        reject_unauth_destination,
        reject_unlisted_recipient,
        check_policy_service inet:127.0.0.1:<span style="">10101</span></pre></div></div>

<h5 id="toc-3-2-2-database">3.2.2. Database</h5>
<p>Postfix is very flexible when it comes to address and route handling. In fact, its configuration doesn&#8217;t need a database back-end at all. However, using a SQL database makes everything much easier. I decided to use a very straight forward database structure which directly relates to Postfix&#8217; configuration options. </p>
<p>First, create a database <em>postfix</em> and a corresponding read-only user:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">USER</span> <span style="color: #ff0000;">'postfix'</span>@<span style="color: #ff0000;">'127.0.0.1'</span> <span style="color: #993333; font-weight: bold;">IDENTIFIED</span> <span style="color: #993333; font-weight: bold;">BY</span> <span style="color: #ff0000;">'postfixpassword'</span>;
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">DATABASE</span> <span style="color: #993333; font-weight: bold;">IF</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">EXISTS</span> <span style="color: #ff0000;">`postfix`</span> ;
<span style="color: #993333; font-weight: bold;">GRANT</span> <span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #993333; font-weight: bold;">ON</span> <span style="color: #ff0000;">`postfix`</span> <span style="color: #66cc66;">.</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">TO</span> <span style="color: #ff0000;">'postfix'</span>@<span style="color: #ff0000;">'127.0.0.1'</span>;
<span style="color: #993333; font-weight: bold;">FLUSH</span> PRIVILEGES;</pre></div></div>

<p><strong>Note</strong>: It is important that you use <em>127.0.0.1</em> as host, and not <em>localhost</em>, because Postfix runs in a <a href="http://en.wikipedia.org/wiki/Chroot">chroot</a>-environment and wouldn&#8217;t be able to access <em>localhost</em>. </p>
<p>After setting up the database, add the following three tables:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #ff0000;">`relay_domains`</span> <span style="color: #66cc66;">&#40;</span>
  <span style="color: #ff0000;">`domain`</span> <span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">255</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span>
  <span style="color: #ff0000;">`active`</span> enum<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'y'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'n'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">DEFAULT</span> <span style="color: #ff0000;">'y'</span><span style="color: #66cc66;">,</span>
  <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span>  <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`domain`</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span>;
&nbsp;
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #ff0000;">`relay_recipients`</span> <span style="color: #66cc66;">&#40;</span>
  <span style="color: #ff0000;">`email`</span> <span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">255</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span>
  <span style="color: #ff0000;">`active`</span> enum<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'y'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'n'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">DEFAULT</span> <span style="color: #ff0000;">'y'</span><span style="color: #66cc66;">,</span>
  <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span>  <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`email`</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span>;
&nbsp;
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #ff0000;">`transport`</span> <span style="color: #66cc66;">&#40;</span>
  <span style="color: #ff0000;">`pattern`</span> <span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">255</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span>
  <span style="color: #ff0000;">`relay`</span> <span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">255</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span>
  <span style="color: #ff0000;">`active`</span> enum<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'y'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'n'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">DEFAULT</span> <span style="color: #ff0000;">'y'</span><span style="color: #66cc66;">,</span>
  <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span>  <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`pattern`</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>In order to connect Postfix with the database, we need to create the three config files specified above: /etc/postfix/mysql_*.cf:</p>

<div class="wp_syntax"><div class="code"><pre class="properties" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># /etc/postfix/mysql_relay_domains.cf</span>
<span style="color: #000080; font-weight:bold;">hosts</span> <span style="color: #000000;">=</span><span style="color: #008000; font-weight:bold;"> 127.0.0.1</span>
<span style="color: #000080; font-weight:bold;">user</span> <span style="color: #000000;">=</span><span style="color: #008000; font-weight:bold;"> postfix-read</span>
<span style="color: #000080; font-weight:bold;">password</span> <span style="color: #000000;">=</span><span style="color: #008000; font-weight:bold;"> postfixpassword</span>
<span style="color: #000080; font-weight:bold;">dbname</span> <span style="color: #000000;">=</span><span style="color: #008000; font-weight:bold;"> postfix</span>
<span style="color: #000080; font-weight:bold;">query</span> <span style="color: #000000;">=</span><span style="color: #008000; font-weight:bold;"> SELECT domain FROM relay_domains WHERE domain='%s' AND active='y'</span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="properties" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># /etc/postfix/mysql_relay_recipient_maps.cf</span>
<span style="color: #000080; font-weight:bold;">hosts</span> <span style="color: #000000;">=</span><span style="color: #008000; font-weight:bold;"> 127.0.0.1</span>
<span style="color: #000080; font-weight:bold;">user</span> <span style="color: #000000;">=</span><span style="color: #008000; font-weight:bold;"> postfix-read</span>
<span style="color: #000080; font-weight:bold;">password</span> <span style="color: #000000;">=</span><span style="color: #008000; font-weight:bold;"> postfixpassword</span>
<span style="color: #000080; font-weight:bold;">dbname</span> <span style="color: #000000;">=</span><span style="color: #008000; font-weight:bold;"> postfix</span>
<span style="color: #000080; font-weight:bold;">query</span> <span style="color: #000000;">=</span><span style="color: #008000; font-weight:bold;"> SELECT email FROM relay_recipients WHERE email='%s' AND active='y'</span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="properties" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># /etc/postfix/mysql_transport_maps.cf</span>
<span style="color: #000080; font-weight:bold;">hosts</span> <span style="color: #000000;">=</span><span style="color: #008000; font-weight:bold;"> 127.0.0.1</span>
<span style="color: #000080; font-weight:bold;">user</span> <span style="color: #000000;">=</span><span style="color: #008000; font-weight:bold;"> postfix-read</span>
<span style="color: #000080; font-weight:bold;">password</span> <span style="color: #000000;">=</span><span style="color: #008000; font-weight:bold;"> postfixpassword</span>
<span style="color: #000080; font-weight:bold;">dbname</span> <span style="color: #000000;">=</span><span style="color: #008000; font-weight:bold;"> postfix</span>
<span style="color: #000080; font-weight:bold;">query</span> <span style="color: #000000;">=</span><span style="color: #008000; font-weight:bold;"> SELECT relay FROM transport WHERE pattern='%s' AND active='y'</span></pre></div></div>

<p>Before we can now start testing our server, we need to compile these config files to Postfix compatible lookup tables. Do that by running the following command:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ postmap <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>postfix<span style="color: #000000; font-weight: bold;">/</span>mysql_<span style="color: #000000; font-weight: bold;">*</span>.cf</pre></div></div>

<h5 id="toc-3-2-3-populate-the-database">3.2.3. Populate the database</h5>
<p>Now we have to fill Postfix&#8217; database with the domains and addresses we&#8217;d like to relay. In particular, that means we have to add <em>example.com</em> to <em>relay_domains</em> and <em>transport</em>, and the full addresses to <em>relay_recipients</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> <span style="color: #ff0000;">`postfix`</span><span style="color: #66cc66;">.</span><span style="color: #ff0000;">`relay_domains`</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`domain`</span> <span style="color: #66cc66;">,</span><span style="color: #ff0000;">`active`</span><span style="color: #66cc66;">&#41;</span>
   <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'example.com'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'y'</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> <span style="color: #ff0000;">`postfix`</span><span style="color: #66cc66;">.</span><span style="color: #ff0000;">`relay_recipients`</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`email`</span> <span style="color: #66cc66;">,</span><span style="color: #ff0000;">`active`</span><span style="color: #66cc66;">&#41;</span>
   <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'john.doe@example.com'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'y'</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> <span style="color: #ff0000;">`postfix`</span><span style="color: #66cc66;">.</span><span style="color: #ff0000;">`transport`</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`pattern`</span> <span style="color: #66cc66;">,</span><span style="color: #ff0000;">`relay`</span> <span style="color: #66cc66;">,</span><span style="color: #ff0000;">`active`</span><span style="color: #66cc66;">&#41;</span>
   <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'example.com'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'smtp:[mx.my-e-mail-service-provider.tld]'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'y'</span><span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>The entry structure for each table is different. Please refer to the Postfix manual for details (cp. <a href="http://www.postfix.org/transport.5.html">transport</a>, <a href="http://www.postfix.org/postconf.5.html#relay_domains">relay_domains</a>, and <a href="http://www.postfix.org/postconf.5.html#relay_recipient_maps">relay_recipient_maps</a>).</p>
<p><strong>Note</strong>: the database structure above is not optimal since it requires redundant entries in three different tables. Even though the structure is not perfect, I have chosen this layout to make it easily understandable!</p>
<h3 id="toc-4-test-your-server">4. Test your server</h3>
<p>After this short configuration period it&#8217;s now time to finally start the Postfix server:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>init.d<span style="color: #000000; font-weight: bold;">/</span>postfix start</pre></div></div>

<p>To make sure you didn&#8217;t make any mistakes in the configuration, you should now check the log files. Postfix and SQLgrey both use syslog so that you should be able to determine the system&#8217;s status like this:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">tail</span> <span style="color: #660033;">-n</span> <span style="color: #000000;">20</span> <span style="color: #660033;">-f</span> <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>log<span style="color: #000000; font-weight: bold;">/</span>syslog</pre></div></div>

<p>If the log doesn&#8217;t show any errors, we can now try if everything works as expected. To do so, simply connect to the server from your home computer via telnet:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">$ telnet relay.example.com 25
Connected to relay.example.com.
Escape character is '^]'.
220 relay.example.com ESMTP Postfix
HELO somebody
250 relay.example.com
MAIL FROM: some@address.tld
250 2.1.0 Ok
RCPT TO: john.doe@example.com
450 4.7.1 &lt;john.doe@example.com&gt;: 
   Recipient address rejected: Greylisted for 5 minutes</pre></div></div>

<p>If Postfix replies with a 450 error code, i.e., relay temporarily denied, everything works just fine. On the server side, the log should output something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">postfix/smtpd: connect from 1-2-3-4.your-isp.tld[4.3.2.1]
&nbsp;
sqlgrey: grey: new: 4.3.2(4.3.2.1), some@address.tld-&gt;john.doe@example.com 
postfix/smtpd: NOQUEUE: reject: RCPT from 1-2-3-4.your-isp.tld[4.3.2.1]: 
    450 4.7.1 &lt;john.doe@example.com&gt;: 
    Recipient address rejected: Greylisted for 5 minutes; 
    from=&lt;some@address.tld&gt; to=&lt;john.doe@example.com&gt; ....
&nbsp;
postfix/smtpd: disconnect from 1-2-3-4.your-isp.tld[4.3.2.1]</pre></div></div>

<p>Wait 5 minutes and try connecting again via telnet. This time, SQLgrey will detect that this is your second delivery attempt and add the sender e-mail and its IP address to the automatic white list (AWL). Postfix will accept your mail and forward it to your provider&#8217;s mail server (according to the <em>transport</em>-table):</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">postfix/smtpd: connect from 1-2-3-4.your-isp.tld[4.3.2.1]
&nbsp;
sqlgrey: grey: reconnect ok: 4.3.2(4.3.2.1), 
    some@address.tld -&gt; john.doe@example.com (00:22:42) 
sqlgrey: grey: from awl: 4.3.2, some@address.tld added 
&nbsp;
postfix/smtpd: client=1-2-3-4.your-isp.tld[4.3.2.1]
postfix/cleanup: message-id=&lt;201001...@relay.example.com&gt;
postfix/qmgr: from=&lt;some@address.tld&gt;, size=422, ...
postfix/smtp: to=&lt;john.doe@example.com&gt;, 
    relay=mx.my-esp.tld[12.34.56.78]:25, status=sent, ...
postfix/qmgr: removed
&nbsp;
postfix/smtpd: disconnect from 1-2-3-4.your-isp.tld[4.3.2.1]</pre></div></div>

<h3 id="toc-5-go-live-change-the-dns-record">5. Go live: change the DNS record</h3>
<p>Play around a little and make sure that everything works as expected. If it does, change the DNS record like described above, i.e., set the MX record of the domains to be relayed to your server&#8217;s IP address.</p>
<p><strong>Note</strong>: For the first few mails, you should definitely watch the logs. If anything goes wrong, you can always change back the MX record. But be aware that DNS changes might take up to 48h!</p>
<p>If you have any questions, please comment below. I am open for suggestions!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.philippheckel.com/2010/01/28/how-to-postfix-as-mail-relay-with-greylisting-support/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

