mirror of
https://github.com/chatmail/relay.git
synced 2026-05-10 07:54:36 +00:00
initial commit, mostly copied from another repo
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -2,6 +2,7 @@
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
*.swp
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
14
README.md
Normal file
14
README.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# Chat Mail server configuration
|
||||
|
||||
This package deploys Postfix and Dovecot servers, including OpenDKIM for DKIM signing.
|
||||
|
||||
Postfix uses Dovecot for authentication as described in <https://www.postfix.org/SASL_README.html#server_dovecot>
|
||||
|
||||
## Ports
|
||||
|
||||
Postfix listens on ports 25 (smtp) and 587 (submission) and 465 (submissions).
|
||||
Dovecot listens on ports 143(imap) and 993 (imaps).
|
||||
|
||||
## DNS
|
||||
|
||||
For DKIM you must add a DNS entry as in /etc/opendkim/selector.txt (where selector is the opendkim_selector configured in the chatmail inventory).
|
||||
42
deploy.py
Normal file
42
deploy.py
Normal file
@@ -0,0 +1,42 @@
|
||||
import os
|
||||
from pyinfra import host, facts
|
||||
from chatmail import deploy_chatmail
|
||||
|
||||
|
||||
# the following is to prevent rate-limits with querying letsencrypt
|
||||
# servers during deploys. It probably makes more sense to check
|
||||
# in acmetool if a cert exists and skip recreating it because
|
||||
# the acmetool pyinfra will renew certs via its cronjob, anyway.
|
||||
|
||||
def unpack_acme_state():
|
||||
from pyinfra.operations import files, server
|
||||
from io import BytesIO
|
||||
|
||||
local_acme_filename = "acme_state.tar.gz"
|
||||
|
||||
if os.path.exists(local_acme_filename):
|
||||
with open(local_acme_filename, "rb") as f:
|
||||
acme_state = f.read()
|
||||
files.put(
|
||||
name="Upload acme state tar",
|
||||
src=BytesIO(acme_state),
|
||||
dest="/root/acme_state.tar.gz",
|
||||
mode="600",
|
||||
)
|
||||
server.shell(
|
||||
name="Unpack acme state directory",
|
||||
commands=[
|
||||
"mkdir -p /var/lib/acme && tar -C /var/lib/acme -x -z < /root/acme_state.tar.gz"
|
||||
],
|
||||
)
|
||||
else:
|
||||
print("no cached acme state found, deploy will recreate letsencrypt certs")
|
||||
print("use this command to create a cache file:")
|
||||
ssh_host = f"{host.data.ssh_user}@{host.data.host.name}"
|
||||
cmd = f"'tar -C /var/lib/acme -c . -z' > {local_acme_filename}"
|
||||
print(f"ssh {ssh_host} {cmd}")
|
||||
|
||||
|
||||
unpack_acme_state()
|
||||
|
||||
deploy_chatmail()
|
||||
7
pyproject.toml
Normal file
7
pyproject.toml
Normal file
@@ -0,0 +1,7 @@
|
||||
[build-system]
|
||||
requires = ["setuptools>=45"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "chatmail"
|
||||
version = "0.1"
|
||||
215
src/chatmail/__init__.py
Normal file
215
src/chatmail/__init__.py
Normal file
@@ -0,0 +1,215 @@
|
||||
"""
|
||||
Chat Mail pyinfra deploy.
|
||||
"""
|
||||
import importlib.resources
|
||||
from io import StringIO
|
||||
|
||||
from pyinfra import host, logger
|
||||
from pyinfra.operations import apt, files, server, systemd, python
|
||||
from .acmetool import deploy_acmetool
|
||||
|
||||
|
||||
def _install_chatctl() -> None:
|
||||
"""Setup chatctl."""
|
||||
files.put(
|
||||
src=importlib.resources.files(__package__)
|
||||
.joinpath("chatctl/chatctl.py")
|
||||
.open("rb"),
|
||||
dest="/home/vmail/chatctl",
|
||||
user="vmail",
|
||||
group="vmail",
|
||||
mode="755",
|
||||
)
|
||||
|
||||
|
||||
def _configure_opendkim(
|
||||
domain: str, dkim_selector: str, dkim_key: str, dkim_txt: str
|
||||
) -> bool:
|
||||
"""Configures OpenDKIM"""
|
||||
need_restart = False
|
||||
|
||||
main_config = files.template(
|
||||
src=importlib.resources.files(__package__).joinpath("opendkim/opendkim.conf"),
|
||||
dest="/etc/opendkim.conf",
|
||||
user="root",
|
||||
group="root",
|
||||
mode="644",
|
||||
config={"domain_name": domain, "opendkim_selector": dkim_selector},
|
||||
)
|
||||
|
||||
files.directory(
|
||||
name="Add opendkim socket directory to /var/spool/postfix",
|
||||
path="/var/spool/postfix/opendkim",
|
||||
user="opendkim",
|
||||
group="opendkim",
|
||||
mode="750",
|
||||
present=True,
|
||||
)
|
||||
|
||||
if dkim_key:
|
||||
files.put(
|
||||
name="Put the DKIM key",
|
||||
src=StringIO(dkim_key),
|
||||
dest=f"/etc/dkimkeys/{dkim_selector}.private",
|
||||
mode="600",
|
||||
)
|
||||
files.put(
|
||||
name="Put the DKIM DNS textfile",
|
||||
src=StringIO(dkim_txt),
|
||||
dest=f"/etc/dkimkeys/{dkim_selector}.txt",
|
||||
mode="600",
|
||||
)
|
||||
else:
|
||||
server.shell(
|
||||
name="Generate OpenDKIM domain keys",
|
||||
commands=[
|
||||
f"opendkim-genkey -D /etc/dkimkeys -d {domain} -s {dkim_selector}"
|
||||
],
|
||||
_sudo=True,
|
||||
_sudo_user="opendkim",
|
||||
)
|
||||
|
||||
need_restart |= main_config.changed
|
||||
|
||||
return need_restart
|
||||
|
||||
|
||||
def _configure_postfix(domain: str) -> bool:
|
||||
"""Configures Postfix SMTP server."""
|
||||
need_restart = False
|
||||
|
||||
main_config = files.template(
|
||||
src=importlib.resources.files(__package__).joinpath("postfix/main.cf.j2"),
|
||||
dest="/etc/postfix/main.cf",
|
||||
user="root",
|
||||
group="root",
|
||||
mode="644",
|
||||
config={"domain_name": domain},
|
||||
)
|
||||
need_restart |= main_config.changed
|
||||
|
||||
master_config = files.put(
|
||||
src=importlib.resources.files(__package__)
|
||||
.joinpath("postfix/master.cf")
|
||||
.open("rb"),
|
||||
dest="/etc/postfix/master.cf",
|
||||
user="root",
|
||||
group="root",
|
||||
mode="644",
|
||||
)
|
||||
need_restart |= master_config.changed
|
||||
|
||||
return need_restart
|
||||
|
||||
|
||||
def _configure_dovecot(domain: str) -> bool:
|
||||
"""Configures Dovecot IMAP server."""
|
||||
need_restart = False
|
||||
|
||||
main_config = files.template(
|
||||
src=importlib.resources.files(__package__).joinpath("dovecot/dovecot.conf.j2"),
|
||||
dest="/etc/dovecot/dovecot.conf",
|
||||
user="root",
|
||||
group="root",
|
||||
mode="644",
|
||||
config={"hostname": domain},
|
||||
)
|
||||
need_restart |= main_config.changed
|
||||
|
||||
# luarocks install http lpeg_patterns fifo
|
||||
auth_script = files.put(
|
||||
src=importlib.resources.files(__package__).joinpath("dovecot/auth.lua"),
|
||||
dest="/etc/dovecot/auth.lua",
|
||||
user="root",
|
||||
group="root",
|
||||
mode="644",
|
||||
)
|
||||
need_restart |= auth_script.changed
|
||||
|
||||
return need_restart
|
||||
|
||||
|
||||
def deploy_chatmail() -> None:
|
||||
domain = host.data.domain
|
||||
dkim_selector = host.data.dkim_selector
|
||||
dkim_key = host.data.dkim_key
|
||||
dkim_txt = host.data.dkim_txt
|
||||
|
||||
apt.update(name="apt update")
|
||||
server.group(name="Create vmail group", group="vmail", system=True)
|
||||
server.user(name="Create vmail user", user="vmail", group="vmail", system=True)
|
||||
|
||||
server.group(name="Create opendkim group", group="opendkim", system=True)
|
||||
server.user(
|
||||
name="Add postfix user to opendkim group for socket access",
|
||||
user="postfix",
|
||||
groups=["opendkim"],
|
||||
system=True,
|
||||
)
|
||||
|
||||
# Deploy acmetool to have TLS certificates.
|
||||
deploy_acmetool(domains=[domain])
|
||||
|
||||
apt.packages(
|
||||
name="Install Postfix",
|
||||
packages="postfix",
|
||||
)
|
||||
|
||||
apt.packages(
|
||||
name="Install Dovecot",
|
||||
packages=[
|
||||
"dovecot-imapd",
|
||||
"dovecot-lmtpd",
|
||||
"dovecot-auth-lua",
|
||||
],
|
||||
)
|
||||
|
||||
apt.packages(
|
||||
name="Install OpenDKIM",
|
||||
packages=[
|
||||
"opendkim",
|
||||
"opendkim-tools",
|
||||
],
|
||||
)
|
||||
|
||||
_install_chatctl()
|
||||
dovecot_need_restart = _configure_dovecot(domain)
|
||||
postfix_need_restart = _configure_postfix(domain)
|
||||
opendkim_need_restart = _configure_opendkim(
|
||||
domain, dkim_selector, dkim_key, dkim_txt
|
||||
)
|
||||
|
||||
systemd.service(
|
||||
name="Start and enable OpenDKIM",
|
||||
service="opendkim.service",
|
||||
running=True,
|
||||
enabled=True,
|
||||
restarted=opendkim_need_restart,
|
||||
)
|
||||
|
||||
systemd.service(
|
||||
name="Start and enable Postfix",
|
||||
service="postfix.service",
|
||||
running=True,
|
||||
enabled=True,
|
||||
restarted=postfix_need_restart,
|
||||
)
|
||||
|
||||
systemd.service(
|
||||
name="Start and enable Dovecot",
|
||||
service="dovecot.service",
|
||||
running=True,
|
||||
enabled=True,
|
||||
restarted=dovecot_need_restart,
|
||||
)
|
||||
|
||||
def callback():
|
||||
result = server.shell(
|
||||
commands=[
|
||||
f"""sed 's/\tIN/ 600 IN/;s/\t(//;s/\"$//;s/^\t \"//g; s/ ).*//' """
|
||||
f"""/etc/dkimkeys/{dkim_selector}.txt | tr --delete '\n'"""
|
||||
]
|
||||
)
|
||||
logger.info(f"Add this TXT entry into DNS zone: {result.stdout}")
|
||||
|
||||
python.call(name="Print TXT entry for DKIM", function=callback)
|
||||
62
src/chatmail/acmetool/__init__.py
Normal file
62
src/chatmail/acmetool/__init__.py
Normal file
@@ -0,0 +1,62 @@
|
||||
import importlib.resources
|
||||
|
||||
from pyinfra.operations import apt, files, systemd, server
|
||||
|
||||
|
||||
def deploy_acmetool(nginx_hook=False, email="", domains=[]):
|
||||
"""Deploy acmetool."""
|
||||
apt.packages(
|
||||
name="Install acmetool",
|
||||
packages=["acmetool"],
|
||||
)
|
||||
|
||||
files.put(
|
||||
src=importlib.resources.files(__package__).joinpath("acmetool.cron").open("rb"),
|
||||
dest="/etc/cron.d/acmetool",
|
||||
user="root",
|
||||
group="root",
|
||||
mode="644",
|
||||
)
|
||||
|
||||
if nginx_hook:
|
||||
files.put(
|
||||
src=importlib.resources.files(__package__)
|
||||
.joinpath("acmetool.hook")
|
||||
.open("rb"),
|
||||
dest="/usr/lib/acme/hooks/nginx",
|
||||
user="root",
|
||||
group="root",
|
||||
mode="744",
|
||||
)
|
||||
|
||||
files.template(
|
||||
src=importlib.resources.files(__package__).joinpath("response-file.yaml.j2"),
|
||||
dest="/var/lib/acme/conf/responses",
|
||||
user="root",
|
||||
group="root",
|
||||
mode="644",
|
||||
email=email,
|
||||
)
|
||||
|
||||
service_file = files.put(
|
||||
src=importlib.resources.files(__package__)
|
||||
.joinpath("acmetool-redirector.service")
|
||||
.open("rb"),
|
||||
dest="/etc/systemd/system/acmetool-redirector.service",
|
||||
user="root",
|
||||
group="root",
|
||||
mode="644",
|
||||
)
|
||||
systemd.service(
|
||||
name="Setup acmetool-redirector service",
|
||||
service="acmetool-redirector.service",
|
||||
running=True,
|
||||
enabled=True,
|
||||
restarted=service_file.changed,
|
||||
)
|
||||
|
||||
for domain in domains:
|
||||
server.shell(
|
||||
name=f"Request certificate for {domain}",
|
||||
commands=[f"acmetool want {domain}"],
|
||||
)
|
||||
11
src/chatmail/acmetool/acmetool-redirector.service
Normal file
11
src/chatmail/acmetool/acmetool-redirector.service
Normal file
@@ -0,0 +1,11 @@
|
||||
[Unit]
|
||||
Description=acmetool HTTP redirector
|
||||
|
||||
[Service]
|
||||
Type=notify
|
||||
ExecStart=/usr/bin/acmetool redirector --service.uid=daemon
|
||||
Restart=always
|
||||
RestartSec=30
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
4
src/chatmail/acmetool/acmetool.cron
Normal file
4
src/chatmail/acmetool/acmetool.cron
Normal file
@@ -0,0 +1,4 @@
|
||||
SHELL=/bin/sh
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
|
||||
MAILTO=root
|
||||
20 16 * * * root /usr/bin/acmetool --batch reconcile
|
||||
5
src/chatmail/acmetool/acmetool.hook
Normal file
5
src/chatmail/acmetool/acmetool.hook
Normal file
@@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
EVENT_NAME="$1"
|
||||
[ "$EVENT_NAME" = "live-updated" ] || exit 42
|
||||
systemctl restart nginx.service
|
||||
2
src/chatmail/acmetool/response-file.yaml.j2
Normal file
2
src/chatmail/acmetool/response-file.yaml.j2
Normal file
@@ -0,0 +1,2 @@
|
||||
"acme-enter-email": "{{ email }}"
|
||||
"acme-agreement:https://letsencrypt.org/documents/LE-SA-v1.3-September-21-2022.pdf": true
|
||||
17
src/chatmail/chatctl/chatctl.py
Normal file
17
src/chatmail/chatctl/chatctl.py
Normal file
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env python3
|
||||
import base64
|
||||
import sys
|
||||
|
||||
if sys.argv[1] == "hexauth":
|
||||
login = base64.b16decode(sys.argv[2])
|
||||
password = base64.b16decode(sys.argv[3])
|
||||
if login == b"link2xt@instant2.testrun.org" and password == b"Ahyei6ie":
|
||||
sys.exit(0)
|
||||
else:
|
||||
sys.exit(1)
|
||||
elif sys.argv[1] == "hexlookup":
|
||||
login = base64.b16decode(sys.argv[2])
|
||||
if login == b"link2xt@instant2.testrun.org":
|
||||
sys.exit(0)
|
||||
else:
|
||||
sys.exit(1)
|
||||
35
src/chatmail/dovecot/auth.lua
Normal file
35
src/chatmail/dovecot/auth.lua
Normal file
@@ -0,0 +1,35 @@
|
||||
-- Lua based authentication script for Dovecot.
|
||||
--
|
||||
-- It calls external chatctl command to answer requests.
|
||||
|
||||
-- Hexadecimal aka base16 encoding.
|
||||
function hex(data)
|
||||
return (data:gsub(".", function(char) return string.format("%2X", char:byte()) end))
|
||||
end
|
||||
|
||||
-- Escape shell argument by hex encoding it and wrapping in quotes.
|
||||
function escape(data)
|
||||
return ("'"..hex(data).."'")
|
||||
end
|
||||
|
||||
function auth_password_verify(request, password)
|
||||
if os.execute("/home/vmail/chatctl hexauth "..escape(request.user).." "..escape(password)) then
|
||||
return dovecot.auth.PASSDB_RESULT_OK, {}
|
||||
end
|
||||
return dovecot.auth.PASSDB_RESULT_PASSWORD_MISMATCH, ""
|
||||
end
|
||||
|
||||
function auth_passdb_lookup(request)
|
||||
if os.execute("/home/vmail/chatctl hexlookup "..escape(request.user)) then
|
||||
return dovecot.auth.PASSDB_RESULT_OK, {}
|
||||
end
|
||||
return dovecot.auth.PASSDB_RESULT_USER_UNKNOWN, "no such user"
|
||||
end
|
||||
|
||||
function auth_userdb_lookup(request)
|
||||
if os.execute("/home/vmail/chatctl hexlookup "..escape(request.user)) then
|
||||
return dovecot.auth.USERDB_RESULT_OK, "uid=vmail gid=vmail"
|
||||
end
|
||||
|
||||
return dovecot.auth.USERDB_RESULT_USER_UNKNOWN, "no such user"
|
||||
end
|
||||
94
src/chatmail/dovecot/dovecot.conf.j2
Normal file
94
src/chatmail/dovecot/dovecot.conf.j2
Normal file
@@ -0,0 +1,94 @@
|
||||
## Dovecot configuration file
|
||||
|
||||
protocols = imap lmtp
|
||||
|
||||
auth_mechanisms = plain
|
||||
|
||||
# Authentication for system users.
|
||||
passdb {
|
||||
driver = lua
|
||||
args = file=/etc/dovecot/auth.lua
|
||||
}
|
||||
userdb {
|
||||
driver = lua
|
||||
args = file=/etc/dovecot/auth.lua
|
||||
}
|
||||
|
||||
##
|
||||
## Mailbox locations and namespaces
|
||||
##
|
||||
|
||||
# Mailboxes are stored in the "mail" directory of the vmail user home.
|
||||
mail_location = maildir:/home/vmail/mail/%d/%u
|
||||
|
||||
namespace inbox {
|
||||
inbox = yes
|
||||
|
||||
mailbox Drafts {
|
||||
special_use = \Drafts
|
||||
}
|
||||
mailbox Junk {
|
||||
special_use = \Junk
|
||||
}
|
||||
mailbox Trash {
|
||||
special_use = \Trash
|
||||
}
|
||||
|
||||
# For \Sent mailboxes there are two widely used names. We'll mark both of
|
||||
# them as \Sent. User typically deletes one of them if duplicates are created.
|
||||
mailbox Sent {
|
||||
special_use = \Sent
|
||||
}
|
||||
mailbox "Sent Messages" {
|
||||
special_use = \Sent
|
||||
}
|
||||
}
|
||||
|
||||
mail_uid = vmail
|
||||
mail_gid = vmail
|
||||
mail_privileged_group = vmail
|
||||
|
||||
##
|
||||
## Mail processes
|
||||
##
|
||||
|
||||
# Enable IMAP COMPRESS (RFC 4978).
|
||||
# <https://datatracker.ietf.org/doc/html/rfc4978.html>
|
||||
protocol imap {
|
||||
mail_plugins = $mail_plugins imap_zlib
|
||||
}
|
||||
|
||||
plugin {
|
||||
imap_compress_deflate_level = 6
|
||||
}
|
||||
|
||||
service lmtp {
|
||||
user=vmail
|
||||
|
||||
unix_listener /var/spool/postfix/private/dovecot-lmtp {
|
||||
group = postfix
|
||||
mode = 0600
|
||||
user = postfix
|
||||
}
|
||||
}
|
||||
|
||||
service auth {
|
||||
unix_listener /var/spool/postfix/private/auth {
|
||||
mode = 0660
|
||||
user = postfix
|
||||
group = postfix
|
||||
}
|
||||
}
|
||||
|
||||
service auth-worker {
|
||||
# Default is root.
|
||||
# Drop privileges we don't need.
|
||||
user = $default_internal_user
|
||||
}
|
||||
|
||||
ssl = required
|
||||
ssl_cert = </var/lib/acme/live/{{ config.hostname }}/fullchain
|
||||
ssl_key = </var/lib/acme/live/{{ config.hostname }}/privkey
|
||||
ssl_dh = </usr/share/dovecot/dh.pem
|
||||
ssl_min_protocol = TLSv1.2
|
||||
ssl_prefer_server_ciphers = yes
|
||||
51
src/chatmail/opendkim/opendkim.conf
Normal file
51
src/chatmail/opendkim/opendkim.conf
Normal file
@@ -0,0 +1,51 @@
|
||||
# This is a basic configuration for signing and verifying. It can easily be
|
||||
# adapted to suit a basic installation. See opendkim.conf(5) and
|
||||
# /usr/share/doc/opendkim/examples/opendkim.conf.sample for complete
|
||||
# documentation of available configuration parameters.
|
||||
|
||||
Syslog yes
|
||||
SyslogSuccess yes
|
||||
#LogWhy no
|
||||
|
||||
# Common signing and verification parameters. In Debian, the "From" header is
|
||||
# oversigned, because it is often the identity key used by reputation systems
|
||||
# and thus somewhat security sensitive.
|
||||
Canonicalization relaxed/simple
|
||||
#Mode sv
|
||||
#SubDomains no
|
||||
OversignHeaders From
|
||||
|
||||
# Signing domain, selector, and key (required). For example, perform signing
|
||||
# for domain "example.com" with selector "2020" (2020._domainkey.example.com),
|
||||
# using the private key stored in /etc/dkimkeys/example.private. More granular
|
||||
# setup options can be found in /usr/share/doc/opendkim/README.opendkim.
|
||||
Domain {{ config.domain_name }}
|
||||
Selector {{ config.opendkim_selector }}
|
||||
KeyFile /etc/dkimkeys/{{ config.opendkim_selector }}.private
|
||||
|
||||
# In Debian, opendkim runs as user "opendkim". A umask of 007 is required when
|
||||
# using a local socket with MTAs that access the socket as a non-privileged
|
||||
# user (for example, Postfix). You may need to add user "postfix" to group
|
||||
# "opendkim" in that case.
|
||||
UserID opendkim
|
||||
UMask 007
|
||||
|
||||
# Socket for the MTA connection (required). If the MTA is inside a chroot jail,
|
||||
# it must be ensured that the socket is accessible. In Debian, Postfix runs in
|
||||
# a chroot in /var/spool/postfix, therefore a Unix socket would have to be
|
||||
# configured as shown on the last line below.
|
||||
#Socket local:/run/opendkim/opendkim.sock
|
||||
#Socket inet:8891@localhost
|
||||
#Socket inet:8891
|
||||
Socket local:/var/spool/postfix/opendkim/opendkim.sock
|
||||
|
||||
PidFile /run/opendkim/opendkim.pid
|
||||
|
||||
# Hosts for which to sign rather than verify, default is 127.0.0.1. See the
|
||||
# OPERATION section of opendkim(8) for more information.
|
||||
#InternalHosts 192.168.0.0/16, 10.0.0.0/8, 172.16.0.0/12
|
||||
|
||||
# The trust anchor enables DNSSEC. In Debian, the trust anchor file is provided
|
||||
# by the package dns-root-data.
|
||||
TrustAnchorFile /usr/share/dns/root.key
|
||||
#Nameservers 127.0.0.1
|
||||
48
src/chatmail/postfix/main.cf.j2
Normal file
48
src/chatmail/postfix/main.cf.j2
Normal file
@@ -0,0 +1,48 @@
|
||||
myorigin = {{ config.domain_name }}
|
||||
|
||||
smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
|
||||
biff = no
|
||||
|
||||
# appending .domain is the MUA's job.
|
||||
append_dot_mydomain = no
|
||||
|
||||
# Uncomment the next line to generate "delayed mail" warnings
|
||||
#delay_warning_time = 4h
|
||||
|
||||
readme_directory = no
|
||||
|
||||
# See http://www.postfix.org/COMPATIBILITY_README.html -- default to 2 on
|
||||
# fresh installs.
|
||||
compatibility_level = 2
|
||||
|
||||
# TLS parameters
|
||||
smtpd_tls_cert_file=/var/lib/acme/live/{{ config.domain_name }}/fullchain
|
||||
smtpd_tls_key_file=/var/lib/acme/live/{{ config.domain_name }}/privkey
|
||||
smtpd_tls_security_level=may
|
||||
|
||||
smtp_tls_CApath=/etc/ssl/certs
|
||||
smtp_tls_security_level=may
|
||||
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
|
||||
|
||||
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
|
||||
myhostname = {{ config.domain_name }}
|
||||
alias_maps = hash:/etc/aliases
|
||||
alias_database = hash:/etc/aliases
|
||||
|
||||
# Postfix does not deliver mail for any domain by itself.
|
||||
# Primary domain is listed in `virtual_mailbox_domains` instead
|
||||
# and handed over to Dovecot.
|
||||
mydestination =
|
||||
|
||||
relayhost =
|
||||
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
|
||||
mailbox_size_limit = 0
|
||||
recipient_delimiter = +
|
||||
inet_interfaces = all
|
||||
inet_protocols = all
|
||||
|
||||
virtual_transport = lmtp:unix:private/dovecot-lmtp
|
||||
virtual_mailbox_domains = {{ config.domain_name }}
|
||||
|
||||
smtpd_milters = unix:opendkim/opendkim.sock
|
||||
non_smtpd_milters = $smtpd_milters
|
||||
72
src/chatmail/postfix/master.cf
Normal file
72
src/chatmail/postfix/master.cf
Normal file
@@ -0,0 +1,72 @@
|
||||
#
|
||||
# Postfix master process configuration file. For details on the format
|
||||
# of the file, see the master(5) manual page (command: "man 5 master" or
|
||||
# on-line: http://www.postfix.org/master.5.html).
|
||||
#
|
||||
# Do not forget to execute "postfix reload" after editing this file.
|
||||
#
|
||||
# ==========================================================================
|
||||
# service type private unpriv chroot wakeup maxproc command + args
|
||||
# (yes) (yes) (no) (never) (100)
|
||||
# ==========================================================================
|
||||
smtp inet n - y - - smtpd
|
||||
#smtp inet n - y - 1 postscreen
|
||||
#smtpd pass - - y - - smtpd
|
||||
#dnsblog unix - - y - 0 dnsblog
|
||||
#tlsproxy unix - - y - 0 tlsproxy
|
||||
submission inet n - y - - smtpd
|
||||
-o syslog_name=postfix/submission
|
||||
-o smtpd_tls_security_level=encrypt
|
||||
-o smtpd_sasl_auth_enable=yes
|
||||
-o smtpd_sasl_type=dovecot
|
||||
-o smtpd_sasl_path=private/auth
|
||||
-o smtpd_tls_auth_only=yes
|
||||
-o smtpd_reject_unlisted_recipient=no
|
||||
-o smtpd_client_restrictions=$mua_client_restrictions
|
||||
-o smtpd_helo_restrictions=$mua_helo_restrictions
|
||||
-o smtpd_sender_restrictions=$mua_sender_restrictions
|
||||
-o smtpd_recipient_restrictions=
|
||||
-o smtpd_relay_restrictions=permit_sasl_authenticated,reject
|
||||
-o milter_macro_daemon_name=ORIGINATING
|
||||
smtps inet n - y - - smtpd
|
||||
-o syslog_name=postfix/smtps
|
||||
-o smtpd_tls_wrappermode=yes
|
||||
-o smtpd_tls_security_level=encrypt
|
||||
-o smtpd_sasl_auth_enable=yes
|
||||
-o smtpd_sasl_type=dovecot
|
||||
-o smtpd_sasl_path=private/auth
|
||||
-o smtpd_reject_unlisted_recipient=no
|
||||
-o smtpd_client_restrictions=$mua_client_restrictions
|
||||
-o smtpd_helo_restrictions=$mua_helo_restrictions
|
||||
-o smtpd_sender_restrictions=$mua_sender_restrictions
|
||||
-o smtpd_recipient_restrictions=
|
||||
-o smtpd_relay_restrictions=permit_sasl_authenticated,reject
|
||||
-o milter_macro_daemon_name=ORIGINATING
|
||||
#628 inet n - y - - qmqpd
|
||||
pickup unix n - y 60 1 pickup
|
||||
cleanup unix n - y - 0 cleanup
|
||||
qmgr unix n - n 300 1 qmgr
|
||||
#qmgr unix n - n 300 1 oqmgr
|
||||
tlsmgr unix - - y 1000? 1 tlsmgr
|
||||
rewrite unix - - y - - trivial-rewrite
|
||||
bounce unix - - y - 0 bounce
|
||||
defer unix - - y - 0 bounce
|
||||
trace unix - - y - 0 bounce
|
||||
verify unix - - y - 1 verify
|
||||
flush unix n - y 1000? 0 flush
|
||||
proxymap unix - - n - - proxymap
|
||||
proxywrite unix - - n - 1 proxymap
|
||||
smtp unix - - y - - smtp
|
||||
relay unix - - y - - smtp
|
||||
-o syslog_name=postfix/$service_name
|
||||
# -o smtp_helo_timeout=5 -o smtp_connect_timeout=5
|
||||
showq unix n - y - - showq
|
||||
error unix - - y - - error
|
||||
retry unix - - y - - error
|
||||
discard unix - - y - - discard
|
||||
local unix - n n - - local
|
||||
virtual unix - n n - - virtual
|
||||
lmtp unix - - y - - lmtp
|
||||
anvil unix - - y - 1 anvil
|
||||
scache unix - - y - 1 scache
|
||||
postlog unix-dgram n - n - 1 postlogd
|
||||
Reference in New Issue
Block a user