Discourse와 Stalwart-mail로 완전 독립적인 이메일 구성

troubleshooting

Stalwart-mail+Discourse: POP3 EOF reached (again) 토론을 이어가며:

@programmerjake 님도 Discourse ↔ Stalwart-mail을 탐구하고 계시기 때문에, SMTPS에서 TLS 오류를 경험하고 있는지 여쭙고 싶었습니다:

2024-07-01T17:37:49.718793Z DEBUG common::listener: Failed to accept TLS connection: tls handshake eof context="tls" event="error" instance="smtps" protocol=Smtp remote.ip="128.140.68.114"
2024-07-01T17:37:49.899171Z DEBUG common::listener: Failed to accept TLS connection: tls handshake eof context="tls" event="error" instance="smtps" protocol=Smtp remote.ip="128.140.68.114"

Discourse 측에서는 오류 팝업이 표시됩니다:

ERROR - Net::ReadTimeout with #<TCPSocket:(closed)>

Ruby의 OpenSSL 라이브러리가 TLSv1.3을 지원하지 않아서인 것 같지만, TLSv1.2에서는 정상적으로 작동해야 하므로 이는 다소 무리한 추측입니다.


정상 작동하는 설치

Stalwart-mail >= v0.8.3

이것이 전부입니다. 이 릴리스를 통해 Stalwart-mail은 이제 Discourse와 이메일 송신 및 수신이 모두 가능합니다. :tada:

Stalwart-mail은 Postfix + Spamassassin + Dovecot 등 수십 년간 익숙해져 온 복잡한 구성의 혼란 없이 모든 이메일 요구 사항을 충족하는 단일 바이너리 메일 서비스입니다. 여기서는 설치를 설정하면 ACME와 LetsEncrypt를 통한 완전한 TLS 자동화, SPF, DMARC, DKIM, ARC, DANE 지원(도메인에서부터 도메인으로의 보고 포함), TLSA 및 기타 DNS 레코드 준비, 메일 클라이언트 설정을 위한 자동 구성 및 자동 탐색, "그룹"을 통한 공유 폴더, 별칭, 프로세스의 다양한 단계에서 모든 수신 및 발신 메시지에 대한 ManageSieve 필터, 웹 관리, 2FA 및 TOTP 지원, OAUTH 등 모든 것이 준비된 상태로 제공됩니다. 더 이상 이메일을 외부로 확장할 필요가 없습니다!

  1. SMTP를 위해 포트 587에서 submission 리스너를 사용하십시오.
    1. 암시적 TLS를 비활성화 하십시오(즉: STARTTLS 사용)
    2. 클라이언트 순서 무시(ignore client order)가 _비활성화_되어 있는지 확인하십시오(기본 설정 또는 리스너의 TLS 옵션에서 오버라이드)
  2. 암시적 TLS를 사용하여 포트 995에서 POP3 리스너를 활성화하십시오.

Discourse

Submission은 587(STARTTLS 사용), POP3s는 995(SSL/TLS 사용)를 사용하여 이메일을 정상적으로 구성하십시오.

그러니까 이것은 Mailgun 같은 서비스의 오픈소스 대안이라는 거군요? 대부분의 해당 서비스가 적은 양의 사용량에 비해 가격이 꽤 비싸기 때문에, 점점 더 매력적으로 느껴집니다.

이것은 자체 (가상) 머신이 필요하다는 뜻이겠죠. Discourse와 동일한 머신에서 쉽게 실행할 수 있다면 정말 훌륭할 텐데요.

Stalwart Mail의 단일 인스턴스가 여러 Discourse 인스턴스를 처리할 수 있는지 알고 계신가요?

네, 여러 도메인을 쉽게 지원할 수 있습니다.

먼저 도메인을 추가하면 MX(메일 교환) 설정을 위한 DNS 레코드가 제공됩니다. 모든 도메인이 동일한 MX를 사용하게 됩니다.

Stalwart-mail을 Discourse와 동일한 머신에서 실행하는 것은 비교적 쉬울 것입니다. 두 서비스 모두 TLS 포트 443을 필요로 하므로, 해당 포트에서 프록시를 사용해 두 서비스로 트래픽을 전달하게 됩니다. 하지만 Discourse 인스턴스 하나당 메일 인스턴스를 하나씩 두는 것은 큰 의미가 없으며, 두 서비스를 분리하는 것이 좋습니다. 이렇게 하면 이메일 인프라를 쉽게 확장할 수 있고, Discourse에만 국한되지 않는 더 다양한 요구사항을 충족할 수 있습니다.

참고로, 저는 Hetzner VPS(CPX21, RAM 4GB, x86 AMD vCPU 3개, 스토리지 80GB)에서 Stalwart-mail을 실행하고 있으며, 10여 개 도메인에 약 30개 계정을 두고 있고 전체 로그를 활성화한 상태입니다. 이 환경에서 RAM 사용량은 564MB, 스토리지 사용량은 7GB(대부분이 OS)입니다. Stalwart-mail 자체는 레지던트 RAM 184MB(전체 RAM의 5% 미만), 가상 메모리 1.2GB를 사용한다고 보고합니다.

포트 587에 STARTTLS를 사용 중이며, 방금 테스트했을 때 오류가 발생하지 않았습니다…

또한 Stalwart-mail 로그를 보면 TLSv1.3을 사용하고 있으며 오류가 발생하지 않는 것으로 보입니다… 현재 테스트 중인 약간 비표준적인 설정(로컬 ACME 서버를 실행하기 위해 pebble을 사용하고 .test 도메인 이름을 사용하는 것)이 있지만, 이것만으로 시스템이 깨지거나 고쳐질 정도는 아닐 것입니다…)

포트 587 리스너에서 "TLS 옵션 오버라이드"를 사용하지 않고 있습니다…

지난 몇 달간 Stalwart-mail을 Discourse와 함께 독점적으로 사용해 왔는데, 아주 잘 작동합니다. 이제 Submission(587 포트, STARTTLS)과 Submissions(465 포트, TLS)를 모두 사용할 수 있습니다. 특별한 설정이나 셋업이 필요하지 않았습니다.

다만 주의할 점으로, 도메인 DNS 레코드 설정은 두 단계의 과정입니다.

  1. 먼저 Directory에 도메인 이름을 추가합니다. 이렇게 하면 DNS 존 파일에 추가할 리소스 레코드가 제공됩니다.
  2. DNS가 업데이트되면 해당 도메인에 대해 TLS 프로바이더를 생성합니다. 다음 호스트네임을 추가해야 합니다: mail, autoconfig, autodiscover, 그리고 mta-tls(도메인을 붙인 형태, 예: mail.example.org).[1]
  3. 잠시 후(수 초에서 수 분), 내부 ACME 프로바이더가 변경 사항을 감지하여 TLS 인증서를 발급합니다. 이 시점에 도메인 설정이 레코드를 업데이트합니다: 새로운 id를 가진 _mta-tls RR과 모든 _tlsa 레코드를 존 파일에 추가하면 준비가 끝납니다.

Stalwart-mail은 현재 매우 강력한 스팸 필터와 통합된 fail2ban 기능(인증 실패 또는 잘못된 URI를 요청한 IP 주소를 차단)을 갖추고 있습니다.


  1. 최소한의 Stalwart-mail + Discourse 구성의 경우, autoconfig와 autodiscover는 IMAP 클라이언트와 함께 유용하므로 아마도 필요하지 않을 것입니다. ↩︎