Wednesday, March 14, 2007

Basic SMTP Server Setup in Kubuntu (Postfix)

Kubuntu is mostly a desktop oriented linux distribution, but this does not mean that it cannot be used as a server. Several guides exist on the Ubuntu Wiki that teach you how to setup different kinds of servers.

This small tutorial will show you how to set up a local SMTP server (Postfix) for a small office or school with a single domain.

This configuration was tested on Kubuntu Feisty Fawn and in Ubuntu Server distributions. This configuration may work also with Dapper and with Edgy but I have not tested it.

Installing Software

In a fresh installation of Kubuntu simply install the postfix and support packages:

sudo aptitude install postfix libsasl2 sasl2-bin libsasl2-modules libdb3-util

Note that the above command installs SASL too that will be used to enable roaming in our server. During the installation of postfix the package manager will give you the opportunity to configure the most basic options of postfix. I simply select not to configure it at the time and latter modify the configurations files with a text editor. This way I get more control on the look of the file and can format it in a easy to read layout.

Configuring the server

The main configuration file main.cf of postfix can be found inside the "/etc/postfix" directory. One of the selling points of Postfix when compared to other SMTP servers like qmail and sendmail is the simplicity of it's configuration file as we will see.

Edit the file with your favorite editor:

sudo vi /etc/postfix/main.cf

or

sudo kate /etc/postfix/main.cf

or (if you prefer Gnome)

sudo gedit /etc/postfix/main.cf

Simply delete everything in there and copy/paste the following configuration. Make sure to read the comments and replace setting values to reflect your domain name, IP addresses, etc.

###
# Search hostnames in the hosts file before querying DNS.
# This option is very when trying a new domain that has not
# been published by your DNS server or when testing a replacement
# server.

smtp_host_lookup = native,dns

###
# Add a nice banner to say Hi to the mail clients.
# Add a message that reflects your company or school

smtpd_banner = Welcome to SchoolName ESMTP Server.

###
# Some default configuration settings
#

append_dot_mydomain = no # appending .domain is the MUA's job.
biff = no

###
# Alias maps and databases (Can be configured to use a Databases)
#

alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases

###
# Your host name (FQDN)
# This is the name of the machine your server is being installed.
# Normally this name must be a FQDN (Fully Qualified Domain Name)
# that you need to buy. For testing you can add the name to the
# /etc/hosts file and enable postfix to query that file before querying
# a DNS server. Refer to the first option on this setup file

myhostname = you_host_name
mydomain = your_domain.com
myorigin = $mydomain

###
# Domains this server is the final destination. Any mail address
# whose domain is listed here will be delivered locally and no further
# forwarding will occur.

mydestination = $mydomain, $myhostname, localhost.$mydomain, localhost

###
# List of IP subnets allowed to use this server as mail relay. Only
# machines with these IP addresses will be able to send email to addresses
# other than your own domains defined in the "mydestination" option.

relayhost =
mynetworks_style = subnet
mynetworks = 127.0.0.0/8 192.168.1.1/28 169.168.2.1/28

###
# Allows to add comments to mail recipients as specified on RFC 822.
# (i.e. user+comment@your_domain.com)

recipient_delimiter = +

###
# Allow connections to all network interfaces in all IP protocol versions
#

inet_interfaces = all
inet_protocols = all

###
# Enable support for maildir format. The trailing / is important!
# The trailing / tells postfix it must use maildirs instead of mbox format.
#

home_mailbox = .maildir/

###
# Set user mail quota. (0 -> unlimited)
#

mailbox_size_limit = 0

###
# END
#

Some important notes you must remember:

myhostname/mydomain: Replace your_host_name with a FQDN hostname you have registered and your_domain.com with the domain part of the FQDN.

mydestination: This is the list (space separated) of all the domains for which this server is the final destination. This server will deliver all emails addressed to those domains locally (i.e. to your users maildir directories). As you can see we use the values from the mydomain and myhostname options.

