NET::ERR_CERT_COMMON_NAME_INVALID 원인별 해결 — 도메인과 인증서가 안 맞을 때

NET::ERR_CERT_COMMON_NAME_INVALID 는 이름과 달리 Common Name 을 보는 에러가 아니다. Chrome 은 인증서의 Common Name 을 보지 않은 지 오래다. 이 에러가 말하는 것은 하나다 — 서버가 내민 인증서의 SAN(subjectAltName) 목록에 주소창의 이름이 없다.

발급자가 믿을 만한지와는 별개다. 공인 CA 가 발급한 멀쩡한 인증서여도 이름이 안 맞으면 이 화면이 뜬다. 그래서 AUTHORITY_INVALID 와 달리 원인이 대개 서버 쪽에 있다. 인증서의 이름 목록이 틀렸거나, 서버가 맞는 인증서를 두고 엉뚱한 인증서를 내보내고 있거나.

에러의 정체

Chrome 내부 코드는 -200 이다. 바로 옆 번호들과 함께 보면 이렇다.

에러 코드 번호 의미
ERR_CERT_COMMON_NAME_INVALID -200 접속한 이름이 인증서에 없음
ERR_CERT_DATE_INVALID -201 유효기간 밖
ERR_CERT_AUTHORITY_INVALID -202 신뢰 경로를 못 만듦

-202 와 헷갈린다면 NET::ERR_CERT_AUTHORITY_INVALID 원인별 해결 의 구분표부터 본다.

Chromium 소스의 이 에러 정의에는 원인 후보 네 가지가 주석으로 달려 있다.

  1. 공격자가 트래픽을 다른 곳으로 돌렸다
  2. 서버 설정이 잘못돼 엉뚱한 인증서로 응답한다
  3. 무선망 로그인 페이지(캡티브 포털)로 끌려갔다
  4. OS 가 DNS 검색 접미사를 붙였는데, 서버에 주소창의 짧은 이름용 인증서가 없다

서버 운영자가 고칠 수 있는 건 2번과 4번이다. 3번은 호텔·카페 와이파이에서 망 로그인 전에 HTTPS 사이트를 열 때 나온다. 망 로그인을 마친 뒤 다시 열어 본다.

경고 화면이 이미 답의 절반을 준다

경고 화면의 상세 문구는 이렇다(영문 UI 기준).

This server could not prove that it is www.example.com;
its security certificate is from example.com.

앞은 주소창의 이름, 뒤는 서버가 실제로 내민 인증서의 이름 중 대표 하나(CN 과 같은 SAN, 없으면 첫 번째 SAN)다. 뒤쪽 이름을 보면 방향이 잡힌다.

  • 우리 도메인의 변형(example.com ↔ www.example.com) → 인증서의 이름 누락
  • 전혀 모르는 이름(호스팅 플랫폼 기본 도메인, 같은 서버의 다른 사이트) → 서버가 엉뚱한 인증서를 내보내는 중

인증서에 DNS SAN 이 아예 없으면 문구가 달라진다.

This server could not prove that it is www.example.com;
its security certificate does not specify Subject Alternative Names.

이 문구면 CN 전용 인증서다(원인 2).

30초 판별 — SAN 목록을 직접 본다

OpenSSL 1.1.1 이상이 필요하다. macOS 기본 /usr/bin/openssl 은 LibreSSL 이라 -ext 를 지원하지 않는다. Homebrew 의 openssl@3 를 쓴다.

openssl s_client -connect www.example.com:443 -servername www.example.com </dev/null 2>/dev/null \
  | openssl x509 -noout -subject -ext subjectAltName

-connect 와 -servername 에 모두 주소창에 친 이름을 그대로 넣는다. -servername 은 브라우저가 SNI 로 보내는 값이고, -connect 에도 같은 이름을 줘야 DNS 로 브라우저가 실제로 가는 IP 에 붙는다. www 와 apex 가 서로 다른 서버(CDN·원서버)를 가리키는 구성이면 이름이 하나만 달라도 엉뚱한 서버를 검사하게 된다.

