TLS 핸드셰이크 및 인증서 오류 해결

v2rayN에서 인증서가 유효하지 않거나 핸드셰이크에 실패하는 일반적인 원인을 정리했습니다. 시스템 시간 보정, SNI와 위장 도메인 설정, 인증서 검증을 건너뛸 때의 위험을 다룹니다.

이 글의 핵심

v2rayN, v2rayNG, v2flyNG에서 노드에 연결할 때 발생하는 TLS 핸드셰이크 및 인증서 검증 문제를 다룹니다. 먼저 코어 로그에서 시간 초과, 인증서 날짜 오류, 도메인 불일치를 구분한 뒤 시스템 시간, 노드 주소, SNI, 전송 설정, 서버 인증서 체인을 차례로 확인하세요. 문제를 진단할 때는 한 번에 한 항목만 변경하고 인증서 검증은 유지하세요. TUN 모드 활성화를 핸드셰이크 오류의 만능 해결책으로 여기지 마세요.

1. 먼저 실패한 단계를 확인하세요

TLS 핸드셰이크는 보안 연결을 설정하는 과정에서 진행되며, 일반적으로 실제 데이터 전송보다 먼저 이루어집니다. 노드 목록에서 지연 시간이 측정되더라도 TLS 연결까지 성공했다고 볼 수는 없습니다. TCP 연결 테스트는 포트에 접속할 수 있다는 사실만 확인할 뿐, 인증서와 사용자 인증, 프록시 전달이 모두 정상인지 증명하지 못합니다. VMess와 VLESS는 프록시 프로토콜 이름이고 TLS는 보안 계층 옵션이므로 서로 같은 설정으로 혼동하면 안 됩니다.

v2rayN 메인 창 하단의 로그 영역에서 연결 실패 전후의 내용을 확인하세요. Android에서는 사이드 메뉴에서 ‘로그’를 열 수 있습니다. 버전에 따라 메뉴 위치가 달라질 수 있으니 현재 화면을 기준으로 확인하세요. 먼저 기존 로그를 지우거나 시간을 기록한 다음 한 번만 접속해 보세요. 구독 다운로드 오류, 노드 연결 오류, 대상 웹사이트 오류를 같은 문제로 오인하지 않도록 주의해야 합니다.

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

원인: 기기의 시간이 인증서 유효 기간과 맞지 않거나 서버 인증서가 실제로 만료됐을 수 있습니다. 해결 방법: 먼저 기기의 시계를 동기화하고, 로그에 표시된 현재 시간과 인증서 유효 기간을 대조하세요. 시간이 정확한데도 문제가 계속되면 노드 관리자에게 인증서를 확인해 달라고 요청하세요.

오류: x509: certificate signed by unknown authority

원인: 인증서 체인이 신뢰할 수 있는 루트 인증서까지 연결되지 않았을 수 있습니다. 중간 인증서 누락, 자체 서명 인증서, 로컬 HTTPS 검사 등이 원인일 수 있습니다. 해결 방법: 시스템 업데이트, 네트워크 환경, 서버의 전체 인증서 체인을 확인하세요. 검증 기능을 바로 끄지는 마세요.

오류: remote error: tls: handshake failure

원인: 상대 서버가 핸드셰이크를 거부했습니다. SNI, TLS 설정 또는 서버 진입점 구성이 서로 맞지 않을 수 있습니다. 해결 방법: 기존 노드 설정을 기준으로 보안 계층과 전송 방식을 확인하고, 같은 시각의 서버 로그를 노드 관리자에게 확인해 달라고 요청하세요.

로그에 i/o timeout, connection refused 또는 EOF만 표시된다면 인증서 문제라고 단정하기 어렵습니다. 먼저 노드 주소가 올바르게 해석되는지, 원격 포트에 연결할 수 있는지, 해당 포트에서 실제로 TLS 서비스를 제공하는지 확인하세요. 오류 메시지의 마지막 단어만 캡처하는 것보다 전체 오류 내용을 기록하는 편이 문제 해결에 도움이 됩니다.

2. 시스템 시간을 동기화한 뒤 다시 연결하세요

