From 9e71165dd3fa31accbcce8d5875aa774ab8b8fe1 Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Wed, 30 Aug 2023 11:40:19 +0200 Subject: run Exim in container --- exim.conf | 262 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 262 insertions(+) create mode 100644 exim.conf (limited to 'exim.conf') diff --git a/exim.conf b/exim.conf new file mode 100644 index 0000000..a5b2ec2 --- /dev/null +++ b/exim.conf @@ -0,0 +1,262 @@ +# SPDX-License-Identifier: GPL-2.0-or-later and CC0-1.0 +# Copyright (c) 2004-2023 University of Cambridge +# Copyright (C) 2023 Wojtek Kosior + +# Changes by Wojtek are available under CC0. + +# Adapted from +# https://git.exim.org/exim.git/blob/3e6d406e8ae9681a8cc1b404e7f5d1bd6d65d201:/src/src/configure.default + +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:koszko.org:koszkonutek-tmp.pl.eu.org +domainlist relay_to_domains = +hostlist relay_from_hosts = : 127.0.0.1 : ::::1 + +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/letsencrypt/live/guixbot_koszko.org/fullchain.pem +tls_privatekey = /etc/letsencrypt/live/guixbot_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 = 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 = + +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 + + require verify = sender + + 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 = * + # TODO: only use this for email sent by the admin + control = submission/sender_retain + 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 condition = ${if > {$max_received_linelength}{998}} + message = maximum allowed line length is 998 octets, \ + got $max_received_linelength + + 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 + +system_aliases: + driver = redirect + allow_fail + allow_defer + data = ${lookup{$local_part}lsearch{/etc/aliases}} + +userforward: + driver = redirect + check_local_user +# local_part_suffix = +* : -* +# local_part_suffix_optional + file = $home/.forward +# allow_filter + no_verify + no_expn + check_ancestor + file_transport = address_file + pipe_transport = address_pipe + reply_transport = address_reply + +localuser: + driver = accept + check_local_user + transport = local_delivery + cannot_route_message = Unknown user + +begin transports + +remote_smtp: + driver = smtp + +dkim_domain = koszko.org +dkim_selector = mail +dkim_private_key = /etc/exim/dkim.pem + +.ifdef _HAVE_DANE +dnssec_request_domains = * +hosts_try_dane = * +.endif + +local_delivery: + driver = appendfile + directory = $home/Maildir + create_directory + delivery_date_add + envelope_to_add + return_path_add + maildir_format + directory_mode = 0700 + mode = 0600 + mode_fail_narrower = false + +address_pipe: + driver = pipe + return_fail_output + +address_file: + driver = appendfile + delivery_date_add + envelope_to_add + return_path_add + +address_reply: + driver = autoreply + +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{/etc/exim/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{/etc/exim/passwd}{$value}{*:*}}}}}{1}{0}}" + server_advertise_condition = ${if def:tls_in_cipher } + +# Hehe +HAPPY_HACKING: + driver = plaintext + server_set_id = $auth1 + 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 -- cgit v1.2.3