단, 주소창이 IP 면 -servername 을 빼고 -connect IP:443 만 쓴다(원인 4).

subject=CN=example.com
X509v3 Subject Alternative Name:
    DNS:example.com

OpenSSL 3.1 이하에서는 subject=CN = example.com 처럼 = 앞뒤에 공백이 붙는다.

읽는 법:

SAN 출력 원인
www 와 apex 중 한쪽만 있음 이름 누락 (원인 1)
SAN 줄이 없음, No extensions in certificate(1.1.1 은 No extensions matched with subjectAltName) CN 전용 인증서 (원인 2)
*.example.com 뿐인데 접속은 example.com·a.b.example.com 와일드카드 범위 밖 (원인 3)
w*.example.com, *.intranet 같은 형태 Chrome 이 거부하는 와일드카드 (원인 3)
IP 로 접속했는데 IP Address: 항목이 없음 IP 접속 (원인 4)
전혀 다른 도메인 기본 인증서 응답 (원인 5·6)
접속한 이름이 있음 여기서는 정상. 실패하는 PC 의 DNS·망, 또는 주소창의 이름을 본다 (원인 7)

함정 — OpenSSL·curl 은 Chrome 보다 관대하다

호스트명 검사 옵션으로 한 번에 끝내고 싶어진다. OpenSSL 에는 두 가지가 있다.

# 파일로 받은 인증서 검사
openssl x509 -in cert.pem -noout -checkhost www.example.com

# 핸드셰이크 중 검사
openssl s_client -connect www.example.com:443 -servername www.example.com \
  -verify_hostname www.example.com -verify_return_error -brief </dev/null

불일치면 verify error:num=62:hostname mismatch, 일치하면 Verified peername: www.example.com 이 나온다. 단 공인 인증서일 때 얘기다. 사설 CA·자체 서명이면 체인 검증이 먼저 실패해 num=18(self-signed)·19·20 에서 끝나고 이름 판정까지 가지 않는다. -CAfile <루트.pem> 을 함께 줘야 62 여부가 나온다.

이 결과를 Chrome 결과로 읽으면 안 된다. OpenSSL 의 호스트명 검사는 기본값에서 세 가지를 Chrome 보다 느슨하게 본다.

  • CN 폴백 — DNS 타입 SAN 이 하나도 없으면(IP SAN 만 있어도) subject 의 CN 을 본다. OpenSSL 백엔드 curl 도 SAN(dNSName·iPAddress)이 둘 다 없으면 CN 으로 폴백한다
  • 부분 와일드카드 — w*.example.com 이 www.example.com 에 맞는다고 판정한다. curl 은 부분 와일드카드를 거부한다
  • 공개 접미사 — *.co.uk 가 example.co.uk 에 맞는다고 판정한다(Chrome 은 거부)

그래서 CN 전용 인증서를 검사하면 이런 결과가 나온다.

$ openssl x509 -in cn-only.pem -noout -checkhost www.example.com
Hostname www.example.com does match certificate

$ openssl x509 -in cn-only.pem -noout -ext subjectAltName
No extensions in certificate

OpenSSL 은 맞다고 하고, Chrome 은 -200 을 낸다. 최종 판단은 -ext subjectAltName 출력으로 한다. 접속 이름이 SAN 에 글자 그대로 있거나, 왼쪽 첫 레이블 전체가 * 인 와일드카드로 덮여야 Chrome 기준으로 통과다.

원인 1 — SAN 에 그 이름이 없다 (www vs apex)

가장 흔하다. example.com 으로만 받은 인증서에 www.example.com 으로 들어오거나, 그 반대다. 서브도메인을 새로 열면서 인증서에 넣는 걸 잊은 경우도 같다.

Let’s Encrypt 라면 인증서별 이름 목록부터 본다.

sudo certbot certificates
  Certificate Name: example.com
    ...
    Identifiers: example.com

Certbot 5.1 이하는 이 줄이 Domains: 로 나온다. Identifiers(구버전 Domains)에 빠진 이름이 있으면 같은 인증서 이름으로 목록을 다시 지정한다.

