User Tools

Site Tools


email

This is an old revision of the document!


Email

Overview

The aim is to put together a simple but secure mail setup for <tt>sihnon.net</tt>.

  • Sending and receiving mail: postfix
  • Reading mail: dovecot (imap), roundcube (https)
  • Security: tls, ssl, sasl, ldap
  • content filtering: amavisd, clamav, spamassassin

The primary MX will be Shadow and the intention is to install a backup MX at a later date.

Installation

Configuration

Postfix

These configuration files are stored in subversion, under configs:/mail/primary/postfix.

/etc/postfix/main.cf|<syntax lang="pfmain"> - Set the proper host and domainname for the server myhostname = shadow.sihnon.net mydomain = sihnon.net - Where locally generated mail appears to come from myorigin = $mydomain - Which domains we are the final destination for mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain - Listen on all interfaces inet_interfaces = all - Define the list of trusted network addresses, able to relay mail mynetworks = cidr:/etc/postfix/network_table - Masquerade incoming and outgoing mail to sihnon.net, no other hosts handle mail for this domain asquerade_domains = sihnon.net masquerade_classes = envelope_sender, envelope_recipient, header_sender, header_recipient - Allow mail of the form user+extension@mydomain recipient_delimiter = + - Don't show the software version in the banner smtpd_banner = $myhostname ESMTP $mail_name - Get alias information from LDAP alias_maps = ldap:/etc/postfix/ldap-aliases.cf - Mail Delivery local_recipient_maps = - Sasl smtpd_sasl_auth_enable = yes smtpd_sasl_type = dovecot smtpd_sasl_path = private/auth smtpd_sasl_security_options = noanonymous broken_sasl_auth_clients = yes - Use TLS when relaying mail smtp_use_tls = yes smtp_tls_note_starttls_offer = yes - Use TLS for receiving mail smtpd_use_tls = yes smtpd_tls_auth_only = yes smtpd_tls_key_file = /etc/postfix/smtp.sihnon.net.key smtpd_tls_cert_file = /etc/postfix/smtp.sihnon.net/crt smtpd_tls_CAfile = /etc/postfix/sub.class2.server.startcom.bundle.crt smtpd_tls_loglevel = 1 smtpd_tls_received_header = yes smtpd_tls_session_cache_timeout = 3600s tls_random_source = dev:/dev/urandom - Restrictions smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination, check_policy_service unix:private/policy - Prevent spammers harvesting email addresses disable_vrfy_command = yes - Be strict about well formed connections and messages strict_rfc821_envelopes = yes smtpd_helo_required = yes smtpd_delay_reject = yes - Content filtering empty_address_recipient = MAILER-DAEMON queue_minfree = 120000000 smtpd_delay_reject = yes - Route all mail through amavis running on the local machine, using the smtp-amavis transport defined in master.cf content_filter = smtp-amavis:[[127.0.0.1]]:10024 - Alerts in a user's shell when there's new mail biff = no </syntax>

The <tt>network_table</tt> hash defines the list of local network addresses. Hosts in these ranges will be allowed to relay mail through postfix. According to http://www.irbs.net/internet/postfix/0709/1630.html, the format of this file requires a CIDR block on the left hand side, and any arbitrary comment on the right hand side: /etc/postfix/network_table|<syntax lang="pf"> 127.0.0.0/8 Localhost 10.0.0.0/24 Local 10.0.2.0/24 Wireless 10.10.0.0/24 VPN 10.10.1.0/24 VPN 78.86.202.79 Public 78.86.202.81 Public 78.86.202.83 Public 78.86.202.85 Public 78.86.202.87 Public 78.86.202.89 Public 78.86.202.91 Public 78.86.202.93 Public </syntax>

The <tt>ldap-aliases.cf</tt> file contains the configuration for reading aliases from LDAP: /etc/postfix/ldap-aliases.cf|<syntax lang="conf"> server_host = ldap://ldap.sihnon.net ldap://ldap-slave.sihnon.net server_port = 389 start_tls = yes version = 3 bind_dn = cn=Postfix,ou=Services,ou=People,dc=sihnon,dc=net bind_pw = ****** scope = sub search_bash = dc=sihnon,dc=net </syntax>

