Installation of Exim4, DoveCot, SquirrelMails

From Andreida
Revision as of 19:12, 23 February 2023 by Andreas (talk | contribs) (→‎Misc)

This is for Debian 7 Wheezy, but seems to work for Debian 10 Buster too


(old Installation of Exim4, DoveCot, SquirrelMails, Debian 5, Debian 6)

Goals

  • Using Debian 7 Wheezy
  • Exim 4 as mail server
  • Using self created certificate
  • Dovecot for imap access
  • Horde as web client
  • SpamAssassin for spam filtering
  • Access from
    • Thunderbird
    • Outlook: works out of the box, but you have to have certificates which match the domain names
  • Backup of mails to a different system
  • virtual users
  • remote management of sieve filters

Exim 4

install

We will use the heavy version to be able to later integrate SpamAssassin.

apt-get install exim4-daemon-heavy

(I don't use this anymore: If you can start programs with X-Server, you would like to get geximon:

apt-get install geximon xauth

Remember to ssh with "-X" or "ForwardX11 yes" in your config)

paniclog

If you get paniclog entries like "address already in use", find out about the other process with

netstat -4anp | grep 25

Chances are, it is something about sendmail. Do

which sendmail

and "ls -l" on the result like

ls -l /usr/sbin/sendmail

or just (ticks, not single quotes)

ls -l `which sendmail`

Chances are, it is a link to exim4 and the installation went wrong. Happens every time for me. Remove the paniclog and restart the server. Check the log /var/log/exim4/mainlog

If it is not the above, perhaps you need to remove the sendmail(-bin) package.

validating

Have a look at the ports:

netstat -apn | grep exim

If you have exim4 listen on port 25, you should be ok.

  • add at least one local user so you can set him as receiver for postmaster etc in the next step

Now you should reconfigure exim4

dpkg-reconfigure exim4-config
  • internet site
  • accept the domain name if you don't know better
  • IP addresses to listen to:
    • leave this empty or make sure you include the external ip
    • ::1 the IP6 variant, if you keep this empty, don't bother now
  • final destination: your domains
  • domains to relay for: normally none (empty)
  • machines to relay for: normally none (empty)
  • DNS queries minimal: your choice (default: no)
  • delivery method: maildir in home directory
  • split: your choice (default: no !!!) The main difference is, where will you later put your modifications
    • non-split: /etc/exim4/exim4.conf.localmacros
    • split: /etc/exim4/conf.d/main/000_localmacros
  • root/postmaster: select the above created user, should really read his mail

Now send a mail:

echo Hello You | mail <user>@<OTHER-domain> -s test-1

You should receive the mail at your account at the OTHER domain.

open firewall

If you have a firewall, open it for incoming at port 25. For example ufw:

ufw allow smtp

or firehol in /etc/firehol/firehol.conf

server smtp accept

An example for a whole firehol.conf:


FIREHOL_LOG_PREFIX="firehol: "

server_mySsh_ports="tcp/23"
client_mySsh_ports="default"

interface any world
  protection strong
  policy drop

  client all accept

  server ICMP accept
  server mySsh accept

  server https accept
  server imaps accept
  server smtp accept
  server imap accept
  server smtps accept

TLS for SMTP

If you will have different mail domains at one ip you will get into problems with Outlook if you do not have one certificate per domain where the certificate matches the domain name. (TODO)


  • install openssl (for certificate) and swaks (for tests) and libnet-ssleay-perl
apt-get install openssl swaks libnet-ssleay-perl
  • edit the cert creation script, check at least the DAYS value. 7300 would be 20 years.
vi /usr/share/doc/exim4-base/examples/exim-gencert
  • execute the script
/usr/share/doc/exim4-base/examples/exim-gencert
  • create file /etc/exim4/exim4.conf.localmacros (non-split!) with
MAIN_TLS_ENABLE = 1
  • reload exim
/etc/init.d/exim4 reload
  • test it locally
swaks -f yourMail@YourDomain.com -t yourMail@YourDomain.com -tls -s localhost
  • What would be bad:
Host did not advertise STARTTLS

sasl for system login

Currently we want system users and system user passwords, so we use SASL:

  • install it
apt-get install sasl2-bin
  • enable for system restart in /etc/default/saslauthd
START=yes
  • add exim user to sasl group
adduser Debian-exim sasl
  • start sasl
/etc/init.d/saslauthd start

enable exim to ask clients for passwords if they want to SEND mails

in /etc/exim4/exim4.conf.template enable the following 2 sections