sudo certbot certonly --cert-name example.com -d example.com,www.example.com
sudo systemctl reload nginx   # apache 면 apache2

-d 는 기존 목록에 더하는 게 아니라 목록 전체를 새로 지정한다. 기존 이름도 빠짐없이 다시 적는다. 빠뜨린 이름은 새 인증서에서 사라진다.

certonly 는 인증서 파일만 바꾼다. 웹서버를 reload 하기 전까지는 옛 인증서가 계속 나가므로 “재발급했는데 그대로”로 오진하기 쉽다. 갱신 때마다 자동으로 하려면 --deploy-hook "systemctl reload nginx" 를 붙인다.

상용 CA 인증서도 원리는 같다. 인증서는 서명된 문서라 SAN 만 고칠 수 없다. 두 이름을 모두 넣어 새로 발급받는다. 발급 절차는 인증서 발급 공통 가이드에 있다.

Chrome 이 이 문제를 가려 준다

www·apex 누락은 Chrome 에서 안 보일 때가 있다. Chrome 은 아래 조건이 모두 맞으면 경고 화면 대신 다른 URL 로 조용히 이동한다.

  • 에러가 이름 불일치 하나뿐이고, HSTS 등으로 경고 우회가 막힌 상태가 아니다
  • 인증서 SAN 에 주소창 이름에서 www 를 붙이거나 뗀 이름이 있다
  • 그 이름의 같은 경로 URL 에 보낸 HEAD 요청이 3초 안에 HTTPS 200 으로 응답한다 (301·302 리다이렉트면 해당 없음)

www.example.com 인증서만 있는 서버에 https://example.com 으로 들어가면 경고 없이 www 로 넘어간다. 주소창이 www 로 바뀌고, 이유는 개발자 도구 콘솔에 남는다.

Redirecting navigation example.com -> www.example.com because the server
presented a certificate valid for www.example.com but not for example.com.

그래서 “Chrome 에서는 되는데 curl·앱·서버 간 API 호출에서만 실패” 하는 사례가 생긴다. 다른 클라이언트는 이런 보정을 하지 않는다. curl(OpenSSL 백엔드)은 이렇게 끝난다.

curl: (60) SSL: no alternative certificate subject name matches target hostname 'example.com'

curl 8.8 이하는 target host name 으로 나오고, Windows 기본 curl(Schannel)은 SEC_E_WRONG_PRINCIPAL 처럼 문구가 아예 다르다.

Chrome 에서 열린다고 인증서가 맞는 게 아니다. 판별은 항상 위의 openssl 명령으로 한다.

원인 2 — CN 에만 있고 SAN 에 없다

-ext subjectAltName 에 아무것도 안 나오고 subject 의 CN 에만 도메인이 있는 인증서다. CN 이 접속 이름과 글자 하나 안 틀리고 같아도 Chrome 에서는 실패한다.

현재 Chrome 의 호스트명 검증은 SAN 의 dNSName·iPAddress 가 하나도 없으면 CN 을 열어 보지도 않고 바로 실패한다. Chrome 58(데스크톱 stable 2017년 4월 19일)에서 CN 매칭을 제거한 결과다. 갑작스러운 변경은 아니었다.

시점 문서·제품 내용
2000 RFC 2818 dNSName SAN 이 있으면 그것을 쓰고, 없을 때만 CN. CN 사용은 deprecated
2012~ CA/B Forum Baseline Requirements 공인 인증서에 SAN 필수
2017 Chrome 58 CN 매칭 제거
2023 RFC 9525 RFC 6125 대체. CN 으로 서비스를 식별하면 안 된다(MUST NOT)

Firefox 도 Firefox 48 부터 새 공인 인증서에 SAN 을 요구했다.