Delivery using Dovecot

In order to have dovecot handle the mail delivery itself, we need to add a record to the <tt>master.cf</tt> file so that postfix knows how to pass the mails on. Add the following line to the file.

  • <tt>user=mail:mail</tt> defines the permissions to run the deliver program as.
  • <tt>-d ${user}</tt> defines the email address of the recipient.

/etc/postfix/master.cf|<syntax lang="conf"> dovecot unix - n n - - pipe flags=DRhu user=mail:mail argv=/usr/libexec/dovecot/deliver -d ${user} </syntax>

Then tell postfix to use the dovecot transport instead of local for mail delivery

/etc/postfix/main.cf|<syntax lang="pfmain"> - Transport - we use mailbox_transport rather than local_transport here so that local(8) can - process aliases for us, and then send mails to dovecot for delivery to the end - users only mailbox_transport = dovecot dovecot_destination_recipient_limit = 1 </syntax>

To deliver mail using the recipient user's uid/gid, the deliver binary needs to be run as root using setuid. This carries a security implication, so the permissions must be changed so that only postfix can execute it. The <tt>user=mail:mail</tt> option in the postfix <tt>master.cf</tt> sets which user deliver will be run as; it's important that this group is not shared with any other users. <source lang="bash"> chown root:mail /var/libexec/dovecot/deliver chmod 0754 /var/libexec/dovecot/deliver chmod u+s /var/libexec/dovecot/deliver </source>

Delivery using Procmail

Using procmail has the advantage that users can implement server-side mail filtering before mails are delivered to the inbox. The main disadvantage of using procmail alone is that the dovecot indexes won't get updated as new mail arrives. The solution is to have procmail invoke dovecot's deliver to put the mail in the right place after working out where it needs to go.

This requires a slightly different setup than the dovecot approach above: deliver is invoked by the user rather than <tt>mail</tt>, and should not be setuid. This also means users will need the privileges to create their own maildir in <tt>/var/spool/mail/</tt>.

The maildir needs to be created in advance, otherwise deliver will create an mbox instead of a maildir. Still looking for a way to correct this behaviour.

Setup postfix to deliver through postfix: /etc/postfix/main.cf|<syntax lang="pfmain"> - Pass all mail to procmail; the -p ensures the user's procmailrc is consulted before the system default mailbox_command = /usr/bin/procmail -p -a "$EXTENSION" </syntax>

Setup the default procmailrc, which hands all mail straight off to deliver /etc/procmailrc|<syntax lang="procmail"> - Use dovecot to deliver mail to a maildir in /var/spool/mail/ SHELL="/bin/bash" SENDMAIL="/usr/sbin/sendmail -oi -t" DELIVER="/usr/libexec/dovecot/deliver" MAILDIR="/var/spool/mail/$LOGNAME/" DEFAULT="$MAILDIR/" - Remove the leading space on the next line, required for wiki formatting. :0 | $DELIVER -d $LOGNAME - vim: set filetype=procmail: </syntax>

Set appropriate permissions on <tt>/var/spool/mail</tt>. The directory sticky bit ensures that a user may only delete his or her own maildir, and not anyone elses. <source lang="bash"> chgrp mailusers /var/spool/mail chmod g+w /var/spool/mail chmod +t /var/spool/mail </source>

The <tt>mailusers</tt> group is defined in ldap, and contains any user who should be able to receive mail.

Finishing up

SPF

We will set up SPF to ensure that other sites know which mail servers are allowed to send mail for the sihnon.net domain. All local machines will be configured to route mail through the mail gateways here, which will be marked as trusted. To set up SPF for the local network, add the following records to DNS.

/var/named/zones/sihnon.net|<syntax lang="bindzone"> ; SOA sihnon.net. IN MX 10 mail.sihnon.net. ; SPF sihnon.net. IN TXT "v=spf1 mx mx:jellybean.sihnon.net ~all" mail IN TXT "v=spf1 a ~all" shadow IN TXT "v=spf1 a ~all" </syntax>

