Compare commits

...

23 Commits

Author SHA1 Message Date
missytake
f26d2da23b Try without gcc 2025-01-27 11:37:07 +01:00
link2xt
3b32387bf8 Install python3-dev 2025-01-26 20:10:12 +00:00
link2xt
a651fba8b6 Install gcc 2025-01-26 19:58:48 +00:00
adbenitez
20f76c83f8 replace deprecated crypt package with crypt-r 2025-01-26 19:48:46 +00:00
link2xt
b2995551a2 ci: remove iroh relay from zonefiles
iroh subdomain is not needed
since 95f8c4b269
2025-01-26 19:22:45 +00:00
link2xt
c8f46147e0 chore: ruff 0.9.2 fixes and formatting 2025-01-24 20:57:13 +01:00
missytake
9f6ea8121c added changelog 2025-01-08 17:21:18 +01:00
missytake
9c08cbfbec DNS: recommend DKIM record without space in between for some DNS web interfaces 2025-01-08 17:21:18 +01:00
missytake
c3190dd51a doc: fix migration guide
fix #464
2025-01-08 16:55:10 +01:00
missytake
5b8de76c22 fix tests 2024-12-21 00:04:40 +01:00
missytake
d6205d9a04 add changelog 2024-12-21 00:04:40 +01:00
missytake
6a32192e50 Revert rest of #462
This reverts commit 88a8dc905b.
2024-12-21 00:04:40 +01:00
missytake
5c78619750 DNS: make --all non-optional for cmdeploy dns 2024-12-21 00:04:40 +01:00
missytake
a7b808ebaf Release 1.5.0 2024-12-20 10:53:36 +01:00
missytake
d11038b7b3 DNS: out() instead of print() 2024-12-20 10:46:42 +01:00
missytake
88a8dc905b DNS: recommend cmdeploy dns --all in the README 2024-12-20 10:46:42 +01:00
missytake
a2fbb5dc37 add changelog 2024-12-20 10:46:42 +01:00
missytake
97c31e3820 fix tests 2024-12-20 10:46:42 +01:00
missytake
08c88caa46 CI: test all DNS records 2024-12-20 10:46:42 +01:00
missytake
8e5174ae44 DNS: add -all to cmdeploy dns 2024-12-20 10:46:42 +01:00
missytake
69fe5eac2b DNS: more elegant solution to fix mta-sts record 2024-12-17 18:27:56 +01:00
missytake
46f6a07239 Revert "DNS: fix _mta-sts TXT record on initial setup"
This reverts commit 6d4af3cf0c.
2024-12-17 18:27:56 +01:00
missytake
b268efbc6e DNS: fix _mta-sts TXT record on initial setup 2024-12-17 18:27:56 +01:00
14 changed files with 59 additions and 24 deletions

View File

@@ -17,5 +17,4 @@ $TTL 300
;; DNS records. ;; DNS records.
@ IN A 37.27.95.249 @ IN A 37.27.95.249
mta-sts.staging-ipv4.testrun.org. CNAME staging-ipv4.testrun.org. mta-sts.staging-ipv4.testrun.org. CNAME staging-ipv4.testrun.org.
iroh.staging-ipv4.testrun.org. CNAME staging-ipv4.testrun.org.
www.staging-ipv4.testrun.org. CNAME staging-ipv4.testrun.org. www.staging-ipv4.testrun.org. CNAME staging-ipv4.testrun.org.

View File

@@ -17,6 +17,5 @@ $TTL 300
;; DNS records. ;; DNS records.
@ IN A 37.27.24.139 @ IN A 37.27.24.139
mta-sts.staging2.testrun.org. CNAME staging2.testrun.org. mta-sts.staging2.testrun.org. CNAME staging2.testrun.org.
iroh.staging2.testrun.org. CNAME staging2.testrun.org.
www.staging2.testrun.org. CNAME staging2.testrun.org. www.staging2.testrun.org. CNAME staging2.testrun.org.

View File

