butter-portal/install_madmail.py

110 lines
3.9 KiB
Python

import pexpect
import json
import socket
from app import app
from subprocess import run
def resolve_butterbox_ip(hostname):
"""Best-effort lookup of the box's current address, falling back to the
configured default. Mirrors app.routes.resolve_butterbox_ip but avoids a
circular import (routes imports this module) and reuses the hostname that
was already loaded from settings.txt."""
# 1. Resolve the box's own mDNS/.local name.
try:
ip = socket.gethostbyname(f"{hostname}.local")
if ip and not ip.startswith("127."):
return ip
except OSError:
pass
# 2. Fall back to the address of the primary outbound interface. The
# connect() picks a route without sending any packets.
try:
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
s.connect(("8.8.8.8", 80))
ip = s.getsockname()[0]
if ip and not ip.startswith("127."):
return ip
except OSError:
pass
# 3. Give up and use the configured access-point default.
return app.config['BUTTERBOX_DEFAULT_IP']
def run_madmail_installer():
with open("./settings.txt", "r") as f:
settings = json.load(f)
butterbox_hostname = settings["butterbox_hostname"]
cmd = f"sudo ../madmail/madmail install"
child = pexpect.spawnu(cmd)
child.logfile = open("install_log.txt", "w")
child.expect("Customize every setting")
child.sendline("2")
child.expect("Primary domain")
child.sendline(f"{butterbox_hostname}.local")
child.expect("MX record")
child.sendline(f"{butterbox_hostname}.local")
child.expect("Public IP address")
child.sendline(resolve_butterbox_ip(butterbox_hostname))
child.expect("Additional domains")
child.sendline("")
child.expect("State directory")
child.sendline("")
child.expect("Configuration directory")
child.sendline("")
child.expect("TLS mode")
child.sendline("self_signed")
child.expect("Disable TLS")
child.sendline("y")
child.expect("SMTP port")
child.sendline("25")
child.expect("Submission port")
child.sendline("587")
child.expect("Submission TLS port")
child.sendline("465")
child.expect("IMAP port")
child.sendline("143")
child.expect("IMAP TLS port")
child.sendline("993")
child.expect("Enable chatmail")
child.sendline("y")
child.expect("Chatmail HTTP port")
child.sendline("8081")
child.expect("Chatmail HTTPS port")
child.sendline("8443")
child.expect("Chatmail username length")
child.sendline("8")
child.expect("Chatmail password length")
child.sendline("16")
child.expect("Enable Shadowsocks proxy for faster messaging")
child.sendline("n")
child.expect("Enable TURN server")
child.sendline("n")
child.expect("Allow cleartext SMTP submission")
child.sendline("n")
child.expect("Allow secure join requests without encryption")
child.sendline("y")
child.expect("Passthrough senders")
child.sendline("")
child.expect("Passthrough recipients")
child.sendline("")
child.expect("Maximum message size")
child.sendline("")
child.expect("Add Cloudflare proxy disable tags to DNS records")
child.sendline("n")
child.expect("Enable logging for the server")
child.sendline("y")
child.expect(pexpect.EOF)
daemon_enable = run(["sudo", "systemctl", "enable", "madmail"], capture_output=True, text=True)
if daemon_enable.returncode != 0:
print(f"Issue running systemctl daemon_enable")
daemon_start = run(["sudo", "systemctl", "start", "madmail"], capture_output=True, text=True)
if daemon_start.returncode != 0:
print(f"Issue running systemctl daemon_start")
daemon_reload = run(["sudo", "systemctl", "daemon-reload"], capture_output=True, text=True)
if daemon_reload.returncode != 0:
print(f"Issue running systemctl daemon_reload")