제거를 예고할 당시 Chrome 팀 집계로, 공인 인증서 검증의 0.002% 미만, 사설 CA 인증서의 1.57%(전체 검증 대비 0.1%)가 CN 폴백에 기대고 있었다. 공인 CA 는 BR 상 SAN 없이 발급할 수 없으므로, 지금 CN 전용 인증서가 나오는 곳은 사설 CA 와 자체 서명 쪽이다. 오래된 스크립트로 만든 내부 인증서, 장비 관리 페이지 인증서가 대표적이다.

처리 — SAN 을 넣어 다시 발급한다. OpenSSL 로 CSR 을 만든다면 -addext 로 넣는다.

openssl req -new -newkey rsa:2048 -nodes -keyout app.key -out app.csr \
  -subj "/CN=app.corp.example.com" \
  -addext "subjectAltName=DNS:app.corp.example.com"

-nodes 는 OpenSSL 3.0 부터 deprecated 이고 -noenc 가 대체다. 동작은 같다.

  • 사설 CA 가 CSR 의 SAN 을 그대로 반영하는지는 CA 설정에 따라 다르다. 발급된 인증서에서 -ext subjectAltName 을 반드시 다시 확인한다
  • 자체 서명이면 같은 명령에 -x509 -days 365 를 붙인다. CSR 대신 SAN 이 들어간 인증서가 바로 나온다(-out 파일명은 바꿔 둔다). -days 를 빼면 기본 30일이라 한 달 뒤 DATE_INVALID 로 다시 깨진다
  • CN 은 남겨도 된다. BR 은 CN 을 NOT RECOMMENDED 로 두고, 넣는다면 SAN 값 중 하나를 그대로 써야 한다고 정한다. 검증에는 쓰이지 않는다

원인 3 — 와일드카드: Chrome 은 RFC 보다 엄격하다

apex 를 안 덮는다, 한 단계만 덮는다 — 기본 규칙은 와일드카드 vs SAN 인증서, 언제 무엇을 쓰나에서 다뤘다. 여기서는 인증서는 만들어지는데 Chrome 에서만 막히는 형태를 본다.

Chrome 의 와일드카드 규칙은 짧다. 왼쪽 첫 레이블 전체가 정확히 * 일 때만 인정하고, 나머지 부분은 글자 그대로 일치해야 한다.

SAN 값 접속 이름 Chrome
*.example.com www.example.com ✅
*.corp.example.com wiki.corp.example.com ✅
*.example.com example.com ❌ apex 미포함
*.example.com a.b.example.com ❌ 한 단계만
w*.example.com www.example.com ❌ 부분 와일드카드
*.co.uk example.co.uk ❌ 공개 접미사
*.intranet wiki.intranet ❌ 미등록 TLD

부분 와일드카드. w*.example.com 같은 형태는 RFC 2818 이 허용했다(f*.com 이 foo.com 에 맞는다는 예시까지 있다). RFC 6125(2011)는 왼쪽 첫 레이블이 아닌 곳의 와일드카드는 SHOULD NOT 으로 막았지만, 첫 레이블 안의 부분 와일드카드(baz*.example.net)는 여전히 MAY 로 허용했다. 이를 대체한 RFC 9525 §6.3 에서 비로소 금지됐다.

  • 와일드카드 문자는 하나뿐이다
  • 왼쪽 첫 레이블의 전체 내용으로만 나타난다
  • 레이블 하나만 매칭한다

부분 와일드카드를 막는 점에서 Chrome 은 이 규칙과 같고, 아래 제약을 더 얹는다. 반면 OpenSSL 은 기본값에서 아직 부분 와일드카드를 받아 준다. OpenSSL 통과를 믿으면 안 되는 두 번째 이유다.

공개 접미사와 미등록 TLD. Chrome 은 공개 레지스트리 도메인(*.com, *.co.uk)에 대한 와일드카드를 인정하지 않는다(OpenSSL 은 *.co.uk 도 통과시킨다). 레지스트리 데이터셋에 없는 TLD(사내에서 쓰는 intranet 같은 이름)는 그 마지막 레이블을 레지스트리로 취급하므로 *.intranet 처럼 TLD 바로 아래 와일드카드가 막힌다. *.corp.intranet 처럼 한 단계 아래면 Chrome 도 받아 준다. 숫자로만 된 호스트명과 점이 없는 단일 레이블 이름에도 와일드카드 매칭을 하지 않는다.

