TLS 인증서 오류 해결: 시스템 시간 동기화 및 SNI 설정 확인

인증서 무효·TLS 핸드셰이크 실패가 발생하면 기기 시간, SNI와 위장 도메인 일치 여부, allowInsecure 설정, 지문을 차례로 확인하세요.

핵심 내용

v2rayN, v2rayNG, v2flyNG 연결 중 인증서 검증 실패나 TLS 핸드셰이크 중단이 발생할 때 확인할 내용입니다. 먼저 로그에서 시간, 도메인, 인증서 체인 오류를 구분한 뒤 노드의 연결 주소, SNI, 전송 계층 Host를 확인하세요. 일반 TLS와 REALITY는 각각 따로 점검해야 합니다. 한 번에 한 항목씩 수정하고 인증서 검증은 유지한 채 실제 요청으로 연결이 복구됐는지 확인하세요.

1. 로그부터 확인: 인증서 오류와 포트 연결 실패는 다릅니다

TLS 핸드셰이크는 전송 연결이 성립한 뒤 진행됩니다. TCP 연결에 성공했다는 것은 대상 주소의 포트가 응답했다는 뜻일 뿐, 인증서를 신뢰할 수 있거나 도메인이 일치하거나 프록시 인증이 성공했다는 의미는 아닙니다. v2rayN에서 TCPing 결과가 나오지만 실제 연결 테스트는 실패할 수 있습니다. 이때 로컬 프록시 포트를 반복해서 바꾸지 마세요.

클라이언트 이름과 버전, 실제 실행 중인 코어 버전, 노드의 보안 유형, 오류 발생 시각을 기록하세요. 백그라운드에서 반복 테스트하는 작업을 멈추고 노드 하나에 한 번만 연결한 다음, 로그에서 같은 시각에 기록된 가장 안쪽 오류를 찾으세요. 바깥쪽의 failed to find an available destination은 요약 메시지일 뿐이므로 뒤이어 나오는 구체적인 원인을 확인해야 합니다.

오류: x509: certificate has expired or is not yet valid

원인: 기기의 현재 시간이 인증서 유효 기간을 벗어났거나 서버 인증서가 실제로 만료됐을 수 있습니다. 해결: 먼저 기기 시간을 동기화하고 인증서의 유효 시작일과 만료일을 확인하세요. 시간이 맞는데도 오류가 계속되면 서버 운영자가 인증서를 갱신하거나 배포 설정을 바로잡아야 합니다.

오류: x509: certificate signed by unknown authority

원인: 인증서 체인을 구성할 수 없는 상태입니다. 중간 인증서 누락, 자체 서명 인증서, 네트워크에서의 인증서 교체 등이 원인일 수 있습니다. 해결: 인증서 발급자와 전체 체인을 확인하고 검증을 바로 끄지 마세요.

오류: remote error: tls: handshake failure

원인: 상대 서버가 핸드셰이크를 거부했습니다. SNI, 프로토콜 버전, 클라이언트 인증서 요구 사항 또는 서버 정책이 원인일 수 있습니다. 해결: 먼저 서버가 요구하는 보안 유형과 SNI를 확인한 뒤 서버 로그를 살펴보세요. 이 한 줄만으로 인증서 만료라고 단정할 수는 없습니다.

2. 시스템 시간 동기화: 날짜, 시간대, 인증서 유효 기간 확인

