This is an installation guide for installing MailScanner 5.3 with Postfix on Ubuntu 20.04 LTS. The situation we want to create is first have an incoming mail scanned by MailScanner and after it is found ok to be delivered to your Exchange or Zimbra mail server.
This document is a step by step guide, so you might do some steps differently because you prefer other options or packages.
This document is not finished yet
TTL of your Domains
In the DNS servers of your domain set it to something very short: 15 minutes or so
Update your server
I created a fresh VM for the purpose of writing this how-to, so the first thing you have to do is update everything to the latest and greatest version.
sudo apt-get update
sudo apt-get -y dist-upgrade
sudo apt-get -y upgrade
sudo apt-get -y autoremove
And finally reboot the server:
sudo reboot
Install Chrony NTP Server
As we are running a server and not some kind of desktop, keeping time as accurate as possible is always a good idea. Chrony will keep your system clock within a couple of micro seconds (a couple of thousands of a second) of the real time
sudo apt -y install chrony
Wait a couple of minutes and check wether Chrony is getting the correct time from a source:
chronyc sources
This will display a list of the NTP servers Chrony is polling to get its time. One of the lines should start with “^*” tosignal that is the server Chrony is currently getting its time from.
List all time zones, to get the correct description of your own time zone:
sudo timedatectl list-timezones
Set your correct timezone. In my case “Europe/Amsterdam”, so:
sudo timedatectl set-timezone Europe/Amsterdam
Install Postfix
To install postfix enter:
sudo apt -y install postfix
When asked choose “No configuration”
Install ClamAV
sudo apt install -y clamav clamav-daemon
Enable and start clamd
sudo systemctl enable clamav-daemon sudo systemctl enable clamav-freshclam sudo systemctl start clamav-daemon
Optional: Extra ClamAV signatures
It does not cost much and gives you a load of extra protection: the 4.000.000 virus/malware signatures of securiteinfo.com.
Install Spamassassin
sudo apt -y install spamassassin
Optional: Extra definitions for Spamassassin
Here are some links with extra spamassassin definition files:
- KAM
- Script to install KAM with MailScanner
- Dutch Spamassassin Rules
- Script to install DSR with MailScanner
The extra cf files shoud be placed in /etc/mail/spamassassin
Note for day to day operations: After updatung or installing extra spamassassin cf files MailScanner should be restarted.
Download and install MailScanner
wget https://github.com/MailScanner/v5/releases/download/5.3.4-3/MailScanner-5.3.4-3.noarch.deb
To install MailScanner type:
sudo apt -y install ./MailScanner-5.3.4-3.noarch.deb
Run the configure script:
sudo /usr/sbin/ms-configure
Disable automatic startup of mailscanner for now:
sudo systemctl disable mailscanner
Configure Apparmor
Edit /etc/apparmor.d/usr.sbin.clamd
sudo vi /etc/apparmor.d/usr.sbin.clamd
Add following lines:
# For use with MailScanner
/var/spool/MailScanner/** rw,
/var/spool/MailScanner/incoming/** rw,
As Apparmor can be a pain in the ass: Reboot
sudo reboot
Configure Postfix
To tell Postfix to move all messages to the HOLD queue, do the following: Create the file /etc/postfix/header_checks and add this line:
/^Received:/ HOLD
Create some needed files if they are not already present:
sudo touch /etc/postfix/access
sudo touch /etc/postfix/relay_recipients
sudo touch /etc/postfix/transport
sudo touch /etc/postfix/virtual
Create the Postfix configuration file /etc/postfix/main.cf and add the following lines. Please note the bold lines, you probably need to change something here:
queue_directory = /var/spool/postfix command_directory = /usr/sbin daemon_directory = /usr/lib/postfix/sbin data_directory = /var/lib/postfix mail_owner = postfix myhostname = mail.yourdomain.com # I only use IPv4, so I only enable IPv4 inet_protocols = ipv4 # Listen on all interfaces inet_interfaces = all # The proxy_interfaces parameter specifies the network interface # addresses that this mail system receives mail on by way of a # proxy or network address translation unit. This setting extends # the address list specified with the inet_interfaces parameter. # # You must specify your proxy/NAT addresses when your system is a # backup MX host for other domains, otherwise mail delivery loops # will happen when the primary MX host is down. # #proxy_interfaces = #proxy_interfaces = 1.2.3.4 # The mydestination parameter specifies the list of domains that this # machine considers itself the final destination for. # # These domains are routed to the delivery agent specified with the # local_transport parameter setting. By default, that is the UNIX # compatible delivery agent that lookups all recipients in /etc/passwd # and /etc/aliases or their equivalent. # # The default is $myhostname + localhost.$mydomain. On a mail domain # gateway, you should also include $mydomain. # # Do not specify the names of virtual domains - those domains are # specified elsewhere (see VIRTUAL_README). # # Do not specify the names of domains that this machine is backup MX # host for. Specify those names via the relay_domains settings for # the SMTP server, or use permit_mx_backup if you are lazy (see # STANDARD_CONFIGURATION_README). # # The local machine is always the final destination for mail addressed # to user@[the.net.work.address] of an interface that the mail system # receives mail on (see the inet_interfaces parameter). # # Specify a list of host or domain names, /file/name or type:table # patterns, separated by commas and/or whitespace. A /file/name # pattern is replaced by its contents; a type:table is matched when # a name matches a lookup key (the right-hand side is ignored). # Continue long lines by starting the next line with whitespace. # # See also below, section "REJECTING MAIL FOR UNKNOWN LOCAL USERS". # mydestination = $myhostname, localhost.$mydomain, localhost #mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain #mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain, # mail.$mydomain, www.$mydomain, ftp.$mydomain # REJECTING MAIL FOR UNKNOWN LOCAL USERS # # The local_recipient_maps parameter specifies optional lookup tables # with all names or addresses of users that are local with respect # to $mydestination, $inet_interfaces or $proxy_interfaces. # # If this parameter is defined, then the SMTP server will reject # mail for unknown local users. This parameter is defined by default. # # To turn off local recipient checking in the SMTP server, specify # local_recipient_maps = (i.e. empty). # # The default setting assumes that you use the default Postfix local # delivery agent for local delivery. You need to update the # local_recipient_maps setting if: # # - You define $mydestination domain recipients in files other than # /etc/passwd, /etc/aliases, or the $virtual_alias_maps files. # For example, you define $mydestination domain recipients in # the $virtual_mailbox_maps files. # # - You redefine the local delivery agent in master.cf. # # - You redefine the "local_transport" setting in main.cf. # # - You use the "luser_relay", "mailbox_transport", or "fallback_transport" # feature of the Postfix local delivery agent (see local(8)). # # Details are described in the LOCAL_RECIPIENT_README file. # # Beware: if the Postfix SMTP server runs chrooted, you probably have # to access the passwd file via the proxymap service, in order to # overcome chroot restrictions. The alternative, having a copy of # the system passwd file in the chroot jail is just not practical. # # The right-hand side of the lookup tables is conveniently ignored. # In the left-hand side, specify a bare username, an @domain.tld # wild-card, or specify a user@domain.tld address. # #local_recipient_maps = unix:passwd.byname $alias_maps #local_recipient_maps = proxy:unix:passwd.byname $alias_maps #local_recipient_maps = # The unknown_local_recipient_reject_code specifies the SMTP server # response code when a recipient domain matches $mydestination or # ${proxy,inet}_interfaces, while $local_recipient_maps is non-empty # and the recipient address or address local-part is not found. # # The default setting is 550 (reject mail) but it is safer to start # with 450 (try again later) until you are certain that your # local_recipient_maps settings are OK. # unknown_local_recipient_reject_code = 550 # TRUST AND RELAY CONTROL # The mynetworks parameter specifies the list of "trusted" SMTP # clients that have more privileges than "strangers". # # In particular, "trusted" SMTP clients are allowed to relay mail # through Postfix. See the smtpd_recipient_restrictions parameter # in postconf(5). # # You can specify the list of "trusted" network addresses by hand # or you can let Postfix do it for you (which is the default). # # By allmynetworks_style = subnet), Postfix "trusts" SMTP # clients in the same IP subnetworks as the local machine. # On Linux, this does works correctly only with interfaces specified # with the "ifconfig" command. # # Specify "mynetworks_style = class" when Postfix should "trust" SMTP # clients in the same IP class A/B/C networks as the local machine. # Don't do this with a dialup site - it would cause Postfix to "trust" # your entire provider's network. Instead, specify an explicit # mynetworks list by hand, as described below. # # Specify "mynetworks_style = host" when Postfix should "trust" # only the local machine. # #mynetworks_style = class #mynetworks_style = subnet #mynetworks_style = host # Alternatively, you can specify the mynetworks list by hand, in # which case Postfix ignores the mynetworks_style setting. # # Specify an explicit list of network/netmask patterns, where the # mask specifies the number of bits in the network part of a host # address. # # You can also specify the absolute pathname of a pattern file instead # of listing the patterns here. Specify type:table for table-based lookups # (the value on the table right-hand side is not used). # # # # #mynetworks = 168.100.189.0/28, 127.0.0.0/8 #mynetworks = $config_directory/mynetworks #mynetworks = hash:/etc/postfix/network_table mynetworks = 10.0.0.0/24, 127.0.0.0/8 # This is a space separated list of all the domain names your MailScanner server relay_domains = yourdomain.com yourotherdomain.com yourveryfantasticdomain.com virtual_alias_maps = hash:/etc/postfix/virtual transport_maps = hash:/etc/postfix/transport relay_recipient_maps = hash:/etc/postfix/relay_recipients alias_maps = hash:/etc/aliases alias_database = hash:/etc/aliases # If you forget the line below, MailScanner wont work header_checks = regexp:/etc/postfix/header_checks # As a security measure we hide version info etc. from the standard SMTP header # so if somebody issues the command "telnet mail.yourdomain.com 25" # your server will reply with "mail.yourdomain.com ESMTP" smtpd_banner = mail.yourdomain.com ESMTP debug_peer_level = 2 debugger_command = PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin ddd $daemon_directory/$process_name $process_id & sleep 5 sendmail_path = /usr/sbin/sendmail.postfix # newaliases_path: The full pathname of the Postfix newaliases command. # This is the Sendmail-compatible command to build alias databases. # newaliases_path = /usr/bin/newaliases.postfix # mailq_path: The full pathname of the Postfix mailq command. This # is the Sendmail-compatible mail queue listing command. # mailq_path = /usr/bin/mailq.postfix # setgid_group: The group for mail submission and queue management # commands. This must be a group name with a numerical group ID that # is not shared with other accounts, not even with the Postfix account. # setgid_group = postdrop # html_directory: The location of the Postfix HTML documentation. # html_directory = no # manpage_directory: The location of the Postfix on-line manual pages. # manpage_directory = /usr/share/man mailbox_size_limit = 102400000000 message_size_limit = 1024000000 smtpd_client_restrictions = check_client_access hash:/etc/postfix/access maximal_queue_lifetime = 14d delay_warning_time = 12h smtpd_relay_restrictions = permit_mynetworks reject_unauth_destination # For now we disable all the SSL/TLS settings. # These are the real settings so when we install the SSLcerts in the right place # You simply have to uncomment the following lines #smtpd_use_tls = yes #smtpd_tls_loglevel = 1 #smtpd_tls_received_header = yes #smtpd_tls_security_level = may #smtpd_tls_cert_file = /etc/letsencrypt/live/mail.yourdomain.com/cert.pem #smtpd_tls_key_file = /etc/letsencrypt/live/mail.yourdomain.com/privkey.pem #smtpd_tls_CAfile = /etc/letsencrypt/live/mail.yourdomain.com/fullchain.pem #smtpd_tls_CApath = /etc/ssl/certs #smtpd_tls_received_header = yes #smtpd_tls_session_cache_timeout = 3600s #smtpd_tls_protocols = TLSv1.2, TLSv1.1, !TLSv1, !SSLv2, !SSLv3 #smtpd_tls_exclude_ciphers = MD5, DES, ADH, RC4, PSD, SRP, 3DES, eNULL, aNULL #smtpd_tls_ciphers = high #smtpd_tls_mandatory_protocols = TLSv1.2, TLSv1.1, !TLSv1, !SSLv2, !SSLv3 #smtpd_tls_mandatory_ciphers = high #smtpd_tls_mandatory_exclude_ciphers = MD5, DES, ADH, RC4, PSD, SRP, 3DES, eNULL, aNULL #smtp_use_tls = yes #smtp_tls_loglevel = 1 #smtp_tls_received_header = yes #smtp_tls_security_level = may #smtp_tls_cert_file = /etc/letsencrypt/live/mail.yourdomain.com/cert.pem #smtp_tls_key_file = /etc/letsencrypt/live/mail.yourdomain.com/privkey.pem #smtp_tls_CAfile = /etc/letsencrypt/live/mail.yourdomain.com/fullchain.pem #smtp_tls_CApath = /etc/ssl/certs #smtp_tls_session_cache_timeout = 3600s #smtp_tls_protocols = TLSv1.2, TLSv1.1, !TLSv1, !SSLv2, !SSLv3 #smtp_tls_mandatory_exclude_ciphers = MD5, DES, ADH, RC4, PSD, SRP, 3DES, eNULL, aNULL #smtp_tls_exclude_ciphers = MD5, DES, ADH, RC4, PSD, SRP, 3DES, eNULL, aNULL #smtp_tls_ciphers = high #smtp_tls_mandatory_protocols = TLSv1.2, TLSv1.1, !TLSv1, !SSLv2, !SSLv3 #smtp_tls_mandatory_ciphers = high #tls_preempt_cipherlist = yes #tls_random_source = dev:/dev/urandom
In the file /etc/postfix/transport add the following for all domains you want to forward to your Exchange/Zimbra server:
yourdomain.com smtp:exchangeserver.yourdomain.com .yourdomain.com smtp:exchangeserver.yourdomain.com yourotherdomain.com smtp:exchangeserver.yourdomain.com .yourotherdomain.com smtp:exchangeserver.yourdomain.com yourveryfantasticdomain.com smtp:exchangeserver.yourdomain.com .yourveryfantasticdomain.com smtp:exchangeserver.yourdomain.com
Add to the file /etc/postfix/relay_recipients all your users e-mail adresses:
john.doe@yourdomain.com x
pete@yourdomain.com x
hank@yourotherdomain.com x
Create if needed the directories for postfix:
sudo mkdir /var/spool/postfix/hold sudo mkdir /var/spool/postfix/incoming sudo chown postfix. /var/spool/postfix/hold sudo chown postfix. /var/spool/postfix/incoming
You will need to ensure that the user “postfix” can write to /var/spool/MailScanner/incoming and /var/spool/MailScanner/quarantine:
sudo chown postfix. /var/spool/MailScanner/incoming
sudo chown postfix. /var/spool/MailScanner/quarantine
Create a script /usr/local/etc/postfix-db
Add the following:
#!/bin/sh cd /etc/postfix newaliases /usr/sbin/postmap /etc/postfix/virtual /usr/sbin/postmap /etc/postfix/transport /usr/sbin/postmap /etc/postfix/access /usr/sbin/postmap /etc/postfix/relay_recipients
Make it executable:
sudo chmod a+x /usr/local/etc/postfix-db
Run it:
sudo /usr/local/etc/postfix-db
Set some permissions
sudo mkdir /var/spool/MailScanner/spamassassin sudo chown postfix.postfix /var/spool/MailScanner/spamassassin
Enable and Restart postfix
sudo systemctl enable postfix
sudo systemctl restart postfix
Configure MailScanner
In your /etc/MailScanner/MailScanner.conf file change the following settings:
Run As User = postfix Run As Group = postfix Incoming Queue Dir = /var/spool/postfix/hold Outgoing Queue Dir = /var/spool/postfix/incoming MTA = postfix Clamd Socket = /var/run/clamav/clamd.ctl SpamAssassin User State Dir = /var/spool/MailScanner/spamassassin
Stop the ClamAV daemon:
sudo systemctl stop clamav-daemon
Edit
sudo vi /etc/clamav/clamd.conf
Change the following:
LocalSocketGroup mtagroup
Change ownership of the files
sudo chown -R postfix.mtagroup /etc/clamav/
Add users Postfix and clamav to mtagroup
sudo usermod -a -G mtagroup postfix
sudo usermod -a -G mtagroup clamav
Restart ClamAV
sudo systemctl enable clamav-daemon sudo systemctl restart clamav-daemon
Test-run MailScanner:
sudo MailScanner --lint
Output should give no errors and look something like this:
$ sudo MailScanner --lint
Trying to setlogsock(unix)
Reading configuration file /etc/MailScanner/MailScanner.conf
Reading configuration file /etc/MailScanner/conf.d/README
Read 868 hostnames from the phishing whitelist
Read 5807 hostnames from the phishing blacklists
Checking version numbers…
Version number in MailScanner.conf (5.3.4) is correct.
Your envelope_sender_header in spamassassin.conf is correct.
MailScanner setting GID to (120)
MailScanner setting UID to (115)
Checking for SpamAssassin errors (if you use it)…
Using SpamAssassin results cache
Connected to SpamAssassin cache database
SpamAssassin reported no errors.
Auto: Found virus scanners: clamd
Connected to Processing Attempts Database
Created Processing Attempts Database successfully
There are 0 messages in the Processing Attempts Database
Using locktype = posix
MailScanner.conf says "Virus Scanners = auto"
Found these virus scanners installed: clamd
Filename Checks: Windows/DOS Executable (1 eicar.com)
Other Checks: Found 1 problems
Virus and Content Scanning: Starting
Clamd::INFECTED:: Win.Test.EICAR_HDB-1 :: ./1/eicar.com
Virus Scanning: Clamd found 2 infections
Infected message 1 came from 10.1.1.1
Virus Scanning: Found 2 viruses
Virus Scanner test reports:
Clamd said "eicar.com was infected: Win.Test.EICAR_HDB-1"
If any of your virus scanners (clamd)
are not listed there, you should check that they are installed correctly
and that MailScanner is finding them correctly via its virus.scanners.conf
Edit defaults file:
sudo vi /etc/MailScanner/defaults
Change following and save file:
run_mailscanner=1
Enable and start MailScanner:
sudo systemctl enable mailscanner
sudo systemctl start mailscanner
Watch the logs for errors
cat /var/log/mail.log