@@ -2,6 +2,23 @@
## untagged ## untagged
- cmdeploy dns: offer alternative DKIM record format for some web interfaces
([#470](https://github.com/deltachat/chatmail/pull/470))
- migration guide: let opendkim own the DKIM keys directory
([#468](https://github.com/deltachat/chatmail/pull/468))
## 1.5.0 2024-12-20
- cmdeploy dns: always show recommended DNS records
([#463](https://github.com/deltachat/chatmail/pull/463))
- add `--all` to `cmdeploy dns`
([#462](https://github.com/deltachat/chatmail/pull/462))
- fix `_mta-sts` TXT DNS record
([#461](https://github.com/deltachat/chatmail/pull/461)
- deploy `iroh-relay` and also update "realtime relay services" in privacy policy. - deploy `iroh-relay` and also update "realtime relay services" in privacy policy.
([#434](https://github.com/deltachat/chatmail/pull/434)) ([#434](https://github.com/deltachat/chatmail/pull/434))
([#451](https://github.com/deltachat/chatmail/pull/451)) ([#451](https://github.com/deltachat/chatmail/pull/451))

View File

@@ -281,7 +281,7 @@ to make sure you can connect with SSH.
`ssh root@13.37.13.37 tar c /etc/dkimkeys | ssh root@13.12.23.42 tar x -C /etc/` `ssh root@13.37.13.37 tar c /etc/dkimkeys | ssh root@13.12.23.42 tar x -C /etc/`
so the DKIM DNS record stays correct. so the DKIM DNS record stays correct.
3. On the new server, run `chown root: -R /var/lib/acme` and `chown root: -R /etc/dkimkeys` to make sure the permissions are correct. 3. On the new server, run `chown root: -R /var/lib/acme` and `chown opendkim: -R /etc/dkimkeys` to make sure the permissions are correct.
4. Run `cmdeploy run --disable-mail --ssh-host 13.12.23.42` to install chatmail on the new machine. 4. Run `cmdeploy run --disable-mail --ssh-host 13.12.23.42` to install chatmail on the new machine.
postfix and dovecot are disabled for now, postfix and dovecot are disabled for now,

View File

@@ -12,6 +12,7 @@ dependencies = [
"deltachat-rpc-client", "deltachat-rpc-client",
"filelock", "filelock",
"requests", "requests",
"crypt-r",
] ]
[tool.setuptools] [tool.setuptools]

View File

@@ -1,9 +1,10 @@
import crypt
import json import json
import logging import logging
import os import os
import sys import sys
import crypt_r
from .config import Config, read_config from .config import Config, read_config
from .dictproxy import DictProxy from .dictproxy import DictProxy
from .migrate_db import migrate_from_db_to_maildir from .migrate_db import migrate_from_db_to_maildir
@@ -13,7 +14,7 @@ NOCREATE_FILE = "/etc/chatmail-nocreate"
def encrypt_password(password: str): def encrypt_password(password: str):
# https://doc.dovecot.org/configuration_manual/authentication/password_schemes/ # https://doc.dovecot.org/configuration_manual/authentication/password_schemes/
passhash = crypt.crypt(password, crypt.METHOD_SHA512) passhash = crypt_r.crypt(password, crypt_r.METHOD_SHA512)
return "{SHA512-CRYPT}" + passhash return "{SHA512-CRYPT}" + passhash

View File

@@ -32,7 +32,7 @@ def migrate_from_db_to_maildir(config, chunking=10000):
# don't transfer special/CI accounts # don't transfer special/CI accounts
rows = [row for row in all_rows if row[0][:3] not in ("ci-", "ac_")] rows = [row for row in all_rows if row[0][:3] not in ("ci-", "ac_")]
logging.info(f"ignoring {len(all_rows)-len(rows)} CI accounts") logging.info(f"ignoring {len(all_rows) - len(rows)} CI accounts")
logging.info(f"migrating {len(rows)} sqlite database passwords to user dirs") logging.info(f"migrating {len(rows)} sqlite database passwords to user dirs")
for i, row in enumerate(rows): for i, row in enumerate(rows):

View File

@@ -10,7 +10,7 @@ import sys
from pathlib import Path from pathlib import Path
from chatmaild.config import Config, read_config from chatmaild.config import Config, read_config
from pyinfra import host, facts from pyinfra import facts, host
from pyinfra.facts.files import File from pyinfra.facts.files import File
from pyinfra.facts.systemd import SystemdEnabled from pyinfra.facts.systemd import SystemdEnabled
from pyinfra.operations import apt, files, pip, server, systemd from pyinfra.operations import apt, files, pip, server, systemd
@@ -78,6 +78,11 @@ def _install_remote_venv_with_chatmaild(config) -> None:
always_copy=True, always_copy=True,
) )
apt.packages(
name="install python3-dev to build crypt_r source package",
packages=["python3-dev"],
)
server.shell( server.shell(
name=f"forced pip-install {dist_file.name}", name=f"forced pip-install {dist_file.name}",
commands=[ commands=[
@@ -517,9 +522,9 @@ def deploy_iroh_relay(config) -> None:
need_restart |= systemd_unit.changed need_restart |= systemd_unit.changed
iroh_config = files.put( iroh_config = files.put(
name=f"Upload iroh-relay config", name="Upload iroh-relay config",
src=importlib.resources.files(__package__).joinpath("iroh-relay.toml"), src=importlib.resources.files(__package__).joinpath("iroh-relay.toml"),
dest=f"/etc/iroh-relay.toml", dest="/etc/iroh-relay.toml",
user="root", user="root",
group="root", group="root",
mode="644", mode="644",

View File

@@ -70,6 +70,6 @@ def deploy_acmetool(email="", domains=[]):
) )
server.shell( server.shell(
name=f"Request certificate for: { ', '.join(domains) }", name=f"Request certificate for: {', '.join(domains)}",
commands=[f"acmetool want --xlog.severity=debug { ' '.join(domains)}"], commands=[f"acmetool want --xlog.severity=debug {' '.join(domains)}"],
) )

View File

@@ -56,12 +56,12 @@ def run_cmd_options(parser):
"--disable-mail", "--disable-mail",
dest="disable_mail", dest="disable_mail",
action="store_true", action="store_true",
help="install/upgrade the server, but disable postfix & dovecot for now" help="install/upgrade the server, but disable postfix & dovecot for now",
) )
parser.add_argument( parser.add_argument(
"--ssh-host", "--ssh-host",
dest="ssh_host", dest="ssh_host",
help="specify an SSH host to deploy to; uses mail_domain from chatmail.ini by default" help="specify an SSH host to deploy to; uses mail_domain from chatmail.ini by default",
) )

View File

@@ -11,7 +11,7 @@ def main():
"CHATMAIL_INI", "CHATMAIL_INI",
importlib.resources.files("cmdeploy").joinpath("../../../chatmail.ini"), importlib.resources.files("cmdeploy").joinpath("../../../chatmail.ini"),
) )
disable_mail = bool(os.environ.get('CHATMAIL_DISABLE_MAIL')) disable_mail = bool(os.environ.get("CHATMAIL_DISABLE_MAIL"))
deploy_chatmail(config_path, disable_mail) deploy_chatmail(config_path, disable_mail)

View File

@@ -29,7 +29,7 @@ def check_initial_remote_data(remote_data, *, print=print):
def get_filled_zone_file(remote_data): def get_filled_zone_file(remote_data):
sts_id = remote_data.get("sts_id") sts_id = remote_data.get("sts_id")
if not sts_id: if not sts_id:
sts_id = datetime.datetime.now().strftime("%Y%m%d%H%M") remote_data["sts_id"] = datetime.datetime.now().strftime("%Y%m%d%H%M")
template = importlib.resources.files(__package__).joinpath("chatmail.zone.j2") template = importlib.resources.files(__package__).joinpath("chatmail.zone.j2")
content = template.read_text() content = template.read_text()
@@ -49,16 +49,23 @@ def check_full_zone(sshexec, remote_data, out, zonefile) -> int:
kwargs=dict(zonefile=zonefile, mail_domain=remote_data["mail_domain"]), kwargs=dict(zonefile=zonefile, mail_domain=remote_data["mail_domain"]),
) )
returncode = 0
if required_diff: if required_diff:
out.red("Please set required DNS entries at your DNS provider:\n") out.red("Please set required DNS entries at your DNS provider:\n")
for line in required_diff: for line in required_diff:
out(line) out(line)
return 1 out("")
elif recommended_diff: returncode = 1
if remote_data.get("dkim_entry") in required_diff:
out(
"If the DKIM entry above does not work with your DNS provider, you can try this one:\n"
)
out(remote_data.get("web_dkim_entry") + "\n")
if recommended_diff:
out("WARNING: these recommended DNS entries are not set:\n") out("WARNING: these recommended DNS entries are not set:\n")
for line in recommended_diff: for line in recommended_diff:
out(line) out(line)
return 0
out.green("Great! All your DNS entries are verified and correct.") if not (recommended_diff or required_diff):
return 0 out.green("Great! All your DNS entries are verified and correct.")
return returncode

View File

@@ -27,7 +27,9 @@ def perform_initial_checks(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"] = shell("acmetool account-url", fail_ok=True) res["acme_account_url"] = shell("acmetool account-url", fail_ok=True)
res["dkim_entry"] = get_dkim_entry(mail_domain, dkim_selector="opendkim") res["dkim_entry"], res["web_dkim_entry"] = get_dkim_entry(
mail_domain, dkim_selector="opendkim"
)
if not MTA_STS or not WWW or (not A and not AAAA): if not MTA_STS or not WWW or (not A and not AAAA):
return res return res
@@ -48,7 +50,11 @@ def get_dkim_entry(mail_domain, dkim_selector):
return return
dkim_value_raw = f"v=DKIM1;k=rsa;p={dkim_pubkey};s=email;t=s" dkim_value_raw = f"v=DKIM1;k=rsa;p={dkim_pubkey};s=email;t=s"
dkim_value = '" "'.join(re.findall(".{1,255}", dkim_value_raw)) dkim_value = '" "'.join(re.findall(".{1,255}", dkim_value_raw))
return f'{dkim_selector}._domainkey.{mail_domain}. TXT "{dkim_value}"' web_dkim_value = "".join(re.findall(".{1,255}", dkim_value_raw))
return (
f'{dkim_selector}._domainkey.{mail_domain}. TXT "{dkim_value}"',
f'{dkim_selector}._domainkey.{mail_domain}. TXT "{web_dkim_value}"',
)
def query_dns(typ, domain): def query_dns(typ, domain):

View File

@@ -85,7 +85,7 @@ class TestEndToEndDeltaChat:
attachsize = 1 * 1024 * 1024 attachsize = 1 * 1024 * 1024
num_to_send = quota // attachsize + 2 num_to_send = quota // attachsize + 2
lp.sec(f"ac1: send {num_to_send} large files to ac2") lp.sec(f"ac1: send {num_to_send} large files to ac2")
lp.indent(f"per-user quota is assumed to be: {quota/(1024*1024)}MB") lp.indent(f"per-user quota is assumed to be: {quota / (1024 * 1024)}MB")
alphanumeric = "abcdefghijklmnopqrstuvwxyz1234567890" alphanumeric = "abcdefghijklmnopqrstuvwxyz1234567890"
msgs = [] msgs = []
for i in range(num_to_send): for i in range(num_to_send):
@@ -97,7 +97,7 @@ class TestEndToEndDeltaChat:
msg = chat.send_file(str(attachment)) msg = chat.send_file(str(attachment))
msgs.append(msg) msgs.append(msg)
lp.indent(f"Sent out msg {i}, size {attachsize/(1024*1024)}MB") lp.indent(f"Sent out msg {i}, size {attachsize / (1024 * 1024)}MB")
lp.sec("ac2: check messages are arriving until quota is reached") lp.sec("ac2: check messages are arriving until quota is reached")