도움 필요해요, 이메일 설정 디버깅에 막혀 있어요 (Infomaniak/Brevo)

안녕하세요!

저희 작은 비영리 단체를 위해 Discourse를 설치하고 있습니다. Infomaniak의 퍼블릭 클라우드에서 Ubuntu 22.04 클라우드 인스턴스를 선택했고, 무료 플랜에서 월 300통의 메일을 지원하기 때문에 트랜잭션 메일은 Brevo를 사용하기로 했습니다.

서버를 설정하는 동안 여러 문제를 하나씩 겪었고, 문서와 여기 게시글들이 큰 도움이 되었습니다…

하지만
이제 더 이상 어떻게 진행해야 할지 모르는 지점에 도달했습니다.

  1. 제 인스턴스는 forum.aether-labs.fr 서브도메인으로 접근 가능합니다.

  2. Brevo 계정은 정상적으로 작동하며, Thunderbird를 통해 noreply@forum.aether-labs.fr에서 메일 전송에 성공했습니다.

  3. 하지만 계정을 인증하기 위한 첫 관리자 메일을 받지 못하고 있습니다.

그래서 Troubleshoot email on a new Discourse install (신규 사용자의 규칙 때문에 링크는 없습니다) 게시글을 자세히 읽고 여러 가지를 시도해 보았습니다.

  1. 앱 컨테이너(인 것 같습니다)는 Brevo SMTP 서버 포트에 도달하는 데 성공했습니다.
