Skip to content

Commit 55eeeda

Browse files
authored
Merge pull request #69 from vedetta-com/wip
- Add and bayes classification of messages - Fix MUA Autoconfiguration - Fix autoinstall - Update the Installation Guide
2 parents d67ea37 + 013f4fc commit 55eeeda

File tree

13 files changed

+115
-78
lines changed

13 files changed

+115
-78
lines changed

INSTALL.md

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -108,15 +108,15 @@ dsync [SSH](src/etc/ssh/sshd_config) limited to one "[command](src/home/dsync/.s
108108
su - dsync
109109
ssh-keygen
110110
echo "command=\"doas -u vmail \${SSH_ORIGINAL_COMMAND#*}\" $(cat ~/.ssh/id_rsa.pub)" | \
111-
ssh puffy@hermes.example.com "cat >> ~/.ssh/authorized_keys"
111+
ssh puffy@hermes.example.com "cat >> /home/dsync/.ssh/authorized_keys"
112112
exit
113113
```
114114

115115
Update [/home/dsync](src/home/dsync), on primary and backup MX:
116116
```sh
117117
chown -R root:dsync /home/dsync
118118
chmod 750 /home/dsync/.ssh
119-
chmod 640 /home/dsync/.ssh/{authorized_keys,id_rsa.pub,config}
119+
chmod 640 /home/dsync/.ssh/{authorized_keys,id_rsa.pub}
120120
chmod 400 /home/dsync/.ssh/id_rsa
121121
chown dsync /home/dsync/.ssh/id_rsa
122122
```
@@ -182,7 +182,7 @@ grep -r hermes .
182182
find . -type f -exec sed -i "s|hermes|$(dig +short $(hostname | sed "s/$(hostname -s).//") mx | awk -vhostname="$(hostname)" '{if ($2 != hostname".") print $2;}')|g" {} +
183183
```
184184

