Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
95423ebf63 | |||
2bcc807b91 | |||
bcd250d2b0 |
4
Makefile
4
Makefile
@ -14,10 +14,10 @@ requirements.txt: Pipfile.lock
|
|||||||
pipenv requirements > requirements.txt
|
pipenv requirements > requirements.txt
|
||||||
|
|
||||||
build: clean requirements.txt
|
build: clean requirements.txt
|
||||||
python3 -m pip install -r requirements.txt --target build
|
python3 -m pip install -r requirements.txt --no-compile --target build
|
||||||
cp -r mail4one/ build/
|
cp -r mail4one/ build/
|
||||||
sed -i "s/DEVELOMENT/$(shell scripts/get_version.sh)/" build/mail4one/version.py
|
sed -i "s/DEVELOMENT/$(shell scripts/get_version.sh)/" build/mail4one/version.py
|
||||||
python3 -m compileall build/mail4one -f
|
rm -rf build/mail4one/__pycache__
|
||||||
rm -rf build/*.dist-info
|
rm -rf build/*.dist-info
|
||||||
python3 -m zipapp \
|
python3 -m zipapp \
|
||||||
--output mail4one.pyz \
|
--output mail4one.pyz \
|
||||||
|
@ -9,14 +9,19 @@ Requires=network-online.target
|
|||||||
[Service]
|
[Service]
|
||||||
User=mail4one
|
User=mail4one
|
||||||
ExecStart=/usr/local/bin/mail4one --config /etc/mail4one/config.json
|
ExecStart=/usr/local/bin/mail4one --config /etc/mail4one/config.json
|
||||||
PrivateTmp=true
|
|
||||||
ProtectSystem=full
|
|
||||||
AmbientCapabilities=CAP_NET_BIND_SERVICE
|
AmbientCapabilities=CAP_NET_BIND_SERVICE
|
||||||
|
|
||||||
StateDirectory=mail4one
|
StateDirectory=mail4one/certs mail4one/mails
|
||||||
|
StateDirectoryMode=0750
|
||||||
|
UMask=
|
||||||
LogsDirectory=mail4one
|
LogsDirectory=mail4one
|
||||||
WorkingDirectory=/var/lib/mail4one
|
WorkingDirectory=/var/lib/mail4one
|
||||||
|
|
||||||
|
ProtectSystem=strict
|
||||||
|
PrivateTmp=true
|
||||||
|
PrivateUsers=true
|
||||||
ProtectHome=yes
|
ProtectHome=yes
|
||||||
|
NoNewPrivileges=yes
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
|
@ -10,7 +10,7 @@ set -x
|
|||||||
if [ "$RENEWED_DOMAINS" = "mail.mydomain.com" ]
|
if [ "$RENEWED_DOMAINS" = "mail.mydomain.com" ]
|
||||||
then
|
then
|
||||||
mkdir -p /var/lib/mail4one/certs
|
mkdir -p /var/lib/mail4one/certs
|
||||||
chmod 500 /var/lib/mail4one/certs
|
chmod 750 /var/lib/mail4one/certs
|
||||||
chown mail4one:mail4one /var/lib/mail4one/certs
|
chown mail4one:mail4one /var/lib/mail4one/certs
|
||||||
cp "$RENEWED_LINEAGE/fullchain.pem" /var/lib/mail4one/certs/
|
cp "$RENEWED_LINEAGE/fullchain.pem" /var/lib/mail4one/certs/
|
||||||
cp "$RENEWED_LINEAGE/privkey.pem" /var/lib/mail4one/certs/
|
cp "$RENEWED_LINEAGE/privkey.pem" /var/lib/mail4one/certs/
|
||||||
|
@ -41,6 +41,7 @@ class TLSCfg(Jata):
|
|||||||
|
|
||||||
|
|
||||||
class ServerCfg(Jata):
|
class ServerCfg(Jata):
|
||||||
|
server_type: str
|
||||||
host: str = "default"
|
host: str = "default"
|
||||||
port: int
|
port: int
|
||||||
# disabled: bool = False
|
# disabled: bool = False
|
||||||
@ -48,22 +49,25 @@ class ServerCfg(Jata):
|
|||||||
|
|
||||||
|
|
||||||
class PopCfg(ServerCfg):
|
class PopCfg(ServerCfg):
|
||||||
|
server_type = "pop"
|
||||||
port = 995
|
port = 995
|
||||||
timeout_seconds = 60
|
timeout_seconds = 60
|
||||||
|
|
||||||
|
|
||||||
class SmtpStartTLSCfg(ServerCfg):
|
class SmtpStartTLSCfg(ServerCfg):
|
||||||
smtputf8 = True
|
server_type = "smtp_starttls"
|
||||||
|
smtputf8 = True # Not used yet
|
||||||
port = 25
|
port = 25
|
||||||
|
|
||||||
|
|
||||||
class SmtpCfg(ServerCfg):
|
class SmtpCfg(ServerCfg):
|
||||||
smtputf8 = True
|
server_type = "smtp_starttls"
|
||||||
|
smtputf8 = True # Not used yet
|
||||||
port = 465
|
port = 465
|
||||||
|
|
||||||
|
|
||||||
class LogCfg(Jata):
|
class LogCfg(Jata):
|
||||||
logfile = "STDOUT"
|
logfile = "CONSOLE"
|
||||||
level = "INFO"
|
level = "INFO"
|
||||||
|
|
||||||
|
|
||||||
@ -77,10 +81,7 @@ class Config(Jata):
|
|||||||
boxes: list[Mbox]
|
boxes: list[Mbox]
|
||||||
users: list[User]
|
users: list[User]
|
||||||
|
|
||||||
pop: PopCfg | None = None
|
servers: list[ServerCfg]
|
||||||
smtp_starttls: SmtpStartTLSCfg | None = None
|
|
||||||
smtp: SmtpCfg | None = None
|
|
||||||
# smtp_port_submission = 587
|
|
||||||
|
|
||||||
|
|
||||||
CheckerFn = Callable[[str], bool]
|
CheckerFn = Callable[[str], bool]
|
||||||
|
@ -23,7 +23,7 @@ def create_tls_context(certfile, keyfile) -> ssl.SSLContext:
|
|||||||
|
|
||||||
def setup_logging(cfg: config.LogCfg):
|
def setup_logging(cfg: config.LogCfg):
|
||||||
logging_format = "%(asctime)s %(name)s %(levelname)s %(message)s @ %(filename)s:%(lineno)d"
|
logging_format = "%(asctime)s %(name)s %(levelname)s %(message)s @ %(filename)s:%(lineno)d"
|
||||||
if cfg.logfile == "STDOUT":
|
if cfg.logfile == "CONSOLE":
|
||||||
logging.basicConfig(level=cfg.level, format=logging_format)
|
logging.basicConfig(level=cfg.level, format=logging_format)
|
||||||
else:
|
else:
|
||||||
logging.basicConfig(filename=cfg.logfile,
|
logging.basicConfig(filename=cfg.logfile,
|
||||||
@ -45,7 +45,7 @@ async def a_main(cfg: config.Config) -> None:
|
|||||||
elif tls == "disable":
|
elif tls == "disable":
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
tls_cfg = config.TLSCfg(pop.tls)
|
tls_cfg = config.TLSCfg(tls)
|
||||||
return create_tls_context(tls_cfg.certfile, tls_cfg.keyfile)
|
return create_tls_context(tls_cfg.certfile, tls_cfg.keyfile)
|
||||||
|
|
||||||
def get_host(host):
|
def get_host(host):
|
||||||
@ -57,8 +57,13 @@ async def a_main(cfg: config.Config) -> None:
|
|||||||
mbox_finder = config.gen_addr_to_mboxes(cfg)
|
mbox_finder = config.gen_addr_to_mboxes(cfg)
|
||||||
servers: list[asyncio.Server] = []
|
servers: list[asyncio.Server] = []
|
||||||
|
|
||||||
if cfg.pop:
|
if not cfg.servers:
|
||||||
pop = config.PopCfg(cfg.pop)
|
logging.warning("Nothing to do!")
|
||||||
|
return
|
||||||
|
|
||||||
|
for scfg in cfg.servers:
|
||||||
|
if scfg.server_type == "pop":
|
||||||
|
pop = config.PopCfg(scfg)
|
||||||
pop_server = await create_pop_server(
|
pop_server = await create_pop_server(
|
||||||
host=get_host(pop.host),
|
host=get_host(pop.host),
|
||||||
port=pop.port,
|
port=pop.port,
|
||||||
@ -68,9 +73,8 @@ async def a_main(cfg: config.Config) -> None:
|
|||||||
timeout_seconds=pop.timeout_seconds,
|
timeout_seconds=pop.timeout_seconds,
|
||||||
)
|
)
|
||||||
servers.append(pop_server)
|
servers.append(pop_server)
|
||||||
|
elif scfg.server_type == "smtp_starttls":
|
||||||
if cfg.smtp_starttls:
|
stls = config.SmtpStartTLSCfg(scfg)
|
||||||
stls = config.SmtpStartTLSCfg(cfg.smtp_starttls)
|
|
||||||
stls_context = get_tls_context(stls.tls)
|
stls_context = get_tls_context(stls.tls)
|
||||||
if not stls_context:
|
if not stls_context:
|
||||||
raise Exception("starttls requires ssl_context")
|
raise Exception("starttls requires ssl_context")
|
||||||
@ -82,9 +86,8 @@ async def a_main(cfg: config.Config) -> None:
|
|||||||
ssl_context=stls_context,
|
ssl_context=stls_context,
|
||||||
)
|
)
|
||||||
servers.append(smtp_server_starttls)
|
servers.append(smtp_server_starttls)
|
||||||
|
elif scfg.server_type == "smtp":
|
||||||
if cfg.smtp:
|
smtp = config.SmtpCfg(scfg)
|
||||||
smtp = config.SmtpCfg(cfg.smtp)
|
|
||||||
smtp_server = await create_smtp_server(
|
smtp_server = await create_smtp_server(
|
||||||
host=get_host(smtp.host),
|
host=get_host(smtp.host),
|
||||||
port=smtp.port,
|
port=smtp.port,
|
||||||
@ -93,11 +96,13 @@ async def a_main(cfg: config.Config) -> None:
|
|||||||
ssl_context=get_tls_context(smtp.tls),
|
ssl_context=get_tls_context(smtp.tls),
|
||||||
)
|
)
|
||||||
servers.append(smtp_server)
|
servers.append(smtp_server)
|
||||||
|
else:
|
||||||
|
logging.error(f"Unknown server {scfg.server_type=}")
|
||||||
|
|
||||||
if servers:
|
if servers:
|
||||||
await asyncio.gather(*[server.serve_forever() for server in servers])
|
await asyncio.gather(*[server.serve_forever() for server in servers])
|
||||||
else:
|
else:
|
||||||
logging.warn("Nothing to do!")
|
logging.warning("Nothing to do!")
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
|
Reference in New Issue
Block a user