CAA 레코드로 인증서 발급 제한하기

CAA 레코드는 어느 인증기관이 이 도메인의 SSL 인증서를 발급할 수 있는지 DNS에 적어 두는 레코드입니다. issue, issuewild, iodef 태그의 의미와 여러 기관을 함께 쓰는 방법, 갱신 실패를 피하는 점검 순서를 정리했습니다.

작성 최종 수정

CAA(Certification Authority Authorization) 레코드는 어느 인증기관이 이 도메인 이름으로 SSL/TLS 인증서를 발급할 수 있는지를 DNS에 적어 두는 레코드입니다. 인증기관은 인증서를 내주기 전에 반드시 이 값을 조회해야 하고, 목록에 자기 식별자가 없으면 발급을 거부합니다. 즉 CAA는 접속 암호화나 서버 설정과는 무관하고, 제3자가 우리 도메인 이름으로 인증서를 받아 가는 경로를 DNS 한 줄로 막아 두는 장치입니다.

CAA는 RFC 8659로 정의된 인터넷 표준 레코드이므로 특정 업체의 기능이 아니라 그 도메인의 존을 실제로 보관한 네임서버에 넣습니다. 따라서 설정 화면은 지금 도메인이 위임된 DNS 호스팅의 콘솔이고, 거기서 타입을 CAA로 고른 뒤 아래에 설명한 플래그, 태그, 값을 입력하면 됩니다.

아래 내용은 존을 어디에 두든 그대로 적용됩니다. 인증서 자체를 발급받고 서버에 적용하는 절차는 SSL 인증서 적용하기에 있습니다.

CAA 가 통제하는 것과 통제하지 않는 것

통제한다통제하지 않는다
앞으로 어느 인증기관이 이 이름의 인증서를 발급할 수 있는지이미 발급되어 유통 중인 인증서
와일드카드 인증서의 발급 허용 여부서버가 쓰는 TLS 버전이나 암호 방식
갱신 시점의 재발급 가능 여부인증서를 누가 서버에 올리는지
위반 시도를 통보받을 연락처브라우저의 신뢰 여부 판단

오해하기 쉬운 부분은 마지막 줄입니다. 브라우저는 접속할 때 CAA를 보지 않습니다. CAA 위반으로 발급된 인증서가 어떤 경로로든 존재한다면 브라우저는 그대로 신뢰합니다. CAA는 발급 단계의 사전 차단 장치이고, 이미 발급된 인증서를 찾아내는 일은 인증서 투명성 로그 모니터링의 영역입니다.

issue, issuewild, iodef 태그

레코드 하나는 플래그, 태그, 값 세 부분으로 구성됩니다.

example.co.kr.   3600   IN   CAA   0 issue "ca.example.net"
example.co.kr.   3600   IN   CAA   0 issuewild "ca.example.net"
example.co.kr.   3600   IN   CAA   0 iodef "mailto:security@example.co.kr"
태그의미비워 두면
issue일반 인증서를 발급할 수 있는 기관모든 기관이 발급 가능
issuewild와일드카드 인증서를 발급할 수 있는 기관issue 목록이 와일드카드에도 적용
iodef허용되지 않은 발급 시도를 통보할 연락처통보 없음

값에 넣는 문자열은 인증기관이 문서에 명시한 식별자입니다. 비슷한 도메인 이름을 임의로 적으면 해당 기관이 자기 식별자를 찾지 못해 발급이 거부되므로, 쓰려는 기관의 안내 문서에 적힌 값을 그대로 복사하세요. 위 예시의 ca.example.net 은 설명용 자리표시자입니다.

세미콜론 하나만 값으로 넣으면 "아무 기관도 허용하지 않는다"는 뜻입니다. 인증서를 쓸 계획이 없는 도메인이나 와일드카드만 막고 싶을 때 씁니다.

example.co.kr.   3600   IN   CAA   0 issuewild ";"
parked.example.co.kr.   3600   IN   CAA   0 issue ";"

