일반 TLS를 사용하는 노드에서 클라이언트 로그에 핸드셰이크 실패 또는 x509 인증서 오류가 표시될 때 확인하세요. ‘로그 원문 → 시스템 시간 → 연결 주소와 SNI → 인증서 체인 → 클라이언트 설정’ 순서로 점검하고, 네트워크 시간 초과와 인증서 검증 실패를 구분하세요. 인증서 검증은 켜 둔 상태에서 한 번에 한 항목씩 변경하고 로그로 결과를 확인합니다.
인증서 오류와 연결 실패 구분하기
‘TLS 핸드셰이크 실패’는 연결 단계에 대한 설명일 뿐, 원인이 하나로 정해져 있는 것은 아닙니다. 클라이언트는 먼저 노드 주소와 포트에 연결한 다음 TLS 협상과 인증서 검증을 진행하고, 이후 프록시 프로토콜을 주고받습니다. 연결 시간 초과, 서버의 연결 종료, 인증서 도메인 불일치가 모두 상위 단계에서는 연결 실패로 표시될 수 있습니다. 문제를 점검할 때는 속도 측정 목록의 실패 표시만 보지 말고 커널 로그를 펼쳐 오류 원인의 가장 안쪽 항목을 확인하세요.
v2rayN은 메인 화면의 로그 영역에서 현재 연결 기록을 확인할 수 있습니다. v2rayNG와 v2flyNG는 메인 메뉴의 로그 항목을 이용하세요. 버전에 따라 메뉴 이름이나 위치가 다를 수 있습니다. 먼저 클라이언트 버전, 커널 이름, 전송 방식, 전체 오류 메시지를 기록한 뒤 대상 노드 하나에만 요청을 한 번 보내세요. 여러 연결이 백그라운드에서 동시에 발생하면 로그가 뒤섞일 수 있습니다.
오류: x509: certificate has expired or is not yet valid
원인: 검증 시각이 인증서 유효 기간에 포함되지 않습니다. 기기 시간이 틀렸거나 서버 인증서가 실제로 만료됐을 수 있습니다. 해결: 먼저 기기 시간을 동기화한 다음 로그의 현재 시각과 인증서 유효 기간을 대조하세요. 오류가 계속되면 서버에서 인증서를 갱신하고 다시 불러와야 합니다.
오류: x509: certificate signed by unknown authority
원인: 인증서에서 신뢰할 수 있는 루트 인증서까지 전체 체인을 구성할 수 없습니다. 중간 인증서 누락, 자체 서명 인증서, 연결 변조 등이 원인일 수 있습니다. 해결: 서버가 전체 인증서 체인을 제공하는지와 기기의 신뢰 저장소를 확인하고 발급자를 대조하세요. 검증을 끄는 것으로 문제를 덮어서는 안 됩니다.
오류: tls: first record does not look like a TLS handshake
원인: 대상 포트에서 예상한 TLS 데이터가 반환되지 않았습니다. TLS를 사용하지 않는 서비스에 연결했을 수 있습니다. 해결: 노드 포트, 전송 보안 설정, 리버스 프록시의 리스닝 설정을 확인하세요.
오류: context deadline exceeded
원인: 작업이 제한 시간을 초과했습니다. 이 메시지만으로 인증서 문제라고 판단할 수는 없습니다. 해결: 앞뒤 로그를 함께 보고 도메인 조회, TCP 연결 가능 여부, 핸드셰이크 단계를 확인하세요. 우선 인증서 옵션부터 바꾸지는 마세요.
시스템 시간: 먼저 동기화한 뒤 인증서 만료 여부 확인
인증서에는 유효 시작 시각과 만료 시각이 있습니다. 기기 시계가 실제보다 빠르면 ‘아직 유효하지 않음’, 느리면 ‘이미 만료됨’ 오류가 발생할 수 있습니다. 시간대만 바꿔도 실제 시스템 시각은 보통 달라지지 않습니다. 실제 날짜와 시간을 바로잡아야 합니다. 듀얼 부팅, 장기간 전원 종료 후 부팅, 자동 시간 동기화 실패가 있었다면 먼저 확인하세요.
-
시간 동기화
Windows 11: ‘설정’ → ‘시간 및 언어’ → ‘날짜 및 시간’에서 ‘자동으로 시간 설정’을 켜고, ‘추가 설정’에서 ‘지금 동기화’를 누르세요. 동기화에 실패하면 먼저 기기의 네트워크 연결을 확인하세요.
-
다른 기기도 확인
macOS: ‘시스템 설정’ → ‘일반’ → ‘날짜 및 시간’에서 날짜 및 시간 자동 설정을 켜세요. Android: 시스템 ‘설정’ → ‘시스템’ → ‘날짜 및 시간’에서 자동 시간을 켜세요. 제조사에 따라 메뉴가 ‘추가 설정’ 아래에 있을 수 있습니다.
-
연결 다시 시도
시간을 동기화한 뒤 클라이언트 연결을 중지했다가 다시 시작하고 새 오류 로그를 확인하세요. 시간을 수정하기 전에 기록된 로그로 해결 여부를 판단하지 마세요.
-
인증서 유효 기간 확인
기기 시간이 정확한데도 만료 오류가 표시되면 실제로 수신한 인증서의 유효 기간을 확인하세요. 인증서를 갱신한 뒤에는 TLS 종료 서비스에서 인증서를 다시 불러와야 합니다. 디스크에 새 파일이 있다고 해서 현재 연결에 새 인증서가 적용된 것은 아닙니다.
연결 주소, SNI, Host를 혼동하지 마세요
노드 편집 화면의 ‘주소’는 연결 대상입니다. SNI는 TLS ClientHello에 전달하는 서버 이름으로, 서버는 이를 바탕으로 인증서를 선택하는 경우가 많습니다. WebSocket의 Host는 핸드셰이크 이후 HTTP 요청 헤더에 포함됩니다. 세 항목에 같은 도메인을 쓰기도 하고 서로 다른 값을 쓰기도 하지만, 서버 설정에 맞춰야 합니다. ‘위장 도메인’을 임의로 바꿔도 되는 장식용 항목으로 취급하지 마세요.
| 설정 항목 | 적용 단계 | 중점 확인 사항 |
|---|---|---|
| 주소 및 포트 | 네트워크 연결 수립 | 서버에서 안내한 접속 주소를 사용하고, 도메인이 예상한 서버로 확인되는지 점검하세요. |
serverName / SNI | TLS 핸드셰이크 | 인증서에 포함된 서버 이름을 입력하세요. 프로토콜, 포트, 경로는 넣지 않습니다. |
| WebSocket Host | HTTP 업그레이드 요청 | 리버스 프록시의 가상 호스트와 일치해야 합니다. TLS의 SNI를 대신할 수 없습니다. |
| WebSocket path | HTTP 경로 일치 | 서버에서 지정한 경로를 사용하세요. 경로 오류는 보통 인증서 도메인 오류와는 별개입니다. |
allowInsecure | 인증서 검증 | 일반적인 공개 인증서를 사용하는 경우 false로 유지하세요. |
문서용 도메인 edge.example.com을 예로 들겠습니다. 인증서의 Subject Alternative Name에 이 이름이 포함되어 있다면 SNI에는 https://edge.example.com/path가 아니라 호스트 이름을 입력해야 합니다. IP 주소로 연결하더라도 서버에서 요구하는 도메인을 SNI로 지정할 수 있습니다. IP 주소 자체로 검증하려면 인증서에 일치하는 IP 항목이 있어야 합니다. 도메인 항목만으로는 충분하지 않습니다.
판단 기준: 포트 번호로 프로토콜을 추측하지 말고 서버 설정을 확인하세요
포트 번호는 관례일 뿐입니다. 먼저 노드에서 일반 TLS를 실제로 사용하는지 확인한 다음 SNI와 인증서 도메인을 점검하세요. WebSocket Host만 바꿔서는 HTTP 요청 이전에 발생한 인증서 이름 오류를 해결할 수 없습니다.
클라이언트에서 SNI와 allowInsecure 확인하기
화면의 메뉴 이름은 버전에 따라 달라질 수 있으므로, 아래에서는 노드 편집 메뉴와 실제 필드를 기준으로 안내합니다. 구독으로 가져온 설정은 업데이트할 때 덮어써질 수 있습니다. 수정하기 전에 노드를 복제해 점검용으로 사용하고 기존 값을 기록해 두세요. 한 번의 테스트에서 주소, 포트, SNI, 전송 방식을 동시에 바꾸면 연결이 복구되더라도 원인을 찾기 어렵습니다.
- v2rayN: 메인 화면에서 대상 노드를 더블클릭해 서버 편집 창을 여세요. ‘주소’와 ‘포트’를 확인한 뒤 전송 계층 보안 영역의
tls, ‘SNI’, ‘인증서 검증 건너뛰기’ 또는 ‘안전하지 않은 연결 허용’ 항목을 살펴보세요. 일반 TLS에서는 마지막 항목을 꺼야 합니다. 사용자 지정 설정을 사용한다면 실제로 불러온 JSON을 기준으로 확인하세요. 일반 편집 창에서 해당 파일이 수정되지 않을 수도 있습니다. - v2rayNG: 노드 목록에서 대상 노드의 편집 아이콘을 누르고 아래로 내려 TLS 설정을 확인하세요. 전송 계층 보안이
tls인지, ‘SNI’와 ‘안전하지 않은 연결 허용(allowInsecure)’ 값이 올바른지 확인합니다. WebSocket을 사용한다면 전송 설정의 Host와 path도 별도로 점검하세요. 이 클라이언트는 Xray 커널을 사용하므로 REALITY 노드는 해당 설정 항목에 맞춰 확인해야 합니다. - v2flyNG: 노드 목록에서 편집 화면을 열고 TLS, 서버 이름 또는 SNI, 안전하지 않은 연결 허용 항목을 확인하세요. 이 클라이언트는 v2fly 커널을 사용하므로 Xray 전용 보안 설정을 그대로 적용하면 안 됩니다. 편집 화면에 해당 항목이 없다면 Host에 값을 대신 입력하지 말고 노드 유형과 사용 중인 버전을 확인하세요.
다음은 일반 TLS의 streamSettings 설정 예시입니다. 전체 노드 설정이 아니라 필드를 확인하기 위한 조각입니다. 예시에서는 TCP 전송을 사용하며 도메인은 설명용입니다. 기존 노드가 WebSocket이나 다른 전송 방식을 사용한다면 예시를 그대로 따라 하려고 TCP로 바꾸지 마세요. 실제 지원 필드는 사용 중인 커널을 기준으로 확인하세요.
{
"streamSettings": {
"network": "tcp",
"security": "tls",
"tlsSettings": {
"serverName": "edge.example.com",
"allowInsecure": false
}
}
}
인증서 체인과 SNI: 별도 핸드셰이크로 원인 좁히기
터미널 도구를 사용할 수 있다면 같은 기기와 네트워크에서 서버가 반환하는 인증서를 별도로 확인할 수 있습니다. 아래 명령을 실행하려면 시스템에 OpenSSL이 설치되어 있어야 합니다. 실행 전에 예시 호스트 이름, SNI, 포트를 실제 값으로 바꾸세요. 연결 주소와 SNI를 따로 지정하므로 ‘IP로 연결하고 도메인으로 검증’하는 설정을 점검할 때 특히 유용합니다.
openssl s_client -connect edge.example.com:443 -servername edge.example.com -showcerts -verify_hostname edge.example.com -verify_return_error
- 먼저 인증서가 수신되는지 확인: 연결이 성립되기 전에 시간이 초과된다면 네트워크, DNS, 포트, 방화벽부터 확인하세요. 인증서 출력이 없다는 이유만으로 인증서가 만료됐다고 판단할 수는 없습니다.
- 다음으로 이름과 유효 기간 확인: 반환된 인증서의 도메인 항목, 유효 시작 시각, 만료 시각을 확인하세요. SNI에 따라 기본 사이트 인증서가 선택됐다면 서버의 가상 호스트와 인증서 연결 설정을 점검하세요.
- 인증서 체인 확인: 서버는 보통 리프 인증서와 필요한 중간 인증서를 전송하고, 루트 인증서는 클라이언트의 신뢰 저장소에서 제공합니다. 브라우저에서 접속된다고 해서 모든 커널에서 동일한 신뢰 체인이 구성되는 것은 아닙니다.
- 신뢰 환경 비교: OpenSSL과 클라이언트 커널은 서로 다른 신뢰 저장소를 사용할 수 있습니다. 명령이 성공해도 해당 도구와 대상, 인수 조합에서만 확인된 결과입니다. 클라이언트에서 다시 테스트해야 합니다.
특정 네트워크에서만 발급자가 다른 인증서를 받는다면 해당 네트워크에 HTTPS 검사, 포털 로그인, 트래픽 전달 기능이 있는지 확인하세요. 오류 창에 표시된 알 수 없는 루트 인증서를 임의로 설치하지 마세요. 서버를 다른 사람이 관리한다면 개인정보를 가린 오류의 마지막 줄, 발생 시각, SNI, 포트만 전달하세요. 구독 전체 주소, UUID, 기타 인증 정보는 보내지 마세요.
자주 묻는 질문과 수정 후 확인
allowInsecure를 켜면 연결됩니다. 계속 켜 둬도 되나요?
일반 인증서 검증 단계가 문제일 가능성이 있다는 뜻일 뿐, 도메인 문제가 확인됐다는 의미는 아닙니다. 시간을 동기화하고 SNI, 인증서 유효 기간, 전체 체인을 확인하세요. 문제를 해결한 뒤에는 해당 옵션을 끄고 실제 요청을 보내 확인해야 합니다.
브라우저에서는 노드 도메인이 열리는데 클라이언트에서 오류가 나는 이유는 무엇인가요?
먼저 두 프로그램이 같은 주소, 포트, SNI에 접속하는지 확인하세요. 브라우저는 다른 프록시를 사용하거나 다른 주소로 연결될 수 있으며, 사용하는 신뢰 저장소도 다를 수 있습니다. 클라이언트가 실제로 연결한 주소와 수신한 인증서를 기준으로 확인하세요.
구독을 업데이트한 뒤 SNI가 다시 바뀌었습니다. 어떻게 해야 하나요?
별도의 점검용 노드를 보관하고 변경이 실제로 효과가 있는지 확인한 뒤 구독 제공자에게 전달되는 설정을 수정해 달라고 요청하세요. 업데이트 후에는 원래 노드의 값을 확인해 자동 덮어쓰기를 클라이언트가 저장하지 못한 것으로 오해하지 않도록 하세요.
노드가 REALITY인데도 TLS 항목을 확인해야 하나요?
먼저 security의 실제 값을 확인하세요. REALITY에는 일반 TLS 인증서 문제 해결 절차를 그대로 적용할 수 없습니다. 서버에서 요구하는 serverName, 공개 키, shortId 등의 항목을 확인하세요. 일반 TLS로 바꾸거나 검증 건너뛰기를 켜서 해결하려 하지 마세요.
수정한 뒤에는 먼저 노드를 저장하고 연결을 다시 시작한 다음 같은 요청으로 재검사하세요. 지연 시간만 보지 말고 로그에 기존 인증서 오류가 더 이상 표시되지 않는지, 실제 요청이 완료되는지 확인해야 합니다. 일반 TLS 노드라면 인증서 검증을 계속 켜 두세요. 핸드셰이크가 성공한 뒤 경로 오류, 비정상 HTTP 상태 코드, 프로토콜 인증 실패가 발생하면 전송 경로와 계정 설정을 확인하고 SNI를 계속 바꾸지는 마세요.