Have you either been in the situation (recently) that you personal email was disclosed because some website was hacked ?
Wouldn't be cool to have a fwd.facebook@mydomain.com email and use that when registering on Facebook ?
Even better if you did not have to setup such email account on your mail client ?
The solution I'm disclosing here allows you to use any email in the form fwd.*xxx*@domain.com
to forward to a single email account transparently, without any prior configuration when creating a new email account.
It's sweet, simple and a lot more useful, because now, you'll know what website sells your email address to the spammer, what website was hacked and never said so and so on.
Ok, let's give the recipe now.
We will set up mail SMTP server who's in charge of accepting only email for your domain, using a specific format for the user part of the email, and forward it to your personal email's. Then we'll update the DNS records so that other will be able to send you emails to your domain's fresh server Finally, we'll ensure that this mail server is not a relay.
IP
is your public IP address. If it's IPv4, it's in the format a.b.c.d
(for example: 134.23.24.54), if it's IPv6 it's in the format [abc:def::234]
domain.com
is your domain name. I expect you already have some DNS rules that links your domain to your's server IP address (so you have a domain.com A IN IP
rule in your zone). Typically, if you do ping domain.com
from anywhere, it should answer with your IP.your@email
your personal (private) email address/home/you
replace by the path to your home folder$
should be typed as regular user, and command starting with #
should be typed as root. You don't need to type the dollar or hash sign. Please notice that you should be very careful with commands run as root (double check before validating them)Haraka needs nodeJS for its core. So let's install it first:
$ sudo su
# curl -sL https://deb.nodesource.com/setup_10.x | bash -
# apt-get install -y nodejs gcc g++ make swaks
Then, because you might have versioning issue in the future, it's a good idea to load a node versioning manager:
$ curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash
$ export NVM_DIR="$HOME/.nvm"
$ [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
$ [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
We'll need nodejs LTS version:
$ nvm install v10.15.0
Then install Haraka (beware the uppercase here):
$ npm install -g Haraka
This should give some warning but no errors. Ensure everything is working by typing $ haraka -h
This should give this answer:
$ haraka -h
Haraka.js — A Node.js Email Server project
Usage: haraka [options] [path]
Options:
-v, --version Outputs version number
-h, --help Outputs this help message
-h NAME Shows help for NAME
-c, --configs Path to your config directory
-i, --install Copies the default configs to a specified dir
-l, --list List the plugins bundled with Haraka
-p, --plugin Generate a new plugin with the given name
-f, --force Force overwriting of old files
--qlist List the outbound queue
--qstat Get statistics on the outbound queue
--qunstick Unstick (force delivery) for a given domain
-o, --order Show all registered plugins and their run order
-t PLUGIN Plugin test mode
--------------- PLUGIN TEST MODE OPTIONS (all optional) --------------
--ip IP IP address to use
--helo HELO HELO to use
--ehlo EHLO EHLO to use
--envfrom FROM MAIL FROM to use
--envfrom TO RCPT TO(s) to use
--message FILE Message file to use
--dump-mime Dump the MIME structure and body text
--dump-stream Dump the MessageStream to stdout
--skip-deny Continue running hooks after DENY/DENYSOFT
--set-relay Set connection.relaying
Then, we need to install it definitively so it can be run as root (don't worry, it'll decay to a no-priviledge user afterward).
$ sudo ln -sf /home/you/.nvm/versions/node/v10.15.0/bin/haraka /usr/bin/haraka
$ sudo mkdir /var/lib/haraka
$ sudo haraka -i /var/lib/haraka
Haraka's config and queue will be stored in /var/lib/haraka
and will run as unpriviledged user smtp
. Let's create such user and group:
$ sudo addgroup smtp
$ sudo adduser --system --no-create-home --disabled-password --disabled-login smtp --ingroup smtp
Then, we'll need some specific plugin here for the forwarding called rcpt_to.alias_forword
(yes, the name is wrong):
$ cd /home/you/.nvm/versions/node/v10.15.0/lib/node_modules/Haraka/plugins
$ wget https://raw.githubusercontent.com/guoyiang/haraka-alias-forward/master/plugins/rcpt_to.alias_forword.js
$ cd ../config
$ wget https://raw.githubusercontent.com/guoyiang/haraka-alias-forward/master/config/rcpt_to.alias_forword
Unlike other email servers (with those complex term like MTA, MDA, MSA, LDA, etc...), this server is not in charge of keeping (queueing) emails. You don't care about spam filtering here, or antivirus and so on. This work will be done by your usual email provider.
Typically Haraka architecture is based on plugins. For each selected plugin, you must provide a configuration. In this example, I'm running with the minimum set of plugins for the task (you are free to add more later on, but start simple, test and then improve, not the opposite).
The plugins we are using are the following (type the commands below):
$ sudo mv /var/lib/haraka/config/plugins /var/lib/haraka/config/plugins.old
$ sudo su
# echo -e "syslog\ndnsbl\nhelo.checks\nrcpt_to.alias_forword\ndata.headers\nqueue/discard\nlimit" /var/lib/haraka/config/plugins
# nano /var/lib/haraka/config/rcpt_to.alias_forword
This last command should have opened an editor, where you'll enter this (replacing domain by your domain name and your@email by your personal email:
{
"accept_when_match" : true,
"discard_income_mail" : true,
"alias": {
"domain": [
{
"local_name": "fwd.*",
"forward_to": "your@email"
}]
}
}
If you want to also accept regular mail, you can add non wildcard rules in the domain
section like this:
{
"local_name" : "info",
"forward_to": "your@email"
}
This will accept info@domain
and forward to your@email
and also info-whatever@domain
but not something@domain
.
Configure the server with $ sudo nano /var/lib/haraka/smtp.ini
and enter this (replacing IP by your server's IP address):
listen=IP:25,IP:587,[IPv6]:25,[IPv6]:587
public_ip=IP
user=smtp
group=smtp
daemonize=true
daemon_log_file=/var/log/haraka.log
daemon_pid_file=/var/run/haraka.pid
spool_dir=/var/spool/haraka
spool_after=524288
Then test the server is working:
$ sudo kill `cat /var/run/haraka.pid`; sudo rm /var/run/haraka.pid; sudo haraka -c /var/lib/haraka
If the server is working, you shouldn't get a message saying "server shutting down" Please notice that the configuration above listen on TLS (secure) port. In this tutorial, I'm not explaining how to get a certificate for your domain and how to run the TLS plugin. If Haraka complains, remove the port 587 from the config above. It will be a good idea to set up TLS later, since at least to a man in the middle, the email will transit ciphered on the internet
We now need to set up the MX record in your DNS zone. Typically, when someone wants to send a mail to @some.com
, she'll query the DNS record typed MX of the domain some.com
. This will redirect to a server address and she'll then connect on this address and port 25 (SMTP) or 587 (ESMTP) to deliver the mail.
On our side, we'll simply need to tell we have a SMTP server listening on our server by adding a DNS record.
Provided you already have domain. 3600 IN A IP
the number is not that important, you'll need to add (replacing domain by your domain name, beware of the final dot that's required):
domain. 3600 IN MX 10 domain.
If I'm talking chinese here, you'll need to go to your registrar website, that's usually where you can edit your domain's DNS zone record. So for example, let's I have the domain bob.com
on my server located at 1.1.1.1, then I should get the following record in the end:
bob.com. 3600 IN A 1.1.1.1
bob.com. 3600 IN MX 10 bob.com.
Now that the server is started and the domain zone is ready, it's time to test.
Try to send an email either via command line (through swaks
) or your email program to bob@domain
.
You should get a notice that it's rejected (if not, double check the configuration above)
Then try to send a mail to fwd.test@domain
and magically, it should appear in your personal mailbox few seconds later.
If everything is working correctly, we'll need to finalize the installation.
First, we'll only allow smtp user to read/write to the haraka working folder and create a systemd service so the mail server is started on boot.
Use your favorite editor to create the file /lib/systemd/system/haraka.service
as root that should contain:
[Unit]
Description=Haraka MTA
After=syslog.target network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/var/run/haraka.pid
ExecStart=/usr/bin/haraka -c /var/lib/haraka
KillMode=process
PrivateTmp=true
[Install]
WantedBy=multi-user.target
Then run these commands:
$ sudo chown smtp:smtp -R /var/lib/haraka
$ sudo chmod 0660 -R /var/lib/haraka
$ sudo systemctl enable haraka
$ sudo kill `cat /var/run/haraka.pid`; sudo rm /var/run/haraka.pid
$ sudo systemctl start haraka
Provided you're using a password manager (you should), then now, whenever you browse and need to create an account on any website, you'll give the following email fwd.websitename@domain
and a generated password that you'll save in your password manager.
Please notice however that you can't reply to these emails (unless you create the identity in your mail client, but this is a bit painful), so this is mainly used for website that never expect to receive emails like (shopping website, newsletter, etc...)
Next, whenever you'll receive spam, you'll see in the header what website sold your contact or just get hacked. It's then up to you to replicate ;-)
Update: Please see the updated steps required for 100% delivery with new SMTP server's policy in 2020.