root@server-1:/var/discourse# 
root@server-1:/var/discourse# ./launcher enter app
x86_64 arch detected.
root@server-1-app:/var/www/discourse# 
root@server-1-app:/var/www/discourse# openssl s_client -connect smtp-relay.sendinblue.com:587 -starttls smtp
CONNECTED(00000003)
depth=2 C = US, ST = New Jersey, L = Jersey City, O = The USERTRUST Network, CN = USERTrust RSA Certification Authority
verify return:1
depth=1 C = GB, ST = Greater Manchester, L = Salford, O = Sectigo Limited, CN = Sectigo RSA Domain Validation Secure Server CA
verify return:1
depth=0 CN = *.sendinblue.com
verify return:1
---
Certificate chain
 0 s:CN = *.sendinblue.com
   i:C = GB, ST = Greater Manchester, L = Salford, O = Sectigo Limited, CN = Sectigo RSA Domain Validation Secure Server CA
 1 s:C = GB, ST = Greater Manchester, L = Salford, O = Sectigo Limited, CN = Sectigo RSA Domain Validation Secure Server CA
   i:C = US, ST = New Jersey, L = Jersey City, O = The USERTRUST Network, CN = USERTrust RSA Certification Authority
 2 s:C = US, ST = New Jersey, L = Jersey City, O = The USERTRUST Network, CN = USERTrust RSA Certification Authority
   i:C = GB, ST = Greater Manchester, L = Salford, O = Comodo CA Limited, CN = AAA Certificate Services
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIGODCCBSCgAwIBAgIQf3BN6DJXk+R4MhMClPwXSzANBgkqhkiG9w0BAQsFADCB
jzELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
A1UEBxMHU2FsZm9yZDEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTcwNQYDVQQD
Ey5TZWN0aWdvIFJTQSBEb21haW4gVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENB
MB4XDTIyMTIwMTAwMDAwMFoXDTIzMTIxMzIzNTk1OVowGzEZMBcGA1UEAwwQKi5z
ZW5kaW5ibHVlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKym
RK7t+EAo9Vtl+7laiPy2QTvaxT7WLrLGNGzSzorOBTKkjpjEOveSaa9SMav+qX/T
n4Q/eVQdjggQqFrUAYAN7aXa83K9zYMrSAzsPzg/k3O5iXl3GC5KT3yF9IzNNso0
oljczFaYDdhLr6iovk03DXQB0hMmfX3RLJyqYmyGEshoJwSAMTfW06Iob25JFVG7
tKngYEQMx/IC/WsFKuJ8t2AKaK7xZyEklQqJ95j9lzbfP27VNIkfcZ3DjMDK3shL
xgkpsys8LiH5P1MUAEq4fmOE9IIkewGYMAuKSRyzH1DdgeDvMW8RYcVwGmAfEjQ4
W/515j9q6f1OLQPK1zUCAwEAAaOCAwEwggL9MB8GA1UdIwQYMBaAFI2MXsRUrYrh
d+mb+ZsF4bgBjWHhMB0GA1UdDgQWBBQt3X5DvoJzqs7qZ1t/7m1fRPcJGTAOBgNV
HQ8BAf8EBAMCBaAwDAYDVR0TAQH/BAIwADAdBgNVHSUEFjAUBggrBgEFBQcDAQYI
KwYBBQUHAwIwSQYDVR0gBEIwQDA0BgsrBgEEAbIxAQICBzAlMCMGCCsGAQUFBwIB
FhdodHRwczovL3NlY3RpZ28uY29tL0NQUzAIBgZngQwBAgEwgYQGCCsGAQUFBwEB
BHgwdjBPBggrBgEFBQcwAoZDaHR0cDovL2NydC5zZWN0aWdvLmNvbS9TZWN0aWdv
UlNBRG9tYWluVmFsaWRhdGlvblNlY3VyZVNlcnZlckNBLmNydDAjBggrBgEFBQcw
AYYXaHR0cDovL29jc3Auc2VjdGlnby5jb20wKwYDVR0RBCQwIoIQKi5zZW5kaW5i
bHVlLmNvbYIOc2VuZGluYmx1ZS5jb20wggF9BgorBgEEAdZ5AgQCBIIBbQSCAWkB
ZwB1AK33vvp8/xDIi509nB4+GGq0Zyldz7EMJMqFhjTr3IKKAAABhM6AGCkAAAQD
AEYwRAIgLXDREGRQg02jNvL1Vvuwmbc8G1OpnwgHOsWKB/Gi5hQCIEmjtO9/O9DQ
nBNawCpH/ppW57f49W90ecV0Ng2qHWs9AHcAejKMVNi3LbYg6jjgUh7phBZwMhOF
TTvSK8E6V6NS61IAAAGEzoAX8gAABAMASDBGAiEAzTTpiWsKzHjVN7czz0Iw+TW8
17jAlGb8/LvgNuyb+yoCIQD4W8vpQd7aoLwFL1ZuuEh3zhrDL/iNa1FbnPTXrCSx
hQB1AOg+0No+9QY1MudXKLyJa8kD08vREWvs62nhd31tBr1uAAABhM6AF8EAAAQD
AEYwRAIgaLYUtDrQms9/CbKsZIsJ0ootg6Swnori9rmkiQlZklwCICerSmuiXVAg
thR3zAcjsEd4o1hXgMjEjM3ct4T1WDLdMA0GCSqGSIb3DQEBCwUAA4IBAQC+X/Us
keEDvt4AG0j9CgcP+QrZliJMsKNz7YR8Mt+NJiXr69Kg/hZNvw5aToCgjgbPlzPj
cs4i/6plivGmBsH94qIcl+PbHm1wJFSodDvahKuP0xZbBcynel9cIeCLRfYLr8nI
qJnB7sqK3Fpda98EY4x5kYbbiKJ2CaMABD8WZBEbJglTY3cmZkpI6m76sEgrlVm+
O+jp2fw7cFda+vzUmBmd8z1i7dZbB7Oj4Wy/SjT0SPbousz7JXXBh2YDiIzLBfvt
8mhjeQmLZMCnvL74zxFfuB44v4X0SIfQPjSgZy8vTYYMrSn40pzLbL1np7t+jpEb
ratD0fgmtozDRDWw
-----END CERTIFICATE-----
subject=CN = *.sendinblue.com

issuer=C = GB, ST = Greater Manchester, L = Salford, O = Sectigo Limited, CN = Sectigo RSA Domain Validation Secure Server CA

