Install your own iOS IMAP mail server with Dovecot and mpop



I have spent a lot of time to get an IMAP server setup for an Apple TV 2.
Except for a small log file imperfection, I have found a well working Apple TV tool composition and configuration. It based on 'Dovecot' and 'mpop'.


Sorry, but this is not an 'One Click Solution'. :-(





What you will get

You will get a small sized and expandable IMAP server with virtual mailboxes which can be used for multiple mail addresses. All connections could be encrypted with TLS/SSL (and PFS). If you are use a trustable and secure Smarthost and if you are encrypt your IMAP communication, you don't have think much about mail password sniffer.
It is up to you to expand the basic configuration the way you want.

What you will not get

This software composition does not (yet) contain a MTA like sendmail or postfix. Your mail client must send the mails directly (and hopefully TLS/SSL encrypted) to a SMTP Smarthost of your choice.
Furthermore the example mail server setup does not contain any Virus, SPAM or Malware protection.
You don't get a fully configured and safe mail server. It is just an example setup to show you IMAP basic functionalities.

What you need


Add the iOS WebStack Cydia Repo Source

You will find all the iOS WebStack project packages here: http://ios-webstack.tk/cydia
ATV2 users can use following shell command:

echo 'deb http://ios-webstack.tk/cydia/ ./' > /etc/apt/sources.list.d/ios-webstack.list
apt-get update


For your security I advice you to:

  • Add the GPG public key of the iOS WebStack repo. (How to)
  • Update/upgrade your Cydia software parts cyclically.



Setup in 4 Steps


In the following example setup, three email addresses are hosted from two mail hoster:
alice@hoster_one.com
a.smith@hoster_one.com
alice_in_wonderland@hoster_two.com
(replace these with your own mail addresses)

The IMAP server setup:

  1. Install and configure 'Dovecot' to let your ATV2 deliver mails to your mail client.
  2. Daemonize 'Dovecot'
  3. Install and configure 'mpop' to retrieves mails from your previous mail provider.
  4. Cyclic call of 'mpop'

You must be logged in as root.


Step 1 - Install and configure Dovecot

Install Dovecot

apt-get update
apt-get install dovecot

Two new unprivileged users are created automatically during the package installation. dovecot:dovecot and dovenull:dovenull

Configure Dovecot

With this configuration 'Dovecot' requires the user 'vmail'.
The new user must have a UID >= 500 !
The user home folder must be /var/vmail .
It it is not possible to login in your iOS device with this user.
This new system user 'vmail' will be the owner of all mail adress files.
'Dovecot' will handle it as a 'Virtual Mail User'.

Create a new system user 'vmail' and a new system group 'vmail':

fullname="Virtual Mail User"
user="vmail"
group=$user
uid="547"
echo "$group:*:$gid:$user" >> /etc/group
echo "$user:*:$uid:$gid::0:0:$fullname:/var/vmail:/usr/bin/false" >> /etc/master.passwd
echo "$user:*:$uid:$gid:$fullname:/var/vmail:/usr/bin/false" >> /etc/passwd
mkdir -p /var/vmail
chown vmail:vmail /var/vmail

Then create the 'Dovecot' log folder /var/log/dovecot

mkdir -p /var/log/dovecot

Now you have to fix a small imperfection. The user 'vmail' must have write permission at this folder (not yet but later)!

chown vmail:wheel /var/log/dovecot

Create a SSL certificates for 'Dovecot'.
What you enter in the fields is entirely your choice. This certificate will be valid for 10 years (10 times 365 days).

openssl req -new -x509 -days 3650 -nodes -out /etc/ssl/certs/dovecot.crt -keyout /etc/ssl/private/dovecot.key

Do not forget to set the permissions on the private key so that no unauthorized people can read it:

chmod 600 /etc/ssl/private/dovecot.key

Now you have to create the 'Dovecot' password file /etc/dovecot/passwd. This file must be include the user/login names and passwords for your local ATV 2 IMAP server. It does not include user/login names from your already existing mail accounts from your mail provider! The usernames does not necessarily correspond to your mail provider mail addresses. However they can be the same. It is easyer to handle them, but it is hard to distinguish them.

alice@hoster_one.com:{PLAIN}flower
a.smith@hoster_one.com:{PLAIN}cherry
alice_in_wonderland@hoster_two.com:{PLAIN}wonderland

And again, set the permissions so that no unauthorized people can read the file:

chown root:dovecot /etc/dovecot/passwd
chmod 640 /etc/dovecot/passwd

After that you have to create the 'Dovecot' config file /etc/dovecot/dovecot.conf with following content:

# Configuration files go to this directory.
# See example configuration files in /usr/local/share/doc/dovecot/example-config/

# This example configuration is a patchwork from some of the files in /usr/local/share/doc/dovecot/example-config/
# It is up to you to expand the configuration the way you want.

# Protocols we want to be serving.
protocols = imap

# SSL/TLS support: yes, no, required.
ssl = required

# PEM encoded X.509 SSL/TLS certificate and private key. They're opened before
# dropping root privileges, so keep the key file unreadable by anyone but
# root. Included doc/mkcert.sh can be used to easily generate self-signed
# certificate, just make sure to update the domains in dovecot-openssl.cnf
ssl_cert = </etc/ssl/certs/dovecot.crt
ssl_key = </etc/ssl/private/dovecot.key

# Disable LOGIN command and all other plaintext authentications unless
# SSL/TLS is used (LOGINDISABLED capability). Note that if the remote IP
# matches the local IP (ie. you're connecting from the same computer), the
# connection is considered secure and plaintext authentication is allowed.
# See also ssl=required setting.
disable_plaintext_auth = yes

# NOTE: See also disable_plaintext_auth setting.
auth_mechanisms = plain

passdb {
  driver = passwd-file
  args = /etc/dovecot/passwd
}

userdb {
  driver = static
  args = uid=vmail gid=vmail home=/var/vmail/%u
}

# Location for users' mailboxes. The default is empty, which means that Dovecot
# tries to find the mailboxes automatically. This won't work if the user
# doesn't yet have any mail, so you should explicitly tell Dovecot the full
# location.
mail_location = maildir:~/Maildir

# It's nice to have separate log files for Dovecot. You could do this
# by changing syslog configuration also, but this is easier.
log_path = /var/log/dovecot/dovecot.log
info_log_path = /var/log/dovecot/dovecot-info.log

# Space-separated list of elements we want to log. The elements which have
# a non-empty variable value are joined together to form a comma-separated
# string.
login_log_format_elements = user=<%u> method=%m rip=%r lip=%l mpid=%e %c %k

#Set permission for LDA
protocol lda {
  # remember to give proper permissions for these files as well
  log_path = /var/log/dovecot/dovecot-deliver-errors.log
  info_log_path = /var/log/dovecot/dovecot-deliver.log
}

Well done

Now you can test your new IMAP server. Please run 'Dovecot' and hope that everything works.

dovecot

I think the following warning is to ignore. If you don't think so, please let me know.

Warning: fd limit (ulimit -n) is lower than required under max. load (256 < 1000), because of default_client_limit

Try to establish a connection with oppenssl.

openssl s_client -connect localhost:imaps

You will find the log file here: /var/log/dovecot

It is time to connect your mail client to your local Apple TV 2 IMAP server.
Please use following client settings:

  • IMAP server address: IP Address of your ATV2
  • IMAP port: 993
  • IMAP TLS/SSL required: yes
  • IMAP user name: with the example config try alice@hoster_one.com
  • IMAP password: with the example config try flower
  • SMTP server address: name of a Smarthost SMTP server
  • SMTP port: you know best
  • SMTP user name: you know best
  • SMTP password: you know best

At this point you can connect to your own IMAP server. You can check for new mails without any error.
Hmm, but there are no new mails. This behavior will be changed in Step 3 :-)