plain_saslauthd_server:
driver = plaintext
public_name = PLAIN
server_condition = ${if saslauthd{{$auth2}{$auth3}}{1}{0}}
server_set_id = $auth2
server_prompts = :
.ifndef AUTH_SERVER_ALLOW_NOTLS_PASSWORDS
server_advertise_condition = ${if eq{$tls_cipher}{}{}{*}}
.endif

login_saslauthd_server:
   driver = plaintext
   public_name = LOGIN
   server_prompts = "Username:: : Password::"
   # don't send system passwords over unencrypted connections
   server_condition = ${if saslauthd{{$auth1}{$auth2}}{1}{0}}
   server_set_id = $auth1
   .ifndef AUTH_SERVER_ALLOW_NOTLS_PASSWORDS
   server_advertise_condition = ${if eq{$tls_cipher}{}{}{*}}
   .endif
  • activate it
update-exim4.conf && /etc/init.d/exim4 reload
  • add one of the system users you will want to add anyway
  • after installation of dovecot try for example to send a mail with Thunderbird, you should get asked to accept the certificate and give the password

virtual users

Source: https://www.organicdesign.co.nz/Configure_mail_server#Setting_up_mail_users

in exim4.conf.template set domainlist to

vi /etc/exim4/exim4.conf.template
domainlist local_domains = @ : @[] : localhost : partial-lsearch;/etc/exim4/virtual.domains

after section "real_local" add

virtual:
	driver = redirect
	allow_defer
	allow_fail
	data = ${lookup{$local_part@$domain}lsearch*@{/etc/exim4/virtual.users}}
	domains = partial-lsearch;/etc/exim4/virtual.domains
	retry_use_local_part

create the file /etc/exim4/virtual.domains

example.com
example.net

reload settings

update-exim4.conf && /etc/init.d/exim4 reload

change /etc/exim4/virtual.users, you don't have to restart the server for this

regularuser@example.com     : localuser@localhost
forwardinguser@example.com  : someuser@example.org
foo@example.com             : :fail: Foo no longer lives here.
bar@example.com             : :blackhole:
*@example.com               : catchall1@localhost
regularuser@example.net     : localuser2@localhost
forwardinguser@example.net  : someuser2@example.org
*@example.net               : catchall2@localhost

If you have the local user smith but you want only to allow smith to get mail via huber@example.com, then use the following pattern:

huber@example.com : smith@localhost
*@example.com     : :fail: Your message

disable ipv6

to be able to send messages to providers like google, you will have to support ipv6 completely or not at all. So:

add to /etc/exim4/update-exim4.conf.conf

disable_ipv6='true'

add to /etc/sysctl.conf

net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
net.ipv6.conf.eth0.disable_ipv6 = 1

restart the server

shutdown -r now

set some receivers to external mail accounts

  • edit /etc/aliases
  • change the entries to something you like, for example
root : you@yourDomain.com
  • then run
newaliases
  • perhaps you just need to allow root@your-domain.com as valid mail receiver

DoveCot

  • allow in your firewall, for example for ufw
ufw limit imap

or for firehol in /etc/firehol/firehol.conf

server imap accept

Don't forget

firehol start
  • install it
apt-get install dovecot-imapd
  • use same directory for mail as exim4:
vi /etc/dovecot/conf.d/10-mail.conf
mail_location = maildir:~/Maildir
#mail_location = mbox:~/mail:INBOX=/var/mail/%u
/etc/init.d/dovecot restart
  • first test (look for "Dovecot ready")
telnet localhost 143
  • remote test (look for "Dovecot ready") from another computer
telnet <domain> 143
  • remote tls test
openssl s_client -connect <domain>:143 -starttls imap

folders below inbox

Attention: Only customize this for NEW servers where ALL mailboxes are NEW. Otherwise, use the same settings as the old server. Exception: if you know what you are doing :-)


If you want the folders junk, sent etc. below the inbox, then do the following but keep in mind that is is not possible to just copy mail/ or Maildir/ from another server AND change the separator etc.

vi /etc/dovecot/conf.d/10-mail.conf

search for "namespace inbox" and inside that scope change

separator = 

to

separator = /

Then open

vi /etc/dovecot/conf.d/15-mailboxes.conf

and have it look like the following (INBOX/ and auto=subscribe and \Archive), do NOT reformat it to something like:

  mailbox INBOX/Junk   
  {
    special_use = \Junk
    auto=subscribe
  }