---
No client certificate CA names sent
Peer signing digest: SHA512
Peer signature type: RSA
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 5482 bytes and written 476 bytes
Verification: OK
---
New, TLSv1.2, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES128-GCM-SHA256
    Session-ID: FF96A2562FFDC00C5948FE7E6123CE9CD4CFB4939A4546728F60584ED2EC12EB
    Session-ID-ctx: 
    Master-Key: 287A2ECAB44E3F1EB919B4AD0EF98981A05F866381485781BB46AFEA2F361E987C31E57DA1098B01F69B75679E07E430
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 300 (seconds)
    TLS session ticket:
    0000 - 6d 30 ab bf 0a 44 79 06-0a 1a 67 1a 25 b5 f8 05   m0...Dy...g.%...
    0010 - 8e 33 6c 9a db 35 cd 9e-64 d6 a3 44 59 36 d4 e1   .3l..5..d..DY6..
    0020 - 69 b2 46 6a d5 7a 22 25-c2 36 bd bc ef ca d8 bf   i.Fj.z"%.6......
    0030 - 1c e2 b5 31 4e ab 43 cf-ea a0 1a b8 39 69 cd 5c   ...1N.C.....9i.\
    0040 - 15 b5 94 17 9c 70 d0 9d-ff 7c 7f e9 3f c8 87 a2   .....p...|..?...
    0050 - d0 12 5d a2 2b 6c e3 54-aa 33 10 fa b5 08 57 9f   ..].+l.T.3....W.
    0060 - 64 ce cc 08 53 24 f1 5c-4f 6b 4c 19 f1 f8 83 be   d...S$.\OkL.....
    0070 - 97 11 17 3f 83 5f 9f 9c-16 73 86 98 c8 d6 72 a8   ...?._...s....r.
    0080 - 44 7a bd 43 e3 40 44 a5-f4 6d 7f 36 19 e4 f3 84   Dz.C.@D..m.6....
    0090 - ec 3f 0b 65 0c 53 ef 73-ef 43 19 8c 34 27 87 40   .?.e.S.s.C..4'.@
    00a0 - 7e 52 5f 6f 7a 2d e6 08-a6 fc 6f 77 a9 47 f3 fa   ~R_oz-....ow.G..
    00b0 - eb 56 ac 1d f0 42 de 45-37 22 ec 5e 13 48 09 41   .V...B.E7".^.H.A

    Start Time: 1700936536
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
    Extended master secret: no
---
250 STARTTLS
^C
root@server-1-app:/var/www/discourse# 
root@server-1-app:/var/www/discourse# 

마지막 로그는 이전 게시글에 명시된 250 DSN 대신 250 STARTTLS로 표시되며, 비전문가인 제 눈에는 괜찮아 보입니다.

  1. 하지만 discourse-doctor는 메일을 보내지 못하고 포트가 닫혀 있다고 말합니다. (starttls 없이 587, 2525, 465 포트를 모두 시도해 보았습니다)
==================== MAIL TEST ====================
For a robust test, get an address from http://www.mail-tester.com/
Or just send a test message to yourself.
Email address for mail test? ('n' to skip) [contact@aether-labs.fr]: test-f2ps9wb2f@srv1.mail-tester.com
Sending mail to test-f2ps9wb2f@srv1.mail-tester.com. . . 
Testing sending to test-f2ps9wb2f@srv1.mail-tester.com using smtp-relay.sendinblue.com:587, username:forum@aether-labs.fr with plain auth.
======================================== ERROR ========================================
Connection to port 587 failed.
====================================== SOLUTION =======================================
The most likely problem is that your server has outgoing SMTP traffic blocked.
If you are using a service like Mailgun or Sendgrid, try using port 2525.
=======================================================================================

(4)번에서 확인했듯이 아웃바운드 SMTP 트래픽이 차단되어 있지 않은 것으로 보이는데, 트랜잭션 메일의 설정이 올바르게 되도록 어떻게 계속 진행해야 하고 어떤 설정을 변경해야 할지 모르겠습니다.

VM 제공업체에 문의하여 출구 포트가 차단되어 있는지 확인해 보세요.

@pfaffman 감사합니다!
방금 이메일을 보냈습니다.

하지만

openssl s_client -connect smtp-relay.sendinblue.com:587 -starttls smtp

