Note
- 7/10/2024: "mail.kctang.com.hk" also added as email domain name.
- 19/9/2024: Delete separate configuration instructions for spamassassin. Change micro to nano as non-graphical editor.
- 13/2/2023: Use Letsencrypt ssl. Change gedit to micro as non-graphical editor.
- 11/2/2023: Add full config files. Correct opendkim socket.
- 1/2/2023: Correct typos.
- 10/10/2022: Add DKIM setting.
- 18/6/2021: Adjust TLS setting.
- 5/1/2021: Increase imap-login process limit. List Dovecot full custom settings.
- 9/12/2020: Define cron job to delete filtered mails.
- 20/9/2020: Stop using mail-stack-delivery.
- 8/5/2020: Correct typo errors.
- 30/5/2019: Add anti-virus and spam mail filtering.
- 17/5/2019: Add copying emails to external accounts.
- 7/5/2019: Change "gksudo gedit" to "sudo gedit" as Ubuntu 18.04 dropped "gksudo". Add header_checks. Add auto creation of Trash folders. Add webmaster.
- 29/9/2018: Add "body_checks" for spam control.
- 20/9/2018: Increase message_size_limit to 20 times the default.
- 5/4/2018: Increase message_size_limit to 10 times the default.
- 25/12/2018: Publish on web.
- 12/4/2014: Specify maximal_queue_lifetime to notify unsuccessful delivery immediately.
- 2/4/2014: Specify fully qualified domain name.
Intro
Postfix is a mail transfer agent (MTA) responsible for sending out and receiving emails between servers.
Dovecot is a mail delivery agent (MDA) responsible for sending out and receiving emails between a server and its users.
Mail-stack-delivery was a combined package containing both Postfix and Dovecot. It is now no longer supported.
Re-direct to server ports
Set the internet router to re-direct the following connections to server ports:
- SMTP = port 25 (for receiving or sending emails)
- secure SMTP = port 465 (for receiving or sending emails securely)
- IMAP = port 143 (for retrieving emails)
- secure IMAP = port 993 (for retrieving emails securely)
- POP3 = port 110 (for retrieving emails)
Install both Postfix and Dovecot
Ubuntu 20.04 does not support the combined package "mail-stack-delivery" anymore.
Install Dovecot and Postfix individually:
$ sudo apt install dovecot-imapd dovecot-pop3d $ sudo apt install postfix
However, the previous config file "/etc/dovecot/conf.d/99-mail-stack-delivery.conf" is still retained for use, because "99" represents the last and overriding config file. This eliminates the need to change the individual config files.
(revised to install individually, 20/9/2020)
Reconfigure Postfix
Reconfig:
$ sudo dpkg-reconfigure postfix
Use Tab key to change selection.
Select "Internet Site".
Enter the following information:
System mail name: <fully qualified domain name, such as "kctang.com.hk"> Root and postmaster mail recipient: <such as "kctang"> Other destinations to accept mail: <fully qualified domain name, such as "mail.kctang.com.hk" and "kctang.com.hk">, <server name such as "server">, localhost.localdomain, localhost Force synchronous updates on mail queue: No Local networks: <leave it blank to accept the default> Use procmail for local delivery: No Mailbox size limit (bytes): 0 Local address extension character: + Internet protocols to use: all
("mail.kctang.com.hk" also added, 7/10/2024)
Edit "main.cf" settings:
$ sudo nano /etc/postfix/main.cf
Specify in full:
# See /usr/share/postfix/main.cf.dist for a commented, more complete version
# Debian specific: Specifying a file name will cause the first # line of that file to be used as the name. The Debian default # is /etc/mailname. #myorigin = /etc/mailname
smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu) biff = no
# appending .domain is the MUA's job. append_dot_mydomain = no
# Uncomment the next line to generate "delayed mail" warnings #delay_warning_time = 4h
readme_directory = no
# See http://www.postfix.org/COMPATIBILITY_README.html -- default to 2 on # fresh installs. compatibility_level = 2
# the following automatically set by dpkg-reconfigure postfix myhostname = kctang.com.hk # fully qualified domain name instead of server name used, # otherwise some servers would not accept e-mails sent without fully qualified domain name, 2/4/2014
alias_maps = hash:/etc/aliases alias_database = hash:/etc/aliases myorigin = /etc/mailname mydestination = mail.kctang.com.hk, kctang.com.hk, server3, localhost.localdomain, localhost
# "mail.kctang.com.hk" also added, 7/10/2024 relayhost = mynetworks = 127.0.0.1/32 10.8.0.1/32 [::1]/128 # something similar to the above line, not the same mailbox_size_limit = 0 recipient_delimiter = + inet_interfaces = all
# ALL the following added to default inet_protocols = all home_mailbox = Maildir/ mailbox_command = /usr/lib/dovecot/deliver -c /etc/dovecot/dovecot.conf -m "${EXTENSION}"
message_size_limit = 204800000 # last line added to increase the default to 10 times, KCTang 5/4/2014 # increased to 20 times, KCTang 20/9/2018
maximal_queue_lifetime = 0 # last line added to report unsuccessful delivery immediately instead of after the default of 5 days, KCTang 12/4/2014
bounce_queue_lifetime = 0 # last line added, this should not be bigger than maximal_queue_lifetime, KCTang 20/5/2019
# smtpd setting #smtpd_proxy_timeout = 240s smtpd_sasl_type = dovecot smtpd_sasl_path = private/dovecot-auth smtpd_sasl_local_domain = $myhostname smtpd_sasl_security_options = noanonymous,noplaintext # noplaintext in last line added to prevent unencrypted credentials, KCTang 13/2/2023 smtpd_sasl_tls_security_options = noanonymous # last line added, KCTang 13/2/2023 broken_sasl_auth_clients = yes smtpd_sasl_auth_enable = yes smtpd_sasl_authenticated_header = yes smtpd_recipient_restrictions = reject_unknown_sender_domain reject_unknown_recipient_domain reject_unauth_pipelining permit_mynetworks permit_sasl_authenticated reject_unauth_destination check_policy_service unix:private/policyd-spf # last line added to enable spf, KCTang 19/2/2022 smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination smtpd_sender_restrictions = reject_unknown_sender_domain
# TLS parameters smtp_use_tls = yes smtp_tls_security_level=may smtpd_tls_security_level=may smtp_tls_note_starttls_offer=yes smtpd_tls_loglevel = 1 smtpd_tls_received_header = yes
# use the following two as provided as default #smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem #smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
# use the following two if self define key and certificate #smtpd_tls_key_file=/etc/ssl/private/server.key #smtpd_tls_cert_file=/etc/ssl/certs/server.crt
# use the following two if using letsencrypt , KCTang 13/2/2023
# using those set up when setting up Apache2 web server, actually they are soft-linked to the following files, KCTang 19/9/2024 smtpd_tls_cert_file=/etc/letsencrypt/live/kctang.com.hk/fullchain.pem smtpd_tls_key_file=/etc/letsencrypt/live/kctang.com.hk/privkey.pem
# use the following if using self certification authority #smtp_tls_CApath=/etc/ssl/certs/
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache smtpd_tls_auth_only = yes smtpd_tls_mandatory_ciphers = medium # smtpd_tls_mandatory_protocols = SSLv3, TLSv1 # commented, replaced below, KCTang 18/6/2021 # next 2 lines added to enhance security, KCTang 1/7/2021 smtp_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1 smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1 tls_random_source = dev:/dev/urandom
#header_checks = regexp:/etc/postfix/header_checks # last line added to check headers, KCTang 30/9/2018, disabled after using amavis 1/6/2019
#body_checks = regexp:/etc/postfix/body_checks # last line added to refer to another file to check contents of email bodies, KCTang 29/9/2018, disabled after using amavis 1/6/2019
# virtual_alias_domains = kctang.com.hk # last line added on 17/5/2019, but disabled since same domain name already defined as destination above, KCTang 20/5/2019
virtual_alias_maps = hash:/etc/postfix/virtual # last line added to forward emails to another server, KCTang 17/5/2019
content_filter = smtp-amavis:[127.0.0.1]:10024 # last line added for amavis, KCTang 1/6/2019
# the following line added to enable spf, KCTang 19/2/2022 policyd-spf_time_limit = 3600
# Milter configuration, added but disabled, KCTang 2/6/2019, enabled again, KCTang 19/2/2022 milter_default_action = accept milter_protocol = 6 smtpd_milters = local:opendkim/opendkim.sock non_smtpd_milters = $smtpd_milters
(full file given, 11/2/2023)
(updated, 13/2/2023)
(note regaridng letsencrypt added, 19/9/2024)
Edit "master.cf" settings:
$ sudo nano /etc/postfix/master.cf
Specify in full:
# # Postfix master process configuration file. For details on the format # of the file, see the master(5) manual page (command: "man 5 master" or # on-line: http://www.postfix.org/master.5.html). # # Do not forget to execute "postfix reload" after editing this file. # # ========================================================================== # service type private unpriv chroot wakeup maxproc command + args # (yes) (yes) (no) (never) (100) # ========================================================================== smtp inet n - y - - smtpd #smtp inet n - y - 1 postscreen #smtpd pass - - y - - smtpd #dnsblog unix - - y - 0 dnsblog #tlsproxy unix - - y - 0 tlsproxy #submission inet n - y - - smtpd # -o syslog_name=postfix/submission # -o smtpd_tls_security_level=encrypt # -o smtpd_sasl_auth_enable=yes # -o smtpd_tls_auth_only=yes # -o smtpd_reject_unlisted_recipient=no # -o smtpd_client_restrictions=$mua_client_restrictions # -o smtpd_helo_restrictions=$mua_helo_restrictions # -o smtpd_sender_restrictions=$mua_sender_restrictions # -o smtpd_recipient_restrictions= # -o smtpd_relay_restrictions=permit_sasl_authenticated,reject # -o milter_macro_daemon_name=ORIGINATING smtps inet n - y - - smtpd # last line uncommented, KCTang 2/4/2014 # -o syslog_name=postfix/smtps -o smtpd_tls_wrappermode=yes # last line added to force use of TLS, KCTang 2/4/2014 -o smtpd_sasl_auth_enable=yes # last line uncommented to enable STARTTLS authentication, KCTang 2/4/2014 # -o smtpd_reject_unlisted_recipient=no # -o smtpd_client_restrictions=$mua_client_restrictions # -o smtpd_helo_restrictions=$mua_helo_restrictions # -o smtpd_sender_restrictions=$mua_sender_restrictions # -o smtpd_recipient_restrictions= -o smtpd_relay_restrictions=permit_sasl_authenticated,reject # last line uncommented to reject if not authenticated, KCTang 2/4/2014 -o milter_macro_daemon_name=ORIGINATING # last line uncommented, KCTang 2/4/2014 #628 inet n - y - - qmqpd pickup unix n - y 60 1 pickup -o content_filter= -o receive_override_options=no_header_body_checks # last two lines added for anti-spam, KCTang 29/5/2019 cleanup unix n - y - 0 cleanup qmgr unix n - n 300 1 qmgr #qmgr unix n - n 300 1 oqmgr tlsmgr unix - - y 1000? 1 tlsmgr rewrite unix - - y - - trivial-rewrite bounce unix - - y - 0 bounce defer unix - - y - 0 bounce trace unix - - y - 0 bounce verify unix - - y - 1 verify flush unix n - y 1000? 0 flush proxymap unix - - n - - proxymap proxywrite unix - - n - 1 proxymap smtp unix - - y - - smtp relay unix - - y - - smtp -o syslog_name=postfix/$service_name # -o smtp_helo_timeout=5 -o smtp_connect_timeout=5 -o smtp_connect_timeout=60s # last line added, KCTang 10/3/2021 showq unix n - y - - showq error unix - - y - - error retry unix - - y - - error discard unix - - y - - discard local unix - n n - - local virtual unix - n n - - virtual lmtp unix - - y - - lmtp anvil unix - - y - 1 anvil scache unix - - y - 1 scache postlog unix-dgram n - n - 1 postlogd # # ==================================================================== # Interfaces to non-Postfix software. Be sure to examine the manual # pages of the non-Postfix software to find out what options it wants. # # Many of the following services use the Postfix pipe(8) delivery # agent. See the pipe(8) man page for information about ${recipient} # and other message envelope options. # ==================================================================== # # maildrop. See the Postfix MAILDROP_README file for details. # Also specify in main.cf: maildrop_destination_recipient_limit=1 # maildrop unix - n n - - pipe flags=DRhu user=vmail argv=/usr/bin/maildrop -d ${recipient} # # ==================================================================== # # Recent Cyrus versions can use the existing "lmtp" master.cf entry. # # Specify in cyrus.conf: # lmtp cmd="lmtpd -a" listen="localhost:lmtp" proto=tcp4 # # Specify in main.cf one or more of the following: # mailbox_transport = lmtp:inet:localhost # virtual_transport = lmtp:inet:localhost # # ==================================================================== # # Cyrus 2.1.5 (Amos Gouaux) # Also specify in main.cf: cyrus_destination_recipient_limit=1 # #cyrus unix - n n - - pipe # user=cyrus argv=/cyrus/bin/deliver -e -r ${sender} -m ${extension} ${user} # # ==================================================================== # Old example of delivery via Cyrus. # #old-cyrus unix - n n - - pipe # flags=R user=cyrus argv=/cyrus/bin/deliver -e -m ${extension} ${user} # # ==================================================================== # # See the Postfix UUCP_README file for configuration details. # uucp unix - n n - - pipe flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient) # # Other external delivery methods. # ifmail unix - n n - - pipe flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient) bsmtp unix - n n - - pipe flags=Fq. user=bsmtp argv=/usr/lib/bsmtp/bsmtp -t$nexthop -f$sender $recipient scalemail-backend unix - n n - 2 pipe flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store ${nexthop} ${user} ${extension} mailman unix - n n - - pipe flags=FR user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py ${nexthop} ${user}
# the following added, KCTang 29/5/2019 smtp-amavis unix - - - - 2 smtp -o smtp_data_done_timeout=1200 -o smtp_send_xforward_command=yes -o disable_dns_lookups=yes -o max_use=20 127.0.0.1:10025 inet n - - - - smtpd -o content_filter= -o local_recipient_maps= -o relay_recipient_maps= -o smtpd_restriction_classes= -o smtpd_delay_reject=no -o smtpd_client_restrictions=permit_mynetworks,reject -o smtpd_helo_restrictions= -o smtpd_sender_restrictions= -o smtpd_recipient_restrictions=permit_mynetworks,reject -o smtpd_data_restrictions=reject_unauth_pipelining -o smtpd_end_of_data_restrictions= -o mynetworks=127.0.0.0/8 -o smtpd_error_sleep_time=0 -o smtpd_soft_error_limit=1001 -o smtpd_hard_error_limit=1000 -o smtpd_client_connection_count_limit=0 -o smtpd_client_connection_rate_limit=0 -o receive_override_options=no_header_body_checks,no_unknown_recipient_checks,no_milters # the following added for spf, KCTang 1/6/2019, # then disabled as considered not necessary # then re-enabled 19/2/2022 to overcome rejection by gmail policyd-spf unix - n n - 0 spawn user=policyd-spf argv=/usr/bin/policyd-spf
(full file given, 11/2/2023)
Create "body_checks" file, if required:
$ sudo nano /etc/postfix/body_checks
Specify one or more lines of texts within //:
/unique text contained in email you do not want to receive/ DISCARD
"DISCARD" means delete from the server.
Create "header_checks" file, if required:
$ sudo nano /etc/postfix/header_checks
Specify similarly.
(header checks added, 7/5/2019)
Change Dovecot settings
Edit config file:
$ sudo nano /etc/dovecot/conf.d/99-mail-stack-delivery.conf
Note that a number of default config files are contained in sub-directory "conf.d". To override them, create a config file beginning with "99" so that it is read the latest to override the others. The name is based on the previous "mail-stack-delivery" config file, but can be any.
Specify in full:
# Some general options # Installed protocols are now auto-included by /etc/dovecot/dovecot.conf # Since mail-stack-delivery depends on them it is more flexible to not # explicitly list them here, but achieves the same. # protocols = imap pop3 sieve disable_plaintext_auth = yes # Since 18.04 basic SSL enablement is set up by dovecot-core and configured # in /etc/dovecot/conf.d/10-ssl.conf. # So by default basic enablement is no more done here. The old section is kept # as comment for reference to the old defaults. # # ssl = yes # ssl_cert = </etc/dovecot/dovecot.pem # ssl_key = </etc/dovecot/private/dovecot.pem # # If you keep a formerly used custom SSL enablement in this file it will (as # before) continue to overwrite the new defaults in 10-ssl.conf as this file is # sorted later being 99-*.conf # # If you choose to take the new defaults (no ssl config in this file) please # make sure you have also chosen the package defaults for 10-ssl.conf (to enable # it there) when dovecot-core configures. Also check that the links for cert/key # set up there got created correctly (they would not be created if they conflict with your # old keys done by mail-stack-delivery). # # use letsencrypt ssl, KCTang 13/2/2023 ssl = yes ssl_cert = </etc/letsencrypt/live/kctang.com.hk/fullchain.pem ssl_key = </etc/letsencrypt/live/kctang.com.hk/privkey.pem ssl_client_ca_dir = #ssl_protocols = !SSLv2 !SSLv3 mail_location = maildir:~/Maildir:LAYOUT=fs # LAYOUT=fs added to last line, to use "/" instead of "." to denote sub-folders, KCTang 25/5/2019 auth_username_chars = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890.-_@ # IMAP configuration protocol imap { mail_max_userip_connections = 1000 # 10 in last line increased to 1000, KCTang 25/5/2019 imap_client_workarounds = delay-newmail } # POP3 configuration protocol pop3 { mail_max_userip_connections = 50 # 10 in last line increased to 50, KCTang 25/5/2019 pop3_client_workarounds = outlook-no-nuls oe-ns-eoh } # LDA configuration protocol lda { postmaster_address = postmaster mail_plugins = sieve quota_full_tempfail = yes deliver_log_format = msgid=%m: %$ rejection_reason = Your message to <%t> was automatically rejected:%n%r } # Plugins configuration plugin { sieve=~/.dovecot.sieve sieve_dir=~/sieve } # Authentication configuration auth_mechanisms = plain login service auth { # Postfix smtp-auth unix_listener /var/spool/postfix/private/dovecot-auth { mode = 0660 user = postfix group = postfix } } # The following are additional to those in 15-mailboxes.conf. # They are to auto create Trash folders. # Trash folders would not be backed up with back-in-time, # and therefore would need to be re-created after email recovery is done from back-in-time. namespace inbox { mailbox Trash { auto = subscribe } } # process_limit increased, KCTang 4/1/2021 service imap-login { process_limit = 200 } # The following added to resolve stats-writer failure, KCTang 3/6/2021 service stats { unix_listener stats-reader { user = root group = root mode = 0660 } unix_listener stats-writer { user = root group = dovecot mode = 0660 } }
(full file given, 11/2/2023)
(updated, 13/2/2023)
Activate the changes:
$ sudo systemctl reload postfix or $ sudo service postfix reload and $ sudo systemctl restart dovecot or $ sudo service dovecot reload
Verify success
See whether the Postfix server is running:
$ telnet localhost 25
should display:
220 kctang.com.hk ESMTP Postfix (Ubuntu)
ehlo localhost
should display the following:
250-kctang.com.hk
250-PIPELINING
250-SIZE 102400000
250-VRFY
250-ETRN
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
Ctrl-]
to exit to "telnet >" prompt.
quit
to exit telnet.
Try also:
$ telnet localhost 993
("993", not "995", 1/2/2023)
similarly:
$ telnet localhost 465
should display either one:
Connected to localhost
Connected to kctang.com.hk
"Ctrl-]"
to exit to "telnet >" prompt.
quit
to exit telnet.
Specify internal email forwarding
Edit "aliases" file:
$ sudo nano /etc/aliases
Specify:
postmaster: kctang webmaster: kctang kctcl: kctcl, kctclpop
meaning:
- forwarding e-mails sent to postmaster@localhost and webmaster@localhost to kctang@localhost, no email will be left at postmaster or webmaster
(webmaster added, 7/5/2019)
- forwarding e-mails sent to kctcl@localhost to kctcl@localhost (itself) and to kctclpop@localhst, i.e. making a copy
"localhost" means "kctang.com.hk" in our case. For the email user name before "@", there is no need to create a file system user account for it if all emails addressed to it are forwarded elsewhere. The name serves as an alias only of the email account forwarded to.
(added, 17/5/2019)
Activate setting everytime the "aliases" file has been changed:
$ sudo newaliases
Copy to external email accounts
(section added, 17/5/2019)
Execute:
$ sudo nano /etc/postfix/main.cf
Specify at the end of the file (already shown above):
virtual_alias_domains = kctang.com.hk virtual_alias_maps = hash:/etc/postfix/virtual
Execute:
$ sudo nano /etc/postfix/virtual
Specify to make a copy to itself and a copy to the external email account:
# from to one or more addresses, separated by a space kctang@kctang.com.hk kctang@kctang.com.hk name1@external.account.name kctcl@kctang.com.hk kctcl@kctang.com.hk name2@external.account.name
Omit making a copy to itself if only email forwarding is required.
Save and exit.
Execute after the "virtual" file is created or changed:
$ sudo postmap /etc/postfix/virtual
Execute:
$ sudo systemctl restart postfix
Test by sending emails.
Install anti-virus Clamav-Daemon
(section added, 30/5/2019)
Install clamav-daemon:
$ sudo apt update $ sudo apt install clamav-daemon (clamav-freshclam also automatically installed) $ sudo dpkg-reconfigure clamav-daemon (must be done, generally accept all defaults, set yes to scan emails) $ sudo systemctl start clamav-freshclam $ sudo systemctl start clamav-daemon $ sudo systemctl status clamav-freshclam (check if running) $ sudo systemctl status clamav-daemon (check if running, OK if reported "/bin/mkdir /run/clamav (code=exited, status=1/FAILURE" because directory already created) $ sudo tail -f /var/log/clamav/clamav.log (see running progress, Ctrl-Z to exit)
(typo corrected, 8/5/2020)
(use sudo, 11/2/2023)
Filter spam mails
(section added, 30/5/2019)
Execute to install various software:
$ sudo apt update $ sudo apt install amavisd-new spamassassin $ sudo apt install postfix-policyd-spf-python (optionally required for spf) $ sudo apt install opendkim (optionally required for opendkim) $ sudo apt install pyzor razor (optional extras)
$ sudo apt install arj cabextract cpio lhasa nomarch pax rar unrar unzip zip ("lhasa", not "lha")
$ sudo razor-admin -create (added 19/9/2024) $ sudo razor-admin -register (added 19/9/2024)
Configure ClamAV:
$ sudo adduser clamav amavis $ sudo adduser amavis clamav
Configure SpamAssassin:
$ sudo micro /etc/default/spamassassin
Change "ENABLED=0" to:
(no need to configure because amavisd-new handles it, 19/9/2024)
ENABLED=1
(no longer set here, 8/5/2020)
Start the service:
$ sudo systemctl start spamassassin.service
(no need to configure because amavisd-new handles it, 19/9/2024)
Configure Amavisd-new:
$ sudo nano /etc/amavis/conf.d/15-content_filter_mode
Specify:
use strict; # Uncomment the two lines below to enable antivirus checking mode @bypass_virus_checks_maps = ( \%bypass_virus_checks, \@bypass_virus_checks_acl, \$bypass_virus_checks_re); # Uncomment the two lines below to enable SPAM checking mode @bypass_spam_checks_maps = ( \%bypass_spam_checks, \@bypass_spam_checks_acl, \$bypass_spam_checks_re); 1; # insure a defined return
Execute:
$ sudo nano /etc/amavis/conf.d/20-debian_defaults
Change "D_PASS" to:
$final_spam_destiny = D_DISCARD
(deleted, 8/5/2020, reinstated, 26/7/2021)
Adjust the following values only if desired to flag more messages as spam:
$sa_tag_level_deflt = 2.0; # add spam info headers if at, or above that level $sa_tag2_level_deflt = 6.31; # add 'spam detected' headers at that level $sa_kill_level_deflt = 6.31; # triggers spam evasive actions $sa_dsn_cutoff_level = 10; # spam level beyond which a DSN is not sent
Execute:
$ sudo nano /etc/amavis/conf.d/50-user
Specify:
$myhostname = 'kctang.com.hk';
Re-start the service:
$ sudo systemctl restart amavis.service
Edit the following file to specify domains to be whitelisted if necessary:
$ sudo nano /etc/amavis/conf.d/40-policy_banks
Test that the Amavisd-new SMTP is listening:
telnet localhost 10024 Trying 127.0.0.1... Connected to kctang.com.hk. Escape character is '^]'. 220 [127.0.0.1] ESMTP amavisd-new service ready
Press Ctrl-] and enter "quit" to exit.
Configure Postfix master.cf:
$ sudo nano /etc/postfix/master.cf
Add the following to the end of the file (already done above):
smtp-amavis unix - - - - 2 smtp -o smtp_data_done_timeout=1200 -o smtp_send_xforward_command=yes -o disable_dns_lookups=yes -o max_use=20 127.0.0.1:10025 inet n - - - - smtpd -o content_filter= -o local_recipient_maps= -o relay_recipient_maps= -o smtpd_restriction_classes= -o smtpd_delay_reject=no -o smtpd_client_restrictions=permit_mynetworks,reject -o smtpd_helo_restrictions= -o smtpd_sender_restrictions= -o smtpd_recipient_restrictions=permit_mynetworks,reject -o smtpd_data_restrictions=reject_unauth_pipelining -o smtpd_end_of_data_restrictions= -o mynetworks=127.0.0.0/8 -o smtpd_error_sleep_time=0 -o smtpd_soft_error_limit=1001 -o smtpd_hard_error_limit=1000 -o smtpd_client_connection_count_limit=0 -o smtpd_client_connection_rate_limit=0 -o receive_override_options=no_header_body_checks,no_unknown_recipient_checks,no_milters
Add the following immediately below the "pickup" transport service (already done above):
-o content_filter= -o receive_override_options=no_header_body_checks
Configure Postfix main.cf:
$ sudo nano /etc/postfix/main.cf
Add the following to the end of the file (already done above):
content_filter = smtp-amavis:[127.0.0.1]:10024
Comment it with "#" at the start of the line if desired to stop using amavis.
Restart service:
$ sudo systemctl restart postfix
Check the hidden header of email received after the above to see the presence of one or more of the following:
X-Spam-Level: X-Virus-Scanned: Debian amavisd-new at kctang.com.hk X-Spam-Status: X-Spam-Level:
If present, the spam filter is working.
See https://help.ubuntu.com/lts/serverguide/mail-filtering.html.en for a full explanation of the above.
(outdated, 19/9/2024)
Delete filtered mails
(section added, 9/12/2020)
Filtered files are stored in /var/lib/amavis/virusmails and should be deleted regularly.
Edit to define a scheduled job to delete filtered files:
$ sudo crontab -e -u amavis
where:
-e = edit
-u amavis = user amavis
Define as follows:
0 0 * * * find /var/lib/amavis/virusmails/ -type f -mtime +15 -delete
which means at
0 = 0 minute
0 = 0 hour
* = every day of month
* = every month
* = every day of week
find /var/lib/amavis/virusmails = find in that directory
-type f = regular files
-mtime +15 = file modified more than 15 days ago
-delete = delete the file
Set up DKIM
(implemented, 19/2/2022
section added, 10/10/2022)
Set up DomainKeys Identified Mail (DKIM) to prevent email phishing by others by putting a digital key in the outgoing email headers so that the receiving email server can verify the digital key by looking up the public key in the DNS record of the sender domain.
Install OpenDKIM:
$ sudo apt install opendkim opendkim-tools
Add postfix user to opendkim group:
$ sudo gpasswd -a postfix opendkim
Configure:
$ sudo nano /etc/opendkim.conf
Specify:
# keep to log in /var/log/mail.log Syslog yes SyslogSuccess yes # change to "yes" if desired to log more details Logwhy no # keep Canonicalization relaxed/simple # uncomment Mode sv SubDomains no # keep OversignHeaders from # add AutoRestart yes AutoRestartRate 10/1M Background yes DNSTimeout 5 SignatureAlgorithm rsa-sha256 # keep UserID opendkim UMask 007 # comment #Socket local:/run/opendkim/opendkim.sock # add Socket local:/var/spool/postfix/opendkim/opendkim.sock # keep PidFile /run/opendkim/opendkim.pid TrustAnchorFile /usr/share/dns/root.key # keep KeyTable refile:/etc/opendkim/key.table SigningTable refile:/etc/opendkim/signing.table ExternalIgnoreList /etc/opendkim/trusted.hosts InternalHosts /etc/opendkim/trusted.hosts
Create a directory structure:
$ sudo mkdir /etc/opendkim $ sudo mkdir /etc/opendkim/keys $ sudo chown -R opendkim:opendkim /etc/opendkim $ sudo chmod go-rw /etc/opendkim/keys
Create the signing table:
$ sudo nano /etc/opendkim/signing.table
Specify:
*@kctang.com.hk default._domainkey.kctang.com.hk # if sub-domain used *@*.kctang.com.hk default._domainkey.kctang.com.hk
Create the key table:
$ sudo nano /etc/opendkim/key.table
Specify:
default._domainkey.kctang.com.hk kctang.com.hk:default:/etc/opendkim/keys/kctang.com.hk/default.private
Create the trusted hosts file:
$ sudo nano /etc/opendkim/trusted.hosts
Specify to sign but not to verify emails from localhost or the following domain:
127.0.0.1 localhost *.kctang.com.hk
("*" added, 1/2/2023)
Create separate folder for the domain and generate Private/Public Keypair:
$ sudo mkdir /etc/opendkim/keys/kctang.com.hk $ sudo opendkim-genkey -b 1024 -d kctang.com.hk -D /etc/opendkim/keys/kctang.com.hk -s default -v
Use -b 2048 instead of -b 1024 for bits of key if the domain name server permits.
-d for domain name
-D for directory to store the keys
-s for selector
The private key will be written to default.private file and the public key will be written to default.txt file.
Change owner and permission:
$ sudo chown opendkim:opendkim /etc/opendkim/keys/kctang.com.hk/default.private $ sudo chmod 600 /etc/opendkim/keys/kctang.com.hk/default.private
Display the public key:
$ sudo cat /etc/opendkim/keys/kctang.com.hk/default.txt
The string after the p
parameter is the public key:
default._domainkey IN TXT ( "v=DKIM1; h=sha256; k=rsa; " "p=..." ) ; ----- DKIM key default for kctang.com.hk
Define in the Domain Name Record on the domain name host:
Name = default._domainkey
Address or value = the text in ( ) above, but deleting double quotes and spaces
Type = SPF (txt)
Test DKIM Key:
$ sudo opendkim-testkey -d kctang.com.hk -s default -vvv
Successful if an opendkim-testkey output is key OK.
No problem if an opendkim-testkey output is key not secure because DNSSEC may not have been enabled on the domain name.
The DKIM record may take up to 24 hours to propagate to the Internet.
Can also go to https://www.dmarcanalyzer.com/dkim/dkim-check/, enter "kctang.com.hk" as the domain name and "default" as the selector to check DKIM record propagation.
In case of the query timed out error, comment out the following line in /etc/opendkim.conf
file and restart opendkim.service
.
TrustAnchorFile /usr/share/dns/root.key
Create a directory to hold the OpenDKIM socket file, and allow only opendkim user and postfix group to access it:
$ sudo mkdir /var/spool/postfix/opendkim $ sudo chown opendkim:postfix /var/spool/postfix/opendkim
Edit:
$ sudo nano /etc/default/opendkim
Comment out:
# SOCKET=local:$RUNDIR/opendkim.sock
Add to suit Ubuntu:
SOCKET=local:/var/spool/postfix/opendkim/opendkim.sock
Create the file
$ sudo mkdir /var/spool/postfix/opendkim $ sudo chown -R opendkim:opendkim /var/spool/postfix/opendkim
(file creation added, 11/2/2023)
Edit Postfix main.cf to configure Milter as shown above.
Restart opendkim
and postfix
service and check status to see any errors:
$ sudo systemctl restart opendkim postfix $ sudo systemctl status opendkim postfix
(status check added, 11/2/2023)
Set up Domain Name record
Set up the Domain Name record at the domain hosting company as follows:
v=DMARC1; p=quarantine; pct=10 v=spf1 ip4:202.69.68.114 include:_spf.google.com include:spf.protection.outlook.com ~all
The ip4 is our company's IP address. This is not a secret.
(added, 21/2/2023)