Extended Brain Storage

OpenBSD: Rspamd and ClamAV

Posted on September 24, 2016

The installation and configuration of Rspamd and ClamAV in OpenBSD...

Theory

Here comes a little bit of theory to better understand what the "mail dance" is all about.

Sender Policy Framework (SPF)

... is a mechanism defined in RFC7208, which has been designed to detect forged e-mail. Leveraging specially formatted TXT records of the Domain Name System (DNS), domain owners are enabled to propagate information about legitimate sources of their e-mails (list of authorised IPs/hosts) and actions when different sources are detected by the receiving servers.

DomainKeys Identified Mail (DKIM)

... is a method defined in RFC6376, which has also been designed to detect e-mail spoofing through cryptographic authentication (digital signatures). Compared to the SPF, the DKIM also uses DNS TXT records, however; to publish domain's public key, based-on which the receiving servers can carry out e-mail verification (that is was not tampered with).

Domain-based Message Authentication, Reporting and Conformance (DMARC)

... is an e-mail authentication, policy and reporting protocol, which was defined in RFC7489 and which has also been designed to detect fraudulent e-mails. It builds on top of SPF and DKIM by announcing what to do if neither of them passes the validation test. Again, it utilises the DNS in order to publish policies and e-mail address(es) to send reports to, and providing a reporting mechanism to send statistics from receivers to senders.

Authenticated Received Chain (ARC)

... is an IETF protocol draft designed to eliminate DMARC drawbacks, since a strict DMARC policy may block legitimate e-mails sent through a mailing list or a forwarder (message gets modified and signature validation fails). ARC enables the subsequent intermediate servers ("hops") to sign the original message's validation results (either with the DKIM's or a different key). The receiving server can choose to validate the ARC, even if the SPF or DKIM validation fail.

Conclusion

It is completely up to each and every receiving service to decide which intermediaries to trust, as it may choose to ignore the failed SPF, DKIM or DMARC validation and accept the messages anyway.


Clam Antivirus Installation

Clam Antivirus (ClamAV) is a free open source multi-threaded antivirus engine for detecting trojans, viruses, malware and other malicious threats.

Installation of ClamAV is straightforward:

$ pkg_add clamav
quirks-2.367 signed on 2017-10-03T11:21:28Z
clamav-0.99.2p5:libmilter-8.16.0.21: ok
clamav-0.99.2p5:pcre2-10.23: ok
clamav-0.99.2p5: ok
The following new rcscripts were installed: /etc/rc.d/clamav_milter /etc/rc.d/clamd /etc/rc.d/freshclam
See rcctl(8) for details.

Virus database of ClamAV needs to be set up in the following way:

$ vi /etc/freshclam.conf
# Comment or remove the line below.
#Example
# Uncomment the following line and replace XY with your country
# code. See http://www.iana.org/cctld/cctld-whois.htm for the full list.
# You can use db.XY.ipv6.clamav.net for IPv6 connections.
DatabaseMirror db.cz.clamav.net
# database.clamav.net is a round-robin record which points to our most
# reliable mirrors. It's used as a fall back in case db.XY.clamav.net is
# not working. DO NOT TOUCH the following line unless you know what you
# are doing.
DatabaseMirror database.clamav.net
# Number of database checks per day.
# Default: 12 (every two hours)
#Checks 24

Note: Should not the above setup update ClamAV, crontab can ensure that as well by:

$ crontab -e
0 */2 * * * /usr/local/bin/freshclam >/dev/null 2>&1
# or using the following syntax (depends on the cron version)
0 0,2,4,6,8,10,12,14,16,18,20,22 * * * /usr/local/bin/freshclam >/dev/null 2>&1

First, a manual refreshment of ClamAV's database needs to be performed (it will take a few minutes):

$ freshclam
# alternatively and for more details:
$ freshclam -v

After the database is updated, the ClamAV daemon settings need to be set up in the following way:

$ vi /etc/clamd.conf
# Comment or remove the line below.
#Example
# TCP port address.
# Default: no
TCPSocket 3310
# TCP address.
# By default we bind to INADDR_ANY, probably not wise.
# Enable the following to provide some degree of protection
# from the outside world. This option can be specified multiple
# times if you want to listen on multiple IPs. IPv6 is now supported.
# Default: no
TCPAddr 127.0.0.1
# Enable internal e-mail scanner.
# If you turn off this option, the original files will still be scanned, but
# without parsing individual messages/attachments.
# Default: yes
#ScanMail yes
###
# and many more options to tweak with (just for the curious ones)

Traditionally, ClamAV needs to be enabled and started using:

$ rcctl {enable|start} clamd

Verification that the daemon is running (TCP port 3310) can be performed as follows:

$ netstat -naf inet | grep 3310
tcp          0      0  127.0.0.1.3310         *.*                    LISTEN

Redis Installation

Redis is an open source, in-memory data structure store, used as a database, cache and message broker. It supports various sorts of abstract data structures, such as strings, hashes, lists, sets, sorted sets with range queries, bitmaps, hyperloglogs and geospatial indexes with radius queries. Compared to Memcached, Redis is, simply put, more popular and better supported.

Installation of Redis is straightforward:

$ pkg_add redis
quirks-2.367 signed on 2017-10-03T11:21:28Z
redis-4.0.2:lua-5.1.5p6: ok
useradd: Warning: home directory `/var/redis' doesn't exist, and -m was not specified
redis-4.0.2: ok
The following new rcscripts were installed: /etc/rc.d/redis
See rcctl(8) for details.

Generally, the default configuration is sufficient and can be checked by:

$ grep -v -E "^#|^.#|^$" /etc/redis/redis.conf
bind 127.0.0.1
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize yes
supervised no
pidfile /var/run/redis/redis_6379.pid
loglevel notice
syslog-enabled yes
syslog-ident redis
syslog-facility daemon
<OUTPUT OMITTED>

However, it is recommended to limit the amount of memory allowed for Redis to allocate during runtime. It can be performed as follows (e.g. for 512MB):

$ echo "### Limiting the maximum amount of memory used
### appropriate value depends on e-mail volume
maxmemory 512mb
maxmemory-policy volatile-lru" >> /etc/redis/redis.conf

Traditionally, Redis needs to be enabled and started using:

$ rcctl {enable|start} redis

Verification that the daemon is running (TCP port 6379) can be performed as follows:

$ netstat -naf inet | grep 6379
tcp          0      0  127.0.0.1.6379         *.*                    LISTEN

Rspamd Basic Setup

As discussed in OpenBSD: Mail Server, the notoriously known SpamAssassin is not a bad software, but it can become very resource-hungry and its setup may be clumsy for some. Therefore, Rspamd was selected to filter e-mails not only because it is:

Rspamd can be installed as follows:

$ pkg_add rspamd
quirks-2.367 signed on 2017-10-03T11:21:28Z
rspamd-1.6.4p0:libmagic-5.32: ok
rspamd-1.6.4p0:luajit-2.0.5p0: ok
rspamd-1.6.4p0:fann-2.2.0: ok
rspamd-1.6.4p0: ok
The following new rcscripts were installed: /etc/rc.d/rspamd
See rcctl(8) for details.

For local configuration to be stored, the following directory needs to be created:

$ mkdir -p /etc/rspamd/local.d/

Rspamd defines several types of worker processes. If it is not required otherwise, it is better to restrict the normal and proxy workers to listen on localhost only:

$ echo "bind_socket = \"localhost:11333\";" > /etc/rspamd/local.d/worker-normal.inc
$ echo "bind_socket = \"localhost:11332\";" > /etc/rspamd/local.d/worker-proxy.inc

Rspamd controller worker trusts only the loopback interface by default. However, password for unprivileged access should be set up as follows:

$ echo "password = \"`rspamadm pw`\";" > /etc/rspamd/local.d/worker-controller.inc

Password for privileged access to the controller worker can be set up as follows:

$ echo "enable_password = \"`rspamadm pw`\";" >> /etc/rspamd/local.d/worker-controller.inc

The default backend for statistics and caching of learned messages is SQLite3:

$ grep backend /etc/rspamd/statistic.conf
  backend = "sqlite3";

Since already installed, Redis can be successfully utilised instead:

$ echo "servers = \"127.0.0.1\";
backend = \"redis\";" > /etc/rspamd/local.d/classifier-bayes.conf
$ echo "servers = \"127.0.0.1:6379\";" > /etc/rspamd/local.d/redis.conf

To check if the configuration is sane:

$ rspamadm configtest
syntax OK

To review the configuration:

$ rspamadm configdump

Traditionally, Rspamd needs to be enabled and started using:

$ rcctl {enable|start} rspamd

Verification that the three workers are running (TCP ports 11332, 11333 and 11334) can be performed as follows:

$ netstat -naf inet | grep 1133
tcp          0      0  127.0.0.1.11334        *.*                    LISTEN
tcp          0      0  127.0.0.1.11333        *.*                    LISTEN
tcp          0      0  127.0.0.1.11332        *.*                    LISTEN

In order to have remote access to the controller worker WebGUI, an SSH tunnel can be used from another machine, e.g.:

$ ssh -p SSH_PORT -L 11334:localhost:11334 user1@server.domain.tld

The remote WebGUI should be accessible locally using: http://localhost:11334

Note: Depending on the connection quality, it may take up to several seconds to the password prompt to appear (unfortunately, it even times-out sometimes).


ClamAV Integration into Rspamd

By default, ClamAV is enabled in Rspamd. It can be verified by running:

$ rspamadm configdump antivirus
*** Section antivirus ***
clamav {
    attachments_only = true;
    symbol = "CLAM_VIRUS";
    type = "clamav";
    patterns {
        JUST_EICAR = "^Eicar-Test-Signature$";
    }
    whitelist = "/etc/rspamd/antivirus.wl";
}

*** End of section antivirus ***

Just to make sure, IP address and port of the ClamAV server (e.g. 127.0.0.1:3310) can be configured as follows:

$ echo "clamav {
  servers = "127.0.0.1:3310";
}" > /etc/rspamd/local.d/antivirus.conf

In order to apply changes, Rspamd needs to be reloaded (or restarted):

$ rcctl restart rspamd

Rspamd Integration into Postfix

In order to enable communication between Postfix and Rspamd, milter protocol needs to be used. Since Rspamd 1.6, Rspamd proxy worker should be used.

To enable milter in Postfix, either main.cf or master.cf can be used. Considering the fact that Rspamd will be invoked for both directions, the following needs to be added at the end of the main.cf configuration file:

$ vi /etc/postfix/main.cf
### Rspamd via a TCP socket
smtpd_milters = inet:localhost:11332
non_smtpd_milters = $smtpd_milters
milter_protocol = 6
milter_mail_macros = i {mail_addr} {client_addr} {client_name} {auth_authen}
milter_rcpt_macros = i {rcpt_addr}
milter_default_action = accept

Since the normal worker is not used in self-scan mode, it can be disabled to free up system resources as follows:

$ echo "enabled = false;" > /etc/rspamd/local.d/worker-normal.inc

In order to apply changes, Rspamd needs to be reloaded (or restarted):

$ rcctl restart rspamd

A quick test that the normal worker is not running anymore can be performed as follows:

$ netstat -naf inet | grep 1133
tcp          0      0  127.0.0.1.11332        *.*                    LISTEN
tcp          0      0  127.0.0.1.11334        *.*                    LISTEN

The Self-scan mode can be configured as follows:

$ vi /etc/rspamd/local.d/worker-proxy.inc
bind_socket = "localhost:11332";
milter = yes;
timeout = 120s;    # Needed for Milter usually
upstream "local" {
  default = yes;   # Self-scan upstreams are always default
  self_scan = yes; # Enable self-scan
}

Finally, Rspamd needs to understand, which networks should be considered as local:

$ echo "# Local networks
local_addrs = \"127.0.0.0/8, ::1\";" > /etc/rspamd/local.d/options.inc

For various reasons, some e-mail headers (milter headers) may be required to be changed. For instance:

It can be achieved using the following configuration:

$ vi /etc/rspamd/local.d/milter_headers.conf
# List of headers to be enabled for authenticated users (default empty)
authenticated_headers = [
  "add-headers",
  "authentication-results",
  "x-spam-status",
  "x-virus"
];
# Set false to always add headers for local IPs (default true)
skip_local = false;
# Set false to always add headers for authenticated users (default true)
skip_authenticated = false;
# Routines to use- this is the only required setting (may be omitted if using extended_spam_headers)
use = [
  "add-headers",
  "authentication-results",
  "x-virus",
  "x-spam-status"
];
# this is where we may configure our selected routines
routines {
  add-headers {
    headers {
      X-Rspamd-Server = "Rspamd (server.domain.tld)";
    }
  }
  authentication-results {
    # Set this false not to add SMTP usernames in authentication-results
    add_smtp_user = false;
  }
}

In order to apply changes, Rspamd needs to be reloaded (or restarted):

$ rcctl restart rspamd

Virus Testing

By default, Rspamd scans only messages with non-image attachments. The testing can be performed using a file, which contains a real virus. Such file can be obtained from eicar.org. Attempts to send e-mails with this attachment should generate logs similar to the following:

$ tail -f /var/log/rspamd/rspamd.log
2016-09-13 10:11:12 #17266(normal) <726a5f>; lua; antivirus.lua:43: clamav: virus found: "Eicar-Test-Signature"
2016-09-13 10:11:12 #17266(normal) <726a5f>; task; bayes_classify: skip classification as ham class has not enough learns: 0, 200 required
2016-09-13 10:11:12 #17266(normal) <726a5f>; task; rspamd_task_write_log: id: <20160913012345.jzbudij3l2kcashe@server.domain.tld>, ip: EGRESS_IP, from: <user1@domain.tld>, (default: F (greylist): [4.00/15.00] [MIME_BAD_EXTENSION(4.00){com;},MIME_GOOD(-0.10){text/plain;multipart/mixed;},MIME_UNKNOWN(0.10){application/x-zip-compressed;},FROM_EQ_ENVFROM(0.00){},FROM_HAS_DN(0.00){},HAS_ATTACHMENT(0.00){},JUST_EICAR(0.00){Eicar-Test-Signature;},PREVIOUSLY_DELIVERED(0.00){user2@domain.tld;},RCPT_COUNT_ONE(0.00){1;},RCVD_COUNT_TWO(0.00){2;},TO_DN_ALL(0.00){}]), len: 1420, time: 3741ms real, 35ms virtual, dns req: 0, digest: <a4266dead056beef5febc1c1a9cecb30>, mime_rcpt: <user2@domain.tld>
2016-09-13 10:11:12 #17266(normal) <726a5f>; task; rspamd_protocol_http_reply: regexp statistics: 85 pcre regexps scanned, 1 regexps matched, 272 regexps total, 34 regexps cached, 10.02k bytes scanned using pcre, 10.02k bytes scanned total

As expected, the received e-mail header contains an increased score and more symbols:

X-Spam-Scanner: rspamc 1.6.4
X-Spam-Scan-Time: 3.746
X-Spam-Action: greylist
X-Spam-Score: 4.00 / 15.00
X-Spam-Level: ****
X-Spam-Symbols: FROM_HAS_DN,HAS_ATTACHMENT,PREVIOUSLY_DELIVERED,
        MIME_GOOD,MIME_UNKNOWN,TO_DN_ALL,FROM_EQ_ENVFROM,JUST_EICAR,RCPT_COUNT_ONE,
        MIME_BAD_EXTENSION,RCVD_COUNT_TWO

SPF, DKIM, DMARC, ARC in Rspamd

If possible, a reverse DNS record should exist in the DNS pointing to the e-mail server's domain name (e.g. EGRESS_IP to server.domain.tld). Verification can be performed using the dig command as follows:

$ dig +noall +answer -x EGRESS_IP
PI_SSERGE.in-addr.arpa. 3600 IN	PTR	server.domain.tld.

As discussed earlier, the Sender Policy Framework (SPF) needs to be set up in in the DNS. Considering that the domain owner wants to allow domain's MXes to send mail for the domain and prohibit all others, the SPF TXT record is: "v=spf1 mx -all". Once done, it can be verified using the dig command:

$ dig +noall +answer domain.tld -t TXT
domain.tld.		1800	IN	TXT	"v=spf1 mx -all"

The DomainKeys Identified Mail (DKIM) is used to verify digital signatures in incoming messages and cryptographically sign outgoing messages. It can be configured as follows:

$ cat /etc/rspamd/local.d/dkim_signing.conf
# If false, messages with empty envelope from are not signed
allow_envfrom_empty = true;
# If true, envelope/header domain mismatch is ignored
allow_hdrfrom_mismatch = false;
# If true, multiple from headers are allowed (but only first is used)
allow_hdrfrom_multiple = false;
# If true, username does not need to contain matching domain
# (i.e. the "@domain.tld" suffix does not neet to be present)
allow_username_mismatch = true;
# If false, messages from authenticated users are not selected for signing
auth_only = true;
# Default selector to use
selector = "dkim";
# If false, messages from local networks are not selected for signing
sign_local = true;
# Symbol to add when message is signed
symbol = "DKIM_SIGNED";
# Whether to Fallback to global config
try_fallback = true;
# Domain to use for DKIM signing:
# can be "header" (MIME From), "envelope" (SMTP From) or "auth" (SMTP username)
use_domain = "header";
# Whether to normalise domains to eSLD
use_esld = false;
# Whether to get keys from Redis
use_redis = true;
# Hash for DKIM keys in Redis
key_prefix = "DKIM_KEYS";

First, a new directory should be created to hold DKIM (and ARC) keys:

$ mkdir -p /etc/dkim/

The DKIM keys can be generated as follows (e.g. with: name dkim and key length 2048 bits):

$ rspamadm dkim_keygen -s 'dkim' -d domain.tld -b 2048 > /tmp/dkim.domain.tld

The private key section (does not contain any quotation marks) can be extracted and saved as follows:

$ grep -v -E "\"|;" /tmp/dkim.domain.tld > /etc/dkim/dkim.domain.tld

The public part of the DNS record section (contains the quotation marks and needs to be published in the DNS) can be extracted as follows:

$ awk 'f{print;f=10} /-----END/{f=1}' /tmp/dkim.domain.tld
dkim._domainkey IN TXT ( "v=DKIM1; k=rsa; "
        "p=MIIBIjANBg..."
        "...=="
) ;

In order to populate the private key in Redis, a Lua script needs to be prepared as follows:

$ echo "local key = [[`cat /etc/dkim/dkim.domain.tld`]]\nredis.call('HMSET', 'DKIM_KEYS', 'dkim.domain.tld', key)" > /tmp/dkim.lua

Finally, the named hash with DKIM keys can be uploaded into Redis using its CLI client:

# redis-cli -h 127.0.0.1 -p 6379 --eval /tmp/dkim.lua
(nil)

Verification that the DKIM keys are stored in Redis can be done using its CLI client:

$ redis-cli
127.0.0.1:6379> HGETALL DKIM_KEYS
1) "dkim.domain.tld"
2) "-----BEGIN PRIVATE KEY-----\nMIIE...\n-----END PRIVATE KEY-----"
127.0.0.1:6379> quit

or:

$ redis-cli
127.0.0.1:6379> HMGET DKIM_KEYS dkim.domain.tld
1) "-----BEGIN PRIVATE KEY-----\nMIIE...\n-----END PRIVATE KEY-----"
127.0.0.1:6379> quit

The DNS record availability can be verified using the dig command:

$ dig +noall +answer dkim._domainkey.domain.tld -t TXT
dkim._domainkey.domain.tld. 1800	IN	TXT	"v=DKIM1; k=rsa; p=MII..."

The temporary files can be removed now:

$ rm -f /tmp/dkim.domain.tld
$ rm -f /tmp/dkim.lua

Even thought the private key is in Redis, it may be useful to keep its copy in the /etc/dkim directory as a fallback solution:

$ ls -lA /etc/dkim

The Domain-based Message Authentication, Reporting and Conformance (DMARC) is not enabled by default in Rspamd. The following empty file needs to be created in order to enable it:

$ echo "" > /etc/rspamd/local.d/dmarc.conf

Considering that the domain owner wants that:

the following TXT record need to be populated in the DNS:

_dmarc          IN TXT "v=DMARC1; p=reject; rua=mailto:rua-dmarc@domain.tld"

The DNS record availability can be verified using the dig command:

$ dig +noall +answer _dmarc.domain.tld -t TXT
_dmarc.domain.tld	1800	IN	TXT	"v=DMARC1; p=reject; rua=mailto:rua-dmarc@domain.tld"

An experimental support for generation of DMARC reports has been provided since Rspamd 1.6. It can be configured as follows:

$ vi /etc/rspamd/local.d/dmarc.conf
# Enables storing reporting information to Redis
reporting = true;
# Actions to enforce based on DMARC disposition (empty by default)
actions = {
  quarantine = "add_header";
  reject = "reject";
}
# report_settings MUST be present
report_settings {
  # The following elements MUST be present
  # organisation name to use for reports
  org_name = "domain.tld";
  # organisation domain
  domain = "domain.tld";
  # sender address to use for reports
  email = "rua-dmarc@domain.tld";
}

The Authenticated Received Chain (ARC) module is internaly handled by the DKIM module in Rspamd; thus, the configuration is very similar to DKIM and looks as follows:

$ vi /etc/rspamd/local.d/arc.conf
# If false, messages with empty envelope from are not signed
allow_envfrom_empty = true;
# If true, envelope/header domain mismatch is ignored
allow_hdrfrom_mismatch = false;
# If true, multiple from headers are allowed (but only first is used)
allow_hdrfrom_multiple = false;
# If true, username does not need to contain matching domain
# (i.e. the "@domain.tld" suffix does not neet to be present)
allow_username_mismatch = true;
# If false, messages from authenticated users are not selected for signing
auth_only = true;
# Default selector to use
selector = "arc";
# If false, messages from local networks are not selected for signing
sign_local = true;
# Symbol to add when message is signed
symbol_signed = "ARC_SIGNED";
# Whether to fallback to global config
try_fallback = true;
# Domain to use for ARC signing: can be "header" or "envelope"
use_domain = "header";
# Whether to normalise domains to eSLD
use_esld = false;
# Whether to get keys from Redis
use_redis = true;
# Hash for ARC keys in Redis
key_prefix = "ARC_KEYS";

The DKIM key could be reused for this purpose. However, this solution prefers a separate one. The ARC keys can be generated as follows:

$ rspamadm dkim_keygen -s 'arc' -d domain.tld -b 2048 > /tmp/arc.domain.tld

The private key section can be extracted and saved as follows:

$ grep -v -E "\"|;" /tmp/arc.domain.tld > /etc/dkim/arc.domain.tld

The public part of the DNS record section (needs to be published in the DNS) can be extracted as follows:

$ awk 'f{print;f=10} /-----END/{f=1}' /tmp/arc.domain.tld | sed "s/v=DKIM1; //"
arc._domainkey IN TXT ( "k=rsa; "
  "p=MIIBIj..."
) ;

Note: The v=DKIM1; is an optional feature and does not need to be present in the DNS RR.

In order to populate the private key in Redis, a Lua script needs to be prepared as follows:

$ echo "local key = [[`cat /etc/dkim/arc.domain.tld`]]\nredis.call('HMSET', 'ARC_KEYS', 'arc.domain.tld', key)" > /tmp/arc.lua

Finally, the named hash with ARC keys can be uploaded into Redis using its CLI client:

$ redis-cli -h 127.0.0.1 -p 6379 --eval /tmp/arc.lua
(nil)

Verification that the ARC keys are stored in Redis can be done using its CLI client:

$ redis-cli
127.0.0.1:6379> HGETALL ARC_KEYS
1) "arc.domain.tld"
2) "-----BEGIN PRIVATE KEY-----\nMIIEv...\n-----END PRIVATE KEY-----"
127.0.0.1:6379> quit

or:

$ redis-cli
127.0.0.1:6379> HMGET ARC_KEYS arc.domain.tld
1) "-----BEGIN PRIVATE KEY-----\nMIIEv...\n-----END PRIVATE KEY-----"
127.0.0.1:6379> quit

The DNS record availability can be verified using the dig command:

$ dig +noall +answer arc._domainkey.domain.tld -t TXT
arc._domainkey.domain.tld. 1800	IN	TXT	"k=rsa; p=MII..."

The temporary files can be removed now:

$ rm -f /tmp/arc.domain.tld
$ rm -f /tmp/arc.lua

Even thought the private key is in Redis, it may be useful to keep its copy in the /etc/dkim directory as a fallback solution:

$ ls -lA /etc/dkim

Finally in order to apply the settings, Rspamd needs to be restarted (reloaded):

$ rcctl restart rspamd

Final Test and Verification

Considering that the SPF, DKIM, DMARC and ARC TXT records are present in the DNS, sending e-mails to and receiving from anyone implementing these mechanism should allow the e-mails to be singed and verified correctly, and delivered into recipients mailboxes.

Sending an e-mail from a Google account to a configured one (e.g. user1@domain.tld) should cause that the following headers will appear in the e-mail:

ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=domain.tld;
        s=arc; t=1500503927;
        h=from:subject:date:message-id:to:mime-version:content-type;
...
ARC-Seal: i=1; s=arc; d=domain.tld; t=1500503927; a=rsa-sha256;
        cv=none;
...
ARC-Authentication-Results: i=1; auth=pass smtp.auth=user1@domain.tld
        smtp.mailfrom=user1@domain.tld
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=domain.tld;
        s=dkim; t=1500503927; h=from:subject:date:message-id:to:mime-version:content-type;
...

The DMARC policy specified earlier defines reporting e-mail address as rua-dmarc@domain.tld. Considering that it is enabled (or aliased to one of the existing accounts) it will most probably receive 24h-aggregated status reports (once a day).

Many public websites exist that help with e-mail server testing, such as mxtoolbox.com.


Rspamd Fine-tuning

Rspamd can also check DNS MX Resource Record (RR) as part of the evaluation process. By default, this check is disabled:

$ rspamadm configdump mx_check
*** Section mx_check ***
timeout = 1.0;
symbol_bad_mx = "MX_INVALID";
symbol_no_mx = "MX_MISSING";
symbol_good_mx = "MX_GOOD";
expire = 86400;
key_prefix = "rmx";
enabled = false;

*** End of section mx_check ***

It can be simply enabled by:

$ echo "enabled = true;" > /etc/rspamd/local.d/mx_check.conf

Finally in order to apply the settings, Rspamd needs to be restarted (reloaded):

$ rcctl restart rspamd

Rspamd Troubleshooting

General usage:

$ rspamadm help pw
$ rspamadm help control
$ rspamadm control stat
$ rspamadm control reload

By default, the log file is available in:

$ tail -f /var/log/rspamd/rspamd.log

A specific option can be shown directly from the configdump, e.g. dkim_signing section:

$ rspamadm configdump dkim_signing

Tags: #OpenBSD #security #Rspamd #ClamAV #antivirus #spam #filter #SPF #DKIM #DMARC #ARC

⏴ Previous Post Next Post ⏵