Skip to content
This repository

An event driven SMTP server

Merge pull request #550 from msimerson/smtpproxy

smtp_proxy: bug fix, defines an undefined variable
latest commit f5ee4ab58d
Matt Sergeant authored
Octocat-spinner-32 bin Add new -o option to bin/haraka February 11, 2014
Octocat-spinner-32 config geoip: use net_utils.get_public_ip March 29, 2014
Octocat-spinner-32 contrib bsd.rc: added start method March 05, 2014
Octocat-spinner-32 docs geoip: use net_utils.get_public_ip March 29, 2014
Octocat-spinner-32 plugins smtp_proxy: bug fix, defines an undefined variable April 08, 2014
Octocat-spinner-32 tests Merge pull request #537 from msimerson/geoip March 31, 2014
Octocat-spinner-32 .gitignore Changes as suggested by baudehlo: LMTP trigger moved to notes.using_l… February 09, 2014
Octocat-spinner-32 .gitmodules working on packaging change. May 24, 2012
Octocat-spinner-32 .travis.yml Merge branch 'travis' into tests March 25, 2014
Octocat-spinner-32 Dockerfile Added Dockerfile August 17, 2013
Octocat-spinner-32 LICENSE LICENSE and TODO files March 12, 2011
Octocat-spinner-32 Remove additional Travis icon added in error March 25, 2014
Octocat-spinner-32 TODO access: add deprecated notice to legacy plugins March 25, 2014
Octocat-spinner-32 UPGRADE add deprecated notice within legacy plugins December 27, 2013
Octocat-spinner-32 address.js Reconstruct Address objects without parsing February 11, 2014
Octocat-spinner-32 attachment_stream.js Store attachment headers on stream February 23, 2014
Octocat-spinner-32 chunkemitter.js Support node v0.6 by adding in Buffer.concat November 13, 2012
Octocat-spinner-32 config.js Remove console.log entries from config.js March 18, 2014
Octocat-spinner-32 configfile.js config: fix for .ini booleans being returned as strings March 22, 2014
Octocat-spinner-32 connection.js connection: check for transaction before attempts to access objects i… April 08, 2014
Octocat-spinner-32 constants.js Improve logging of plugins and common plugin errors January 12, 2012
Octocat-spinner-32 dsn.js Change all 'instanceof Array' to 'Array.isArray(foo)' July 03, 2012
Octocat-spinner-32 fsync_writestream.js Address v0.10 compatibility April 29, 2013
Octocat-spinner-32 haraka.js Switch to SIGHUP because SIGUSR1 triggers debugger July 02, 2013
Octocat-spinner-32 line_socket.js Allow bind IP to be set in outbound connections March 14, 2013
Octocat-spinner-32 logger.js Exit with error status on logger.dump_logs() December 13, 2012
Octocat-spinner-32 mailbody.js Merge pull request #487 from godsflaw/godsflaw March 17, 2014
Octocat-spinner-32 mailheader.js Prevent plugins adding empty headers February 13, 2014
Octocat-spinner-32 messagestream.js Prevent original message buffer from being modified November 28, 2013
Octocat-spinner-32 net_utils.js net_utils: added get_public_ip, using 'stun' package March 28, 2014
Octocat-spinner-32 outbound.js More outbund fixes/improvements February 11, 2014
Octocat-spinner-32 package.json geoip: added geoip-lite to optional deps March 29, 2014
Octocat-spinner-32 plugins.js Revert c087990 and trim whitespace for 'list' types February 11, 2014
Octocat-spinner-32 result_store.js results: one bug fix, one new feature, 14 new tests March 22, 2014
Octocat-spinner-32 rfc1869.js Finally fix RCPT parsing December 03, 2013
Octocat-spinner-32 run_tests Fix run_tests shell return code on error March 25, 2014
Octocat-spinner-32 server.js Fix worker/master communication with namespacing July 02, 2013
Octocat-spinner-32 smtp_client.js This is a fix for issue #441 February 04, 2014
Octocat-spinner-32 spf.js Fix mx mechanism when no records are returned March 20, 2014
Octocat-spinner-32 timer_queue.js Major fixes to all aspects of outbound July 02, 2013
Octocat-spinner-32 tls_socket.js Add smtp_client idle timeout and add keepalives September 16, 2013
Octocat-spinner-32 transaction.js Add resetting flag to transaction August 21, 2013
Octocat-spinner-32 utils.js spamassassin: Steve's patch January 27, 2014

