2
0

BootstrapPostfix.py 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. from jinja2 import Environment, FileSystemLoader
  2. from modules.BootstrapBase import BootstrapBase
  3. from pathlib import Path
  4. class BootstrapPostfix(BootstrapBase):
  5. def bootstrap(self):
  6. # Connect to MySQL
  7. self.connect_mysql()
  8. # Wait for DNS
  9. self.wait_for_dns("mailcow.email")
  10. self.create_dir("/opt/postfix/conf/sql/")
  11. # Setup Jinja2 Environment and load vars
  12. self.env = Environment(
  13. loader=FileSystemLoader([
  14. '/service_config/custom_templates',
  15. '/service_config/config_templates'
  16. ]),
  17. keep_trailing_newline=True,
  18. lstrip_blocks=True,
  19. trim_blocks=True
  20. )
  21. extra_vars = {
  22. "VALID_CERT_DIRS": self.get_valid_cert_dirs()
  23. }
  24. self.env_vars = self.prepare_template_vars('/service_config/overwrites.json', extra_vars)
  25. print("Set Timezone")
  26. self.set_timezone()
  27. print("Set Syslog redis")
  28. self.set_syslog_redis()
  29. print("Render config")
  30. self.render_config("/service_config")
  31. # Create aliases DB
  32. self.run_command(["newaliases"])
  33. # Create SNI Config
  34. self.run_command(["postmap", "-F", "hash:/opt/postfix/conf/sni.map"])
  35. # Fix Postfix permissions
  36. self.set_owner("/opt/postfix/conf/sql", user="root", group="postfix", recursive=True)
  37. self.set_owner("/opt/postfix/conf/custom_transport.pcre", user="root", group="postfix")
  38. for cf_file in Path("/opt/postfix/conf/sql").glob("*.cf"):
  39. self.set_permissions(cf_file, 0o640)
  40. self.set_permissions("/opt/postfix/conf/custom_transport.pcre", 0o640)
  41. self.set_owner("/var/spool/postfix/public", user="root", group="postdrop", recursive=True)
  42. self.set_owner("/var/spool/postfix/maildrop", user="root", group="postdrop", recursive=True)
  43. self.run_command(["postfix", "set-permissions"], check=False)
  44. # Checking if there is a leftover of a crashed postfix container before starting a new one
  45. pid_file = Path("/var/spool/postfix/pid/master.pid")
  46. if pid_file.exists():
  47. print(f"Removing stale Postfix PID file: {pid_file}")
  48. pid_file.unlink()
  49. def get_valid_cert_dirs(self):
  50. certs = {}
  51. base_path = Path("/etc/ssl/mail")
  52. if not base_path.exists():
  53. return certs
  54. for cert_dir in base_path.iterdir():
  55. if not cert_dir.is_dir():
  56. continue
  57. domains_file = cert_dir / "domains"
  58. cert_file = cert_dir / "cert.pem"
  59. key_file = cert_dir / "key.pem"
  60. if not (domains_file.exists() and cert_file.exists() and key_file.exists()):
  61. continue
  62. with open(domains_file, "r") as f:
  63. domains = [line.strip() for line in f if line.strip()]
  64. if domains:
  65. certs[str(cert_dir)] = domains
  66. return certs