This is considered an invalid format by Dovecot :-(


This is the normal format:

namespace inbox {
  mailbox INBOX/Drafts   {
    special_use = \Drafts
    auto=subscribe
  }

  mailbox INBOX/Junk   {
    special_use = \Junk
    auto=subscribe
  }

  mailbox INBOX/Trash   {
    special_use = \Trash
    auto=subscribe
  }

  mailbox INBOX/Sent   {
    special_use = \Sent
    auto=subscribe
  }

  mailbox INBOX/Archive   {
    special_use = \Archive
    auto=subscribe
  }
}

switch server

You can copy "mail" or "Maildir" directories from one server or account to the other. If you copy between servers you will have to have the same prefix/separator in both locations. Or you have to understand this: http://wiki2.dovecot.org/Namespaces or something like it. Whatever you do, after the copy of a Maildir, do

chown -R newUser:newUser Maildir

Spam Assassin

the following is from sysadmin world

  • install spamassassin and the exim filter
apt-get install sa-exim  spamassassin
  • old debian (7): start on each boot:
vi /etc/default/spamassassin
ENABLED=1 
  • new debian (10): start on each boot:
update-rc.d spamassassin enable
  • new debian (10):
vi /etc/default/spamassassin
CRON=1
  • What about Debian 8 and 9? No idea.
  • start
service spamassassin start
  • in /etc/exim4/exim4.conf.template at the top in MAIN CONFIGURATION SETTINGS add:
local_scan_path = /usr/lib/exim4/local_scan/sa-exim.so
  • enable the connector in /etc/exim4/sa-exim.conf. Please be careful, there are some lines with SAEximRunCond but only one with SAEximRunCond: 0. Comment this line out.
#SAEximRunCond: 0 

Logging:

SAEximDebug: 0
  • activate changes in /etc/exim4/exim4.conf.template
/usr/sbin/update-exim4.conf 
  • restart exim
/etc/init.d/exim4 restart

Let Spam Assassin learn from your folders

Spam Assassin can learn what is junk and what is ham (not junk) from your folders, if the users of your mail server put junk mails into certain folders and good mails into certain other folders. If Thunderbird is being used, it is easy.

crontab -e
32 1 * * * . /etc/profile && /usr/bin/sa-learn  --spam /home/*/Maildir/.INBOX.Junk/ > /dev/null
45 2 * * * . /etc/profile && /usr/bin/sa-learn  --ham /home/*/Maildir/.INBOX.Archive* > /dev/null

This way your Spam Assassin will learn each night more. It is important to realize that Spam Assassin does not put junk into certain folders. It will only mark the messages as junk. You have to configure your e-mail program to trust Spam Assassin headers and put marked mails into its junk folders.

SquirrelMail

SquirrelMail does not exist for Debian 10, here the old instructions for Debian 7: SquirrelMail Installation for Debian 7

Do NOT use this! I just point to it and keep it because I don't wan to delete it.

Horde (Webmail, instead of SquirrelMail)

info

Please be careful in this section. I am not 100% sure what I did here. Make sure you have created a real user who will be using his mail account later because you need to give his name as the first admin.

install

Make sure you have the locales installed (should do nothing, but...just in case):

apt-get install locales

Configure them:

dpkg-reconfigure locales

I always keep en_US.UTF-8 and the locale for my country (de_DE.UTF-8).

Install horde and the PDO driver for sqlite for PHP - I hope this made sense ;-)

apt-get install php-horde-webmail php7.3-sqlite3

setup

Modify the port for ssl use:

vi /usr/share/horde/config/conf.php.dist
// $conf['server']['port'] = 80;
$conf['server']['port'] = 443;

prepare the database directory

mkdir /usr/share/horde/database
chown -R www-data:www-data /usr/share/horde/database

call the setup

webmail-install
> sqlite
> /usr/share/horde/database/horde


At some point after this the database file will exist

ls -l /usr/share/horde/database/horde

If it exists and looks like this:

-rw-r--r-- 1 root root 1892352 Nov 20 09:43 horde

then it's wrong. And you should do the same stuff as always:

chown www-data:www-data /usr/share/horde/database/horde
chmod 600 /usr/share/horde/database/horde

HINT HINT HINT: if your horde login succeeded but you get the information that a read-only database can't be written into... then you know you forgot it!


doing weird stuff in the hope it will activate ssl

You already changed the default port above to 443. That was in this context too.

Check the rights for the folders (look for "Directory") and consider to only allow /usr/share/horde

vi /etc/apache2/apache2.conf
<Directory />
    Options FollowSymLinks
    AllowOverride None
    Require all denied
</Directory>

<Directory /usr/share/horde>
    AllowOverride None
    Require all granted
</Directory>

<Directory /var/www/>
    Options Indexes FollowSymLinks
    AllowOverride None
    Require all denied
</Directory>

