aboutsummaryrefslogtreecommitdiff
path: root/exim.conf
blob: 0692c47a66cef80cd95cbd25f3c01de264446f26 (about) (plain)
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
# SPDX-License-Identifier: GPL-2.0-or-later and CC0-1.0
# Copyright (c) 2004-2023 University of Cambridge
# Copyright (C) 2023, 2024 Wojtek Kosior <koszko@koszko.org>

# Changes by Wojtek are available under CC0.

# Adapted from
# https://git.exim.org/exim.git/blob/3e6d406e8ae9681a8cc1b404e7f5d1bd6d65d201:/src/src/configure.default

exim_group = vmail
deliver_drop_privilege

spool_directory = /var/spool/exim
log_file_path = $spool_directory/log/%slog
log_selector = +smtp_protocol_error +smtp_syntax_error \
        +tls_certificate_verified +tls_peerdn

domainlist    local_domains = @ : localhost : happyhacking.pl : koszko.org : \
                              koszkonutek-tmp.pl.eu.org
domainlist    relay_to_domains =
hostlist      relay_from_hosts = <; ; 127.0.0.1 ; ::1
localpartlist vmail_usernames = ${sg {${readfile{/var/vmail/passwd}{:::}}}\
                                     {\N:?[^:]+:::\N}\
                                     {:}}

acl_smtp_rcpt =         acl_check_rcpt
.ifdef _HAVE_PRDR
# currently does nothing
acl_smtp_data_prdr =    acl_check_prdr
.endif
acl_smtp_data =         acl_check_data

tls_certificate = /etc/certs/smtp.koszko.org/fullchain.pem
tls_privatekey = /etc/certs/smtp.koszko.org/privkey.pem

tls_verify_certificates = ${if exists{/etc/ssl/certs/ca-certificates.crt}\
                               {/etc/ssl/certs/ca-certificates.crt}\
			       {/dev/null}}

.ifdef _HAVE_GNUTLS
tls_dhparam = historic
.endif

# For OpenSSL, prefer EC- over RSA-authenticated ciphers
.ifdef _HAVE_OPENSSL
tls_require_ciphers = ECDSA:RSA:!COMPLEMENTOFDEFAULT
.endif

daemon_smtp_ports = 25 : 12525 : 465 : 587
tls_on_connect_ports = 465 : 587

primary_hostname = salamina.koszko.org
qualify_domain = koszko.org

never_users = root

host_lookup = *

dns_dnssec_ok = 1

#rfc1413_hosts = *
#rfc1413_query_timeout = 5s

.ifdef _HAVE_PRDR
prdr_enable = true
.endif

ignore_bounce_errors_after = 2d

timeout_frozen_after = 7d

freeze_tell = admin

check_rfc2047_length = false

accept_8bitmime = false

keep_environment =

received_header_text =\
Received: from dummy-client.koszko.org ([192.168.193.169])\n\t\
          by $primary_hostname\
          ${if def:received_protocol\
               { with $received_protocol}}\
          ${if def:tls_in_ver\
               { ($tls_in_ver)}}\
          ${if def:tls_in_cipher_std\
               { tls $tls_in_cipher_std\n\t}}\
          (Exim $version_number)\n\t\
          ${if def:sender_address\
               {(envelope-from <$sender_address>)\n\t}}\
          id $message_exim_id\
          ${if def:received_for\
               {\n\tfor $received_for}}

begin acl