공인 CA 는 이런 인증서를 애초에 못 낸다. BR 이 *.co.uk, *.local 같은 발급을 금지한다. BR 의 와일드카드 도메인명 정의도 *. 바로 뒤에 FQDN 이 오는 형태뿐이라 w*. 같은 부분 와일드카드는 공인 인증서에 들어갈 자리가 없다. 그래서 표의 아래쪽 행들은 사설 CA 로 사내 도메인 전체를 와일드카드 하나로 덮으려 할 때 나온다. 사내 전용 TLD 를 쓰고 있다면 호스트 이름을 SAN 에 나열하거나, 한 단계 아래 와일드카드를 쓴다. 다만 미등록 TLD 는 나중에 공개 TLD 와 이름이 겹칠 위험이 있으니 실제로 소유한 도메인 아래(*.corp.example.com)로 옮기는 편이 낫다.

원인 4 — IP 주소로 접속

https://203.0.113.10/ 처럼 IP 로 들어가면 규칙이 달라진다.

  • Chrome 은 IP 로 접속하면 SAN 의 iPAddress 항목만 비교한다. dNSName 에 203.0.113.10 이라는 문자열을 넣어도 매칭되지 않는다
  • SNI 에는 IP 를 넣을 수 없다(RFC 6066). 서버는 어떤 이름으로 들어왔는지 모른 채 기본 인증서를 준다

그래서 IP 접속은 거의 항상 엉뚱한 인증서를 받는다. 직접 확인할 수 있다.

openssl s_client -connect 203.0.113.10:443 </dev/null 2>/dev/null \
  | openssl x509 -noout -subject -ext subjectAltName

s_client 는 -connect 가 IP 면 SNI 를 보내지 않는다. 브라우저의 IP 접속과 같은 조건이다. 인증서 파일이 있다면 IP 매칭만 따로 검사한다.

openssl x509 -in cert.pem -noout -checkip 203.0.113.10

처리

  • 가장 간단한 건 이름으로 접속하게 하는 것이다. 모니터링 대상, 연동 설정, 북마크에 IP 가 박혀 있지 않은지 본다
  • IP 접속이 꼭 필요하면 iPAddress SAN 이 든 인증서를 쓴다. 사설 CA 라면 CSR 에 -addext "subjectAltName=IP:203.0.113.10" 식으로 넣는다
  • 공인 인증서도 선택지가 됐다. Let’s Encrypt 는 2026년 1월 15일부터 IP 주소 인증서를 정식 제공한다. 다만 IP 인증서는 shortlived 프로필(유효기간 160시간, 6일 남짓) 로만 나온다. 자동 갱신이 멈추면 일주일 안에 만료된다. 만료 감시 없이 쓰면 안 된다 — SSL 인증서 만료일 확인하는 방법

원인 5 — SNI 없이 들어온 요청: 기본 vhost 인증서

한 서버에 여러 도메인이 올라가 있으면, 서버는 TLS 핸드셰이크의 SNI 를 보고 줄 인증서를 고른다. TLS 연결은 HTTP 요청(Host 헤더)보다 먼저 맺어지므로 SNI 가 유일한 단서다.

SNI 가 없거나, SNI 이름과 맞는 server 블록이 없으면 nginx 는 그 listen 의 default server 인증서를 준다. 증상은 이렇게 나온다.

  • 새 도메인의 server_name 에 오타가 있다 → 기본 사이트의 인증서가 나간다
  • SNI 를 안 보내는 구형·특수 클라이언트만 실패한다. 브라우저는 멀쩡하다

SNI 를 끄고 재현한다.

openssl s_client -connect example.com:443 -noservername </dev/null 2>/dev/null \
  | openssl x509 -noout -subject -ext subjectAltName

