Postfix server configuration for receiving email
Description
Configuration for local delivery
Setting the limitation for valid emails
Alias configuration
Configuring a script as an alias
Adding an email / user box
Description
After seeing a very simple email sending configuration for the network, we will see how to receive emails and deliver them locally on the machine. Although this configuration is functional, I do not advise you to use it, here are the reasons why I do not recommend it:
The users who will receive the emails will be the system users, result you will have to assign a UID and a GID to each user wishing to have an email. It will be necessary to be careful not to offer them shell (bash, zsh, …) !! I do not like having this configuration I prefer to have used NON-SYSTEM for this service.
We are going to have the option of having multiple domains, however as we use system users we will be limited on the use of email addresses, for example 2 user named thomas it will not be possible to have thomas@example.com and thomas @ toto.com.
The configuration to the limitation of not scalled, this configuration will not allow you, or at least hardly to have 10 domains of emails on the same machine!
So why we break the ass to see it: P, because this allows us to quietly add simple configurations and see the problems as and when. If we put the configuration directly with Mysql and all a user management system the problem identification is more complex. This gives us the opportunity to see the entire configuration process with “minor” changes.
In addition this configuration is interesting if you want to have a server that receives emails locally, I recommend it for use by humans, but if you have an automated processing service by programs, this is very interesting!
Configuration for local delivery
Let’s go back to our email relay configuration, we had the following configuration /etc/postfix/main.cf:
smtpd_banner = $myhostname ESMTP $mail_name
alias_database =
alias_maps =
smtpd_relay_restrictions = permit_mynetworks defer_unauth_destination
myhostname = $myorigin
myorigin = mail.example.com
# mydestination = {{ RELAY_HOST_NAME }}
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 172.17.0.0/16
inet_interfaces = all
inet_protocols = ipv4
relayhost = mail.shibarecords.com
Let’s change the configuration to allow reception for the domain mailtraining.shibarecords.com, as you see I create a subdomain of shibarecords.com, so we will be able to send emails like toto@mailtraining.shibarecords.com.
Here is the entry I will add:
mydestination = mailtraining.shibarecords.com
We restart postfix and we visualize: D:
$ telnet 172.17.0.2 25
Trying 172.17.0.2...
Connected to 172.17.0.2.
Escape character is '^]'.
220 mail.example.com ESMTP Postfix
ehlo toto
250-mail.example.com
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
mail from: thomas@shibarecords
.com
250 2.1.0 Ok
rcpt to: toto@mailtraining.shibarecords
.com
550 5.1.1 <toto@mailtraining.shibarecords
.com>: Recipient address rejected: User unknown in local recipient table
rcpt to:root@mailtraining.shibarecords
.com
250 2.1.5 Ok
data
354 End data with .
un mail de test
.
250 2.0.0 Ok: queued as 291ACA029B1
quit
221 2.0.0 Bye
Connection closed by foreign host.
COOL !! It’s not too bad: P, we see that when sending an email for toto the latter was rejected, not present as a local user. Actually we do not have a user foo on the machine. So I sent it to the root user because he is there.
As a reminder, the current configuration realizes a local delivery to the SYSTEM user!
The email is sent in the directory / var / spool / mail / [username], so in our case for the user root / var / spool / mail / root, here is the example of the content:
$ sudo cat /var/spool/mail/root
From thomas@shibarecords
.com Tue Jan 17 21:51:04 2017
Return-Path: <thomas@shibarecords
.com>
X-Original-To: root@mailtraining.shibarecords
.com
Delivered-To: root@mailtraining.shibarecords
.com
Received: from toto (unknown [172.17.0.1])
by mail.example.com (Postfix) with ESMTP id 291ACA029B1
for <root@mailtraining.shibarecords
.com>; Tue, 17 Jan 2017 21:50:10 +0000 (UTC)
un mail de test
Setting the limitation for valid emails
As we see in the example above the email address is validated BEFORE taking the email, this ensures that system resources are only used for emails for good address. If you do not have this configuration present an attacker could have made a DDOS on your server by sending a large amount of email. Postfix will have to deal with every email as well as filtering systems all that to see that it is not able to deliver it.
It’s great the configuration is now by default (it was not like that before: P), take the time to see the settings that allow this feature.
First parameter allowing this functionality:
smtpdrejectunlisted_recipient (default: TRUE): Value is used to tell $ postfix to reject emails that are not known local delivery addresses or in a relay domain. The system will reject the email if:
The receiving domain matches the parameters: $ mydestination, $ inet_interfaces or $ proxy_interfaces, but the address is not listed in $ localrecipientmaps
The receiving domain is the $ virtual_alias_domains parameter, but is not listed in $ virtual_alias_maps.
The receiving domain is $ virtual_mailbox_domains, but is not listed in $ virtual_mailbox_maps, and $ virtual_mailbox_maps.
The receiving domain is the $ relay_domains parameter, but is not listed in $ relay_recipient_maps, and $ relay_recipient_maps
Good in our case we are talking about the first option let’s look at values values $ localrecipientmaps
$ sudo postconf | egrep 'local_recipient_maps|local_recipient_maps'
local_recipient_maps = proxy:unix:passwd.byname $alias_maps
We see here that the system will validate that the file / etc / passwd via the proxy entry: unix: passwd.byname we also see the aliases, indeed we would like the emails passed to aliases to also pass: D. When setting up the MySQL database as backend we will also see the appropriate mechanism.
We find the input alias_map that we had previously disabled: D, so it’s time to put it in place: D
Alias configuration
As we had very quickly seen there is 2 parameter for aliases:
alias_maps: This parameter is used to define all the aliases, we can have an alias definition with a local file or use the NIS service for example.
alias_database: set only local aliases, it is not possible to retrieve information from a central server. (to be honest with the time as i set the set in mysql, it’s been a very long time that i did not use these 2 parameters, i made myself to the doc: P)
Let’s take a look at the currently available / etc / aliases file:
$ cat /etc/aliases
# See man 5 aliases for format
postmaster: root
The file structure is simple:
Nom_de_l'alias: nom_de_L'utilisateur_reel
Let’s fix our postfix configuration to get support for aliases. Here is the result :
smtpd_banner = $myhostname ESMTP $mail_name
alias_database = hash:/etc/aliases
alias_maps = hash:/etc/aliases
smtpd_relay_restrictions = permit_mynetworks defer_unauth_destination
myhostname = $myorigin
myorigin = mail.example.com
mydestination = mailtraining.shibarecords
.com
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 172.17.0.0/16
inet_interfaces = all
inet_protocols = ipv4
relayhost = mail_relay.fai.com
As you can see, we specified the name of the / etc / aliases file, but we added the hash: prefix. Since the e-mail service can handle a large amount of e-mail, the system must be efficient, reading a well-structured text file is efficient, but reading a pre-mache binary file is even more efficient. Postfix offers several lookup format mechanism you will find the list in the database type documentation. Of course seen the important list we will not be able to see them all but by covering the system hash and mysql you will have the basic principles allowing you to understand others by reading the documentation when the time comes.
Well, we add an alias? We will add a super-root entry that will send the email to the root user.
I edit the file / etc / aliases and add the entry:
$ cat /etc/aliases
# See man 5 aliases for format
postmaster: root
superRoot: root
Once the file is created / modified we will generate the file “binary” for postfix.
$ postalias /etc/aliases
$ ls -ltr /etc/aliases*
-rw-r--r-- 1 root root 66 Jan 18 13:29 /etc/aliases
-rw-r--r-- 1 root root 12288 Jan 18 13:30 /etc/aliases.db
postalias is the specific command for postfix, it is also possible to use the newaliases command which is a more generic command also used by sendmail. The structure of the file and the result is equivalent in both cases.
Here is the result after the generation, well the important thing is that postfix understands him: P:
# cat /etc/aliases.db
Pэh^rootsuperroot$
It is also possible to define aliases of an alias for the purpose that it is transmitted to the user example:
$ cat /etc/aliases
# See man 5 aliases for format
postmaster: root
wannabe: superRoot
superRoot: root
So here the wannabe address points to a superRoot alias pointing to the root user.
As we have fun pursuing: D, it is also possible to redirect the emails of an alias in the trash, example.
$ cat /etc/aliases
# See man 5 aliases for format
postmaster: root
wannabe: superRoot
superRoot: root
noreply: /dev/null
So here the emails for noreply@leDomaine.com will be accepted by the system and directly transmitted to the file / dev / null so directly to the trash! Note that the person who sent the email will have NO notification of the transaction!
Following the generation send an email to wannabe and or superRoot to the domain @ mailtraining.shibarecords.com. I no longer show the telnet command, because it loads the document too much, I would put it if there is a significant error message.
Send to superRoot:
Jan 19 13:13:30 mail01 postfix/smtpd[187]: EB790A029B1: client=unknown[172.17.0.1]
Jan 19 13:13:37 mail01 postfix/cleanup[190]: EB790A029B1: message-id=<>
Jan 19 13:13:37 mail01 postfix/qmgr[170]: EB790A029B1: from=<toto@shibarecords
.com>, size=205, nrcpt=1 (queue active)
Jan 19 13:13:37 mail01 postfix/cleanup[190]: 2229EA03804: message-id=<>
Jan 19 13:13:37 mail01 postfix/local[191]: EB790A029B1: to=<superroot@mailtraining.shibarecords
.com>, relay=local, delay=14, delays=14/0/0/0.01, dsn=2.0.0, status=sent (forwarded as 2229EA03804)
Jan 19 13:13:37 mail01 postfix/qmgr[170]: 2229EA03804: from=<toto@shibarecords
.com>, size=350, nrcpt=1 (queue active)
Jan 19 13:13:37 mail01 postfix/qmgr[170]: EB790A029B1: removed
Jan 19 13:13:37 mail01 postfix/smtp[192]: warning: relayhost configuration problem
Jan 19 13:13:37 mail01 postfix/smtp[192]: 2229EA03804: to=<root@mail.example.com>, orig_to=<superroot@mailtraining.shibarecords.com>, relay=none, delay=0.24, delays=0.01/0/0.24/0, dsn=4.3.5, status=deferred (Host or domain name not found. Name service error for name=mail_relay.fai.com type=A: Host not found)
Send to wannabe:
Jan 19 13:11:46 mail01 postfix/smtpd[187]: connect from unknown[172.17.0.1]
Jan 19 13:12:02 mail01 postfix/smtpd[187]: 4BCB9A029B1: client=unknown[172.17.0.1]
Jan 19 13:12:11 mail01 postfix/cleanup[190]: 4BCB9A029B1: message-id=<>
Jan 19 13:12:11 mail01 postfix/qmgr[170]: 4BCB9A029B1: from=<toto@shibarecords
.com>, size=215, nrcpt=1 (queue active)
Jan 19 13:12:11 mail01 postfix/cleanup[190]: AE80AA03803: message-id=<>
Jan 19 13:12:11 mail01 postfix/local[191]: 4BCB9A029B1: to=<wannabe@mailtraining.shibarecords
.com>, relay=local, delay=19, delays=19/0.01/0/0.01, dsn=2.0.0, status=sent (forwarded as AE80AA03803)
Jan 19 13:12:11 mail01 postfix/qmgr[170]: AE80AA03803: from=<toto@shibarecords
.com>, size=358, nrcpt=1 (queue active)
Jan 19 13:12:11 mail01 postfix/qmgr[170]: 4BCB9A029B1: removed
Jan 19 13:12:12 mail01 postfix/smtp[192]: warning: relayhost configuration problem
Jan 19 13:12:12 mail01 postfix/smtp[192]: AE80AA03803: to=<superRoot@mail.example.com>, orig_to=<wannabe@mailtraining.shibarecords
.com>, relay=none, delay=0.5, delays=0.01/0.01/0.49/0, dsn=4.3.5, status=deferred (Host or domain name not found. Name service error for name=mail_relay.fai.com type=A: Host not found)
Jan 19 13:12:14 mail01 postfix/smtpd[187]: disconnect from unknown[172.17.0.1] ehlo=1 mail=1 rcpt=1 data=1 quit=1 commands=5
So it does not work, we see errors, the system tries to send to mail.example.com instead of delivering locally, COOL a problem: D.
The use of mailq allows us to visualize that emails are always in the queue.
$ mailq
-Queue ID- --Size-- ----Arrival Time---- -Sender/Recipient-------
AE80AA03803 358 Thu Jan 19 13:12:11 toto@shibarecords
.com
(Host or domain name not found. Name service error for name=mail_relay.fai.com type=A: Host not found)
superRoot@mail.example.com
2229EA03804 350 Thu Jan 19 13:13:37 toto@shibarecords
.com
(Host or domain name not found. Name service error for name=mail_relay.fai.com type=A: Host not found)
root@mail.example.com
-- 0 Kbytes in 2 Requests.
But why when using the alias the system sends it to mail.example.com for the “simple, fast and ugly” solution would be to write the alias file as follows:
$ cat /etc/aliases
# See man 5 aliases for format
postmaster: root@mailtraining.shibarecords
.com
wannabe: superRoot@mailtraining.shibarecords
.com
superRoot: root@mailtraining.shibarecords
.com
noreply: /dev/null
As we say this is a workaround, but it has the advantage of showing us another possibility of using aliases to an external email: D.
Let’s dig a little to know the origin of the entry mail.example.com, as I am ultra lazy then I do not like to search I will use postconf to try to identify where this domain comes from:
$ sudo postconf | grep mail.example.com
myorigin = mail.example.com
Haaa !! That’s when you write anything in the configuration is not surprising that it works badly: P. Must put a good value !!
My origin when the machine will appear on the internet or the rest of the network should be what? His machine name of course, so let’s do that!
$ hostname
mail01.mood.shibarecords
.com
$ cat /etc/postfix/main.cf | grep ^myorigin
myorigin = mail01.mood.shibarecords.com
We restart and we look at the behavior, but it will not work, let’s look at the logs when sending:
Jan 19 13:32:25 mail01 postfix/smtpd[438]: connect from unknown[172.17.0.1]
Jan 19 13:32:46 mail01 postfix/smtpd[438]: 10B00A029B1: client=unknown[172.17.0.1]
Jan 19 13:32:49 mail01 postfix/cleanup[441]: 10B00A029B1: message-id=<>
Jan 19 13:32:49 mail01 postfix/qmgr[437]: 10B00A029B1: from=<toto@shibarecords
.com>, size=202, nrcpt=1 (queue active)
Jan 19 13:32:49 mail01 postfix/cleanup[441]: 76F69A03806: message-id=<>
Jan 19 13:32:49 mail01 postfix/local[442]: 10B00A029B1: to=<superRoot@mailtraining.shibarecords
.com>, relay=local, delay=17, delays=16/0.01/0/0.01, dsn=2.0.0, status=sent (forwarded as 76F69A03806)
Jan 19 13:32:49 mail01 postfix/qmgr[437]: 76F69A03806: from=<toto@shibarecords
.com>, size=352, nrcpt=1 (queue active)
Jan 19 13:32:49 mail01 postfix/qmgr[437]: 10B00A029B1: removed
Jan 19 13:32:49 mail01 postfix/smtp[443]: warning: relayhost configuration problem
Jan 19 13:32:49 mail01 postfix/smtp[443]: 76F69A03806: to=<root@mail01.mood.shibarecords.com>, orig_to=<superRoot@mailtraining.shibarecords
.com>, relay=none, delay=0.25, delays=0.01/0.01/0.23/0, dsn=4.3.5, status=deferred (Host or domain name not found. Name service error for name=mail_relay.fai.com type=A: Host not found)
Jan 19 13:32:51 mail01 postfix/smtpd[438]: disconnect from unknown[172.17.0.1] ehlo=1 mail=1 rcpt=1 data=1 quit=1 commands=5
Well we move on, it still does not work, but look now the email is not sent to the domain mail.example.com but to my machine mail01.mood.shibarecords.com, it’s clearly better. Well the IT director will tell you that it does not work anymore, no problem: D.
Why does not it work ??
Where did we say that we accept this area ?? The mydestination parameter indicates what?
$ postconf | grep ^mydesti
mydestination = mailtraining.shibarecords.com
Here we indicate that we are the destination only for mailtraining.shibarecords.com so if it is not for this domain it balances at smarthost, the email relay server. Works as configure, so we will add another domain.
$ cat /etc/postfix/main.cf | grep ^mydesti
mydestination = mailtraining.shibarecords.com mail01.mood.shibarecords.com
We restart postfix and here is the result:
Jan 19 13:37:20 mail01 postfix/cleanup[578]: 061B1A029B1: message-id=<>
Jan 19 13:37:20 mail01 postfix/qmgr[572]: 061B1A029B1: from=<toto@shibarecords
.com>, size=210, nrcpt=1 (queue active)
Jan 19 13:37:20 mail01 postfix/local[579]: 061B1A029B1: to=<root@mail01.mood.shibarecords
.com>, orig_to=<superRoot@mailtraining.shibarecords
.com>, relay=local, delay=12, delays=12/0.01/0/0.01, dsn=2.0.0, status=sent (delivered to mailbox)
Jan 19 13:37:20 mail01 postfix/qmgr[572]: 061B1A029B1: removed
Honestly this is really simple problems when you’re used to it, I think you have to see it once to understand how it works!
Configuring a script as an alias
As we are Hax0r: P, yeah I think this is my buzz word for 2017: P, we will also set up an alias that will send emails to a script. Well here I will simply make a bash script, very simple, but if the topic interests you quickly look on the internet there are libraries perl or Python to do the manipulation. I wanted to tell you that the feature is present! You will have to dig a little!
$ cat /etc/aliases
# See man 5 aliases for format
postmaster: root
wannabe: superRoot
superRoot: root
noreply: /dev/null
script: | /usr/local/bin/processMail.sh
Of course it is necessary to generate the configuration with postalias, here is an example of script the important thing is not the treatment like, but simply to see the possibility.
$ cat /usr/local/bin/processMail.sh
#!/bin/bash
#
# Récupère le courriel depuis le stdin et l'écrit dans un fichier
#
###############################
REP=/tmp/mails
FILE_TO_STORE=$REP/mails-recu
if ! [ -d $REP ] ; then
mkdir $REP
fi
echo "############# BEGIN ##################" >> $FILE_TO_STORE
# écriture du courriel dans le fichier
cat >> $FILE_TO_STORE
echo "############# END ##################" >> $FILE_TO_STORE
Of course the file must have execute permissions: chmod a + x /usr/local/bin/processMail.sh.
Let’s do the sending with telnet and look at the logs:
Jan 19 13:03:41 mail01 postfix/smtpd[171]: connect from unknown[172.17.0.1]
Jan 19 13:04:02 mail01 postfix/smtpd[171]: C3102A029B1: client=unknown[172.17.0.1]
Jan 19 13:04:08 mail01 postfix/cleanup[174]: C3102A029B1: message-id=<>
Jan 19 13:04:08 mail01 postfix/qmgr[170]: C3102A029B1: from=<thomas@shibarecords
.com>, size=202, nrcpt=1 (queue active)
Jan 19 13:04:08 mail01 postfix/local[175]: C3102A029B1: to=<script@mailtraining.shibarecords
.com>, relay=local, delay=18, delays=18/0.01/0/0.01, dsn=2.0.0, status=sent (delivered to command: /usr/local/bin/processMail.sh)
Jan 19 13:04:08 mail01 postfix/qmgr[170]: C3102A029B1: removed
Jan 19 13:04:09 mail01 postfix/smtpd[171]: disconnect from unknown[172.17.0.1] ehlo=1 mail=1 rcpt=1 data=1 quit=1 commands=5
We see the processing by the script of the email! Of course the possibilities are enormous: D.
Adding an email / user box
Well it’s really what I block, if we want to add a user to the domain we will have to create a system user: – /. Moreover, as we have not yet put a remote email retrieval system via the pop3 or imap protocol we will be obliged to provide ssh access to consult e-mails!
Let’s start to see it to move on: P.
I will create a user with his home:
$ sudo useradd toto
$ getent passwd toto
toto:x:1000:1000::/home/toto:
$ sudo mkdir /home/toto
$ sudo chown toto /home/toto
$ sudo passwd toto
Now we can send an email to the user and here is magic in the logs:
Jan 19 21:46:14 mail01 postfix/smtpd[185]: connect from unknown[172.17.0.1]
Jan 19 21:46:33 mail01 postfix/smtpd[185]: F40D6A029B1: client=unknown[172.17.0.1]
Jan 19 21:46:42 mail01 postfix/cleanup[187]: F40D6A029B1: message-id=<>
Jan 19 21:46:42 mail01 postfix/qmgr[169]: F40D6A029B1: from=<thomas@shibarecords
.com>, size=214, nrcpt=1 (queue active)
Jan 19 21:46:42 mail01 postfix/local[188]: F40D6A029B1: to=<toto@mailtraining.shibarecords
.com>, relay=local, delay=17, delays=17/0.01/0/0.01, dsn=2.0.0, status=sent (delivered to mailbox)
Jan 19 21:46:42 mail01 postfix/qmgr[169]: F40D6A029B1: removed
Well that’s all this but how does the person get the email? In the current state of things the only possible method is to establish an ssh connection and to consult the file in the directory / var / spool / mail /.
Of course everyone loves the command line and loves text clients to check their email: P, 2 options:
mail: command quite minimalist but generally present everywhere: D, except the dockers of course must install it
mutt: super powerful text client, the only problem and that’s why I stopped using it to write an email in HTML and well must write the source code in HTML is a bit heavy: P. But he is super powerful like that ;-).
So before seeing the implementation of a pop3 / imap server see the mail command it seems useless, but if you have a server that does not send outgoing email systems this allows you to view emails.
Here is the result with the user toto for 2 emails:
/var/mail/toto: 2 messages 2 new
N 1 Thu Jan 19 21:46 8/326
N 2 Thu Jan 19 21:59 8/309
? 2
Return-Path: <thomas@shibarecords
.com>
X-Original-To: toto@mailtraining.shibarecords
.com
Delivered-To: toto@mailtraining.shibarecords
.com
Received: from toto (unknown [172.17.0.1])
by mail01.mood.shibarecords
.com (Postfix) with ESMTP id 95BDEA029B1
for <toto@mailtraining.shibarecords
.com>; Thu, 19 Jan 2017 21:58:50 +0000 (UTC)
un courriel
? q
Well normally there is the subject, in the list of emails but as when writing I did not use a complete client, I did not put the header including the subject.