Disable the normal port 80:

vi /etc/apache2/ports.conf
# Listen 80

<IfModule ssl_module>
    Listen 443
</IfModule>

<IfModule mod_gnutls.c>
    Listen 443
</IfModule>

Enable some mods:

cd /etc/apache2/mods-enabled
ln -s ../mods-available/socache_dbm.load
ln -s ../mods-available/socache_memcache.load
ln -s ../mods-available/socache_shmcb.load
ln -s ../mods-available/ssl.conf
ln -s ../mods-available/ssl.load

Disable the default (port 80/html) site and enable the ssl default config:

cd /etc/apache2/sites-enabled 
rm 000-default.conf
ln -s ../sites-available/default-ssl.conf

Restart apache:

/etc/init.d/apache2 restart

.htaccess

Depending on your circumstances (only you as user, more security needed...) you can consider to add a .htaccess file to your /usr/share/horde directory. Check out this for some basic info: Apache 2, quickly protect directory with password


done?

Try to reboot your system and then connect to

https://<your-domain>/horde/

Backup

If you have on some server elsewhere a rsnapshot installation running, you can just add your mail server in your /etc/rsnapshot.conf

backup  root@server-mail:/etc/       server-mail/
backup  root@server-mail:/var/www/   server-mail/
backup  root@server-mail:/home/      server-mail/

For the above to work you will need the following:

  • the backup server must be able to connect to the mail-server with ssh with keys, without passwords
  • the .ssh/config must have an entry like this:
Host server-mail
    HostName        123.123.123.123
    User            root
    Port            22
    ForwardX11      no
    IdentityFile    /root/.ssh/id-rsa-server-mail

Moving Server

If you are moving files from one server to the other, then this section is for you.

Create a local ssh key, paste the public part into the authorized_keys file of the old server.

  • domains?
vi /etc/exim4/virtual.domains
update-exim4.conf && /etc/init.d/exim4 reload
  • virtual users?
/etc/exim4/virtual.users
  • add all users to the system
adduser <username>
  • aliases
vi /etc/aliases
root : you@yourDomain.com
newaliases
  • copy mail directories
cd /home
adduser user1
scp -r old-mail:/home/user1/Maildir/ user1/
chown -R user1:user1 user1/Maildir
  • depending on your system, perhaps get the .htaccess file from your old system AND the file with the password and remember the rwx rights:
ls -la /usr/share/horde/.htaccess
ls -la /etc/apache2/.passwd

DNS

MX / A / PTR

Make sure you have the needed DNS entries.

Example
Hostname Type Address
@ MX (Mail) mail.example.com
mail A (Address) 41.42.43.44
41.42.43.44 PTR (reverse DNS) mail.example.com

The PTR is sometimes in the settings for the machine, not in the settings for the domain.

Make sure https://whatismyipaddress.com/blacklist-check does not contain the IP of your mail server.

Make sure you have the fully qualified hostname in your /etc/hosts as first entry in the line with the real IP, something like:

127.0.0.1       localhost localhost.localdomain
::1     localhost localhost.localdomain
278.241.130.121 imap.yourdomain.com imap
xxxx:xxxx:xx::xxxx:xxxx imap.yourdomain.com imap


Check the MX entry:

dig +noall +answer -t MX yourdomain.com

The answer should be the fully qualified name of your mailserver like

imap.yourdomain.com


Check domain -> ip with dig some (ca. 24) hours after you changed it:

dig +noall +answer -t ANY  <hostname>
dig +noall +answer -t ANY imap.yourdomain.com

The answer should be the correct IP.


Check the qualified hostname of your server locally:

hostname -f

If the answer is

imap.yourdomain.com 

then you are good, if the answer is

imap

then you have to fiddle with the hosts file (See above).

SPF

It seems to be needed by some mail servers so you can send them mail. There are many possible variants, using ips, names or using an automatic entry. There must be only ONE SPF entry for your domain. If you need more data, edit the entry, do NOT create multiple SPF entries.


One working simple version for simple servers (replace 1.1.1.1 with the ip of your server):

Hostname: @ (or whatever you use for "all" entries)
Type: "txt" (preferred) or "SPF"
Value: v=spf1 ip4:1.1.1.1 -all

DKIM

(GoogleMail wants a key of 1024 bits or longer)

(source)


  • Start an ssh session and go to /etc/exim/
  • Generate a private and public key to sign your messages with openssl:
openssl genrsa -out dkim.private.key 1024
  • Extract the public key from the private key
openssl rsa -in dkim.private.key -out dkim.public.key -pubout -outform PEM
  • Open /etc/exim4/exim4.conf.localmacros to modify it:
DKIM_DOMAIN = ${lc:${domain:$h_from:}}
DKIM_SELECTOR = x
DKIM_PRIVATE_KEY = /etc/exim4/dkim_rsa.private
DKIM_CANON = relaxed


  • Restart Exim
/etc/init.d/exim4 restart
  • Adjust your DNS settings, create a TXT setting specifying your DKIM (If you changed "dkim_selector" under "Host", "x" will need to be adjusted accordingly.):
Host: x._domainkey
txt value: v=DKIM1; p=<your public key>

How to test:

Then: send an email from this address to an external email and check if both SPF and DKIM are specified correctly in the header. You should see "spf=pass" and "dkim=pass" as well as other configurations depending on which email provider you send to. Hotmail and GMail are both good to confirm these settings.

DMARC

TODO

Email Deliverability

How it works:

  • Step 1: Send an email to ping@tools.mxtoolbox.com
  • Step 2: Once you have sent that message it will reply. Click the link: "View your full Deliverability Report"

Outlook / Windows Mail Problems

vi /etc/exim4/exim4.conf.localmacros
MAIN_TLS_TRY_VERIFY_HOSTS =
update-exim4.conf && /etc/init.d/exim4 reload

Custom certificate

Add "Outbox" as favourite, then you get the exclamation mark for the failed send and can press it and select to use the "bad" certificate. Then you restart Mail and it should be ok.

Sieve Filter (not working correctly yet)

You can add the ability to create filters which do stuff on the server. Like moving certain mails to certain folders. For example everything from @amazon.de goes to INBOX/Amazon.

This is working but the installation has only be done once so far, so it is kind of a "test in progress":

install sieve filter

  • install the new sieve
apt-get install dovecot-managesieved
  • boot the system (multiple times or wait or change stuff with the help of good ol Google until the next item is valid)
shutdown -r now
  • validate something is listening on port 4190 (I grep for dovecot instead of 4190 to see if everything seems ok)
netstat -4lpn | grep dovecot
  • open your firewall for port 4190
 [...]
 server_mySieve_ports="tcp/4190"
 client_mySieve_ports="default"
 interface any world
   protection strong
   policy drop

  client all accept

  server ICMP accept
  server ssh accept

  server imaps accept
  server smtp accept
  server imap accept
  server smtps accept

  server mySieve accept


Something is missing here! The filters can be executed with the manual command but they are not active for incoming mail.

create sieve filter

Easiest way to use this feature now is to use sieve. It worked well for me when I got from the releases page the archive for my OS. For example in my case: sieve-0.5.3-win32-x64.zip

There you can create filters in the script tab. If you want to copy/paste existing filters easily, use the source tab. Example:

#move mail from Amazon to their own folder
require "copy";
require "mailbox";
require "imap4flags";
require "fileinto";
if address :contains "From" "@amazon.de"{
fileinto "INBOX/Amazon";
}

Save this, then test it with

  • go to your mail server
ssh your-mailserver
  • switch to the directory where the sieve filter is, so you don't have to use paths in your commands
cd /home/YOUR-USER/sieve
  • show the filter(s)
ls -l
  • simulate the execution
sieve-filter -u YOUR-USER Move-Amazon.sieve INBOX
  • execute the filter for real
sieve-filter -eW  -u YOUR-USER Move-Amazon.sieve INBOX


Make sure the target folder exists or add a rule to create the folder. If nothing happens, make sure your folders are accessed correctly. Is "Amazon" under INBOX or parallel to it? Etc.

You can google for more filters or just create your own.

Misc

Usernames

If you are using the virtual users from this setup, then you are free to have any e-mail for any username. This is something you could use to improve the security of the accounts. Often servers are attacked where the attacker uses the pre-@ part of the e-mail-address as username and a dictionary-attack for the password.


If you have the e-mail-address huber@world.com, people will attack with username huber and passwords from a dictionary of some kind. But what if use huber has the login name abcdefghij1234567? The attacker would have to test each password for each tested username which would have to come from some kind of dictionary too. The users should not really care. If the password is complicated enough to have to be copy/pasted to avoid errors, why not do the same for the username?


Keep in mind that usernames in Linux should only use digits/lowercase letters/'-' and always start with a lower case letter. I'd avoid '-' too, but that is my preference after reading of certain tools where the devs forgot to implement the correct use of '-' in usernames.

In case you give out new accounts, consider to use weird letter/digit combinations for the username.

I case you want to change existing accounts, you'll have to do at least two changes:

Perhaps do a restart of the system after the changes, just in case tools like dovecot use caches.