인증서에는 유효 시작 시각과 만료 시각이 정해져 있습니다. 기기 날짜가 실제보다 1년 전으로 설정되어 있거나 가상 머신을 오래된 스냅샷에서 복원해 시계가 어긋나면, 유효한 인증서도 ‘아직 유효하지 않음’ 또는 ‘만료됨’으로 표시될 수 있습니다. 노드 설정을 바꾸기 전에 시간을 바로잡으면 정상적인 설정을 불필요하게 변경하지 않아도 됩니다.

  1. 날짜 확인

    Windows 11에서 ‘설정’ → ‘시간 및 언어’ → ‘날짜 및 시간’을 열고 날짜와 현재 시각을 확인하세요. 작업 표시줄의 시·분만 확인해서는 안 됩니다.

  2. 시간 동기화

    ‘자동으로 시간 설정’을 켜고 ‘추가 설정’에서 ‘지금 동기화’를 선택하세요. 동기화에 실패하면 현재 네트워크에서 시간 서비스에 정상적으로 연결할 수 있는지 확인하세요. 조직에서 관리하는 기기는 관리자 설정을 따르세요.

  3. Android 시간 확인

    Android에서는 일반적으로 ‘설정’ → ‘시스템’ → ‘날짜 및 시간’에서 ‘자동으로 시간 설정’과 ‘자동 시간대 설정’을 켤 수 있습니다. 기기에 따라 ‘추가 설정’에 있을 수 있으니 시스템 검색에서 ‘날짜 및 시간’을 찾아보세요.

  4. 로그 다시 확인

    시간을 바로잡은 후 클라이언트 연결을 중지했다가 다시 시작하고 한 번 접속해 보세요. 날짜 오류가 계속되면 로그에 표시된 인증서 유효 기간을 확인하세요. 노드의 전송 설정을 계속 바꾸는 것은 피해야 합니다.

macOS에서는 ‘시스템 설정’ → ‘일반’ → ‘날짜 및 시간’에서 자동 설정을 확인할 수 있습니다. Linux에서는 아래 명령어로 시계와 동기화 상태를 확인하세요. 시간대는 표시 방식에 영향을 주지만, 인증서 검증은 절대 시간을 기준으로 합니다. 표시 시간대를 현지 시간대로 바꾸는 것만으로 잘못된 시스템 시각을 바로잡을 수는 없습니다.

timedatectl status
443 / TCP
일반적인 TLS 원격 포트(노드 설정 기준)
123 / UDP
일반적인 NTP 시간 동기화 포트
항목 1개
한 번에 변수 하나만 변경한 뒤 새 로그를 확인하세요

판단 기준: 시계를 먼저 확인하고 노드 설정을 변경하세요

서로 다른 출처의 TLS 노드 여러 개에서 동시에 인증서 날짜 오류가 발생한다면 먼저 기기의 시계를 확인하세요. 시간이 정확하고 특정 노드에서만 만료 오류가 발생한다면 오류 시각과 노드 정보를 노드 관리자에게 전달하세요.

3. 서버 주소, SNI, Host를 구분하세요

v2rayN 노드 목록에서 대상 노드를 두 번 클릭해 편집 창을 열고 ‘주소’, ‘포트’와 TLS 영역의 ‘SNI’ 또는 ‘서버 이름’ 항목을 찾으세요. v2rayNG와 v2flyNG에서는 노드 오른쪽의 편집 메뉴에서 해당 설정을 확인할 수 있습니다. 버전과 프로토콜에 따라 항목 이름이 달라질 수 있으므로, 화면 캡처와 맞추려고 프로토콜 유형을 바꾸지 마세요.