여기서 우리 도메인이 아닌 인증서가 나오면 SNI 에 기대는 구성이다. CDN·호스팅 위의 사이트는 SNI 없이 붙으면 플랫폼 기본 인증서가 오거나 연결이 끊기는 경우가 흔하다. 한 CDN 문서는 SNI 로 도메인을 정하지 못하면 연결을 끊는다고 적는다.

테스트 도구 버전도 본다. s_client 는 OpenSSL 1.1.1 부터 -servername 을 안 줘도 -connect 의 이름을 SNI 로 보낸다. 그보다 오래된 OpenSSL 로 -servername 없이 테스트하면 SNI 없이 붙어서 멀쩡한 서버를 오진한다.

nginx 빌드의 SNI 지원 여부:

nginx -V 2>&1 | grep -i 'TLS SNI support'
# TLS SNI support enabled

처리

  • server_name 과 인증서 SAN 이 짝이 맞는지 본다. -connect·-servername 을 도메인마다 바꿔 가며 30초 판별 명령을 돌리면 어느 이름이 기본 인증서로 떨어지는지 보인다
  • 기본 server 가 엉뚱한 인증서를 주는 것 자체를 막을 수 있다. nginx 1.19.4 부터 ssl_reject_handshake 가 있다
server {
    listen 443 ssl default_server;
    ssl_reject_handshake on;
}

기존 server 블록에 이미 default_server 가 있으면 duplicate default server 오류로 설정 로드가 실패하니 그쪽을 떼고 추가한다. IPv6 로도 listen 한다면 listen [::]:443 ssl default_server; 를 같은 블록에 함께 넣는다.

SNI 가 어떤 server_name 과도 안 맞으면 다른 사이트 인증서를 내미는 대신 핸드셰이크를 거부한다. 사용자는 이름 불일치 경고 대신 명확한 연결 실패를 보고, 다른 도메인 이름이 인증서로 노출되지도 않는다. 대신 SNI 를 안 보내는 클라이언트는 확실히 끊긴다. 그런 클라이언트가 없는지 먼저 확인한다. nginx 설정 전반은 Nginx 가이드.

원인 6 — CDN·호스팅에 커스텀 도메인이 안 붙었다

경고 화면 뒤쪽 이름이 *.<플랫폼 기본 도메인> 형태면 여기다. CDN·정적 호스팅은 자기 기본 도메인용 와일드카드 인증서를 기본으로 내보내고, 커스텀 도메인용 인증서는 연결 설정을 마쳐야 나간다.

흔한 경로:

  • DNS 의 CNAME 은 이미 CDN 을 가리키는데, CDN 쪽에 대체 도메인 등록이나 인증서 연결을 안 했다
  • CDN 에 붙인 인증서가 그 도메인을 SAN 으로 덮지 못한다. 주요 CDN 문서도 대체 도메인을 추가하려면 그 이름을 SAN 으로 덮는 인증서가 필요하다고 명시하고, *.example.com 으로는 example.com 이나 marketing.product.example.com 을 추가할 수 없다고 적는다
  • SNI 를 안 보내는 클라이언트다. CDN 도 원인 5 와 같은 이유로 플랫폼 기본 인증서를 주거나 연결을 끊는다
  • 정적 호스팅에 커스텀 도메인을 막 연결했다. 한 호스팅 서비스 문서는 HTTPS 가 붙기까지 최대 1시간이 걸릴 수 있고, DNS 를 바꾼 뒤에는 커스텀 도메인을 지웠다 다시 추가해야 인증서 발급이 시작될 수 있다고 안내한다

DNS 를 전환하기 전에 새 엣지가 이 이름에 맞는 인증서를 주는지 확인한다. --resolve 는 DNS 를 거치지 않고 지정한 IP 에 이 이름으로 붙는다.

curl -sSv -o /dev/null --resolve www.example.com:443:203.0.113.10 https://www.example.com/

불일치면 curl: (60) SSL: no alternative certificate subject name matches target hostname 으로 끝난다(원인 1 의 버전·백엔드별 문구 차이 참고). -S 를 빼고 -s 만 주면 이 마지막 에러 줄이 숨고 종료 코드 60 만 남는다. 전환 뒤 사용자 브라우저에서 알게 되는 것보다 훨씬 싸다.