/var/named/zones/jellybean.sihnon.net-external|<syntax lang="bindzone"> ; SOA jellybean.sihnon.net. IN MX 10 mail.sihnon.net. ; SPF jellybean.sihnon.net. IN TXT "v=spf1 mx ~all" </syntax>

We can also set up postfix to check SPF records for inbound mail too. Add the following configuration to postfix: /etc/postfix/master.cf|<syntax lang="conf"> policy unix - n n - - spawn user=nobody argv=/usr/bin/policyd-spf </syntax>

Then configure postfix to reject mail from invalid mail servers by adding the following to <tt>smtpd_recipient_restrictions</tt» /etc/postfix/main.cf|<syntax lang="pfmain"> smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination, check_policy_service unix:private/policy </syntax>

Then simply reload postfix for the changes to take effect: <source lang="bash"> /etc/init.d/postfix reload </source>

Content filtering

Every mail passing through the system will also be scanned for spam and viruses. Amavis is a mail content filter that handles talking to both SpamAssassin and ClamAV and dealing with mails as appropriate.

Amavis

amavis has an incredibly long and slightly complex configuration file (~2500 lines of perl). That's too long to paste here, so this will only include the more interesting parameters. The full configuration is stored in subversion, under configs:/mail/primary/.

/etc/amavisd.conf|<source lang="perl"> $mydomain = 'sihnon.net'; $myhostname = 'shadow.sihnon.net'; - Where to send mails after they've passed through amavis $forward_method = 'smtp:[[127.0.0.1]]:10025'; - Same, but for notification mails rather than the original mails $notify_method = $forward_method; - Read a list of local networks from a file @mynetworks_maps = read_array('/etc/amavisd-networks.conf'); - Logging $DO_SYSLOG = 1; $syslog_ident = 'amavis'; $syslog_facility = 'mail'; $syslog_priority = 'debug'; $log_level = 2; - Which addresses to send notifications to for certain types of blocked mail $virus_admin = "virus\@$mydomain"; $spam_admin = "spamalert\@$mydomain"; $dsn_bcc = "maildebug\@$mydomain"; - Whom mail alerts appear to have come from $virus_admin = "virus\@$mydomain"; $spam_admin = "spamalert\@$mydomain"; $dsn_bcc = "maildebug\@$mydomain"; $virus_admin = "virus\@$mydomain"; $spam_admin = "spamalert\@$mydomain"; $dsn_bcc = "maildebug\@$mydomain"; - Use multiple directories in the quarantine $quarantine_subdir_levels = 1; - Where to quarantine mails $virus_quarantine_method = 'local:virus-%m'; $spam_quarantine_method = 'local:spam-%m.gz'; $banned_files_quarantine_method = 'local:banned-%m'; $bad_header_quarantine_method = 'local:badh-%m'; $virus_quarantine_to = 'virus-quarantine'; # traditional local quarantine $banned_quarantine_to = 'banned-quarantine'; # local quarantine $bad_header_quarantine_to = 'bad-header-quarantine'; # local quarantine $spam_quarantine_to = 'spam-quarantine'; # local quarantine - Add a header to the mail, showing it was scanned by us $X_HEADER_TAG = 'X-Virus-Scanned'; $remove_existing_x_scanned_headers = 0; - Tag message subjects if nasties are found $sa_spam_subject_tag = '{SPAM} '; $undecipherable_subject_tag = '{UNCHECKED} '; - spamassassin scoring $sa_local_tests_only = 0; $sa_mail_body_size_limit = 400*1024; $sa_tag_level_deflt = 2.0; $sa_tag2_level_deflt = 6.31; $sa_kill_level_deflt = $sa_tag2_level_deflt; $sa_dsn_cutoff_level = 9; - Allow recipient delimiters $recipient_delimiter = '+'; - Enable full debugging for mails from these addresses @debug_sender_maps = ( [["test-sender\@$mydomain"]] ); </source>

Also, go through the configuration file and enable/disable the virus scanners appropriately. We will be using clamd, but nothing else.