Please kill the 'Dovecot' process with killall (cydia package: shell-cmds)

killall dovecot




Step 2 - Daemonize Dovecot


After this step 'Dovecot' will run as long as the Daemon Launcher Services is active (even after a reboot).

Create the Launcher file /Library/LaunchDaemons/com.atv.dovecot.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>Dovecot</string>
    <key>OnDemand</key>
    <false/>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/local/sbin/dovecot</string>
        <string>-F</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>StandardErrorPath</key>
          <string>/var/log/dovecot/dovecot.log</string>
    <key>StandardOutPath</key>
          <string>/var/log/dovecot/dovecot.log</string>
</dict>
</plist>

Hint:
The output of stdout and stderr is redirected to the log file /var/log/dovecot/dovecot.log

If you would like start 'Dovecot', please use the following command:

launchctl load /Library/LaunchDaemons/com.atv.dovecot.plist

If you would like stop 'Dovecot', please use the following command:

launchctl unload /Library/LaunchDaemons/com.atv.dovecot.plist




Step 3 - Install and configure mpop


The following parts of Step 3 and Step 4 are a little bit complicated.

Install mpop

apt-get update
apt-get install mpop

Configure mpop

'mpop' retrieves mails from one or more POP3 mailboxes, and delivers them through a separate mail delivery agent (MDA) to the local recipient's mailboxes (like Fetchmail). This mailboxes are owned by the system user vmail.
The used MDA is the local delivery agent (LDA) of 'Dovecot' 8-O
Normaly 'mpop' expect a config file in the user home folder ~/ , but we will store it in the system configuration folder /etc .

Please create the file /etc/mpoprc with following content:

################################################################
# mpop will fetch your mails via POP3 from your mail provider #
#                                                              #
# See http://mpop.sourceforge.net/doc/mpop.html                #
#                                                              #
################################################################

# Default values for all accounts.
defaults

# This command enables or disables TLS/SSL encrypted connections to the POP3 server.
# Not every server supports TLS, and many that support it require the 'tls_starttls off' command.
# You can disable it individual below
tls on

# Use the POP3-over-TLS variant instead of the STARTTLS variant.
# With STARTTLS (on, default) or POP3-over-TLS (off). Most servers support the latter variant,
# which is also commonly referred to as "POP3 with SSL".
tls_starttls off

# This command enables or disables checks for the server certificate.
# WARNING: When the checks are disabled, TLS/SSL sessions will be vulnerable to man-in-the-middle attacks!
# You can activate it individual below
tls_certcheck off

# Enable full TLS/SSL certificate checks.
#tls_trust_file /etc/ssl/certs/ca-certificates.crt

# For Dovecot:
# Deliver the mails through a delivery agent (MDA / LDA).
# For that the environment variable DOVECOT_PASSWD_USER must be
# contain a user name from /etc/dovecot/passwd
delivery mda /usr/local/libexec/dovecot/deliver -d $DOVECOT_PASSWD_USER

# Set the authentication method to automatic (with "on") or manually choose an authentication method.
auth on

# Keep all mails on the POP3 provider server, never delete them.
# -> Please change it after you are sure that your Dovecot configuration is running well
keep on


############################################################
# Below you have to configure your provider pop3 mailboxes.#
############################################################

#
# alice@hoster_one.com
#
account Alice
host pop.hoster_one.com
user alice@hoster_one.com
password that_is_a_real_password_in_plain_text
#tls_certcheck on
#tls_fingerprint E2:8D:DC:EF:52:B0:D1:23:E1:4F:31:AB:9B:EB:39:9F:3A:90:2C:19

#
# a.smith@hoster_one.com
#
account a.smith@hoster_one.com
host pop.hoster_one.com
user a.smith@hoster_one.com
password that_is_a_real_password_in_plain_text
#tls_certcheck on
#tls_fingerprint E2:8D:DC:EF:52:B0:D1:23:E1:4F:31:AB:9B:EB:39:9F:3A:90:2C:19

#
# alice_in_wonderland@hoster_two.com
#
account Wondeland
host pop3.hoster_two.com
user alice_in_wonderland@hoster_two.com
password that_is_a_real_password_in_plain_text
#tls_certcheck on
#tls_fingerprint B1:72:F3:04:E5:D6:67:48:69:8A:3B:7C:6D:8E:3F:D1:62:93:84:C5

'mpop' requires the file permission 0x600 for the used config file:

chmod 600 /erc/mpoprc

The user vmail will call 'mpop'. Therefore the config file must owned by the user vmail

chown vmail:vmail /etc/mpoprc


Now you can test your configuration (in this case for alice@hoster_one.com).
You have to do that with the user vmail:

su vmail

Try it and see what is happened:

export DOVECOT_PASSWD_USER=alice@hoster_one.com
mpop --file=/etc/mpoprc Alice

Go back to root:

exit

If you have already adjusted /etc/mpoprc with your real account settings, you can run 'Dovecot' and start your mail client to check for new mails.

dovecot -F




Step 4 - Cyclic call of mpop


Now it is time to retrieve mails cyclically from your mail provider.
This step will show you how that works with a pseudo cron job. We will use a launchd job wich will execute a script cyclically (e.g. every 15 minutes). This script will then execute 'mpop'.
Because 'mpop' must be run as vmail the script also must be run with vmail rights (see following .plist).

The Script

At first we need the script which execute 'mpop':

Create the folder /etc/cron

mkdir -p /etc/cron

Create the script file /etc/cron/mpop_mail_retrieving.sh with following content:

#!/bin/sh

# This script is executed by launchd. Launchd runs the script as follow: 'su vmail scriptname'.
# For safety reasons this file must be owned by the user 'vmail' and it must have the permission 0x700.
# 'chown vmail:vmail filename' and 'chmod 700 filename' will help you.


# The environment variable MPOP_ACCOUNT must be contain a mpop account from /etc/mpoprc
# The environment variables DOVECOT_PASSWD_USER must be contain a Dovecot user from /etc/dovecot/passwd

#
# retrieve alice@hoster_one.com
#
export MPOP_ACCOUNT=Alice
export DOVECOT_PASSWD_USER=alice@hoster_one.com
/usr/local/bin/mpop --half-quiet --file=/etc/mpoprc -- $MPOP_ACCOUNT

#
# retrieve a.smith@hoster_one.com
#
export MPOP_ACCOUNT=a.smith@hoster_one.com
export DOVECOT_PASSWD_USER=a.smith@hoster_one.com
/usr/local/bin/mpop --half-quiet --file=/etc/mpoprc -- $MPOP_ACCOUNT