원인 7 — 사내 단축 호스트명

사내에서 주소창에 wiki 만 치고 들어가는 경우다. OS 가 DNS 검색 접미사 (corp.example.com)를 붙여 wiki.corp.example.com 으로 찾아가므로 서버에는 잘 닿는다. 하지만 Chrome 이 인증서와 비교하는 건 주소창의 이름 wiki 다. 인증서에 wiki.corp.example.com 만 있으면 -200 이다. Chromium 주석의 4번 원인이 정확히 이 경우다.

공인 인증서로는 풀 수 없다. BR 은 IANA 루트존에 등록된 TLD 로 끝나지 않는 이름 (Internal Name)이 든 인증서 발급을 금지한다. wiki 같은 단일 레이블 이름은 공인 CA 가 넣어 주지 않는다.

처리

  • FQDN 으로 접속하게 한다 — 사내 포털 링크·북마크·문서의 주소를 https://wiki.corp.example.com/ 으로 정리한다. 이 경우 공인 인증서도 쓸 수 있다
  • 단축 이름도 살려야 하면 사설 CA 로 SAN 에 둘 다 넣는다
openssl req -new -newkey rsa:2048 -nodes -keyout wiki.key -out wiki.csr \
  -subj "/CN=wiki.corp.example.com" \
  -addext "subjectAltName=DNS:wiki.corp.example.com,DNS:wiki"

단일 레이블 이름은 와일드카드로 덮을 수 없으니(원인 3) 이름마다 SAN 에 넣는다. 사설 CA 루트를 PC 들이 신뢰하게 만드는 건 별개 문제다. 그쪽은 AUTHORITY_INVALID 로 나오고, 원인별 해결의 사내 CA 항목에서 다뤘다.

판별 순서 정리

1. 경고 화면의 두 이름 ("could not prove that it is A; its security certificate is from B")
   └ "does not specify Subject Alternative Names" → CN 전용 (원인 2)
   └ B 가 우리 도메인의 변형        → 2번으로
   └ B 가 플랫폼 기본 도메인        → CDN·호스팅 연결 (원인 6)
   └ B 가 같은 서버의 다른 사이트   → 기본 vhost·SNI (원인 5)

2. s_client -connect A:443 -servername A | x509 -ext subjectAltName
   └ SAN 없음                       → CN 전용, SAN 넣어 재발급 (원인 2)
   └ www/apex 한쪽만                → 이름 추가 재발급 (원인 1)
   └ 와일드카드뿐                   → 범위·형태 확인 (원인 3)
   └ A 가 있음                      → 3번으로

3. 주소창의 A 가 어떤 형태인가
   └ IP 주소                        → iPAddress SAN 또는 이름 접속 (원인 4)
   └ 점 없는 단축 이름              → FQDN 접속 또는 SAN 추가 (원인 7)
   └ 정상 FQDN                      → 실패하는 PC 의 DNS·망(캡티브 포털) 확인

OpenSSL(CN 폴백·부분 와일드카드·공개 접미사)과 curl(OpenSSL 백엔드의 CN 폴백)의 “일치” 판정은 이 순서에 넣지 않는다. Chrome 과 결론이 갈린다. 기준은 언제나 SAN 목록 원문이다.

AUTHORITY_INVALID 는 대개 검증하는 쪽 문제라 재발급이 답이 아니었다. 이 에러는 반대다. 인증서의 이름 목록을 바로잡는 재발급(원인 1~3), 맞는 인증서가 나가게 하는 서버·CDN 설정(원인 5·6), 접속 이름 정리(원인 4·7) — 대부분 서버를 운영하는 쪽에서 끝난다.

무료 진단 툴은 CT 로그 기준으로 이 도메인에 발급된 최신 공인 인증서의 SAN·만료일을 보여준다. 재발급한 인증서에 이름이 제대로 들어갔는지 볼 때 쓸 수 있다. 서버가 실제로 내보내는 인증서는 위의 openssl s_client 명령으로 확인한다.

참조