185-
Update the allowed mail relays [source table](https://man.openbsd.org/table.5#Source_tables) [`etc/mail/relays`](src/etc/mail/relays).
185+
Update the allowed mail relays [source table](https://man.openbsd.org/table.5#Source_tables) [`src/etc/mail/relays`](src/etc/mail/relays).
186186

187187
Update wheel user name "puffy":
188188
```sh
@@ -210,7 +210,6 @@ install -o root -g wheel -m 0640 -b src/etc/acme-client.conf /etc/
210210
install -o root -g wheel -m 0640 -b src/etc/dhclient.conf /etc/
211211
install -o root -g wheel -m 0640 -b src/etc/dkimproxy_out.conf /etc/
212212
install -o root -g wheel -m 0640 -b src/etc/doas.conf /etc/
213-
install -o root -g wheel -m 0644 -b src/etc/hosts /etc/
214213
install -o root -g wheel -m 0640 -b src/etc/httpd.conf* /etc/
215214
install -o root -g wheel -m 0644 -b src/etc/login.conf /etc/
216215
install -o root -g wheel -m 0644 -b src/etc/newsyslog.conf /etc/
@@ -265,11 +264,8 @@ install -o root -g wheel -m 0644 -b src/var/unbound/etc/unbound.conf /var/unboun
265264
install -o root -g daemon -m 0755 -d src/var/www/htdocs/mercury.example.com /var/www/htdocs/$(hostname)
266265
install -o root -g daemon -m 0644 -b src/var/www/htdocs/mercury.example.com/index.html /var/www/htdocs/$(hostname)/
267266

268-
install -o root -g daemon -m 0755 -d src/var/www/htdocs/autoconfig.example.com /var/www/htdocs/autoconfig.$(hostname | sed "s/$(hostname -s).//")
269-
install -o root -g daemon -m 0644 -b src/var/www/htdocs/autoconfig.example.com/index.html /var/www/htdocs/autoconfig.$(hostname | sed "s/$(hostname -s).//")/
270-
271-
install -o root -g daemon -m 0755 -d src/var/www/htdocs/autoconfig.example.com/mail /var/www/htdocs/autoconfig.$(hostname | sed "s/$(hostname -s).//")/mail
272-
install -o root -g daemon -m 0644 -b src/var/www/htdocs/autoconfig.example.com/mail/config-v1.1.xml /var/www/htdocs/autoconfig.$(hostname | sed "s/$(hostname -s).//")/mail/
267+
install -o root -g daemon -m 0755 -d src/var/www/htdocs/mercury.example.com/mail /var/www/htdocs/$(hostname)/mail
268+
install -o root -g daemon -m 0644 -b src/var/www/htdocs/mercury.example.com/mail/config-v1.1.xml /var/www/htdocs/$(hostname)/mail/
273269

274270
install -o root -g wheel -m 0644 -b src/root/.ssh/config /root/.ssh/
275271

@@ -282,6 +278,7 @@ Unbound DNS validating resolver from root nameservers, with fallback:
282278
```sh
283279
unbound-anchor -a "/var/unbound/db/root.key"
284280
ftp -o /var/unbound/etc/root.hints https://FTP.INTERNIC.NET/domain/named.cache
281+
rcctl enable unbound
285282
rcctl restart unbound
286283
cp src/etc/resolv.conf /etc/
287284
```
@@ -299,7 +296,9 @@ sievec /var/dovecot/sieve/before/spamtest.sieve
299296

300297
Turn off `httpd` tls:
301298
```sh
302-
sed -i "s|^$(echo -e "\t")tls|$(echo -e "\t")#tls|" /etc/httpd.conf
299+
sed -i -e "s|^$(echo -e "\t")tls|$(echo -e "\t")#tls|" \
300+
-e "/tls port https/s|^$(echo -e "\t")|$(echo -e "\t")#|" \
301+
/etc/httpd.conf
303302
```
304303

305304
Start `httpd`:
@@ -309,33 +308,36 @@ rcctl start httpd
309308

310309
Initialize a new account and domain key:
311310
```sh
311+
mkdir -p /etc/ssl/acme/private
312+
chmod 700 /etc/ssl/acme/private
312313
acme-client -vAD $(hostname)
313314
```
314315

315-
OCSP response:
316-
```sh
317-
/usr/local/bin/get-ocsp.sh $(hostname)
318-
```
319-
320316
Turn on `httpd` tls:
321317
```sh
322-
sed -i "s|^$(echo -e "\t")#tls|$(echo -e "\t")tls|" /etc/httpd.conf
318+
sed -i -e "s|^$(echo -e "\t")#tls|$(echo -e "\t")tls|" \
319+
-e "/tls port https/s|^$(echo -e "\t")#|$(echo -e "\t")|" \
320+
/etc/httpd.conf
323321
```
324322

325-
Restart `httpd`:
323+
OCSP response:
326324
```sh
327-
rcctl restart httpd
325+
/usr/local/bin/get-ocsp.sh $(hostname)
328326
```
329327

330328
Edit [`crontab`](src/var/cron/tabs/root):
331329
```sh
332330
crontab -e
333331
```
334332

333+
*n.b.*: assuming [DKIM](https://github.com/vedetta-com/caesonia/blob/master/README.md#domain-keys-identified-mail-dkim) keys are set.
334+
335335
### Restart
336336

337337
Restart the email service:
338338
```sh
339+
touch /etc/pf.permanentban
340+
chmod 600 /etc/pf.permanentban
339341
pfctl -f /etc/pf.conf
340342
rcctl restart sshd dkimproxy_out rspamd dovecot smtpd
341343
```

README.md

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ Root your Inbox :mailbox_with_mail:
2525
- Flexible: switching roles is easy, making the process of changing VPS hosts a breeze (no downtime)
2626
- DMARC (with DKIM and SPF) email-validation system, to detect and prevent email spoofing
2727
- Uncensored DNS validating resolver from root nameservers
28-
- MUA auto-configuration, for modern clients
28+
- MUA Autoconfiguration, for modern clients
2929
- Daily (spartan) stats, to keep track of things
3030
- Your sieve scripts and managesieve configuration, let's get started
3131

@@ -111,10 +111,8 @@ full sync: replication_full_sync_interval\ =\ 1h
111111

112112
Disklabel: [var/www/htdocs/mercury.example.com/disklabel.min](src/var/www/htdocs/mercury.example.com/disklabel.min)
113113

114-
Ansible: [ansible-role-mailserver](https://github.com/gonzalo-/ansible-role-mailserver/)
115-
116114
## Prerequisites
117-
A DNS name server (from a registrar, a free service, VPS host, or self-hosted) is required, which allows editing the following record types: [A](#forward-confirmed-reverse-dns-fcrdns), [AAAA](#forward-confirmed-reverse-dns-fcrdns), [SRV](#srv-records-for-locating-email-services), [MX](#mail-exchanger-mx), [CAA](#certification-authority-authorization-caa), [SSHFP](#secure-shell-fingerprint-sshfp), [TXT](#sender-policy-framework-spf)
115+
A DNS name server (from a registrar, a free service, VPS host, or self-hosted) is required, which allows editing the following record types: [A](#forward-confirmed-reverse-dns-fcrdns), [AAAA](#forward-confirmed-reverse-dns-fcrdns), [CNAME](#mozilla-autoconfiguration), [SRV](#srv-records-for-locating-email-services), [MX](#mail-exchanger-mx), [CAA](#certification-authority-authorization-caa), [SSHFP](#secure-shell-fingerprint-sshfp), [TXT](#sender-policy-framework-spf)
118116

119117
#### Forward-confirmed reverse DNS ([FCrDNS](https://tools.ietf.org/html/draft-ietf-dnsop-reverse-mapping-considerations-06))
120118
Each MX subdomain has record types A, and AAAA with the VPS' IPv4, and IPv6:
@@ -140,13 +138,12 @@ dig +short -x 2001:0db8::1
140138
```
141139

142140
#### Mozilla [Autoconfiguration](https://developer.mozilla.org/en-US/docs/Mozilla/Thunderbird/Autoconfiguration)
143-
Each autoconfig subdomain has record types A, and AAAA with the VPS' IPv4, and IPv6:
141+
Each autoconfig subdomain has record type CNAME pointing to Autoconfiguration server:
144142
```console
145-
autoconfig.example.com. 86400 IN A 203.0.113.1
146-
autoconfig.example.com. 86400 IN AAAA 2001:0db8::1
143+
autoconfig.example.com. 86400 IN CNAME mercury.example.com.
147144
```
148145

149-
Each *virtual* autoconfig subdomain has record type CNAME pointing to *autoconfig.example.com*:
146+
Each *virtual* autoconfig subdomain has record type CNAME pointing to Autoconfiguration server:
150147
```console
151148
autoconfig.example.net. 86400 IN CNAME autoconfig.example.com.
152149
```

UPGRADE.md

Lines changed: 55 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ rm libpthread-stubs.a \
2323
reboot
2424
boot: bsd.rd
2525
> (I)nstall, (U)pgrade, (A)utoinstall or (S)hell? U
26+
...
2627
Set name(s) = -comp* -game* -x*
28+
...
2729
reboot
2830
sysmerge
2931
pkg_add -u
@@ -49,22 +51,17 @@ pfctl -f /etc/pf.conf
4951

5052
Mozilla [Autoconfiguration](https://developer.mozilla.org/en-US/docs/Mozilla/Thunderbird/Autoconfiguration)
5153
```sh
52-
vi src/var/www/htdocs/autoconfig.example.com/index.html
53-
install -o root -g daemon -m 0755 -d src/var/www/htdocs/autoconfig.example.com /var/www/htdocs/autoconfig.$(hostname | sed "s/$(hostname -s).//")
54-
install -o root -g daemon -m 0644 -b src/var/www/htdocs/autoconfig.example.com/index.html /var/www/htdocs/autoconfig.$(hostname | sed "s/$(hostname -s).//")/
55-
56-
vi src/var/www/htdocs/autoconfig.example.com/mail/config-v1.1.xml
57-
install -o root -g daemon -m 0755 -d src/var/www/htdocs/autoconfig.example.com/mail /var/www/htdocs/autoconfig.$(hostname | sed "s/$(hostname -s).//")/mail
58-
install -o root -g daemon -m 0644 -b src/var/www/htdocs/autoconfig.example.com/mail/config-v1.1.xml /var/www/htdocs/autoconfig.$(hostname | sed "s/$(hostname -s).//")/mail/
54+
vi src/var/www/htdocs/mercury.example.com/mail/config-v1.1.xml
55+
install -o root -g daemon -m 0755 -d src/var/www/htdocs/mercury.example.com/mail /var/www/htdocs/$(hostname)/mail
56+
install -o root -g daemon -m 0644 -b src/var/www/htdocs/mercury.example.com/mail/config-v1.1.xml /var/www/htdocs/$(hostname)/mail/
5957
```
6058

61-
Each autoconfig subdomain has record types A, and AAAA with the VPS' IPv4, and IPv6:
62-
```console
63-
autoconfig.example.com. 86400 IN A 203.0.113.1
64-
autoconfig.example.com. 86400 IN AAAA 2001:0db8::1
59+
Each autoconfig subdomain has record type CNAME pointing to Autoconfiguration server:
60+
```console
61+
autoconfig.example.com. 86400 IN CNAME mercury.example.com
6562
```
6663

67-
Each *virtual* autoconfig subdomain has record type CNAME pointing to *autoconfig.example.com*:
64+
Each *virtual* autoconfig subdomain has record type CNAME pointing to Autoconfiguration server:
6865
```console
6966
autoconfig.example.net. 86400 IN CNAME autoconfig.example.com.
7067
```
@@ -80,8 +77,17 @@ Each autoconfig subdomain needs a TXT record with SPF data:
8077
autoconfig.example.com. 86400 IN TXT "v=spf1 -all"
8178
```
8279

83-
Edit and add the following configuration directive to [`/etc/httpd.conf`](src/etc/httpd.conf):
80+
Edit *autoconfig.example.com*, and add the following configuration directive to [`/etc/httpd.conf`](src/etc/httpd.conf):
8481
```console
82+
...
83+
# Host
84+
server "mercury.example.com" {
85+
alias "autoconfig.example.com"
86+
87+
listen on $IPv4 port http
88+
...
89+
}
90+
8591
# Mozilla Autoconfiguration
8692
server "autoconfig.*" {
8793
listen on $IPv4 port http
@@ -95,15 +101,32 @@ server "autoconfig.*" {
95101
block
96102

97103
location "/*" {
98-
root "/htdocs/autoconfig.example.com"
99-
pass
104+
block return 302 "https://autoconfig.example.com$REQUEST_URI"
100105
}
101106
}
107+
...
108+
```
109+
110+
Revoke `mercury.example.com` certificate:
111+
```sh
112+
acme-client -vr mercury.example.com
113+
```
114+
115+
Update [`/etc/acme-client.conf`](src/etc/acme-client.conf):
116+
```sh
117+
sed -i -e '/alternative names/s|secure.example.com|autoconfig.example.com|' \
118+
-e '/alternative names/s/^#//' /etc/acme-client.conf
119+
```
120+
121+
Get a new certificate for *mercury.example.com*:
122+
```sh
123+
acme-client -v mercury.example.com
124+
get-ocsp.sh mercury.example.com
102125
```
103126

104-
Reload:
127+
Restart:
105128
```sh
106-
rcctl reload httpd
129+
rcctl restart smtpd dovecot
107130
```
108131

109132
When relaying as backup MX, enforce STARTTLS and certificate verification:
@@ -115,3 +138,18 @@ Restart backup MX:
115138
```sh
116139
rcctl restart smtpd
117140
```
141+
142+
Add `per_user` and `per_language` bayes classification of messages:
143+
```sh
144+
rcctl stop rspamd
145+
rm /tmp/*.shm
146+
cp src/etc/rspamd/local.d/classifier-bayes.conf /etc/rspamd/local.d/
147+
cp src/usr/local/bin/learn_*.sh /usr/local/bin/
148+
```
149+
150+
Start with a fresh database:
151+
```
152+
rm /var/rspamd/*
153+
rcctl start rspamd
154+
```
155+

src/etc/acme-client.conf

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@
22
# $OpenBSD: acme-client.conf,v 1.6 2017/11/27 01:59:55 florian Exp $
33
#
44
authority letsencrypt {
5-
api url "https://acme-v01.api.letsencrypt.org/directory"
6-
account key "/etc/acme/letsencrypt-privkey.pem"
5+
api url "https://acme-v01.api.letsencrypt.org/directory"
6+
account key "/etc/acme/letsencrypt-privkey.pem"
77
}
88

99
authority letsencrypt-staging {
10-
api url "https://acme-staging.api.letsencrypt.org/directory"
11-
account key "/etc/acme/letsencrypt-staging-privkey.pem"
10+
api url "https://acme-staging.api.letsencrypt.org/directory"
11+
account key "/etc/acme/letsencrypt-staging-privkey.pem"
1212
}
1313

1414
domain mercury.example.com {
15-
# alternative names { secure.example.com }
15+
alternative names { autoconfig.example.com }
1616
domain key "/etc/ssl/acme/private/mercury.example.com.key"
1717
domain certificate "/etc/ssl/acme/mercury.example.com.crt"
1818
domain full chain certificate "/etc/ssl/acme/mercury.example.com.fullchain.pem"

src/etc/hostname.vio0

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
# https://man.openbsd.org/hostname.if
22
-inet # reset interface to its default state
33
-inet6 # reset interface to its default state
4-
dhcp # static IP
5-
inet6 -autoconfprivacy # static IP
6-
inet6 -soii # disable persistent Semantically Opaque Interface Identifiers
7-
inet6 autoconf # slaac
8-
#inet6 2001:0db8::1 64 # no slaac
9-
#inet6 alias 2001:0db8::2 64 # prefixlen 56 for gateways on different network
4+
dhcp
5+
inet6 -autoconfprivacy
6+
inet6 -soii
7+
inet6 autoconf
8+
# prefixlen 56 for gateways on different network
9+
#inet6 2001:0db8::1 64
10+
#inet6 alias 2001:0db8::2 64

src/etc/httpd.conf

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ prefork 1
1919

2020
# Host
2121
server "mercury.example.com" {
22+
alias "autoconfig.example.com"
23+
2224
listen on $IPv4 port http
2325
listen on $IPv4 tls port https
2426
listen on $IPv6 port http
@@ -63,8 +65,7 @@ server "autoconfig.*" {
6365
block
6466

6567
location "/*" {
66-
root "/htdocs/autoconfig.example.com"
67-
pass
68+
block return 302 "https://autoconfig.example.com$REQUEST_URI"
6869
}
6970
}
7071

src/etc/rspamd/local.d/classifier-bayes.conf

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
# Classifier's algorithm is BAYES
1010

11+
# Unique name used to learn the specific classifier (default: bayes)
12+
#name = "bayes";
1113
# Minimum number of words required for statistics processing
1214
min_tokens = 11;
1315
# Minimum learn count for both spam and ham classes to perform classification
@@ -20,5 +22,12 @@ autolearn = true;
2022
# or use the following Lua function to detect if autolearn is needed (return "ham", "spam", or nil)
2123
#autolearn = "return function(task) ... end";
2224

23-
# v1.7
24-
#backend = "redis";
25+
# Enable per-user statistics
26+
users_enabled = true;
27+
# Use per-user statistics
28+
per_user = true;
29+
# Enable per-language statistics
30+
languages_enabled = true;
31+
# Use per-language statistics
32+
per_language = true;
33+

src/usr/local/bin/learn_ham.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
#!/bin/sh
2-
exec /usr/local/bin/rspamc -h /var/run/rspamd/rspamd.sock learn_ham
2+
exec /usr/local/bin/rspamc -h /var/run/rspamd/rspamd.sock -d "${1}" learn_ham
33
# we don't care about the exit status in this case
44
exit 0

src/usr/local/bin/learn_spam.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
#!/bin/sh
2-
exec /usr/local/bin/rspamc -h /var/run/rspamd/rspamd.sock learn_spam
2+
exec /usr/local/bin/rspamc -h /var/run/rspamd/rspamd.sock -d "${1}" learn_spam
33
# we don't care about the exit status in this case
44
exit 0

src/var/www/htdocs/autoconfig.example.com/index.html

Lines changed: 0 additions & 10 deletions
This file was deleted.

0 commit comments

Comments
 (0)