mynetworks: Only the IP addresses (individual or subnets) that you specify here will be able to use the server to relay email to other domains. This means that if you want to send an email to another domain (not included in mydestination option) you must do so from a machine with one of the IP addresses specified here or you will get a relay denied error message.

home_mailbox: The default setting that comes with Kubuntu is set to "Maildir". I like to replace it with ".maildir" so the mail directory is hidden and normal users won't see it on Konqueror. Many times novice users mess with the Maildir folder and then I have to do magic to restore it.

Creating the Aliases database

We must create an alias database to receive mails for standard users (i.e. postmaster) and redirect those mails to a real user. To do this we simply edit the "/etc/aliases" file like:

alias1: root
alias2: root
postmaster: root
root: username

You can add as much aliases as you want. Make sure to create a root alias to a real user (i.e. username) that is the actual administrator of the system.

Once you finish adding aliases simply save the file and regenerate the aliases database file with the following command:

sudo newaliases

This will create the aliases.db file used by postfix to lookup aliases. If this file is not found then Postfix will fail to start.

Testing the server

Restart the postfix service to get your server running:

sudo /etc/init.d/postfix restart

To test if the service is running use the telnet command in console:

telnet your_host_name 25
Trying 127.0.1.1...
Connected to your_host_name.
Escape character is '^]'.
220 Welcome to SchoolName ESMTP Server.
quit
221 2.0.0 Bye
Connection closed by foreign host.

The text in blue is the server responses and the text in green are your input commands. The first response you get from the server is a 220 message with the text you set on the smtpd_banner option on the configuration file. With the quit command you simply disconnect from the server.

Some notes on mail relay

Most of the headaches people get setting mail servers are mostly due to the relay settings. To explain how postfix allows or denies email relay we must first understand what is a local domain and an external domain.

Local domains are those domains your mail server is responsible for and that usually are hosted in the server itself (i.e. the users mailbox are in the server hard disk). This domains are specified with the mydestination option in the configuration file.

For example if mydestination contains the domain "mydomain.edu" then any email the server receives with a destination address "juan@mydomain.edu" will be delivered to the user "juan" on the local machine. If the user "juan" does not exist in the local machine then the email will be bounced back to the sender with an user not found error.

An external domain is domain not hosted in your mail server. This includes all domains in existence except those configured in the mydestination option. If your email server receives an email with destination address "juan@otherdomain.com" then the server will reject or relay the email depending on your relay settings.

The default relay configuration is to reject all emails whose destination is not a local domain (i.e. not listed in mydestination option). This is a good default to avoid spammers to use your server to send spam but this will also restrict your server to receive and send emails locally only.

To allow your users to relay emails to external domains you must use the mynetwork option and specify the IP addresses or IP subnets of your users. If the server receives an email with destination address "juan@otherdomain.com" and the sender IP address is in the list of mynetwork option then the server will relay the email to the otherdomain.com mail server.

The drawback of using the mynetwork option is that the list of IP addresses you need to specify usually is not fixed. Some users may have dynamic IP addresses at home or school and sometimes your boss/professor may need to access his email from abroad (i.e. international meeting) making it almost impossible to maintain the list of addresses.

The solution to this problem is to enable roaming in the server. Roaming was implemented with a pop-before-send method in which users had to retrieve their emails using POP service before being able to relay emails with the SMTP server. Latter the SMTP protocol implemented the AUTH command that allows the server to challenge for a username and password before relaying any emails and this method is what we will tackle now.

Enabling Roaming

Postfix implements the AUTH command that allows users to authenticate themselves with the server before sending emails. This approach is more flexible than modifying the IP addresses list in the postfix main.cf configuration file.

