Redsift에서 인증서가 일주일 안에 만료된다는 알림을 받았습니다. 보통 Discourse는 충분한 시간 전에 인증서를 갱신합니다. 이번에는 그렇지 않았고, 문제를 해결하기 위해 재빌드(이슈를 해결할 것으로 예상됨)를 시작하기 전에 @Falco 님, 인증서가 갱신되지 않은 근본적인 원인을 파악하는 데 도움이 되도록 확인하고 여기에 게시할 사항이 있나요?
discourse-docker에서 web.ssl.template이 올바르게 작동하는지 누군가 재확인해 주시면 좋겠습니다. 제 판단으로는 포트 80이 Let’s Encrypt가 사용하는 /.well-known/ URL을 실제로 서빙하지 않는 것 같았습니다. /var/www/discourse/public/.well-known/에 수동으로 배치한 테스트 파일까지 포함하여 모든 URL이 SSL로 포워딩되고 있었습니다. 결국 앱 컨테이너 내부에서 /etc/nginx/conf.d/outlets/before-server/20-redirect-http-to-https.conf 파일을 직접 수정해야 했습니다.
바닐라 nginx 설치 환경(1.18.0, 1.26.3에서도 동일할 것으로 보임)에서 테스트해 본 결과, location 블록 외부에 return 301 https://thehostname$request_uri;를 작성하면, catch-all이 아니라 그 앞에 있는 모든 location 블록을 완전히 무시하는 것으로 확인되었습니다. /.well-known/는 301 리다이렉트가 서버 블록의 마지막에 /와 같은 다른 location을 대상으로 하지 않는 한, 포트 80에서 단순히 제공되지 않는 것 같습니다. 이는 이 Stack Overflow 게시물과 동일한 문제일 수 있습니다.
rebuild가 작동하는 것은 다행이지만, 제 경우 인증서가 이미 갱신되어 있었기 때문에, 인증서가 만료된 상태였다면 rebuild가 Let’s Encrypt 검증 서버가 해당 경로에 도달할 수 있게 해주는지 확인할 수 없었습니다. 템플릿을 수정하는 것이 아니라, 해당 템플릿 라인이 적용되기 전에 인증서 갱신을 시작하는 등 rebuild가 갱신을 가능하게 하는 다른 원인이 있을 수 있지만, 이것이 rebuild로 갱신이 작동하는 이유인지는 확인할 수 없습니다.
첫째, return 301 https://${DISCOURSE_HOSTNAME}$request_uri;가 끝에 $request_uri 없이 return 301 https://<내 서버 이름>으로 변환됩니다. 제 셀프호스팅 설치 환경과 지난주에 설정한 친구의 셀프호스팅 설치 환경에서 모두 확인했습니다. Discourse 템플릿이 어떻게 작동하는지 이해하지 못하므로, 왜 이것이 제거되는지 알 수 없습니다.
둘째, @lessLost가 언급했듯이, 301 리다이렉트는 location 블록 밖에 있습니다. 서버 레벨의 리다이렉트가 모든 location 블록을 무시한다고 생각합니다. LetsEncrypt는 갱신에 http를 사용합니다. 그러나 curl -I http://YOUR_DOMAIN/.well-known/acme-challenge/test를 실행하면 404(예상되는 동작; 301이 아닌 404가 필요합니다) 대신 https로 301이 반환됩니다.
제 셀프호스팅 설치 환경에서는 수동으로 이 문제를 수정했지만, 업데이트 시 제 변경 사항이 덮어써질 것으로 예상됩니다. 불행히도 템플릿을 충분히 이해하지 못해 @pfaffman에게 풀 리퀘스트를 제출할 수 없습니다 — 할 수만 있다면 그렇게 할 것입니다.
수정하여 추가:
이것은 오해인 것 같습니다 —
LetsEncrypt가 기본적으로 http를 사용한다는 것에 대해 상당히 확신합니다(명확한 이유: 인증서가 만료되면 갱신할 수 없으므로!). 하지만 서버 블록 레벨에 301을 배치하면 모든 요청이 https로 301되도록 강제되며, 이는 이 갱신 전략과 일치하지 않습니다.
수정 2: http 갱신 전략에 대한 증거, 하지만 이것을 확인하기 위해 구글에서 검색해 보실 수도 있습니다.
제 친구의 새 사이트 설치는 일주일 전이었습니다. 위의 템플릿 37번째 줄은 return 301 https://${DISCOURSE_HOSTNAME}$request_uri;라고 되어 있지만, Discourse Docker 컨테이너에서 그녀의 (그리고 제) /etc/nginx/conf.d/outlets/before-server/20-redirect-http-to-https.conf 파일은 return 301 https://<our_discourse_site>;라고 되어 있습니다. $request_uri가 제거되어 있는 것을 주목하세요. 무언가가 이를 사라지게 하고 있습니다! (무엇인지 모르겠지만).
조사 과정의 일환으로 오늘 아침에 강제 갱신을 시뮬레이션했습니다. 실패했습니다. 그런 다음 /etc/nginx/conf.d/outlets/before-server/20-redirect-http-to-https.conf를 변경했습니다. 성공했습니다!
사실 이건 괜찮습니다. Discourse를 업데이트할 때마다 20-redirect-http-to-https.conf를 수동으로 편집하면 됩니다. 이 댓글에 부딪히는 분들을 위해, 실행해야 하는 명령어는 다음과 같습니다:
이 실패의 원인이 무엇인지 완전히 확신은 하지 못하지만, 위의 conf를 수정하면 해결된다는 것은 알고 있습니다. 또한, letsencrypt 갱신이 더 이상 조용히 실패하지 않도록 notifs도 수정했습니다 — 그래서 사전에 몇 가지 경고를 받을 수 있습니다. 알려드리고 싶어서요!