#
# retrieve alice_in_wonderland@hoster_two.com
#
export MPOP_ACCOUNT=Wondeland
export DOVECOT_PASSWD_USER=alice_in_wonderland@hoster_two.com
/usr/local/bin/mpop --half-quiet --file=/etc/mpoprc -- $MPOP_ACCOUNT

Change owner and permissions:

chown vmail:vmail /etc/cron/mpop_mail_retrieving.sh
chmod 700 /etc/cron/mpop_mail_retrieving.sh

Try it with the user vmail:

su vmail

Then call the script:

/etc/cron/mpop_mail_retrieving.sh

After you have adjusted the script for your own mail provider settings, you can go back to root:

exit

Cyclic Service

After every thing is fine, you have to create the launchd file /Library/LaunchDaemons/com.cron.mail.retrieve.plist with following content:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
        <key>Label</key>
          <string>mpop - retrieve mails cyclic</string>
        <key>ProgramArguments</key>
           <array>
            <string>/bin/su</string>
            <string>vmail</string>
            <string>/etc/cron/mpop_mail_retrieving.sh</string>
           </array>
        <key>LowPriorityIO</key>
          <true/>
        <key>StartInterval</key>
            <integer>900</integer>
        <key>StandardErrorPath</key>
          <string>/var/log/dovecot/mpop-cron-error.log</string>
        <key>StandardOutPath</key>
          <string>/var/log/dovecot/mpop-cron.log</string>
  </dict>
</plist>

The 'mpop retrieve script' will be execute every 900 seconds.
If you would like change the cycle time, please first stop the service, adjust the cycle time, and then start the service again.

Hint:
The output of stdout and stderr is redirected to the log file /var/log/dovecot/dovecot.log

If you would like start the service, please use the following command:

launchctl load /Library/LaunchDaemons/com.cron.mail.retrieve.plist

If you would like stop the service, please use the following command:

launchctl unload /Library/LaunchDaemons/com.cron.mail.retrieve.plist




Well Done

Add a new mail address

If you would like provide new mail addresses with your Apple TV 2, you have to adjust following files:

  1. /etc/mpoprc - Add a new 'mpop' account with POP3 mail provider settings
  2. /etc/dovecot/passwd - Add a new 'Dovecote' mail user
  3. /etc/cron/mpop_mail_retrieving.sh - Let 'mpop' cyclic retrieve the new mails

Size of Log files

Please remember that your log files will very quickly increase in size!
You can use logrotate to fix this problem.



Optional Step 5 - E-MailRelay (Under Construction)


This optional step shows you how your mail client could send mails directly through your Apple TV 2.
Your Apple TV 2 will act as a SMTP relay server and will forward the mails to your ISP Smarthost.

Under Construction! Therefore not complete!
So stay in touch…

E-MailRelay is a simple SMTP proxy and a store-and-forward message transfer agent (MTA).
When running as a proxy all mail messages can be passed through a user-defined program, such as a spam filter, which can drop, re-address or edit messages as they pass through.

Be carefull! You need to know what you are do!
A private MTA is a very dangerous thing!
If you configure something wrong, your iOS device is a perfect target for bad boys to send SPAM mails.

Under Construction


Install E-MailRelay

apt-get update
apt-get install emailrelay

Preparations

cat /etc/ssl/certs/dovecot.crt /etc/ssl/private/dovecot.key > /etc/ssl/private/emailrelay.pem
chown root:daemon /etc/ssl/private/emailrelay.pem
chmod 640 /etc/ssl/private/emailrelay.pem


/etc/emailrelay.auth

# The client-side secret specified with --client-auth is used when E-MailRelay
# acts as a client to talk to a remote ISP server.
# The file should contain at least one LOGIN client or CRAM-MD5 client entry.
LOGIN client alice@hoster_one.com ISP_Password_for_Alice

# A server-side secret specified with --server-auth is used when your email client 
# tries to authenticate with the E-MailRelay server.
# The file should normally contain several LOGIN server or CRAM-MD5 server entries,
# one for each client.
LOGIN server alice flower_pwd
LOGIN server a.smith cherry_pwd
LOGIN server alice_in_wonderland wonderland_pwd


chmod 600 /etc/emailrelay.auth

Try E-MailRelay

emailrelay \
--remote-clients \
--server-tls /etc/ssl/private/emailrelay.pem \
--port 587 \
--forward-to smtp.hoster_one.com:587 \
--immediate \
--client-tls \
--server-auth /etc/emailrelay.auth \
--client-auth /etc/emailrelay.auth \
--no-syslog \
--log \
--verbose > /var/log/emailrelay.log 2>&1




Useful Links

See also

radare cydia repository - Postfix and Fetchmail for jailbroken iDevices