mirror of
https://github.com/chatmail/relay.git
synced 2026-05-15 19:14:44 +00:00
Compare commits
7 Commits
fix/acmeto
...
postfix-lo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0d301f9807 | ||
|
|
a5dffdf2e6 | ||
|
|
9c381e1fbf | ||
|
|
3cc9bc3ceb | ||
|
|
2a89be8209 | ||
|
|
c848b61346 | ||
|
|
49787044ff |
@@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
## untagged
|
## untagged
|
||||||
|
|
||||||
|
- Avoid "acmetool not found" during initial run
|
||||||
|
([#550](https://github.com/chatmail/relay/pull/550))
|
||||||
|
|
||||||
- Enforce end-to-end encryption for incoming messages.
|
- Enforce end-to-end encryption for incoming messages.
|
||||||
New user address mailboxes now get a `enforceE2EEincoming` file
|
New user address mailboxes now get a `enforceE2EEincoming` file
|
||||||
which prohibits incoming cleartext messages from other domains.
|
which prohibits incoming cleartext messages from other domains.
|
||||||
@@ -21,6 +24,9 @@
|
|||||||
- Send SNI when connecting to outside servers
|
- Send SNI when connecting to outside servers
|
||||||
([#524](https://github.com/chatmail/server/pull/524))
|
([#524](https://github.com/chatmail/server/pull/524))
|
||||||
|
|
||||||
|
- postfix master.cf: use 127.0.0.1 for consistency
|
||||||
|
([#544](https://github.com/chatmail/relay/pull/544))
|
||||||
|
|
||||||
- Pass through `original_content` instead of `content` in filtermail
|
- Pass through `original_content` instead of `content` in filtermail
|
||||||
([#509](https://github.com/chatmail/server/pull/509))
|
([#509](https://github.com/chatmail/server/pull/509))
|
||||||
|
|
||||||
|
|||||||
@@ -77,13 +77,13 @@ scache unix - - y - 1 scache
|
|||||||
postlog unix-dgram n - n - 1 postlogd
|
postlog unix-dgram n - n - 1 postlogd
|
||||||
filter unix - n n - - lmtp
|
filter unix - n n - - lmtp
|
||||||
# Local SMTP server for reinjecting outgoing filtered mail.
|
# Local SMTP server for reinjecting outgoing filtered mail.
|
||||||
localhost:{{ config.postfix_reinject_port }} inet n - n - 10 smtpd
|
127.0.0.1:{{ config.postfix_reinject_port }} inet n - n - 10 smtpd
|
||||||
-o syslog_name=postfix/reinject
|
-o syslog_name=postfix/reinject
|
||||||
-o smtpd_milters=unix:opendkim/opendkim.sock
|
-o smtpd_milters=unix:opendkim/opendkim.sock
|
||||||
-o cleanup_service_name=authclean
|
-o cleanup_service_name=authclean
|
||||||
|
|
||||||
# Local SMTP server for reinjecting incoming filtered mail
|
# Local SMTP server for reinjecting incoming filtered mail
|
||||||
localhost:{{ config.postfix_reinject_port_incoming }} inet n - n - 10 smtpd
|
127.0.0.1:{{ config.postfix_reinject_port_incoming }} inet n - n - 10 smtpd
|
||||||
-o syslog_name=postfix/reinject_incoming
|
-o syslog_name=postfix/reinject_incoming
|
||||||
-o smtpd_milters=unix:opendkim/opendkim.sock
|
-o smtpd_milters=unix:opendkim/opendkim.sock
|
||||||
|
|
||||||
|
|||||||
@@ -11,49 +11,10 @@ All functions of this module
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import os
|
|
||||||
import glob
|
|
||||||
|
|
||||||
from .rshell import CalledProcessError, shell
|
from .rshell import CalledProcessError, shell
|
||||||
|
|
||||||
|
|
||||||
def get_acme_account_url():
|
|
||||||
"""Get the acmetool account URL with fallback methods.
|
|
||||||
|
|
||||||
First tries the acmetool command, then falls back to searching the filesystem
|
|
||||||
if the command fails or returns empty.
|
|
||||||
"""
|
|
||||||
# Try the acmetool command first
|
|
||||||
acme_url = shell("acmetool account-url", fail_ok=True)
|
|
||||||
if acme_url:
|
|
||||||
return acme_url
|
|
||||||
|
|
||||||
# Fallback: search for URL files in acme accounts directory
|
|
||||||
try:
|
|
||||||
acct_base = "/var/lib/acme/accounts/"
|
|
||||||
# Find Let's Encrypt directory
|
|
||||||
le_dirs = glob.glob(os.path.join(acct_base, "*letsencrypt*"))
|
|
||||||
if not le_dirs:
|
|
||||||
return ""
|
|
||||||
|
|
||||||
# Find account directories
|
|
||||||
for le_dir in le_dirs:
|
|
||||||
acct_dirs = glob.glob(os.path.join(le_dir, "*"))
|
|
||||||
for acct_dir in acct_dirs:
|
|
||||||
url_file = os.path.join(acct_dir, "url")
|
|
||||||
if os.path.isfile(url_file):
|
|
||||||
# Read the URL file content
|
|
||||||
with open(url_file, "r") as f:
|
|
||||||
url = f.read().strip()
|
|
||||||
if url:
|
|
||||||
return url
|
|
||||||
except Exception:
|
|
||||||
# Any exception during fallback should be ignored
|
|
||||||
pass
|
|
||||||
|
|
||||||
return ""
|
|
||||||
|
|
||||||
|
|
||||||
def perform_initial_checks(mail_domain):
|
def perform_initial_checks(mail_domain):
|
||||||
"""Collecting initial DNS settings."""
|
"""Collecting initial DNS settings."""
|
||||||
assert mail_domain
|
assert mail_domain
|
||||||
@@ -65,7 +26,7 @@ def perform_initial_checks(mail_domain):
|
|||||||
WWW = query_dns("CNAME", f"www.{mail_domain}")
|
WWW = query_dns("CNAME", f"www.{mail_domain}")
|
||||||
|
|
||||||
res = dict(mail_domain=mail_domain, A=A, AAAA=AAAA, MTA_STS=MTA_STS, WWW=WWW)
|
res = dict(mail_domain=mail_domain, A=A, AAAA=AAAA, MTA_STS=MTA_STS, WWW=WWW)
|
||||||
res["acme_account_url"] = get_acme_account_url()
|
res["acme_account_url"] = shell("acmetool account-url", fail_ok=True)
|
||||||
res["dkim_entry"], res["web_dkim_entry"] = get_dkim_entry(
|
res["dkim_entry"], res["web_dkim_entry"] = get_dkim_entry(
|
||||||
mail_domain, dkim_selector="opendkim"
|
mail_domain, dkim_selector="opendkim"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
from subprocess import CalledProcessError, check_output
|
from subprocess import DEVNULL, CalledProcessError, check_output
|
||||||
|
|
||||||
|
|
||||||
def shell(command, fail_ok=False):
|
def shell(command, fail_ok=False):
|
||||||
print(f"$ {command}")
|
print(f"$ {command}")
|
||||||
|
args = dict(shell=True)
|
||||||
|
if fail_ok:
|
||||||
|
args["stderr"] = DEVNULL
|
||||||
try:
|
try:
|
||||||
return check_output(command, shell=True).decode().rstrip()
|
return check_output(command, **args).decode().rstrip()
|
||||||
except CalledProcessError:
|
except CalledProcessError:
|
||||||
if not fail_ok:
|
if not fail_ok:
|
||||||
raise
|
raise
|
||||||
|
|||||||
@@ -6,29 +6,6 @@ interoperable e-mail service for everyone. What's behind a `chatmail` is
|
|||||||
effectively a normal e-mail address just like any other but optimized
|
effectively a normal e-mail address just like any other but optimized
|
||||||
for the usage in chats, especially DeltaChat.
|
for the usage in chats, especially DeltaChat.
|
||||||
|
|
||||||
### Choosing a chatmail address instead of using a random one
|
|
||||||
|
|
||||||
In the Delta Chat account setup you may tap `Create a profile` then `Use other server` and choose `Classic e-mail login`. Here fill the two fields like this:
|
|
||||||
|
|
||||||
- `E-Mail Address`: invent a word with
|
|
||||||
{% if username_min_length == username_max_length %}
|
|
||||||
*exactly* {{ username_min_length }}
|
|
||||||
{% else %}
|
|
||||||
{{ username_min_length}}
|
|
||||||
{% if username_max_length == "more" %}
|
|
||||||
or more
|
|
||||||
{% else %}
|
|
||||||
to {{ username_max_length }}
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
characters
|
|
||||||
and append `@{{config.mail_domain}}` to it.
|
|
||||||
|
|
||||||
- `Existing Password`: invent at least {{ password_min_length }} characters.
|
|
||||||
|
|
||||||
If the e-mail address is not yet taken, you'll get that account.
|
|
||||||
The first login sets your password.
|
|
||||||
|
|
||||||
|
|
||||||
### Rate and storage limits
|
### Rate and storage limits
|
||||||
|
|
||||||
@@ -38,10 +15,11 @@ The first login sets your password.
|
|||||||
|
|
||||||
- You may send up to {{ config.max_user_send_per_minute }} messages per minute.
|
- You may send up to {{ config.max_user_send_per_minute }} messages per minute.
|
||||||
|
|
||||||
- Messages are unconditionally removed {{ config.delete_mails_after }} days after arriving on the server.
|
|
||||||
|
|
||||||
- You can store up to [{{ config.max_mailbox_size }} messages on the server](https://delta.chat/en/help#what-happens-if-i-turn-on-delete-old-messages-from-server).
|
- You can store up to [{{ config.max_mailbox_size }} messages on the server](https://delta.chat/en/help#what-happens-if-i-turn-on-delete-old-messages-from-server).
|
||||||
|
|
||||||
|
- Messages are unconditionally removed latest {{ config.delete_mails_after }} days after arriving on the server.
|
||||||
|
Earlier, if storage may exceed otherwise.
|
||||||
|
|
||||||
|
|
||||||
### <a name="account-deletion"></a> Account deletion
|
### <a name="account-deletion"></a> Account deletion
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user