For authentication we will use SASL that is very flexible. We could authenticate users using the system usernames/passwords or create a separate database to allow relaying to a selected groups of users only. In Kubuntu because Postfix runs chrooted in /var/spool/postfix we have change a couple paths to make SASL live in the false root. (ie. /var/run/saslauthd becomes /var/spool/postfix/var/run/saslauthd):

sudo mkdir -p /var/spool/postfix/var/run/saslauthd

Next we edit the SASL init configuration defaults "/etc/default/saslauthd" to look like:

START=yes
MECH_OPTIONS=""
THREADS=5
OPTIONS="-c -m /var/spool/postfix/var/run/saslauthd"
MECHANISMS="pam"

For Ubuntu Server the init defaults are a little different. If you are using Ubuntu Server (recomended) instead of Feisty/Edgy then use these defaults:

START=yes
NAME="saslauthd"
DAEMON="/usr/sbin/${NAME}"
DESC="SASL Authentication Daemon"
PWDIR=/var/spool/postfix/var/run/${NAME}
PIDFILE="${PWDIR}/${NAME}.pid"
MECH_OPTIONS=""
THREADS=5
PARAMS="-c -m ${PWDIR}"
MECHANISMS="pam"

We must also create the SASL's configuration file that tells postfix what authentication daemon it should connect for authentication. Create a file "/etc/postfix/sasl/smtp.conf" and insert the following options:

#pwcheck_method: authdaemond
#pwcheck_method: pwcheck
pwcheck_method: saslauthd
log_level: 3
mech_list: plain login

You can choose between the three authentication daemons: authdaemond, saslauthd and pwcheck. The most flexibe is saslauthd that can be configured to use several authentication methods like shadow, sasldb, pam, etc.

Now we must configure Postfix to enable SASL authentication by adding the following to the /etc/postfix/main.cf file:

###
# Postfix SASL Authentication configuration. To allow relay of mails
# from roaming users.
#

smtpd_sasl_local_domain =
smtpd_sasl_auth_enable = yes
smtpd_sasl_path = /etc/postfix/sasl/smtpd
smtpd_sasl_security_options = noanonymous
broken_sasl_auth_clients = yes
smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination

###
# END

The "permit_mynetworks" makes SASL honor the "mynetwork" configuration option inside the main.cf file. This way users that are inside those IP networks can still relay emails even without authentication.

Ubuntu Server little hack

After configuring the SASL daemon I found that the init script "/etc/init.d/saslauthd" was failing to start the service. After some debugging I found that the directory checking code was failing causing the script to end with no warnings nor errors.

To fix this problem we must comment two small lines on the init script "/etc/init.d/saslauthd":

#dir=`dpkg-statoverride --list $PWDIR`
#test -z "$dir" || createdir $dir

Simply edit the script and search for the two lines above and make sure they have a "#" sign in front. Save and we will be ready for testing.

Restart and Test

We must restart both the saslauthd and postfix services for the new configurations to take effect.

sudo /etc/init.d/saslauthd restart
sudo /etc/init.d/postfix restart

And to test the new configuration we proceed as before but with an additional check for the AUTH command:

telnet your_host_name 25
Trying 127.0.1.1...
Connected to your_host_name.
Escape character is '^]'.
220 Welcome to SchoolName ESMTP Server.
ehlo localhost
250-AUTH LOGIN PLAIN
250-AUTH=LOGIN PLAIN
quit
221 2.0.0 Bye
Connection closed by foreign host.

In this test you have to issue the "ehlo localhost" command and the server will respond with a lot of 250- messages. Each message refers to some feature the server supports. To see if the server supports AUTH simply look for the messages:

250-AUTH LOGIN PLAIN
250-AUTH=LOGIN PLAIN

If you see this two messages in the list of responses you get then the server is configured to handle authentication.

1 comment:

  1. Anonymous3:05 AM

    Thank you for posting this ... I'll try it at work, I pretend to show the company I work for how to move our mail service from MS Exchange to a Free Software solution.

    Someone in Mexico.

    ReplyDelete