acl_check_rcpt:

  accept  hosts = :
          control = dkim_disable_verify

  deny    message       = Restricted characters in address
          domains       = +local_domains
          local_parts   = ^[.] : ^.*[@%!/|`#&?]

  deny    message       = Restricted characters in address
          domains       = !+local_domains
          local_parts   = ^[./|] : ^.*[@%!`#&?] : ^.*/\\.\\./

  accept  local_parts   = postmaster
          domains       = +local_domains

  warn    !verify       = sender
          log_message   = $acl_verify_message: $sender_verify_failure

  deny    condition     = ${if and {\
                            {>{$rcpt_count}{10}}\
                            {<{$recipients_count}{${eval:$rcpt_count/2}}}\
                            }}
          message       = Rejected for too many bad recipients
          logwrite      = REJECT [$sender_host_address]: \
                          bad recipient count high \
                          [${eval:$rcpt_count-$recipients_count}]

  accept  hosts         = +relay_from_hosts
          control       = submission/sender_retain
          control       = dkim_disable_verify

  accept  authenticated = *
          condition     = ${lookup{$authenticated_id}\
                            lsearch{/var/vmail/admin-users}\
                            {yes}{no}}
          control       = submission/sender_retain
          control       = dkim_disable_verify

  accept  authenticated = *
          control       = submission
          control       = dkim_disable_verify

  require message = relay not permitted
          domains = +local_domains : +relay_to_domains

  require verify = recipient

  accept


.ifdef _HAVE_PRDR
acl_check_prdr:

  warn  set acl_m_did_prdr = y

  accept
.endif

acl_check_data:

  deny    !verify =     header_syntax
          message =     header syntax
          log_message = header syntax ($acl_verify_message)

  accept

begin routers

dnslookup:
  driver = dnslookup
  domains = ! +local_domains
  transport = remote_smtp
  same_domain_copy_routing = yes
  ignore_target_hosts = <; 0.0.0.0 ; 127.0.0.0/8 ; 192.168.0.0/16 ;\
                        172.16.0.0/12 ; 10.0.0.0/8 ; 169.254.0.0/16 ;\
			255.255.255.255 ; ::1
  dnssec_request_domains = *
  no_more

dot_stripping:
  driver = redirect
  data = ${sg{$local_part}{[.]}{}}@$domain

system_aliases:
  driver = redirect
  allow_fail
  allow_defer
  data = ${lookup{$local_part}lsearch{/etc/aliases}}

vmail_aliases:
  driver = redirect
  allow_fail
  allow_defer
  data = ${lookup{$local_part}lsearch{/var/vmail/aliases}}

vmail_user:
  driver = accept
  local_parts = +vmail_usernames
  transport = vmail_delivery
  cannot_route_message = Unknown user

begin transports

remote_smtp:
  driver = smtp
  dkim_domain = ${sender_address_domain}
  helo_data = ${sender_address_domain}

dkim_selector = mail-salamina
dkim_private_key = /etc/exim/dkim.key

.ifdef _HAVE_DANE
dnssec_request_domains = *
hosts_try_dane = *
.endif

vmail_delivery:
  driver = appendfile
  maildir_format
  create_directory
  delivery_date_add
  envelope_to_add
  return_path_add
  no_check_owner
  group = vmail
  directory = /var/vmail/maildirs/$local_part_data
  directory_mode = 0770
  mode = 0660
  mode_fail_narrower = false

begin retry

# Address or Domain    Error       Retries
# -----------------    -----       -------

*                      *           F,2h,15m; G,16h,1h,1.5; F,4d,6h

begin rewrite

begin authenticators

# PLAIN authentication has no server prompts. The client sends its
# credentials in one lump, containing an authorization ID (which we do not
# use), an authentication ID, and a password. The latter two appear as
# $auth2 and $auth3 in the configuration and should be checked against a
# valid username and password. In a real configuration you would typically
# use $auth2 as a lookup key, and compare $auth3 against the result of the
# lookup, perhaps using the crypteq{}{} condition.

PLAIN:
 driver                     = plaintext
 server_set_id              = $auth2
 server_prompts             = :
 server_condition           = "${if crypteq{$auth3}{${extract{1}{:}{${lookup{$auth2}lsearch{/var/vmail/passwd}{$value}{*:*}}}}}{1}{0}}"
 server_advertise_condition = ${if def:tls_in_cipher }

# LOGIN authentication has traditional prompts and responses. There is no
# authorization ID in this mechanism, so unlike PLAIN the username and
# password are $auth1 and $auth2. Apart from that you can use the same
# server_condition setting for both authenticators.

LOGIN:
 driver                     = plaintext
 server_set_id              = $auth1
 server_prompts             = <| Username: | Password:
 server_condition           = "${if crypteq{$auth2}{${extract{1}{:}{${lookup{$auth1}lsearch{/var/vmail/passwd}{$value}{*:*}}}}}{1}{0}}"
 server_advertise_condition = ${if def:tls_in_cipher }

# Hehe
HAPPY_HACKING:
 driver                     = plaintext
 server_prompts             = <| Login hackera: \
                               | Hasło hackera: \
                               | Ulubiony kolor: \
                               | Imię pierwszego zwierzątka domowego: \
                               | Panieńskie nazwisko Babci od strony Mamy:
 server_condition           = 0
 server_advertise_condition = 1