이것은 예상보다 오래 걸린 디버깅이었습니다.
설정
Caddy를 systemd 기반 리눅스 머신에서 리버스 프록시로 실행 중입니다. ACME를 통해 인증서 갱신 중입니다. 로그에는 모든 것이 정상적으로 보입니다. 그런데 어느 날 인증서가 만료되었고, 두 날 동안 누구도 눈치채지 못했습니다.
원인
systemd-resolved는 upstream resolver 상황에 따라 특정 DNS 쿼리에 대해 SERVFAIL을 반환하는 동작을 가지고 있습니다. 일관성이 없습니다. 일부 영역은 잘 해결되지만, 일부는 침묵으로 실패합니다. Caddy의 ACME 클라이언트가 챌린지 요청을 보내면, systemd-resolved는 실패를 보고하며, 갱신이 그냥 일어나지 않습니다.
이것이 귀찮은 것은 systemd-resolve --status에서 아무것도 잘못된 것처럼 보이지 않는다는 점입니다.dig는 8.8.8.8에 대해 잘 작동할 수 있습니다. 스타브 리졸버가 사용자의 애플리케이션을 속이고 있으며, 유용한 곳에 로그를 남기지 않습니다.
수정 방법
이를 처리하는 세 가지 방법:
1. 스타브 리졸버를 무시합니다
Caddy(또는 Go의 네트워크 스택 일반)를 공개 리졸버에 직접 지정합니다. Caddyfile에서:
{
servers :443 {
dns resolver 1.1.1.1
}
}
또는 GODEBUG=netdns=go를 설정하여 Go 리졸버를 강제하고 시스템 리졸버 구성을 신뢰하지 않도록 하세요.
2. systemd-resolved를 재시작하세요.
systemctl restart systemd-resolved는 그것이 모은 손상된 상태를 지웁니다. 이것은 일시적인 해결책입니다 — 다시 마주하게 될 것입니다.
영구적으로는 /etc/resolv.conf를 확인하고 모든 것에 대해 stub 리졸버에 의존하지 않고 있는지 확인하세요.
3. DNS-over-HTTPS를 사용하세요.
해결된 상태로 남아서 더 취약하지 않게 하려면, 평범한 UDP 대신 DoH 업스트림을 사용하도록 구성하세요. SERVFAIL 상황은 해결하지 못하지만, MITM 문제의 한 클래스를 피할 수 있습니다.
알아두어야 할 증상
특정 증상: Caddy 로그는 갱신 실패라고 합니다만, 명백한 이유를 제공하지 않습니다.caddy list은 인증서가 곧 만료될 것임을 보여줍니다. 나머지 모든 것이 작동 중입니다. 브라우저는 인증서 만료 경고를 캐시하기 때문에 사용자들이 불평을 멈추지만—그리고 그것이 월요일 아침에 당신의 문제가 됩니다.
결론
Caddy를 systemd-resolved에서 실행 중이고 인증서가 예기치 않게 만료되고 있다면, 다른 것을 확인하기 전에 스텀프 리졸버를 확인하세요. "DNS가 작동하고 있기 때문에"라는 이유로 숨겨진 종류의 실패입니다.
후원하지 않음. 그냥 오후를 낭비한 것뿐.