항목역할확인 방법
서버 주소클라이언트가 연결할 IP 주소 또는 도메인을 지정합니다구독 원본 값과 DNS 조회 결과를 확인하고 웹 페이지 경로는 입력하지 마세요
원격 포트서비스가 연결을 받는 포트를 지정합니다서버 설정에 맞춰 입력하세요. TLS를 사용한다고 해서 포트를 모두 443으로 바꾸면 안 됩니다
SNI / serverName일반적으로 핸드셰이크에서 도메인을 알리고 인증서 이름을 확인하는 데 사용합니다노드 관리자에게 받은 도메인을 사용하고 인증서에 해당 이름이 포함되어 있는지 확인하세요
WebSocket HostHTTP 요청에서 가상 호스트를 선택하는 데 사용합니다리버스 프록시 또는 CDN 설정과 일치해야 하며 SNI를 대신할 수 없습니다
WebSocket Path요청을 전달할 경로를 지정합니다대소문자와 맨 앞의 슬래시를 확인하고 SNI에는 입력하지 마세요

예를 들어 인증서에는 edge.example.net이 포함되어 있는데 SNI에 other.example.net을 입력하면 이름이 일치하지 않을 수 있습니다. SNI에는 https://, 포트, /ws를 제외한 도메인만 입력하세요. 여기의 도메인은 항목 형식을 보여 주는 예시일 뿐 실제 사용 가능한 노드가 아니므로 연결에 사용하면 안 됩니다.

서버 주소는 IP이고 SNI는 도메인인 구성도 상대 서버 설정과 인증서가 일치한다면 사용할 수 있습니다. 올바른 검증 이름을 설정하지 않은 채 IP로 연결하면 클라이언트가 IP를 기준으로 인증서를 검증할 수 있으며, 일반 도메인 인증서에는 해당 IP가 포함되지 않는 경우가 많습니다. 화면에 표시된 ‘위장 도메인’은 임의의 도메인을 입력하는 항목이 아닙니다. HTTP Host에 해당하는지 TLS 서버 이름에 해당하는지 구분해야 합니다.

4. 인증서 체인과 전송 보안 유형 확인

기기 시간과 SNI가 올바르면 시스템 신뢰 저장소와 서버 인증서 체인을 확인하세요. 오래된 시스템에 루트 인증서 업데이트가 없거나 서버가 사이트 인증서만 보내고 중간 인증서를 누락하면 검증에 실패할 수 있습니다. 같은 도메인의 웹 페이지가 브라우저에서 열린다고 문제가 완전히 배제되는 것은 아닙니다. 브라우저와 프록시 코어가 서로 다른 신뢰 저장소를 사용하거나 인증서 체인을 보완하는 방식이 다를 수 있습니다.

  • 한 기기에서만 실패하는 경우: 시스템 날짜, 시스템 업데이트, 관리형 루트 인증서 정책을 확인하세요. 허가된 다른 네트워크에서 다시 연결해 네트워크 측 HTTPS 검사 여부를 확인할 수 있습니다.
  • 모든 기기에서 같은 노드 연결에 실패하는 경우: 노드 관리자에게 인증서 만료 시각, 전체 인증서 체인, 도메인 적용 범위, 인증서 갱신 후 서비스 재시작 여부를 확인해 달라고 요청하세요.
  • 최근 전송 설정을 변경한 경우: TCP, WebSocket, gRPC와 TLS 설정을 다시 확인하세요. 일반 HTTP 포트에 TLS 핸드셰이크를 보내는 문제는 SNI를 바꿔도 해결되지 않습니다.
  • 구독을 새로고침한 뒤 다시 오류가 발생하는 경우: 노드를 직접 수정했는지 확인하세요. 구독을 업데이트하면 로컬 변경 사항이 덮어써질 수 있습니다. 업데이트할 때마다 설정을 다시 입력하는 대신 구독 원본을 수정하세요.

로그에서 REALITY 검증 실패가 확인되면 신뢰할 수 있는 출처의 전체 설정을 다시 가져온 뒤 클라이언트와 코어가 해당 설정을 지원하는지 확인하세요. 보안 유형을 REALITY에서 TLS로 바꿔 시험하지 말고, 공개 키를 인증서 도메인 항목에 입력하지도 마세요.

5. 인증서 검증을 건너뛰면 안 되는 이유