인증서에는 notBefore와 notAfter 시간이 지정되어 있습니다. 검증에는 시스템 시계가 나타내는 절대 시간이 사용되며, 작업 표시줄에 보이는 시각만 확인하는 것으로는 충분하지 않습니다. 절대 시간이 맞다면 시간대만 변경해도 보통 인증서가 무효가 되지는 않습니다. 반대로 현지 시각을 다른 시간대 기준으로 잘못 설정하면 몇 시간 차이가 날 수 있습니다.

  1. 날짜 확인

    먼저 연도, 월, 일이 정확한지 확인하세요. 기기를 오래 꺼 두었거나 스냅샷을 복원했거나 메인보드 시계에 문제가 있으면 날짜가 과거로 돌아갈 수 있습니다. 분만 대략 맞추는 것으로는 충분하지 않습니다.

  2. 컴퓨터 시간 동기화

    Windows 11에서는 「설정」→「시간 및 언어」→「날짜 및 시간」으로 이동해 「시간 자동 설정」을 켜고 「시간대」를 확인한 다음 「지금 동기화」를 누르세요. macOS에서는 「시스템 설정」→「일반」→「날짜 및 시간」으로 이동해 날짜와 시간 자동 설정을 켜세요.

  3. Android 시간 동기화

    Android에서는 보통 「설정」→「시스템」→「날짜 및 시간」에서 「시간 자동 설정」과 자동 시간대를 켤 수 있습니다. 메뉴 이름은 시스템마다 다를 수 있으니 설정에서 '날짜 및 시간'을 검색해 보세요.

  4. 다시 연결하고 결과 기록

    동기화가 완료됐는지 확인한 뒤 클라이언트 연결을 다시 시작하세요. 만료 오류가 계속되면 오류에 표시된 현재 시각과 인증서 유효 기간을 기록해 노드 운영자에게 전달하고, 서버가 실제로 제공하는 인증서를 확인해 달라고 요청하세요.

Windows에서는 터미널에서 w32tm /query /status를 실행해 시간 동기화 상태를 확인할 수 있습니다. 동기화 명령인 w32tm /resync는 보통 관리자 권한이 필요하며 Windows 시간 서비스가 작동해야 합니다. 명령이 실패하면 먼저 서비스와 네트워크를 확인하세요. 명령을 실행했다는 사실만으로 동기화가 완료된 것은 아닙니다. Linux에서는 timedatectl status로 시스템 시계와 시간 동기화 서비스 상태를 확인할 수 있으며, 활성화 방법은 배포판에 따라 다릅니다.

요약: 시간이 정확한데도 만료 오류가 나면 서버를 확인하세요

동기화가 완료되고 오류에 표시된 현재 날짜도 정확하다면 기기 시각을 계속 바꾸지 마세요. 운영자에게 인증서 갱신 여부, 서비스 재시작 여부, 각 접속 지점에서 오래된 인증서를 제공하고 있지는 않은지 확인해 달라고 요청하세요.

3. SNI, 연결 주소, Host: 각각 따로 확인

SNI는 TLS ClientHello에서 대상 호스트 이름을 알리는 확장입니다. 클라이언트 설정의 serverName은 보통 핸드셰이크 이름 지정과 인증서 이름 검증에 함께 사용되지만, 구체적인 동작은 코어에 따라 다릅니다. 서버 요구 사항에 맞아야 하며 인증서의 SAN에 해당 도메인이 포함되어 있어야 합니다. '위장 도메인'은 정해진 프로토콜 필드명이 아니므로 제공자가 SNI를 뜻하는지, WebSocket Host를 뜻하는지, 다른 전송 계층 설정을 뜻하는지 먼저 확인하세요.

항목역할확인할 내용
연결 주소와 포트실제로 연결할 서버 접속 지점을 지정합니다도메인이나 IP 주소를 입력할 수 있으며, 포트는 노드에 지정된 값을 사용합니다
SNI / serverNameTLS 핸드셰이크 이름과 일반적으로 인증서 이름을 검증할 때 사용하는 값도메인만 입력하고 프로토콜, 경로, 포트는 포함하지 않습니다
WebSocket HostWebSocket 핸드셰이크의 HTTP Host 필드리버스 프록시 또는 업스트림 사이트의 라우팅 설정과 일치해야 합니다
WebSocket pathWebSocket 요청 경로맨 앞의 슬래시를 유지하세요. 경로 오류는 보통 인증서 이름 오류와 다릅니다

연결 주소는 IP이고 SNI는 도메인인 설정도 정상일 수 있습니다. 예를 들어 IP에 직접 연결하면서 도메인으로 TLS 이름을 검증할 수 있습니다. 반대로 SNI를 지운 뒤 IP를 기준으로 검증하면, 인증서에 도메인만 포함된 경우 cannot validate certificate ... because it doesn't contain any IP SANs 오류가 날 수 있습니다. 주소와 SNI가 다르다는 이유만으로 잘못된 설정이라고 판단하지 마세요.