Amavis makes use of a list of local, “trusted” networks, and is configured above to read these from a file: /etc/amavisd-networks.conf|<syntax lang="conf"> - Loopback 127.0.0.1 - Local networks 10.0.0.0/24 10.0.2.0/24 - VPN 10.10.0.0/24 10.10.1.0/24 - Public networks 78.86.202.79 78.86.202.81 78.86.202.83 78.86.202.85 78.86.202.87 78.86.202.89 78.86.202.91 78.86.202.93 </syntax>

Start amavis up, and ensure it runs on boot: <source lang="bash"> /etc/init.d/amavisd start rc-update add amavisd default </source>

Virus scanning

Spam filtering

Dovecot

Dovecot is fairly simple to use, just install and configure it, then start it up.

Dovecot ships with a useful command shows which configuration options have been changed from the defaults values. This is useful for debugging, or documenting which options have been set. <source lang="bash"> dovecot -n </source>

These configuration files are stored in subversion, under configs:/mail/primary/dovecot.

Dovecot has been configured with the following settings changed: /etc/dovecot/dovecot.conf|<syntax> protocols: imaps listen: 78.86.202.85 ssl_cert_file: /etc/dovecot/imap.sihnon.net.crt ssl_key_file: /etc/dovecot/imap.sihnon.net.key login_dir: /var/run/dovecot/login login_executable: /usr/libexec/dovecot/imap-login first_valid_uid: 10000 last_valid_uid: 19999 mail_privileged_group: mail mail_location: maildir:/var/spool/mail/%u mail_debug: yes auth default: passdb: driver: ldap args: /etc/dovecot/dovecot-ldap.conf userdb: driver: prefetch userdb: driver: ldap args: /etc/dovecot/dovecot-ldap.conf socket: type: listen client: path: /var/spool/postfix/private/auth mode: 432 user: postfix group: mail master: path: /var/run/dovecot/auth-master mode: 384 user: mail group: mail </syntax>

The <tt>dovecot-ldap.conf</tt> file configures LDAP authentication: /etc/dovecot/dovecot-ldap.conf|<syntax lang="conf"> - connection details uris = ldap://ldap.sihnon.net ldap://ldap-slave.sihnon.net ldap_version = 3 tls = yes tls_ca_cert_file = /etc/ssl/certs/startcom.crt - authenticate users by looking up the password in the directory using a proxy user auth_bind = no dn = cn=dovecot,ou=Services,ou=People,dc=sihnon,dc=net dnpass = ****** - Directory details base = ou=People,dc=sihnon,dc=net scope = subtree user_arrs = homeDirectory=home,uidNumber=uid,gidNumber=gid - we're matching against local users only, so use the local part of the email address given by postfix user_filter = (&(objectClass=PosixAccount)(uid=%n)) pass_attrs = uid=user,userPassword=password,homeDirectory=userdb_home,uidNumber=userdb_uid,gidNumber=userdb_gid pass_filter = (&(objectClass=posixAccount)(uid=%n)) default_pass_scheme = SSHA </syntax>

Start dovecot up, and make sure it starts on boot: <source lang="bash"> rc-update add dovecot default /etc/init.d/dovecot start </source>

Webmail

Upgrading

Change the current directory to the new branch, eg <source lang="bash"> svn switch https://svn.roundcube.net/branches/release-0.2.1 </source>

Then run the updater script to make sure the configuration file is up to date: <source lang="bash"> ./bin/update.sh </source>

New mail alerts

<tt>pam_mail</tt> alerts you to new (or indeed old) mail in your maildir when you log in (and sometimes after you shell has been inactive for a while). Disable these by commenting out references to <tt>pam_mail</tt> in the <tt>/etc/pam.d/</tt> configuration files.

Troubleshooting

<s>If you see errors like the following, the problem is related to the filesystem permissions - check that the users dovecot runs under has access to the mail directories.</s> Turns out this one is a bug in the 1.1 release, and is fixed in 1.1.14+. To work around the problem, set <tt>log_path</tt> to log to a file instead of using syslog.

0@@

See also

email.1416791658.txt.gz · Last modified: 2014/11/24 01:14 by 0.0.0.0