Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Browse files

Re-apply doc changes

  • Loading branch information...
commit e61262a609bce9ee0ff5df6e38b1908e21315cc6 1 parent c923c71
Matt Sergeant authored
15 docs/
@@ -6,6 +6,10 @@ For each connection to Haraka there is one connection object.
+* connection.uuid
+A unique UUID for this connection.
* connection.remote_ip
The remote IP address
@@ -31,3 +35,14 @@ A safe object in which you can store connection-specific variables
The current transaction object, valid after MAIL FROM, and destroyed at queue
time, RSET time, or if MAIL FROM was rejected. See the Transaction Object
documentation file.
+* connection.relaying
+A boolean flag to say whether this connection is allowed to relay mails (i.e.
+deliver mails outbound). This is normally set by SMTP AUTH, or sometimes via
+an IP address check.
+* connection.current_line
+For low level use. Contains the current line sent from the remote end,
+verbatim as it was sent. Can be useful in certain botnet detection techniques.
25 docs/
@@ -6,8 +6,8 @@ extent that no mail will even be received unless you have a minimum of a 'rcpt'
plugin and a 'queue' plugin.
The 'rcpt' plugin is used to determine if a particular recipient should be
-allowed to be relayed for. The 'queue' plugin queue's the email somewhere -
-perhaps to disk, or perhaps to an onward SMTP server.
+allowed to be relayed or received for. The 'queue' plugin queue's the email
+somewhere - perhaps to disk, or perhaps to an onward SMTP server.
Anatomy of a Plugin
@@ -22,7 +22,7 @@ to hook it:
exports.hook_rcpt = function (next, connection, params) {
// email address is in params[0]
// do something with the address... then call:
- next(OK);
+ next();
We've introduced a couple of new concepts here, so let's go through them:
@@ -43,7 +43,7 @@ See "The Next Function" below for more details.
-Plugins inherit all the logging methods of logger.js, which are:
+Plugins inherit all the logging methods of `logger.js`, which are:
* logprotocol
* logdebug
@@ -115,7 +115,8 @@ need to define them:
* OK
Required by rcpt and queue plugins if are to allow the email, or the queue was
-successful, respectively.
+successful, respectively. Once a plugin calls next(OK) no further plugins
+will run after it.
Available Hooks
@@ -133,11 +134,25 @@ These are just the name of the hook, with any parameter sent to it:
* noop
* mail ([from, esmtp\_params])
* rcpt ([to, esmtp\_params])
+* rcpt_ok (to)
* data
* data_post
* queue
* deny - called if a plugin returns one of DENY, DENYSOFT or DENYDISCONNECT
+The `rcpt` hook is slightly special. If we have a plugin (prior to rcpt) that
+sets the `connection.relaying = true` flag, then we do not need any rcpt
+hooks, or if we do, none of them need call `next(OK)`. However if
+`connection.relaying` remains `false` (as is the default - you don't want an
+open relay!), then one rcpt plugin MUST return `next(OK)` or your sender
+will receive the error message "I cannot deliver for that user". The most
+obvious choice for this activity is the `rcpt_to.in_host_list` plugin, which
+lists the domains for which you wish to receive email.
+If a rcpt plugin DOES call `next(OK)` then the `rcpt_ok` hook is run. This
+is primarily used by the queue/smtp_proxy plugin which needs to run after
+all rcpt hooks.
Further Reading
5 docs/
@@ -6,6 +6,11 @@ An SMTP transaction is valid from MAIL FROM time until RSET or "final-dot".
+* transaction.uuid
+A unique UUID for this transaction. Is equal to the connection.uuid + '.N'
+where N increments for each transaction on this connection.
* transaction.mail\_from
The value of the MAIL FROM command as an `Address` object.
78 docs/
@@ -26,13 +26,10 @@ reject mails to that address after the expiry date. If the address hasn't
expired yet it will re-write the address to `` before onward
-This document assumes you already have Haraka setup and delivering your
-inbound mail.
What You Will Need
-* Node.js
+* Node.js and npm
* Haraka
* A text editor
* [swaks][1]
@@ -43,17 +40,62 @@ What You Will Need
Getting Started
-The first thing we need to do is create our empty plugin file and have
-Haraka load it. This is as simple as:
+First install Haraka via npm if you haven't already:
+ $ sudo npm -g install Haraka
+Now we can create our project directory to get started with:
+ $ haraka -i /path/to/new_project
+Make sure you use a directory that doesn't exist for your project.
+Next, let's create a new plugin:
+ $ haraka -c /path/to/new_project -p rcpt_to.disposable
+This should output a bunch of information about files it has created:
+ Plugin rcpt_to.disposable created
+ Now edit javascript in: /path/to/new_project/plugins/rcpt_to.disposable.js
+ Add the plugin to config: /path/to/new_project/config/plugins
+ And edit documentation in: /path/to/new_project/docs/plugins/
+So let's do the second part now - load up the `config/plugins` file and lets
+set this up to test things. Comment out most of the plugins, except for
+`rcpt_to.in_host_list` and add in our new plugin, and change the queue
+plugin to `test_queue`. The final file should look like this:
- $ touch plugins/rcpt_to.disposable.js
- $ mv config/plugins config/.plugins; (echo rcpt_to.disposable; cat config/.plugins) > config/plugins
+ # default list of plugins
-Note that the second command pre-pends rcpt_to.disposable to the list of
-plugins - we do this because there will be a `rcpt` plugin later in the list
-which confirms the `RCPT TO` commands as valid for your server. This later
-plugin will mean no other `rcpt` plugins get run, so we need to pre-pend your
-new plugin to the list.
+ # block mails from known bad hosts (see config/dnsbl.zones for the DNS zones queried)
+ #dnsbl
+ # allow bad mail signatures from the config/data.signatures file.
+ #data.signatures
+ # block mail from some known bad HELOs - see config/helo.checks.ini for configuration
+ #helo.checks
+ # block mail from known bad email addresses you put in config/mail_from.blocklist
+ #mail_from.blocklist
+ # Only accept mail where the MAIL FROM domain is resolvable to an MX record
+ #mail_from.is_resolvable
+ # Allow dated tagged addresses
+ rcpt_to.disposable
+ # Only accept mail for your personal list of hosts
+ rcpt_to.in_host_list
+ # Queue mail via qmail-queue
+ #queue/qmail-queue
+ test_queue
+Remember that the ordering here is important - our new plugin has to come
+before `rcpt_to.in_host_list`.
Now fire up your favourite editor and put the following into
the `plugins/rcpt_to.disposable.js` file:
@@ -69,20 +111,20 @@ All we are doing here is logging the fact that we got the recipient.
Check this works. You'll need two terminal windows. In window 1:
$ echo LOGDEBUG > config/loglevel
- $ node haraka.js
+ $ echo >> config/host_list
+ $ sudo haraka -c /path/to/new_project
And in window 2:
$ swaks -h -t -f \
-s localhost -p 25
-(this assumes you are running Haraka on localhost port 25)
In the logs you should see:
[INFO] [rcpt_to.disposable] Got recipient: <>
-Which indicates everything is working.
+Which indicates everything is working. You should also have a file
+`/tmp/mail.eml` containing the email that swaks sent.
Parsing Out The Date
@@ -124,7 +166,7 @@ we now have a date object, which we can now compare to the current date.
Rejecting Expired Emails
-The final edit we have to do is to add in code to compare to the current date
+The next edit we have to do is to add in code to compare to the current date
and reject expired emails. Again, this is very simple:
exports.hook_rcpt = function (next, connection, params) {
Please sign in to comment.
Something went wrong with that request. Please try again.