앞자리 플래그는 보통 0 입니다. 128 은 중요 표시로, 인증기관이 그 태그를 이해하지 못하면 발급을 거부해야 한다는 의미입니다. 특별한 이유가 없다면 0 을 쓰는 편이 안전합니다.

인증기관이 CAA 를 찾는 순서

인증기관은 인증서에 넣을 이름마다 CAA를 조회합니다. 요청한 이름에 레코드가 없으면 한 단계씩 상위로 올라가고, 처음 발견한 레코드 집합만 적용합니다.

인증서에 넣을 이름조회 순서적용되는 값
www.example.co.krwww.example.co.kr → example.co.kr → 상위처음 발견된 한 곳의 값만
*.example.co.krexample.co.kr → 상위issuewild 가 있으면 그것만
api.dev.example.co.krapi.dev → dev → example.co.kr처음 발견된 한 곳의 값만

상위 값은 더하기가 아니라 대체입니다. 서브도메인에 CAA를 하나 넣는 순간 apex 에 적어 둔 목록은 그 이름에 적용되지 않습니다. 예외를 두려고 서브도메인에 CAA를 추가할 때, 기존에 허용하던 기관을 함께 적지 않아 갱신이 막히는 사고가 여기서 생깁니다.

인증서에 이름이 여러 개 들어 있으면 모든 이름이 각각 통과해야 합니다. 한 이름만 막혀도 인증서 전체가 발급되지 않습니다.

여러 인증기관을 함께 쓸 때

기관을 여러 곳 허용하려면 레코드를 여러 개 나열합니다. 한 레코드에 값을 쉼표로 묶어 적는 방식이 아닙니다.

example.co.kr.   3600   IN   CAA   0 issue "ca.example.net"
example.co.kr.   3600   IN   CAA   0 issue "ca2.example.org"
example.co.kr.   3600   IN   CAA   0 issuewild "ca.example.net"

실무에서 기관이 여러 곳이 되는 상황은 대개 이렇습니다.

  • 웹은 호스팅 플랫폼이 자동 발급하고, 메일이나 내부 시스템은 별도 기관에서 받는 경우
  • CDN 이 자체 인증서를 발급하고 원본 서버는 다른 기관 인증서를 쓰는 경우
  • 기관을 교체하는 과도기. 새 기관을 먼저 추가하고, 옛 인증서가 모두 교체된 뒤에 옛 기관을 지웁니다
  • 인증서를 직접 구매해 넣는 경로와 자동 갱신 경로가 함께 있는 경우

기관을 바꿀 때는 순서가 중요합니다. 새 기관을 먼저 추가해 두고 발급이 성공하는 것을 확인한 다음 옛 기관을 제거하세요. 순서를 뒤집으면 전환 중에 갱신 시점이 겹쳐 인증서 발급이 막힙니다.

ACME 계정까지 좁히기

자동 발급을 쓰는 환경에서는 같은 인증기관의 다른 계정이 우리 도메인 인증서를 받는 것까지 막을 수 있습니다. accounturi 로 허용할 ACME 계정을 지정하고, validationmethods 로 허용할 검증 방식을 제한하는 방법입니다.

example.co.kr.   3600   IN   CAA   0 issue "ca.example.net; accounturi=https://acme.example.net/acct/12345"
example.co.kr.   3600   IN   CAA   0 issue "ca.example.net; validationmethods=dns-01"

accounturi 는 특정 ACME 계정만, validationmethods 는 특정 검증 방식만 허용합니다. 예를 들어 DNS 방식만 허용해 두면 서버에 파일을 올릴 수 있는 사람이 임의로 인증서를 받아 가는 경로가 막힙니다. 다만 이 매개변수는 인증기관이 지원해야 동작하므로, 쓰려는 기관이 지원하는지 먼저 확인하고 값도 그 기관의 계정 주소 형식을 그대로 써야 합니다. 지원하지 않는 기관은 알 수 없는 매개변수를 무시할 수 있어 의도한 제한이 걸리지 않습니다.

