This repository has been archived by the owner on Oct 7, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
/
main.yml
352 lines (331 loc) · 11.9 KB
/
main.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
#############
# 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 }}"