아래는 일반 TLS의 일부 설정 예시입니다. 연결 가능한 전체 노드 설정이 아니며 REALITY에는 적용되지 않습니다. 실제 노드의 전송 유형은 기존 값을 유지해야 합니다. 예시에서는 연결 주소, 인증 정보, 그 밖의 아웃바운드 필드를 생략했습니다.

{
  "streamSettings": {
    "network": "tcp",
    "security": "tls",
    "tlsSettings": {
      "serverName": "example.com",
      "allowInsecure": false
    }
  }
}

4. allowInsecure: 인증서 오류를 해결하는 설정이 아닙니다

allowInsecure를 true로 설정하면 일반적인 서버 인증서 검증을 건너뜁니다. 인터페이스의 '안전하지 않은 연결 허용'이나 '인증서 검증 건너뛰기' 옵션이 보통 이 동작에 해당합니다. TLS 암호화가 유지될 수는 있지만, 일반적인 인증서 체인 및 이름 검증으로 상대 서버의 신원을 확인할 수 없게 됩니다. 호환성을 높이는 만능 설정이 아닙니다.

증상: 검증을 끄면 연결됨

원인: 네트워크 상태가 아니라 인증서 유효 기간, 도메인 일치 여부 또는 신뢰 체인에 문제가 있을 수 있습니다. 해결: 검증을 다시 켜고 해당 인증서 문제를 하나씩 해결하세요. 연결됐다는 사실만으로 상대 서버의 신뢰성을 확인할 수는 없습니다.

증상: 검증을 꺼도 핸드셰이크 실패

원인: 인증서 검증 전 단계에서 문제가 발생했을 수 있습니다. 포트가 TLS 서비스가 아니거나, 서버가 SNI를 거부하거나, 보안 유형을 잘못 설정했을 수 있습니다. 해결: 주소, 포트, 핸드셰이크 설정을 다시 확인하세요. 안전하지 않은 옵션을 계속 추가하지 마세요.

5. 지문과 REALITY: 실제 사용 중인 코어에 따라 점검

클라이언트 지문은 TLS 핸드셰이크 특성을 나타내며 인증서 도메인이나 검증 생략 옵션이 아닙니다. 해당 기능을 지원하는 Xray 설정의 fingerprint에는 chrome처럼 코어에서 지원하는 값을 사용할 수 있습니다. 값을 바꿔도 만료된 인증서가 다시 유효해지거나 SAN에 없는 도메인이 자동으로 추가되지는 않습니다.

설정 유형우선 확인혼용 금지
일반 TLS기기 시간, serverName, 인증서 유효 기간, 전체 인증서 체인REALITY의 공개 키 매개변수로 인증서 설정을 대신하지 마세요
REALITYserverName, 서버 공개 키, shortId, 지문, 서버 요구 사항일반 TLS처럼 인증서 검증을 끄는 방식으로 해결하려 하지 마세요
TLS를 사용하지 않는 노드해당 오류가 구독 업데이트, 테스트 대상 또는 다른 연결에서 발생한 것은 아닌지 먼저 확인하세요기존 노드에 TLS를 임의로 추가하지 마세요

v2rayNG는 Xray 코어를, v2flyNG는 V2Fly 코어를 사용하므로 기능과 필드를 그대로 옮겨 쓸 수 없습니다. v2rayN에서는 현재 노드가 실제로 사용하는 코어를 기준으로 확인하세요. REALITY 또는 XTLS Vision 설정이라면 선택한 코어가 해당 기능을 지원하는지 먼저 확인해야 합니다. 클라이언트에서 링크를 가져올 수 있다고 해서 모든 매개변수가 적용된 것은 아닙니다.

6. 핸드셰이크 도구로 원인 찾기: 포트, 인증서 체인, 서버

기기에 OpenSSL이 설치되어 있다면 일반 TLS 접속 지점의 인증서를 직접 확인할 수 있습니다. 아래 명령의 example.com은 형식 예시이므로 실행 전에 실제 접속 지점과 서버가 요구하는 SNI로 바꿔야 합니다. 연결 포트도 노드에 지정된 값을 사용하세요. 이 테스트는 TLS 계층만 확인하며 VMess 또는 VLESS 인증 정보는 검증하지 않습니다.

