How can we help?


aspamd - Installation

Stewart -


How do I install aspamd? 


  • atmail aspamd


Requirement to install and configure aspamd service.


System Requirements

  • Red Hat/Centos Operating System
  • atmail-common-1.0.x


If you have not already done so, add access to Atmail's on line software repository to your server by executing the following command:

bash <(curl -s


  1. Use yum to install the atmail-aspamd-[version] software package, and it's prerequisite

    $ yum install atmail-common
    $ yum install atmail-aspamd
  2. Anti-Spam and Malware Protection are licensed separately. Enter your atmail id, and anti-spam / malware detection licenses in /etc/atmail/aspamd/aspamd-ingress.conf (ingress) and/or /etc/atmail/aspamd/aspamd-egress.conf (egress). Licenses are comma separated, and should be enclosed in single quotes:
    # cat /etc/atmail/aspamd/aspamd-ingress.conf
     aspamd ingress config file.
    # the defaults are listed commented out. They should be sane, aspamd will do it’s best
    # to run with no configuration at all. To enable the premium engine, enter your license
  3. Start the aspamd ingress service
    $ systemctl start aspamd@ingress
    $ systemctl status aspamd@ingress
    aspamd.service - atmail-aspamd - aspamd ingress server

       Loaded: loaded (/usr/lib/systemd/system/aspamd@ingress.service; enabled; vendor preset: disabled)

       Active: active (running) since Wed 2019-06-05 09:00:46 AEST; 6 days ago


     Main PID: 948 (aspamd)

       CGroup: /system.slice/aspamd.service/aspamd@ingress.service

               └─948 /usr/bin/aspamd

    Jun 05 09:00:46 vm1 systemd[1]: Started atmail-aspamd - aspamd ingress server.
    Jun 05 09:00:46 vm1 systemd[1]: Starting atmail-aspamd - aspamd ingress server...
    Jun 05 09:00:55 vm1 aspamd[948]: time=“2019-06-05T09:00:55+10:00” level=info msg=“aspamd engine initializing”
    Jun 05 09:00:55 vm1 aspamd[948]: time=“2019-06-05T09:00:55+10:00” level=info msg=“aspamd listening on"

You now have a running atmail aspamd ingress server, but it will require further integration with Exim before it is useful.

CLI Reference

aspamd -h
   aspamd - atmail spamd server

   aspamd [global options] command [command options] [arguments...]


     help, h  Shows a list of commands or help for one command

   --config FILE, -c FILE     Load configuration from FILE [$CONFIG_FILE]
   --listen value             Listen Address for aspamd (default: "") [$LISTEN]
   --readTimeout value        Server timeout (default: 0s) [$READ_TIMEOUT]
   --writeTimeout value       Server timeout (default: 0s) [$WRITE_TIMEOUT]
   --metricsAddr value        Prometheus /metrics address (default: "") [$METRICS]
   --cosURI value             The URI CoS data will be retrieved from [$COS_URI]
   --cosInsecure              allow insecure communications with CoS [$COS_ALLOW_INSECURE]
   --cosV1                    using CoS V1 [$COS_V1]
   --cosVerbose               verbose CoS (http only) [$COS_VERBOSE]
   --consulAddr value         Use consul to locate cosd grpc services at this api addr [$CONSUL_ADDR]
   --consulScheme value       Use consul to locate cosd grpc services with this scheme (default: "http") [$CONSUL_SCHEME]
   --cosCacheTimeout value    CoS Cache timeout (duration) for cache lookups, to reduce traffic. Defaults to -1s (disabled) (default: -1m0s) [$COS_CACHE_KEY_TIMEOUT]
   --defaultEngine value      Default Spamd Engine(s), comma separated (default: "localhost:11333") [$DEFAULT_ENGINE_ADDR]
   --spamThreshold value      (default: 50) [$SPAM_THRESHOLD]
   --unknownScore value       (default: 0) [$SPAM_UNKNOWN_SCORE]
   --unknownAction value      (default: "no action") [$SPAM_UNKNOWN_ACTION]
   --confirmedScore value     (default: 100) [$SPAM_CONFIRMED_SCORE]
   --confirmedAction value    (default: "reject") [$SPAM_CONFIRMED_ACTION]
   --bulkScore value          (default: 50) [$SPAM_BULK_SCORE]
   --bulkAction value         (default: "reject") [$SPAM_BULK_ACTION]
   --suspectedScore value     (default: 50) [$SPAM_SUSPECTED_SCORE]
   --suspectedAction value    (default: "rewrite subject") [$SPAM_SUSPECTED_ACTION]
   --nonSpamScore value       (default: -100) [$SPAM_NON_SPAM_SCORE]
   --nonSpamAction value      (default: "no action") [$SPAM_NON_SPAM_ACTION]
   --virusScore value         (default: 200) [$SPAM_VIRUS_SCORE]
   --virusAction value        (default: "reject") [$SPAM_VIRUS_ACTION]
   --virusHighScore value     (default: 150) [$SPAM_VIRUS_HIGH_SCORE]
   --virusHighAction value    (default: "reject") [$SPAM_VIRUS_HIGH_ACTION]
   --virusMediumScore value   (default: 4) [$SPAM_VIRUS_MEDIUM_SCORE]
   --virusMediumAction value  (default: "no action") [$SPAM_VIRUS_MEDIUM_ACTION]
   --validBulkScore value     (default: 49) [$VALID_BULK_SCORE]
   --validBulkAction value    (default: "no action") [$SPAM_VALID_BULK_ACTION]
   --egress                   Run in egress mode [$EGRESS]
   --cacheFile value          Local cache file (default: "/var/lib/atmail/aspamd/aspamd.cache") [$CACHE_FILE]
   --cacheSaveDuration value  Cache is saved periodically (default: 2m0s) [$CACHE_FILE_SAVE_EVERY]
   --atmailId value           Atmail ID [$ATMAIL_ID]
   --licenceKey value         Atmail License Key(s, comma separated) [$LICENSE_KEY]
   --syslogEnable             enable syslog [$SYSLOG_ENABLE]
   --syslogAddr value         syslog server. Value can be host:port. If not set, uses local syslog [$SYSLOG_ADDR]
   --syslogFacility value     set syslog facility, defaults to mail. See /usr/include/sys/syslog.h (default: 16) [$SYSLOG_FACILITY]
   -V                         Verbose [$VERBOSE]
   --logLevel value           Log Level (panic,fatal,error,warn,info,debug,trace) (default: "info") [$LOG_LEVEL]
   --auditSpamDir value       If set, a copy of all emails classified as spam are copied here. WARNING: i/o intensive [$AUDIT_SPAM_DIR]
   --auditActions value       csv list of auditable actions. WARNING: i/o intensive [$AUDIT_ACTIONS]
   --json                      [$LOG_JSON]
   --logFile value             [$LOG_FILE]
   --help, -h                 show help
   --version, -v              print the version

Integration with MTA

aspamd performs mail content scanning by operating as an rspamd server. It has been tested using the Exim MTA, but if you require integration with other MTA, support may be considered, and may already work, if they support rspamd.


By default aspamd listens on, TCP port 7830. You must set the spamd_address option in the global part of the Exim configuration (/etc/exim/exim.conf) file:

spamd_address = 7830 variant=rspamd

Scanning is performed using the spam condition in a DATA ACL. As scanning can be quite resource intensive, and most spam messages are quite small, it is recommended that you do not scan large messages. Here is a simple example:

        warn condition = ${if < {$message_size}{10K}}
             spam = nobody
        deny message = This message was classified as SPAM
             condition = ${if eq{$spam_action}{reject}}


When running Exim as an outgoing MTA, to better protect your IP reputation, you should send all outgoing mail to aspamd, running in egress mode. To do this, use the command line, flag, --egress, or set EGRESS=true in the configuration file. This will give better configuration results. The installation creates a systemd service, aspamd@egress, which uses the configuration file at /etc/atmail/aspamd/aspamd-egress.conf

atmail Mailserver

atmail Mailserver manages Exim's configuration, so any changes made manually to the exim configuration are likely to be erased on next configuration publish. To integrate this product into a platform that is managed by atmail mailserver the following configurations steps need to be performed (assumes aspamd itself has been configured to listen on port 7830). This requires atmail-mailserver and atmail-mailserver-ansible versions >= 8.6.0-19

Update Exim to use new aspamd Engine

In order to do this it is currently necessary to update and overload some configuration variables in the inventory. Firstly change the connection mode from tcp by updating the spamd_mode configuration:

update inventory set configValue = 'aspamd' where configVariable = 'spamd_mode' and configSection = 'exim';

Next update the variable spamd_socket to take the value for connecting to aspamd:

update inventory set configValue = '$acl_m_spamd' where configVariable = 'spamd_socket' and configSection = 'exim';

These changes will allow you to publish out without changing the current exim.conf.j2 template found in mailserver for the default ss1ip role.

Finally check if the X-atmail-spam-action header variable exists:

select inventoryItem,configSection,configVariable,configValue from inventory where configValue='X-atmail-spam-action';
| inventoryItem | configSection | configVariable | configValue |
| _default | exim | h_spam_action | X-atmail-spam-action |
1 row in set (0.00 sec)

If not then add it:

insert into inventory(inventoryItem, configSection, configVariable, configValue) values('_default','exim','h_spam_action','X-atmail-spam-action');

Update the Exim ACL

This will need to be done on each mailserver instance if using the publish button to push configuration changes.

Change directory the override directory for the in-built ss1ip ansible role.

cd /var/lib/atmail/mailserver/roles/ss1ip/templates/amp/exim

Copy over the current data ACL template file:

cp ../../exim/acl_check_data.j2 .

Ensure that the file has sufficient read permissions:

chmod 0644 acl_check_data.j2

Update the file to use new rules based around aspamd - example is given below:


{% if exim_av_enable|int == 1 %}
message = Virus $malware_name detected.
malware = */defer_ok
logwrite = $pid:$tod_epoch:LOG:ACL_CHECK_CONTENT:REJECT:$sender_host_address:$sender_address:$recipients:Malware/Virus $malware_name detected
{% endif %}

{% if exim_as_enable|int == 1 %}
condition = ${if > {$message_size}{{ '{' }}{{ exim_max_scan_size }}{{ '}}' }}
message = Content Scan skipped due to msg_size $message_size
set acl_m_spamscore = 2
add_header = {{ exim_h_spam_score }}: 2 \n\
{{ exim_h_spam_override }}: SL \n\
{{ exim_h_spam_report }}: Accepted with default score
logwrite = $pid:$tod_epoch_l:LOG:ACL_CONTENT_RELAY:ACCEPT:$sender_host_address:$sender_address:Accepted due to size $message_size

set acl_m_spamd = 7830 variant=rspamd

condition = ${if def:acl_m_outbound}
set acl_m_spamd = 7831 variant=rspamd

spam = nobody:true/defer_ok
add_header = {{ exim_h_spam_score }}: $spam_score_int \n\
{{ exim_h_spam_bar }}: $spam_bar \n\
{{ exim_h_spam_report }}: $spam_report
set acl_m_spamscore = $spam_score_int

condition = ${if def:acl_m_outbound}
condition = {{ '${if > {$spam_score_int}{' }}{{ exim_spamscore_reject_outbound }}{{ '}{1}{0}}' }}
message = Rejected - messages seen as spam ($spam_score)
logwrite = $pid:$tod_epoch:LOG:ACL_CHECK_CONTENT:REJECT:$sender_host_address:$sender_address:Outbound message seen as SPAM

condition = ${if def:acl_m_outbound}
message = Accepted outbound message
logwrite = $pid:$tod_epoch:LOG:ACL_CHECK_CONTENT:ACCEPT:$sender_host_address:$sender_address:Message accepted for outbound ($spam_score)

condition = ${if eq {$acl_m_antispam_override}{1}{yes}{no}}
condition = {{ '${if > {$spam_score_int}{' }}{{ exim_spamscore_reject_inbound }}{{ '}{1}{0}}' }}
add_header = {{ exim_h_spam_override }}: 1
logwrite = $pid:$tod_epoch:LOG:ACL_CHECK_CONTENT:ACCEPT:$sender_host_address:$sender_address:Message accepted due to antispam override - $spam_score

condition = {{ '${if > {$spam_score_int}{' }}{{ exim_spamscore_reject_inbound }}{{ '}{1}{0}}' }}
message = Rejected as SPAM ($spam_score)
logwrite = $pid:$tod_epoch:LOG:ACL_CHECK_CONTENT:REJECT:$sender_host_address:$sender_address:$recipients:Rejected as SPAM - $spam_score

logwrite = $pid:$tod_epoch:LOG:ACL_CHECK_CONTENT:ACCEPT:$sender_host_address:$sender_address:$recipients:Message accepted as non SPAM - $spam_score
{% else %}

logwrite = $pid:$tod_epoch_l:LOG:ACL_CONTENT_RELAY:ACCEPT:$sender_host_address:$sender_address:$recipients:Message accepted"
{% endif %}

Any publish will now insert the custom acl_check_data.j2 into the main configuration file.

Current mailserver is built around SpamAssassin and spam scores and the default sieve rule does not seem to exclude whitelisted recipients the current sieve rule is:

require ["editheader", "comparator-i;ascii-numeric", "relational", "variables", "regex"];
if allof (
not header :matches "X-atmail-spam-score" "-*",
header :value "ge" :comparator "i;ascii-numeric" "X-atmail-spam-score" "50" ) {

if header :regex "subject" "(.*)" {
deleteheader "Subject";
addheader "Subject" "{SPAM} ${1}";

Which will see ANY message with spam core-int > 50 tagged (or if customer has changed moved/deleted).

As such it Is recommend to review the spam scores assigned to the various categories within the aspamd configuration file.

Have more questions? Submit a request


Contact our support team

+61 (7) 5357 6605