사람들이 내게 묻는 가정용 VPN 장애 대부분은 DNS 장애가 아니며, 그런데도 사람들은 먼저 동적 DNS 구독을 산다. 무엇이든 설정하기 전에 호스트 이름이 정말로 망가진 부분인지 결정하라. 갱신기는 ISP가 준 주소가 바뀔 때 레코드를 다시 쓰지만, 포트를 열지도, 통신사 NAT를 뚫지도, 살아 있는 WireGuard 세션이 끝점이 바뀐 것을 알아차리게 하지도 못한다. 동적 DNS가 해결책 전체인지 한 줄뿐인지는 세 조건이 가른다.

조건 하나: 주소가 실제로 바뀐다

가정용 주소는 흔한 이유로 바뀐다. 정전 뒤 모뎀이 다시 동기화하고, ISP가 풀을 재분배하고, 긴 장애 뒤 새 임대가 들어온다. 어떤 회선에서는 거의 바뀌지 않으며 나는 같은 주소가 한 해를 버티는 것을 보았다. 기업 요금제에는 고정 주소가 포함되곤 한다. 열두 달 동안 아무것도 바뀌지 않았다면 손으로 고치는 A 레코드 하나가 살려 둘 데몬을 하나 줄이는 셈이다.

짐작하지 말고 측정하라. 라우터 상태 페이지에서 WAN 주소를 읽고, 바깥 세계가 보는 값과 비교하라. LAN의 한 기계에서 다음을 실행하라:

curl -fsS https://api.ipify.org; echo

두 값이 다르면 라우터 앞에서 무언가가 변환하고 있으며 어떤 호스트 이름 갱신도 그것을 고치지 못한다. 100.64.0.0/10 안의 주소는 통신사 등급 NAT용 공유 대역이고, 올바로 갱신된 이름도 외부에서 시간 초과가 나는 흔한 이유가 이것이다.

조건 둘: 클라이언트가 이름을 다시 조회한다

짧은 TTL은 사람들이 건너뛰는 부분이다. 재귀 리졸버는 레코드의 TTL을 지키지만 클라이언트 스택은 따로 캐시하고, 이미 올라온 터널은 아무것도 다시 해석하지 않는다. 디버깅하는 동안 레코드를 60-300초로 두라. 오래된 응답이 제공되는 창이 줄어들 뿐, 연결된 세션이 이전되지는 않는다.

OpenVPN 은 다시 연결할 때마다 remote vpn.example.net 1194 줄을 다시 해석하고, resolv-retry infinite 는 조회가 실패해도 종료하지 않고 계속 재시도하게 한다. 서버에서는 float 가 출발지 주소가 바뀐 상대를 기존 세션이 따라가게 한다. WireGuard는 더 노골적이다. wg-quick up 는 설정을 적용할 때 Endpoint 을 해석하고, 클라이언트는 터널을 다시 만들 때 그것을 다시 해석한다. 그래서 옛 주소로 여전히 성공하는 핸드셰이크는 멈출 때까지 계속 성공한다.

그 차이가 계획을 만든다. 클라이언트가 필요할 때만 연결하면 주소 변경 비용은 재연결 한 번이다. 며칠씩 세션을 열어 두면 다음 핸드셰이크에서 터널이 죽는다고 보고, 살아 있다고 가정하지 말고 클라이언트가 재시도하게 하라.

조건 셋: 들어오는 경로가 아직 열려 있다

동적 DNS는 이름이 가리키는 곳만 바꾸고 그 밖에는 아무것도 바꾸지 않는다. 라우터의 포트 포워딩, VPN 호스트의 방화벽 규칙, ISP의 인바운드 패킷 허용이 모두 레코드보다 먼저 있어야 한다. 포워딩이 무엇을 향하는지 보라. 인터페이스가 아니라 WAN 주소에 고정되어 있으면 주소 변경이 포워딩을 조용히 깨고 레코드가 비난을 받는다.