openssl s_client -connect example.com:443 -servername example.com -showcerts -verify_hostname example.com -verify_return_error
443
TLS 접속 포트 예시이며 모든 노드에 고정된 값은 아닙니다
TLS 1.2
흔히 협상되는 버전이며 양쪽 모두 지원해야 합니다
TLS 1.3
또 다른 흔한 협상 버전이며 지문 이름이 아닙니다

요약: 도구 통과는 해당 TLS 검사 한 번이 통과했다는 뜻입니다

인증서 검증은 정상이지만 프록시 연결이 실패한다면 전송 경로, 인증 매개변수, 서버 인바운드 설정을 확인하세요. 이미 올바른 SNI를 계속 수정하지 말고 핸드셰이크 이후의 모든 실패를 인증서 문제로 돌리지도 마세요.

7. 수정 후 확인과 자주 묻는 질문

수정할 때마다 노드를 저장한 뒤 연결을 새로 설정하세요. 이미 연결된 상태의 장기 연결에는 새 매개변수가 바로 적용되지 않을 수 있습니다. '코어 정상 실행 → 노드 핸드셰이크 성공 → 실제 요청 사용 가능' 순서로 확인하세요. 클라이언트 로그에 인증서 오류가 더 이상 없는데 브라우저가 여전히 비정상이라면 시스템 프록시, 앱의 프록시 설정, 라우팅 규칙을 확인하세요. 모든 TLS 매개변수를 처음부터 다시 점검할 필요는 없습니다.

  1. 자동 시간 동기화가 성공했는지 확인하고 기기를 재부팅한 뒤에도 날짜가 정확한지 점검하세요.
  2. SNI가 서버 요구 사항과 일치하고 인증서 검증이 켜져 있는지, 전송 계층 Host와 경로를 잘못 바꾸지 않았는지 확인하세요.
  3. 수정한 노드를 선택해 실제 연결 테스트를 한 번 실행한 뒤 프록시가 올바르게 설정된 앱에서 대상 서비스에 접속하세요.
  4. 수정한 항목과 결과를 기록하세요. 구독에서 가져온 설정이라면 제공자에게 원본 데이터를 수정해 달라고 요청해야 다음 업데이트 때 로컬 변경 사항이 덮어써지지 않습니다.
구독 업데이트 중 인증서 오류가 나면 노드의 SNI가 잘못된 건가요?

꼭 그렇지는 않습니다. 구독을 다운로드할 때는 클라이언트가 구독 주소로 HTTPS 요청을 보내며, 검증 대상은 구독 사이트의 인증서입니다. 보통 노드 편집 창의 SNI는 사용하지 않습니다. 먼저 오류가 '구독 업데이트' 중인지 '노드 연결' 중인지 구분한 다음 해당 도메인, 시스템 시간, 신뢰 체인을 확인하세요.

같은 노드가 다른 기기에서는 연결되는데, 서버 문제는 아닌가요?

서버 문제를 완전히 배제할 수는 없습니다. 두 기기가 서로 다른 접속 지점으로 연결되거나 신뢰 저장소, 코어, 시간 설정이 다를 수 있습니다. 실제 연결 주소, SNI, 인증서 발급자와 만료 시각을 먼저 비교한 뒤 설정을 항목별로 대조하세요. 시스템 설정 전체를 그대로 복사하지 마세요.

브라우저에서는 위장 도메인이 열리는데 클라이언트 연결은 왜 실패하나요?

브라우저는 다른 주소에 연결했거나 다른 신뢰 저장소를 사용했을 수 있으며, 전송 경로도 같다고 보장할 수 없습니다. 웹페이지가 열린 것은 해당 웹 요청 한 번이 성공했다는 뜻일 뿐입니다. 클라이언트는 노드에 지정된 주소, 포트, SNI, 전송 매개변수, 인증 매개변수에 따라 연결해야 합니다.

클라이언트 다운로드