이 동작하는 것이 이상합니다. smtp-relay.sendinblue.com:586을 넣으면 결과가 나오지 않으므로, 트래픽이 차단되지 않는 것 같습니다. 응답이 있다는 것은 패킷이 smtp-relay.sendinblue.com:587에 도달하고 있다는 뜻이 아니겠습니까?

지원팀에서 설정(conf)에 문제가 없으며 아웃바운드 포트가 차단되어 있지 않다고 알려주었습니다.

그래서 openssl을 통해 완전히 수동으로 메일 전송을 시도해 보았고, 실제로 도커 컨테이너 내부에서 제게 메일을 성공적으로 보낼 수 있었습니다.

root@server-1-app:/var/www/discourse#  openssl s_client -starttls smtp -connect smtp-relay.sendinblue.com:587

EHLO jai
AUTH PLAIN
AGZvcnVtQGFldGhlci1sYW... # 보안상 일부 생략
mail from: noreply@forum.aether-labs.fr
rcpt to: test-j0erqjxm2@srv1.mail-tester.com
data
subject: test smtp from inside


ok
.

… 하지만 discourse-doctor 명령어는 여전히 smtp-relay.sendinblue.com:587에 대한 연결이 실패했다고 보고합니다.

그래서 discourse-doctor 스크립트를 읽어보니, 해당 테스트가 emails:test라는 rake 작업과 연결되어 있음을 확인했고, lib/tasks/emails.rake에서 이 작업이 발견되었으며, "execution expired"라는 메시지가 실행이 만료되었을 때 발생한다는 것을 알게 되었습니다.

실행이 만료된 것으로 간주되기 전에 타임아웃 값을 변경할 수 있는 옵션이 있을까요?

수정: 아, app/services/email_settings_validator.rb 파일을 편집하여 타임아웃을 수동으로 30으로 설정하면 연결은 정상적으로 이루어지지만, 메일 전송은 여전히 실패합니다(이것은 TestMailer와 관련이 있는 것 같고, 이 값은 증가시킬 수 없을 것 같습니다…)

root@server-1-app:/var/www/discourse# rake emails:test[test-j0erqjxm2@srv1.mail-tester.com]
Testing sending to test-j0erqjxm2@srv1.mail-tester.com using smtp-relay.sendinblue.com:587, username:forum@aether-labs.fr with plain auth.
SMTP server connection successful.
Sending to test-j0erqjxm2@srv1.mail-tester.com. . . 
Sending mail failed.
execution expired

현재 이 인스턴스는 Discourse의 최소 요구사항(1 VCPU + 2GB RAM)에 맞춰져 있으므로, 더 나은 환경(예: 2 VCPU + 4GB RAM)으로 업그레이드해 보는 것도 방법일 것 같습니다.

환경 변수에 다음 항목이 있나요?

DISCOURSE_SMTP_ENABLE_START_TLS: true

기본값이므로 설정할 필요가 없지만, 혹시 꺼두신 건 아닌가요?

네, true로 설정되어 있습니다!
(이전 메시지를 편집하여 타임아웃 실험 내용을 추가했습니다…)

openssl 명령이 연결하고 TLS를 협상하는 데 얼마나 걸립니까?

거의 10초

real	0m9.798s
user	0m0.007s
sys	0m0.010s

와, 그건 정말 어마어마하게 긴 시간이네요.

호스트 시스템에서도 같은 시간이 걸리나요?

방금 테스트를 해보았습니다.
~10초 (Docker에서)
<1초 (호스트에서. 확실히 ctrl+D를 눌러 중지하기까지의 시간이지만, 정말 거의 순식간입니다)

이것은 합리적입니다.

컨테이너 네트워크에 근본적인 문제가 있는 것 같습니다… 이 두 명령은 동일한 시간이 걸려야 합니다:

(호스트에서):point_down:t3:

○ → time openssl s_client -starttls smtp -connect smtp-relay.sendinblue.com:587 </dev/null > /dev/null
depth=2 C = US, ST = New Jersey, L = Jersey City, O = The USERTRUST Network, CN = USERTrust RSA Certification Authority
verify return:1
depth=1 C = GB, ST = Greater Manchester, L = Salford, O = Sectigo Limited, CN = Sectigo RSA Domain Validation Secure Server CA
verify return:1
depth=0 CN = *.sendinblue.com
verify return:1
250 STARTTLS
DONE

real	0m0.277s
user	0m0.007s
sys	0m0.011s

(docker를 통해):point_down:t3:

○ → docker run --rm discourse/base:2.0.20231023-1945 bash -c 'time openssl s_client -starttls smtp -connect smtp-relay.sendinblue.com:587 </dev/null' > /dev/null
depth=2 C = US, ST = New Jersey, L = Jersey City, O = The USERTRUST Network, CN = USERTrust RSA Certification Authority
verify return:1
depth=1 C = GB, ST = Greater Manchester, L = Salford, O = Sectigo Limited, CN = Sectigo RSA Domain Validation Secure Server CA
verify return:1
depth=0 CN = *.sendinblue.com
verify return:1
250 STARTTLS
DONE

real	0m0.239s
user	0m0.006s
sys	0m0.000s

아니에요 :sob:

root@server-1:/var/discourse# time openssl s_client -starttls smtp -connect smtp-relay.sendinblue.com:587 </dev/null > /dev/null
depth=2 C = US, ST = New Jersey, L = Jersey City, O = The USERTRUST Network, CN = USERTrust RSA Certification Authority
verify return:1
depth=1 C = GB, ST = Greater Manchester, L = Salford, O = Sectigo Limited, CN = Sectigo RSA Domain Validation Secure Server CA
verify return:1
depth=0 CN = *.sendinblue.com
verify return:1
250 STARTTLS
DONE

real	0m0.126s
user	0m0.003s
sys	0m0.007s
root@server-1:/var/discourse# docker run --rm discourse/base:2.0.20231023-1945 bash -c 'time openssl s_client -starttls smtp -connect smtp-relay.sendinblue.com:587 </dev/null' > /dev/null
depth=2 C = US, ST = New Jersey, L = Jersey City, O = The USERTRUST Network, CN = USERTrust RSA Certification Authority
verify return:1
depth=1 C = GB, ST = Greater Manchester, L = Salford, O = Sectigo Limited, CN = Sectigo RSA Domain Validation Secure Server CA
verify return:1
depth=0 CN = *.sendinblue.com
verify return:1
250 STARTTLS
DONE

real	0m8.125s
user	0m0.007s
sys	0m0.000s

… 도커를 제거하고 다시 설치해야 할까요?
저는 apt 명령어를 몇 개 실행했을 뿐이고, docker-ce에서 기본적으로 설치된 상태로 두었기 때문에 무엇이 잘못되었는지 모르겠습니다…

제가 유일하게 변경한 부분은 처음에 “unknown host” 오류가 발생해서 다른 게시글에서 제안한 대로 DNS를 추가한 것입니다.

root@server-1:/var/discourse# cat /etc/docker/daemon.json
{
  "dns": ["83.166.143.51", "83.166.143.52", "8.8.8.8"]
}

OK, 작동합니다!

/etc/docker/daemon.json 파일을 수정하여 Google DNS(8.8.8.8)를 마지막이 아닌 첫 번째로 배치했고, STARTTLS에 대해 적절한 응답 시간을 얻었습니다… 그리고 discourse-doctor가 이메일을 성공적으로 보냈습니다 :slight_smile:

@supermathie 와 @pfaffman 님, 시간 내주셔서 정말 감사합니다.

다른 게시글에도 Google이 목록에서 가장 앞에 있어야 한다는 메모를 추가하겠습니다!

모든 제안이 모든 상황에 적용되는 것은 아닙니다. 그것이 바로 남의 조언을 그저 그 사람에게 효과가 있었기 때문에 그대로 채택하는 것의 위험이기도 합니다.

당신의 경우, 구글 네임서버가 ISP에서 제공하는 것보다 더 신뢰할 수 있는 것 같으므로, 구글 네임서버를 사용하는 것이 좋습니다.