노드 편집 화면의 ‘안전하지 않은 연결 허용’ 또는 ‘인증서 검증 건너뛰기’, 설정의 allowInsecure는 서버 신원을 검증하는 방식을 바꿉니다. 데이터가 암호화되어 전송되더라도 상대 서버가 신뢰할 만하다는 뜻은 아닙니다. 잘못된 인증서, 엉뚱한 진입점, 중간에 바뀐 연결에서도 원래 표시되어야 할 인증서 경고가 나타나지 않을 수 있습니다.

  • 날짜가 잘못됐다면 시스템 시계를 바로잡고, 서버 인증서가 만료됐다면 인증서를 갱신하세요. 클라이언트에서 만료를 무시하도록 설정하지 마세요.
  • 도메인이 일치하지 않으면 SNI와 인증서 적용 범위를 확인하세요. 검증 기능을 끈 상태로 계속 사용해서는 안 됩니다.
  • 자체 서버에서 사설 신뢰 체계를 사용해야 한다면 인증서 배포 방식과 신뢰 범위를 충분히 이해한 뒤 설정하세요. 출처를 모르는 사람이 제공한 루트 인증서는 가져오지 마세요.
  • 문제 해결을 위해 이 옵션을 일시적으로 변경했다면 인증 기능을 다시 켜고 테스트해 최종 설정에서도 정상적으로 연결되는지 확인하세요.

시스템 프록시 또는 TUN 모드를 켜면 트래픽이 프록시로 들어오는 방식이 바뀌지만, 일반적으로 노드 자체의 인증서 오류는 해결되지 않습니다. 구독 주소의 HTTPS 요청에서 오류가 발생했다면 구독 도메인과 업데이트에 사용되는 네트워크를 확인하세요. 구독 요청과 현재 노드의 TLS 핸드셰이크는 별개의 연결이므로 노드 SNI를 바꿔도 구독 사이트 인증서 문제는 해결되지 않습니다.

6. 자주 묻는 질문과 문제 해결 기록

시간을 동기화했는데도 인증서가 만료됐다고 표시되나요?

다시 연결한 뒤 새 로그를 확인해 이전 기록이 아닌지 확인하세요. 시스템 날짜가 정확하고 오류에 표시된 만료 시각이 실제로 지났다면 노드 관리자에게 인증서를 갱신하고 관련 서비스를 다시 불러오도록 요청하세요. 기기의 시간대를 계속 바꾸지 마세요.

구독의 SNI 항목이 비어 있는데 입력해야 하나요?

먼저 서버 주소가 도메인인지, 현재 코어가 해당 주소를 바탕으로 서버 이름을 자동으로 설정하는지 확인하세요. 비어 있다고 반드시 잘못된 것은 아닙니다. 로그에 이름 검증 실패가 명시되어 있다면 노드 관리자에게 올바른 SNI를 확인하세요. 다른 노드의 도메인을 복사해 입력하면 안 됩니다.

휴대폰은 연결되는데 PC는 안 됩니다. 무엇부터 바꿔야 하나요?

두 기기의 노드 주소, 포트, SNI, 보안 유형, 전송 설정을 비교한 뒤 PC의 시간과 시스템 신뢰 저장소를 확인하세요. 기존 설정을 보존하고 한 번에 한 항목만 변경하세요. Android에서 연결된다고 해서 데스크톱 코어와 설정의 호환성 문제를 무시하지 마세요.

문제 내용을 노드 관리자에게 어떻게 전달하면 좋나요?

클라이언트와 코어 버전, 오류가 발생한 시각, 앞뒤 맥락을 포함한 오류 원문을 전달하고 시간 동기화 여부와 모든 노드에서 문제가 발생하는지도 알려 주세요. 구독 링크, UUID, 비밀번호, 인증 정보는 가리고 전체 설정 파일을 그대로 보내지 마세요.

마지막으로 같은 노드와 같은 대상에 다시 연결해 새 로그에서 같은 오류가 사라졌는지 확인한 뒤 평소의 라우팅 설정을 복원하세요. 여전히 실패하면 ‘무엇을 변경했는지, 오류가 달라졌는지’를 간단히 기록해 두세요. 인증서 날짜 오류가 연결 시간 초과로 바뀌었다면 새로운 단서입니다. 같은 인증서 조치를 반복하지 마세요.

클라이언트 다운로드 및 설치플랫폼에 맞는 설치 파일 선택