Haraka - a Node.js Mail Server

Build Status

Haraka is an SMTP server which uses a plugin architecture to implement most of its functionality. It uses a highly scalable event model to be able to cope with thousands of concurrent connections. Plugins are written in Javascript using Node.js, and as such perform extremely quickly. The core Haraka framework is capable of processing thousands of messages per second on the right hardware.

Haraka can be used either as an inbound SMTP server, and is designed with good anti-spam protections in mind (see the plugins directory), or it can be used as an outbound mail server - the most common way of doing this is by running it on port 587 with an "auth" plugin to authenticate your users.

A full mail system for end users is vastly complicated, and so Haraka makes no attempt to be an IMAP server, figure out where mails should be delivered, or implement any of the functionality of a mail store. As such it is common to have a backend mail server which Haraka delivers to for that sort of functionality - Exchange, Postfix, Dovecot or Courier would be examples of such systems.

Haraka does have a scalable outbound mail delivery engine built in. Any mail marked as relaying (such as via an auth plugin) will automatically be queued for outbound delivery.

Join the Mailing List

To get started with Haraka and ask questions about it, please join the mailing list: - the mailing list is implemented as a Haraka plugin.


Getting started with Haraka

Why Use Haraka?

Haraka's primary purpose is to provide you with a much easier to extend mail server than most available SMTP servers out there such as Postfix, Exim or Microsoft Exchange, yet while still running those systems for their excellent ability to deliver mail to users.

The plugin system makes it trivial to code new features. A typical example might be to provide qmail-like extended addresses to an Exchange system, whereby you could receive mail as, and yet still have it correctly routed to This is a few lines of code in Haraka, or maybe someone has already written this plugin.

Plugins are already provided for running mail through SpamAssassin, checking for known bad HELO patterns, checking DNS Blocklists, and watching for violators of the SMTP protocol via the "early_talker" plugin.

Furthermore Haraka comes with a simple plugin called "graph" which shows you real-time charts of which plugins rejected the most mail, allowing you to easily fine-tune your list of plugins to more effectively stop spam.

Installing Haraka

Haraka is written in Javascript and requires node.js to run.

Installation is very simple via npm:

$ npm install -g Haraka

That will provide you with a haraka binary which allows you to setup the service.

Running Haraka

Setting up Haraka is simple. Firstly we need to create the service:

$ haraka -i /path/to/haraka_test

That creates the directory haraka_test and creates config and plugin directories in there, and automatically sets the host name used by Haraka to the output of the hostname command.

This assumes that hostname gives you the correct host you want to receive mail for. If not, edit the config/host_list file. For example if you want to receive mail addressed to, add to the config/host_list file.

Finally just start Haraka:

$ haraka -c /path/to/haraka_test

And it will run.

However the big thing you want to do next is to edit the config/plugins file. This determines what plugins run in Haraka, and controls the overall behaviour of the server. By default the server is setup to receive mails for domains in host_list and deliver them via smtp-forward. Configure the destination in config/smtp_forward.ini.

Each plugin has documentation available via haraka -h plugins/<name>. Look there for information about how each plugin is configured, edit your config/plugins file, restart Haraka and enjoy!

Feel free to write to the mailing list with any questions. Or use github "Issues".

Running from git

If you are unable to use npm to install Haraka, you can run from git by following these steps:

First clone the repository:

$ git clone
$ cd Haraka

Edit config/plugins and config/smtp.ini to specify the plugins and config you want.

Finally run Haraka:

$ node haraka.js


Haraka is fast, due to the nature of using the v8 Javascript engine, and it is scalable due to using async I/O everywhere. On my local system I have managed to scale it up to 5000 emails per second (with minimal plugins).

I welcome other performance evaluations.

License and Author

Haraka is MIT licensed - see the LICENSE file for details.

Haraka is a project started by Matt Sergeant, a 10 year veteran of the email and anti-spam world. Previous projects have been the project leader for SpamAssassin and a hacker on Qpsmtpd, a perl based mail server which is quite similar to Haraka (but not as fast due to perl being slower than Javascript).

Something went wrong with that request. Please try again.