이 문제가 해결될 때까지 Discourse를 이전 버전(예: 2.8.0 안정판 또는 2.9.0 베타3)으로 "다운그레이드"할 수 있는 방법이 있을까요?
한 시간 반을 더 들여 이 문제를 파고들기로 했고, 원인을 찾은 것 같습니다.
이 문제는 Rails 7로의 전환과 관련이 있는 것으로 보이는데, 이 과정에서 net-smtp가 0.1.0에서 0.3.1로 업데이트되어 기본 설정이 변경되었습니다.
smtp 게멀이 net-smtp를 호출하는 방식은 enable_starttls_auto와 openssl_verify_mode를 비활성화하지 않으며, 활성화된 경우에만 활성화할 뿐입니다.
잘하셨네요, Richard! 저라면 두 시간, 아니 그 두 배는 걸렸을 거예요. 제 입장에서는 새로운 기본값을 받아들이는 쪽이 더 쉽습니다.
아하. 그래서 제가 어느 정도 맞았던 거군요. 다만 PR을 통해 수정하는 것이 그렇게 어렵지는 않을 것 같습니다.
잘하셨네요 @RGJ!
수정 사항을 기다리는 동안, 부수적으로 이 문제가 제가 경험한 연쇄 장애로 이어지지 않는 것이 좋겠습니다. 이 문제는 포럼이 거의 완전히 다운될 뻔했습니다. 구체적으로 말씀드리면:
- 이메일 실패가 매우 빠르게 재시도되는 것 같습니다. 이로 인해 sidekiq 큐의 크기가 급증하고, 이러한 작업으로 인해 CPU 사용률이 약 100%까지 치솟았습니다.
- 또한, 무엇인가(크래시 또는 재시작)가 Redis가 거대한 임시 파일을 쓰도록 유발했습니다. 이 파일에는 sidekiq 큐의 상태가 포함되어 있다고 추정됩니다. 이러한 파일은 삭제해도 안전했지만, 디스크를 빠르게 채워 추가적인 크래시를 유발하는 등 악순환이 이어졌습니다. 저는 포럼을 재시작하고 원인을 파악할 수 있도록 다른 디스크 공간을 확보할 수 있었지만, 모든 사용자에게 해당되는 일은 아닐 수 있습니다. (이 경우 Redis 임시 파일이 실제로 삭제해도 안전한지 확인하기도 다소 어렵습니다.)
제 추측으로는 가장 간단한 해결책은 실패한 이메일 작업의 재시도를 늦추는 것입니다. 적어도 비밀번호 재설정처럼 시급성이 없는 작업의 경우입니다. 이메일 문제는 빠르게 해결되지 않을 가능성이 높고, 대부분의 메일러는 메시지를 수신한 후 자체적으로 재시도를 수행하기 때문에 적절한 접근 방식인 것 같습니다.
저의 경우, 업그레이드 후 장애가 발생했을 때 제3자 서버와 TLS를 사용하고 있었으며, 인증서의 이름은 SMTP 서버 이름과 일치했습니다. 다만 장애는 한 번만 발생했습니다. 추가적인 문제를 피하기 위해 이후로 재부팅이나 업그레이드를 하지 않았습니다. 패치가 배포되면 업데이트를 시도해 보고 어떻게 되는지 확인해 보겠습니다.
#contribute:bug에서 토픽을 만들어 시작할 예정이지만, 기술적으로 이는 상위(upstream) 제임(gem)의 문제이므로 이 문제가 얼마나 우선순위를 가질지 확신할 수 없습니다.
+1
정말 짜증나는 버그입니다
게임을 롤백할 수 없나요? 이메일 전송이라는 핵심 기능이 문제인 만큼, 주목을 받지 않을 것이라고는 생각하기 어렵습니다. 게다가 일부 사용자의 경우 임시 파일과 CPU 과부하로 인해 서버 장애가 발생하고 있습니다. 포럼의 핵심 안정성이 무너지고 있는 상황입니다.
이 문제는 메일 서버를 적절히 구성하면 쉽게 해결할 수 있다는 점도 잊지 마세요.
AFAIK(제가 아는 한) 내 서버는 올바르게 구성되어 있습니다. 인증서 이름이 SMTP 호스트 이름과 일치하며, 포트 587에서 STARTTLS가 활성화되어 있습니다. 왜 이런 문제가 발생했는지 궁금합니다.
새로운 티켓을 열어 주셔서 감사합니다. YML 파일에서 언급하신 두 변수의 조합에 대해, 다양한 시나리오에서 어떻게 사용해야 하는지 좀 더 자세히 설명해 주실 수 있을까요?
DISCOURSE_SMTP_ENABLE_START_TLS: true
DISCOURSE_SMTP_OPENSSL_VERIFY_MODE: none
예를 들어, 보안상의 이유로 포트 587에서 STARTTLS만 사용하고 다른 포트는 SMTP에 사용하지 않는 경우입니다. 이 경우 두 변수 모두 YML 파일에 지정해야 하는지, 아니면 하나만 지정하면 되는지 궁금합니다.
상황에 따라 다릅니다.
SMTP 서버가 올바르게 구성되어 있다면 둘 다 필요하지 않을 수 있습니다.
하지만 현재 문제는 그것들이 전혀 작동하지 않는다는 것입니다.
SMTP 서버 이름을 개인 메시지로 보내주시면 확인해 보고 왜 작동하지 않는지 찾아보겠습니다.
TLS/SSL 지원이 없는 로컬 SMTP 서버가 있고, StartTls=false로 설정해도 작동하지 않습니다 ![]()
좋은 지적이지만, 항상 우리의 메일 서버인 것은 아닙니다. 다른 팀이 관리하는 내부 메일 서버를 사용 중이므로, 인증서 문제나 메일 서버 설정에 대한 통제 권한이 없습니다.
그럼에도 불구하고, 이 문제로 어려움을 겪고 있는 다른 분들을 위해 하나의 옵션은 로컬호스트에 자체 메일 서버를 설정하고 메일을 단순히 전달하도록 하는 것입니다. 이렇게 하면 Discourse가 통신하는 메일 서버를 직접 통제할 수 있으며, 로컬호스트의 메일 서버는 상류(upstream)에서 발생할 수 있는 다양한 문제를 처리하도록 구성할 수 있습니다. 저는 이전에 이렇게 설정해 두었으나, Discourse가 상류 메일 서버와 직접 통신하는 것이 더 간단하다고 판단하여 어느 시점에 이를 제거했습니다. (아, 실수였네요.)
그 때문에 표준 설치에서는 기존 또는 자체 호스팅 솔루션을 사용하는 대신 서드파티 메일 제공업체를 권장합니다.
메일은 다양한 이유로 처리가 까다롭습니다. 오늘 당장 작동한다고 해서 올바르게 구성되었다고 볼 수 없으며, 단순히 잘못된 구성이 원래 목적에 영향을 미치지 않을 뿐입니다.
디스코urs를 선택한 이유는 작은 자체 호스팅 배포 환경에서 설치와 유지보수가 쉬울 것이라고 기대했기 때문입니다.
추천 사항을 따르시라면 그렇습니다.
다른 경로를 선택하신다면 어떤 보증을 드리기 어렵습니다.
요약하자면, Discourse를 사용할 때 TLS, SSL 또는 StartTLS 없이 SMTP 서버를 사용할 수 없다는 말씀이신가요?
그 누구도 그런 제안을 하고 있는 것이 아닙니다. 이는 해당 문제가 어떻게 발생했는지, 그리고 근본 원인을 찾는 데 시간이 걸렸다는 점과만 관련이 있습니다.
여기서 소수의 사례만 확인되는 이유는, 업데이트된 gem을 설치하면서도 어떤 형태의 보안 전송을 통해 메일을 중계하지 않는 설치 환경이 상대적으로 적기 때문입니다.
Richard는 이미 해당 버그에 대한 주제를 시작했습니다:
이 기능이 더 빨리 작동하기를 원하는 경우 메일 서버에서 TLS를 활성화하거나, 보안 전송을 제공하는 메일 프로바이더로 일시적으로 전환할 수도 있습니다.
저는 처음부터 유효한 인증서와 호스트명이 일치하도록 TLS를 활성화해 두었습니다. 그런데 BETA 4 (461936f211) 업그레이드 이후에 문제가 발생했고, 아래 주제에 로그를 게시했습니다. 다른 사용자도 문제를 겪고 있다고 하며, 그에 따르면 그의 인증서도 정상 상태라고 합니다:
저도 그렇게 들립니다. 이 스레드의 일부 댓글은 정말 화가 날 정도로 불쾌했습니다.
저는 Docker-Discourse를 셀프 호스팅하고 있으며, Docker 호스트를 이메일 서버로 사용하고 있습니다. 6년 전부터 Discourse가 포트 25를 사용하고 TLS 없이 내부 Docker 인터페이스를 통해 이메일을 전달하도록 설정해 왔습니다. 이는 완벽하게 합리적이고 안전한 구성입니다. 모든 트랜잭션은 제 호스트 내부에서만 이루어졌습니다. 이전 구성은 스레드 상단을 참고해 주세요.
제 경우, 문제를 해결하기 위해 다음과 같은 우회 방법을 사용했습니다:
내 도메인의 DNS 존 파일에 호스트의 내부 Docker 인터페이스 IP 주소를 유효한 호스트로 추가했습니다. 즉:
discourse-mail.jag-lovers.com A 172.17.0.1
참고: 저는 와일드카드 인증서(CN = *.jag-lovers.com)를 사용하므로 jag-lovers.com 도메인 내에서 임의의 호스트명을 만들어도 됩니다. 와일드카드 인증서가 없다면, 인증서에 유효한 CN 또는 SAN으로 등록된 호스트명을 반드시 사용하세요.
또한 참고할 점: 위에서 사용한 IP 주소는 제 호스트가 Discourse-Docker 컨테이너와 통신하기 위해 Docker 인터페이스에서 사용하는 내부 IP 주소입니다. 이는 사설(비라우터블) IP 주소입니다.
다음으로, Discourse의 app.yml 설정을 변경하여 방금 만든 호스트명으로 연결하고, TLS를 사용하며, 포트 587로 연결하고, 각 이메일 트랜잭션마다 호스트에 로그인하기 위해 SASL을 사용하도록 설정했습니다(그렇지 않으면 ‘relaying denied’ 오류 메시지가 발생합니다).
DISCOURSE_SMTP_ADDRESS: discourse-mail.jag-lovers.com
DISCOURSE_SMTP_PORT: 587
DISCOURSE_SMTP_USER_NAME: REDACTED
DISCOURSE_SMTP_PASSWORD: "REDACTED"
DISCOURSE_SMTP_ENABLE_START_TLS: true # (선택 사항, 기본값 true)
DISCOURSE_SMTP_OPENSSL_VERIFY_MODE: none
DISCOURSE_SMTP_DOMAIN: jag-lovers.com
마지막으로, Discourse를 다시 빌드했습니다. 이렇게 하면 제 경우 문제가 해결되었습니다.