diff --git a/chatmaild/src/chatmaild/config.py b/chatmaild/src/chatmaild/config.py index 591fd3e0..76b92a3d 100644 --- a/chatmaild/src/chatmaild/config.py +++ b/chatmaild/src/chatmaild/config.py @@ -1,5 +1,6 @@ import ipaddress from pathlib import Path +from random import randint import iniconfig @@ -41,6 +42,11 @@ class Config: self.username_max_length = int(params.pop("username_max_length", 9)) self.password_min_length = int(params.pop("password_min_length", 9)) self.www_folder = params.pop("www_folder", "") + + self.imap_port = int(params.pop("imap_port", 143)) + self.imaps_port = int(params.pop("imaps_port", 993)) + self.smtp_port = int(params.pop("smtp_port", 587)) + self.smtps_port = int(params.pop("smtps_port", 465)) self.filtermail_smtp_port = int(params.pop("filtermail_smtp_port", "10080")) self.filtermail_smtp_port_incoming = int( params.pop("filtermail_smtp_port_incoming", "10081") @@ -138,8 +144,15 @@ def parse_size_mb(limit): def write_initial_config(inipath, mail_domain, overrides): """Write out default config file, using the specified config value overrides.""" - content = get_default_config_content(mail_domain, **overrides) - inipath.write_text(content) + content = get_default_config_content(mail_domain, **overrides).splitlines() + used_ports = [25, 53, 80, 143, 402, 443, 465, 587, 993, 3340, 3903, 3904, 8443, 10080, 10081, 10082, 10083, 10025, 10026] + for config_key in ["smtp_port", "imap_port", "smtps_port", "imaps_port"]: + value = randint(1, 65536) + while value in used_ports: + value = randint(65535) + used_ports.append(value) + content.append(f"{config_key} = {value}") + inipath.write_text("\n".join(content)) def get_default_config_content(mail_domain, **overrides): diff --git a/cmdeploy/src/cmdeploy/deployers.py b/cmdeploy/src/cmdeploy/deployers.py index 88fdfd48..3417e5f8 100644 --- a/cmdeploy/src/cmdeploy/deployers.py +++ b/cmdeploy/src/cmdeploy/deployers.py @@ -495,15 +495,15 @@ def deploy_chatmail(config_path: Path, disable_mail: bool, website_only: bool) - if config.tls_cert_mode == "acme": port_services.append(("acmetool", 402)) port_services += [ - (["imap-login", "dovecot"], 143), + (["imap-login", "dovecot"], config.imap_port), # acmetool previously listened on port 80, # so don't complain during upgrade that moved it to port 402 # and gave the port to nginx. (["acmetool", "nginx"], 80), ("nginx", 443), - (["master", "smtpd"], 465), - (["master", "smtpd"], 587), - (["imap-login", "dovecot"], 993), + (["master", "smtpd"], config.smtp_port), + (["master", "smtpd"], config.smtps_port), + (["imap-login", "dovecot"], config.imaps_port), ("iroh-relay", 3340), ("mtail", 3903), ("stats", 3904), diff --git a/cmdeploy/src/cmdeploy/nginx/autoconfig.xml.j2 b/cmdeploy/src/cmdeploy/nginx/autoconfig.xml.j2 index 6033347b..b3742c87 100644 --- a/cmdeploy/src/cmdeploy/nginx/autoconfig.xml.j2 +++ b/cmdeploy/src/cmdeploy/nginx/autoconfig.xml.j2 @@ -7,14 +7,14 @@ {{ config.mail_domain }} {{ config.mail_domain }} - 993 + {{ config.imaps_port }} SSL password-cleartext %EMAILADDRESS% {{ config.mail_domain }} - 143 + {{ config.imap_port }} STARTTLS password-cleartext %EMAILADDRESS% @@ -28,14 +28,14 @@ {{ config.mail_domain }} - 465 + {{ config.smtps_port }} SSL password-cleartext %EMAILADDRESS% {{ config.mail_domain }} - 587 + {{ config.smtp_port }} STARTTLS password-cleartext %EMAILADDRESS% diff --git a/cmdeploy/src/cmdeploy/nginx/nginx.conf.j2 b/cmdeploy/src/cmdeploy/nginx/nginx.conf.j2 index ac92662e..3b24ead6 100644 --- a/cmdeploy/src/cmdeploy/nginx/nginx.conf.j2 +++ b/cmdeploy/src/cmdeploy/nginx/nginx.conf.j2 @@ -31,6 +31,26 @@ stream { ~\bimap\b 127.0.0.1:993; } + server { + listen {{ config.smtp_port }}; + proxy_pass 127.0.0.1:587; + } + + server { + listen {{ config.imap_port }}; + proxy_pass 127.0.0.1:143; + } + + server { + listen {{ config.smtps_port }}; + proxy_pass 127.0.0.1:465; + } + + server { + listen {{ config.imaps_port }}; + proxy_pass 127.0.0.1:993; + } + server { listen 443; {% if not disable_ipv6 %}