1import ./make-test-python.nix {
2 name = "opensmtpd-rspamd";
3
4 nodes = {
5 smtp1 =
6 { pkgs, ... }:
7 {
8 imports = [ common/user-account.nix ];
9 networking = {
10 firewall.allowedTCPPorts = [
11 25
12 143
13 ];
14 useDHCP = false;
15 interfaces.eth1.ipv4.addresses = pkgs.lib.mkOverride 0 [
16 {
17 address = "192.168.1.1";
18 prefixLength = 24;
19 }
20 ];
21 };
22 environment.systemPackages = [ pkgs.opensmtpd ];
23 services.opensmtpd = {
24 enable = true;
25 extraServerArgs = [ "-v" ];
26 serverConfiguration = ''
27 listen on 0.0.0.0
28 action dovecot_deliver mda \
29 "${pkgs.dovecot}/libexec/dovecot/deliver -d %{user.username}"
30 match from any for local action dovecot_deliver
31
32 action relay_smtp2 relay host "smtp://192.168.1.2"
33 match from any for any action relay_smtp2
34 '';
35 };
36 services.dovecot2 = {
37 enable = true;
38 enableImap = true;
39 mailLocation = "maildir:~/mail";
40 protocols = [ "imap" ];
41 };
42 };
43
44 smtp2 =
45 { pkgs, ... }:
46 {
47 imports = [ common/user-account.nix ];
48 networking = {
49 firewall.allowedTCPPorts = [
50 25
51 143
52 ];
53 useDHCP = false;
54 interfaces.eth1.ipv4.addresses = pkgs.lib.mkOverride 0 [
55 {
56 address = "192.168.1.2";
57 prefixLength = 24;
58 }
59 ];
60 };
61 environment.systemPackages = [ pkgs.opensmtpd ];
62 services.rspamd = {
63 enable = true;
64 locals."worker-normal.inc".text = ''
65 bind_socket = "127.0.0.1:11333";
66 '';
67 };
68 services.opensmtpd = {
69 enable = true;
70 extraServerArgs = [ "-v" ];
71 serverConfiguration = ''
72 filter rspamd proc-exec "${pkgs.opensmtpd-filter-rspamd}/bin/filter-rspamd"
73 listen on 0.0.0.0 filter rspamd
74 action dovecot_deliver mda \
75 "${pkgs.dovecot}/libexec/dovecot/deliver -d %{user.username}"
76 match from any for local action dovecot_deliver
77 '';
78 };
79 services.dovecot2 = {
80 enable = true;
81 enableImap = true;
82 mailLocation = "maildir:~/mail";
83 protocols = [ "imap" ];
84 };
85 };
86
87 client =
88 { pkgs, ... }:
89 {
90 networking = {
91 useDHCP = false;
92 interfaces.eth1.ipv4.addresses = pkgs.lib.mkOverride 0 [
93 {
94 address = "192.168.1.3";
95 prefixLength = 24;
96 }
97 ];
98 };
99 environment.systemPackages =
100 let
101 sendTestMail = pkgs.writeScriptBin "send-a-test-mail" ''
102 #!${pkgs.python3.interpreter}
103 import smtplib, sys
104
105 with smtplib.SMTP('192.168.1.1') as smtp:
106 smtp.sendmail('alice@smtp1', 'bob@smtp2', """
107 From: alice@smtp1
108 To: bob@smtp2
109 Subject: Test
110
111 Hello World
112 Here goes the spam test
113 XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X
114 """)
115 '';
116
117 checkMailBounced = pkgs.writeScriptBin "check-mail-bounced" ''
118 #!${pkgs.python3.interpreter}
119 import imaplib
120
121 with imaplib.IMAP4('192.168.1.1', 143) as imap:
122 imap.login('alice', 'foobar')
123 imap.select()
124 status, refs = imap.search(None, 'ALL')
125 assert status == 'OK'
126 assert len(refs) == 1
127 status, msg = imap.fetch(refs[0], 'BODY[TEXT]')
128 assert status == 'OK'
129 content = msg[0][1]
130 print("===> content:", content)
131 assert b"An error has occurred while attempting to deliver a message" in content
132 '';
133 in
134 [
135 sendTestMail
136 checkMailBounced
137 ];
138 };
139 };
140
141 testScript = ''
142 start_all()
143
144 client.systemctl("start network-online.target")
145 client.wait_for_unit("network-online.target")
146 smtp1.wait_for_unit("opensmtpd")
147 smtp2.wait_for_unit("opensmtpd")
148 smtp2.wait_for_unit("rspamd")
149 smtp2.wait_for_unit("dovecot2")
150
151 # To prevent sporadic failures during daemon startup, make sure
152 # services are listening on their ports before sending requests
153 smtp1.wait_for_open_port(25)
154 smtp2.wait_for_open_port(25)
155 smtp2.wait_for_open_port(143)
156 smtp2.wait_for_open_port(11333)
157
158 client.succeed("send-a-test-mail")
159 smtp1.wait_until_fails("smtpctl show queue | egrep .")
160 client.succeed("check-mail-bounced >&2")
161 '';
162
163 meta.timeout = 1800;
164}