밖에서 시험하라. Wi-Fi를 끈 휴대폰의 셀룰러 데이터가 가장 값싼 정직한 시험이고, 같은 LAN의 노트북은 아니다. 이름이 공인 주소로 해석되고 라우터에 NAT 루프백이 없으면 내부 시험은 실패하는데 레코드는 완전히 올바르다. 그래서 대부분이 잘못된 적 없는 레코드를 고치러 간다.

셋 다 맞을 때 무엇을 돌릴까

작은 호스트에는 ddclient가 가장 덜 놀라운 갱신기다. 최소 설정이 공급자가 보는 주소를 게시하므로 이중 NAT 실수를 피한다:

protocol=dyndns2
use=web, web=https://api.ipify.org
server=updates.your-dns-provider.net
login=vpn-home
password=update-token
vpn.example.net

셸 루프 대신 몇 분마다 systemd 타이머로 돌리고, 성공을 가정하지 말고 공급자의 응답을 기록하라. 자격 증명은 열쇠처럼 다뤄라. 모든 클라이언트가 어디로 보내질지를 그것이 정하기 때문이다. 계정 비밀번호 대신 범위가 제한된 갱신 토큰을 쓰고, 파일은 0600 모드로 두고, 갱신은 HTTPS로 보내라.

확정하기 전에 검증하라

조회 한 번이면 바깥 세계가 보는 값을 알 수 있고, 변경 뒤 기다려야 할 TTL도 출력된다:

dig +noall +answer vpn.example.net @1.1.1.1

그 주소를 라우터의 WAN 주소와 비교하라. 같다면 이름이 제 일을 하는 것이고, 아직 실패하는 것은 인바운드 도달성, 열쇠, 또는 다시 해석하지 않은 클라이언트다. 다르다면 갱신기가 잘못된 인터페이스를 게시하는 것이며, 라우터 자체가 아니라 라우터 뒤의 VPN 호스트에서 돌았기 때문인 경우가 많다.

일 분이면 되는 되돌리기를 준비하라. 마지막으로 작동한 주소와 이전 TTL을 적어 두면 공급자가 곤란한 오후를 보내는 동안 둘 다 손으로 게시할 수 있다.

답이 아니오일 때

조건 하나나 셋이 깨지면 설정이 아니라 결정이 바뀐다. 통신사 NAT 뒤에서 실질적인 선택은 ISP에 공인 주소를 요청하거나, 진입점을 안정된 주소를 가진 작은 VPS로 옮기거나, 또는 자체 랑데부를 유지하는 오버레이를 쓰는 것이다. 주소가 고정이라면 갱신기를 건너뛰라. A 레코드 하나, IPv6를 쓴다면 AAAA 레코드 하나, 포트 포워딩은 그대로다.

클라이언트가 연결된 채 주소가 바뀐다면 정직한 수정은 클라이언트에 있다. 재연결 논리와 재시도 간격이지 더 빠른 갱신기가 아니다. 두 번째 공급자를 더하면 간격만 가려진다.

계속하기 전에 네 가지를 순서대로 확인하라:

  • 갱신기가 게시하는 주소가 라우터의 WAN 주소와 일치한다.
  • 레코드의 TTL이 변경이 몇 분 안에 보일 만큼 짧다.
  • 포트 포워딩이 고정 주소가 아니라 인터페이스에 묶여 있다.
  • 마지막 변경 이후 실제 클라이언트 하나가 재연결해 트래픽을 통과시켰다.

네 가지가 모두 맞으면 설정을 그대로 두라. 다음 장애는 이름 문제가 아니라 열쇠나 방화벽 규칙이다. 하나라도 깨지면 움직이는 부품을 더 넣기 전에 그 줄을 고쳐라. RFC 2136 은 갱신 메커니즘 자체를 설명한다. 데몬이 회선에 무엇을 싣는지 보고 싶다면 읽어 볼 만하다.

관련 글