Permalink
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
353 lines (331 sloc) 11.9 KB
#############
# RPM
#############
# Enable rspamd experimental repo
rspamd_experimental: false
rspamd_rpm_url: "https://rspamd.com/rpm{{ rspamd_experimental | ternary('', '-stable') }}/{{ (ansible_distribution == 'Fedora') | ternary('fedora', 'centos') }}-{{ansible_distribution_major_version}}/rspamd.repo"
rspamd_repo: /etc/yum.repos.d/rspamd.repo
#######################
# System configuration
#######################
rspamd_lib_dir: /var/lib/rspamd
rspamd_runtime_dir: "{{ rspamd_lib_dir }}"
rspamd_config_dir: /etc/rspamd
rspamd_local_config_dir: "{{ rspamd_config_dir }}/local.d"
rspamd_user: _rspamd
###################
# Workers
###################
# Change to a higher count if more CPUs. Cannot infer from
# has_low_memory or CPU count, which forces type to string (and bombs JSON).
# https://github.com/ansible/ansible/issues/30366
rspamd_worker_process_count: 1
# Change to a higher count if more CPUs.
rspamd_fuzzy_worker_process_count: 1
# Default logging level
# See https://rspamd.com/doc/configuration/logging.html
# Additional vars set with "rspamd_logging_custom_config" dict
rspamd_logging_level: info
# Ignore
__default_rspamd_worker_socket: "{{ rspamd_runtime_dir }}/rspamd-worker.sock"
# Change to a different server or host if clustered
rspamd_worker_socket: "{{ __default_rspamd_worker_socket }}"
# Controller used by rspamc direct learns
rspamd_controller_socket: "127.0.0.1:11334"
# Fuzzy worker
rspamd_fuzzy_socket: "127.0.0.1:11335"
######################
# Redis configuration
######################
# Enable redis for rspamd. Enable if worker exists on local socket
rspamd_redis_enabled: "{{ not has_low_memory and rspamd_worker_socket.find('/') != -1 }}"
# Give an absolute path to use a UNIX socket + install service
rspamd_redis_runtime_dir: "{{ rspamd_runtime_dir }}/redis"
rspamd_redis_server: "{{ rspamd_redis_runtime_dir }}/redis.sock"
rspamd_redis_pid_file: "{{ rspamd_redis_runtime_dir }}/redis.pid"
rspamd_redis_service: "{{ rspamd_redis_server.find('/') == 0 }}"
rspamd_redis_config: "{{ rspamd_local_config_dir }}/redis-server.conf"
rspamd_redis_user: "{{ rspamd_user }}"
rspamd_redis_password: ""
# Database storage
rspamd_redis_dir: "{{ rspamd_lib_dir }}/redis"
rspamd_redis_memory_allocation: "{{ has_low_memory | ternary('256mb', (ansible_memtotal_mb * 0.5) | string + 'mb')}}"
# rspamd_redis_custom_config
# rspamd_neural_custom_config
# rspamd_reputation_custom_config etc
# Save every 60 seconds if more than 1000 keys change
rspamd_redis_snapshot_policy: &snapshot_policy
rdbchecksum: "yes"
save: |-
60 100
save 900 1
rspamd_redis_vars:
bind: "127.0.0.1"
daemonize: "yes"
unixsocketperm: "0600"
"maxmemory-policy": "volatile-lru"
port: 0
maxmemory: "{{ rspamd_redis_memory_allocation }}"
"protected-mode": "no"
pidfile: "{{ rspamd_redis_pid_file }}"
unixsocket: "{{ (rspamd_redis_server.find('/') == 0) | ternary(rspamd_redis_server, omit) }}"
dir: "{{ rspamd_redis_dir }}"
"rename-command": |
CONFIG ""
<<: *snapshot_policy
#################
# rspamd milter
#################
rspamd_proxy_port: 10003
rspamd_proxy_host: localhost
# Filter mail that originates from sendmail or PHP mail() function
rspamd_filter_outbound: true
# filter mail that comes from the server as well as SRS forwards
rspamd_filter_origination: true
#############
# Learning
#############
# Valid values: standalone, piggyback.
# Setting spamfilter in apnscp-vars.yml to spamassassin implies piggyback
# "piggyback" will feed off SA data
rspamd_method: "{{ (spamfilter == 'spamassassin') | ternary('piggyback', 'standalone') }}"
# piggyback off results from spamassassin to train algorithm
rspamd_passive_learning_mode: "{{ rspamd_enabled and (rspamd_method == 'piggyback') }}"
# Suitable for low-volume environments
rspamd_use_spamassassin_rules: false
# Learns egregious violators based upon SpamAssassin's scoring
rspamd_piggyback_learn_spam_threshold: 7.0
# Learns roughly half of ham in a trained database
rspamd_piggyback_learn_ham_threshold: -0.5
# Optional location for SA rule usage
rspamd_spamassassin_rules: "/var/lib/spamassassin/3.004002/updates_spamassassin_org/[0-9]*.cf"
# Enable neural training. CPU intensive
rspamd_enable_neural_training: "{{ not has_low_memory and rspamd_redis_enabled }}"
# Autolearn threshold when not piggybacked. Set to false to disable autolearning
rspamd_autolearn_threshold: [-2.5, 10]
# Fuzzy signature storage for detecting spammy attachments
rspamd_fuzzy_learning_active: true
###################
# Action thresholds
###################
# 13.19 is approximately 15% percentile with a trained data set
# n = 532, mu = 18.90, s = 5.39
rspamd_reject_piggyback_score: 25
rspamd_reject_score: 15
rspamd_greylist_piggyback_score: 10
# Used when spamfilter == rspamd, triggers delivery in Spam mailbox
# When piggybacking, a SA score of 4 adds this header anyway
rspamd_add_header_score: 8
rspamd_greylist_score: 4
# Add headers to email
rspamd_extended_spam_headers: "{{ (rspamd_method == 'piggyback') }}"
# Duration an IP address that revisits the mail server will be
# allowed despite scoring >= rspamd_greylist_score
# Time expressed in seconds, 5 days.
# "5d" would be parsed as a string and converted to 5 seconds
rspamd_greylist_expire: 432000
#################
# Weighted scores
#################
# Various weighted scores maximums. As p → 100%, score → var
rspamd_weight_neural_spam: 3.0
rspamd_weight_neural_ham: -3.0
# 5.10 is default, with a mature Bayes DB bump this value up to 10
rspamd_weight_bayes_spam: 5.10
rspamd_weight_bayes_ham: -3.0
# Periodically cull infrequently seen symbols from database
rspamd_bayes_expiry_time: 2592000
# Set to true and expiry time to large to defer to Redis in OOM situations
# See https://rspamd.com/doc/modules/bayes_expiry.html
rspamd_bayes_lazy_expire: false
######################
# Learning commands
######################
rspamd_learn_command: /usr/bin/rspamc
rspamd_learn_spam: '"|{{ rspamd_learn_command }} learn_spam"'
rspamd_learn_ham: '"|{{ rspamd_learn_command }} learn_ham"'
rspamd_piggyback_block: |
/^X-Spam-Score: ([-\d\.]+)/
if ($MATCH1 >= {{ rspamd_piggyback_learn_spam_threshold }})
{% raw -%} { {% endraw %}
cc "! {{ rspamd_learn_spam_email }}"
{% raw -%} } {% endraw %}
elsif ($MATCH1 <= {{ rspamd_piggyback_learn_ham_threshold }})
{% raw -%} { {% endraw %}
cc "! {{ rspamd_learn_ham_email }}"
{% raw -%} } {% endraw %}
rspamd_learn_spam_email: "learn_spam"
rspamd_learn_ham_email: "learn_ham"
maildrop_files:
- "{{ (apnscp_account_root + '/site*/fst/etc/maildroprc') | fileglob }}"
- "{{ apnscp_filelists }}/siteinfo/etc/maildroprc"
#####################
# Postfix integration
#####################
postfix_config:
# All inbound and forwarded mail
smtpd_milters: "{{ rspamd_enabled | ternary('inet:' + rspamd_proxy_host + ':' + rspamd_proxy_port|string, None) }}"
milter_default_action: accept
# Locally originating mail with sendmail
non_smtpd_milters: "{{ rspamd_enabled and rspamd_filter_outbound | ternary('inet:' + rspamd_proxy_host + ':' + rspamd_proxy_port|string, None) }}"
milter_mail_macros: "i {mail_addr} {client_addr} {client_name} {auth_authen}"
##################
# rspamd config
##################
# When rspamd_use_spamassassin_rules is true
rspamd_spamassassin_config:
- file: spamassassin.conf
vars:
ruleset: "{{ rspamd_spamassassin_rules }}"
match_limit: 100k
config_files:
- file: statistics_group.conf
vars:
symbols:
BAYES_HAM:
weight: "{{ rspamd_weight_bayes_ham }}"
BAYES_SPAM:
weight: "{{ rspamd_weight_bayes_spam }}"
- file: neural_group.conf
vars:
symbols:
NEURAL_SPAM:
weight: "{{ rspamd_weight_neural_spam }}"
NEURAL_HAM:
weight: "{{ rspamd_weight_neural_ham }}"
- file: neural.conf
vars:
enabled: "{{ rspamd_enable_neural_training }}"
servers: "{{ rspamd_redis_server }}"
password: "{{ rspamd_redis_password }}"
dbname: "{{ rspamd_neural_db | default(2) }}"
- file: replies.conf
vars:
action: no action
- file: "url_tags.conf"
vars:
enabled: "{{ rspamd_redis_enabled }}"
- file: reputation.conf
vars:
rules:
ip_reputation:
symbol: IP_REPUTATION
selector:
ip: {}
backend: &redis
redis:
spf_reputation:
symbol: SPF_REPUTATION
selector:
spf: {}
backend: *redis
dkim_reputation:
symbol: DKIM_REPUTATION
selector:
dkim: {}
backend: *redis
- file: actions.conf
vars:
add_header: "{{ rspamd_add_header_score }}"
# greylist and reject are computed in enable-rspamd.yml
subject: "{{ rspamd_passive_learning_mode | ternary('%s', '[SPAM] (%d) %s') }}"
- file: classifier-bayes.conf
vars:
backend: "{{ rspamd_redis_enabled | ternary('redis', 'sqlite') }}"
autolearn: "{{ (rspamd_method == 'piggyback') | ternary(false, rspamd_autolearn_threshold) }}"
new_schema: true
name: bayes
expire: "{{ rspamd_bayes_expiry_time }}"
lazy: "{{ rspamd_bayes_lazy_expire }}"
statfile:
BAYES_HAM:
symbol: BAYES_HAM
spam: false
BAYES_SPAM:
symbol: BAYES_SPAM
spam: true
- file: dmarc.conf
vars:
reporting: "{{ rspamd_redis_enabled }}"
actions:
quarantine: add_header
reject: reject
- file: fuzzy_check.conf
vars:
rule:
local:
servers: "{{ rspamd_fuzzy_socket }}"
symbol: "LOCAL_FUZZY_UNKNOWN"
mime_types: ["application/*", "*/octet-stream"]
max_score: 20
skip_unknown: true
read_only: "{{ not rspamd_fuzzy_learning_active }}"
algorithm: mumhash
fuzzy_map:
LOCAL_FUZZY_DENIED:
max_score: 20
flag: 1
LOCAL_FUZZY_PROB:
max_score: 10
flag: 2
LOCAL_FUZZY_WHITE:
max_score: 2
flag: 3
- file: greylist.conf
vars:
expire: "{{ rspamd_greylist_expire }}"
- file: logging.inc
vars:
level: "{{ rspamd_logging_level }}"
- file: metrics.conf
vars:
group:
fuzzy:
max_score: 12
symbol:
LOCAL_FUZZY_UNKNOWN:
weight: 3
description: Generic fuzzy hash match
LOCAL_FUZZY_DENIED:
weight: 12
description: Denied fuzzy hash
LOCAL_FUZZY_PROB:
weight: 6
description: Probable fuzzy hash
LOCAL_FUZZY_WHITE:
weight: -2.5
description: Whitelisted fuzzy hash
- file: milter_headers.conf
vars:
extended_spam_headers: "{{ rspamd_extended_spam_headers }}"
- file: redis.conf
vars: &redis_vars
servers: "{{ rspamd_redis_enabled | ternary(rspamd_redis_server, None) }}"
password: "{{ rspamd_redis_password }}"
expand_keys: true
- file: worker-fuzzy.inc
vars:
backend: "{{ rspamd_redis_enabled | ternary('redis', 'sqlite') }}"
count: "{{ rspamd_fuzzy_worker_process_count }}"
hash_file: "{{ rspamd_redis_enabled | ternary(omit, '${DBDIR}/fuzzy.db') }}"
bind_socket: "{{ rspamd_fuzzy_socket }}"
- file: worker-normal.inc
vars:
enabled: "{{ not has_low_memory }}"
bind_socket: "{{ rspamd_worker_socket }}"
- file: worker-proxy.inc
vars:
self_scan: "{{ (has_low_memory and (__default_rspamd_worker_socket == rspamd_worker_socket )) }}"
bind_socket: "localhost:{{ rspamd_proxy_port }}"
spam_header: 'X-Spam-Flag'
upstream:
local:
default: true
hosts: "{{ rspamd_worker_socket }}"
- file: worker-controller.inc
vars:
# Does this affect just outbound or inbound?
quarantine_on_reject: false
bind_socket: "127.0.0.1:11334"
#bind_socket: "{{ rspamd_runtime_dir }}/rspamd-controller.sock"
count: "{{ rspamd_worker_process_count }}"