설정 후 확인과 갱신 실패 피하기

넣은 값이 실제로 응답되는지 먼저 확인합니다. 인증서에 들어갈 이름과 그 상위 이름을 모두 봐야 합니다.

dig CAA example.co.kr +short
dig CAA www.example.co.kr +short
dig @ns1.example-dns.com CAA example.co.kr +noall +answer

# 레코드가 없을 때의 정상 응답은 status: NOERROR 에 답이 비어 있는 형태입니다
dig CAA example.co.kr +noall +comments +answer

조회가 아예 실패하는 상태가 가장 위험합니다. 인증기관은 CAA 조회가 실패하면 발급을 허용하지 않아야 하므로, 네임서버가 CAA 질의에 오류를 돌려주거나 DNSSEC 검증이 깨진 상태면 인증서를 받을 수 없습니다. DNSSEC를 쓰고 있다면 서명 상태도 함께 점검하세요. 관련 내용은 DNSSEC에 있습니다.

  • 지금 쓰는 인증서의 발급 기관 식별자를 확인하고 목록에 들어 있는지 본다
  • 와일드카드를 쓰고 있으면 issuewild 가 빠지지 않았는지 본다
  • 인증서에 들어가는 모든 이름에 대해 조회 결과를 확인한다
  • 자동 갱신을 쓰는 환경이면 시험 발급이나 다음 갱신 결과를 확인할 때까지 설정을 방치하지 않는다
  • 기관을 교체할 때는 새 기관을 먼저 추가하고 옛 기관은 마지막에 제거한다

인증서 관련 경고 화면의 원인을 단계별로 좁히는 방법은 SSL 오류 해결에, 레토 DNS에서 쓸 수 있는 레코드 타입과 입력 형식은 DNS 레코드 설정에 정리되어 있습니다.

자주 묻는 질문

추가할 수 없습니다. 레토 DNS는 CAA 레코드를 지원하지 않고, 대시보드의 타입 목록은 A, AAAA, CNAME, MX, NS, SRV, TXT 일곱 가지입니다. CAA가 필요하면 그 도메인의 존을 CAA를 지원하는 외부 DNS 호스팅으로 위임하고 그쪽 콘솔에서 넣으세요.

지정한 인증기관 외에는 그 도메인 이름으로 인증서를 발급할 수 없게 됩니다. 인증기관은 발급 직전에 CAA를 조회하고 목록에 자기 식별자가 없으면 발급을 거부해야 합니다. 이미 발급된 인증서나 접속 암호화 방식에는 영향이 없고, 앞으로의 발급과 갱신 단계만 제한합니다.

인증서 자동 갱신이 조용히 실패하고, 기존 인증서가 만료되는 시점에 사이트 전체가 경고 화면이 됩니다. 발급 기관을 바꿨거나 CDN을 새로 붙였는데 CAA를 그대로 둔 경우가 가장 흔합니다. 설정 직후와 갱신 주기가 한 번 돌 때까지는 발급 로그를 확인하는 편이 안전합니다.

issuewild 태그가 하나라도 있으면 와일드카드 발급은 issuewild 목록만 보고 판단합니다. issuewild 가 전혀 없으면 issue 목록이 와일드카드에도 함께 적용됩니다. 와일드카드를 아예 막고 싶다면 issuewild 값에 세미콜론 하나만 넣으면 됩니다.

필요하지 않습니다. 인증기관은 요청한 이름에서 시작해 레코드가 나올 때까지 상위 이름으로 올라가며 찾으므로, apex 에 한 번 넣어 두면 아래 이름에 모두 적용됩니다. 다만 특정 서브도메인에 CAA를 따로 두면 그 이름은 자기 값만 보고 상위 값은 무시하므로, 예외를 만들 때만 개별 설정을 추가하세요.

관련 가이드