VPN이 연결되면 Vagrant VM이 사라진다: 끊긴 경로는 누구의 것인가
일 분 전까지 응답하던 머신이 연결 순간에 사라진다. 무엇이든 고치기 전에 끊긴 경로의 주인을 판단한다.
머신은 일 분 전까지 응답했는데 VPN이 연결되자 같은 주소가 시간 초과된다. 세 가지 결함이 이 증상을 만들며 서로 다른 머신에 있다. 호스트가 사설 네트워크로 가는 경로를 잃거나, 게스트의 NAT 범위가 터널이 지금 광고하는 범위와 충돌하거나, 전체 터널이 호스트의 모든 경로 소유권을 가져갈 수 있다. 구성을 바꾸기 전에 어느 경우인지 먼저 밝혀야 한다. 수정 위치가 각각 다르기 때문이다.
경로를 보라, 머신이 아니라
터널이 살아 있는 동안 게스트 주소에 대한 호스트의 라우팅 결정을 본다. 여전히 호스트 전용 어댑터를 가리키는 경로는 문제가 아니다. 지금 VPN 어댑터를 가리키는 경로가 문제이며, 그것을 바꾼 것은 당신이 아니라 클라이언트다. 어댑터가 주소를 유지한다는 것은 인터페이스가 살아남았다는 뜻이고, 경로가 살아남았다는 사실과는 다르다.
연결 순간에 정확히 끊기는 SSH 세션은 예상된 동작이다. 클라이언트가 어댑터를 재활용하고 경로를 설치하므로 연결이 몇 초 동안 죽는다. 결함은 결코 돌아오지 않는 연결이지, 잠깐 깜빡인 연결이 아니다.
터널 전에 테이블을 뜨고 후에 다시 떠서 그 두 출력을 비교한다. 차이가 곧 진단이며, 네트워크 소유자가 요구할 증거이기도 하다.
ip -4 route get 192.168.56.10
ip -brief addr show
ip route show table main | head -20연결 전과 후에 호스트 테이블을 읽는다
리눅스에서는 겹치는 경로 사이의 우선순위가 프리픽스 길이와 메트릭에서 나오므로 더 구체적인 VPN 경로가 틀려도 이긴다. 윈도우에서는 인터페이스 메트릭이 동점을 가르며, 터널 어댑터는 보통 가상 어댑터보다 낮은 메트릭으로 나타난다. 두 경우 모두 보이는 증상은 같다. 패킷이 터널 어댑터로 나가 사라진다.
게스트 프리픽스의 경로 옆에 어댑터와 그 메트릭을 출력한다. 그 두 출력이 소유권 질문에 한눈에 답한다.
Get-NetAdapter | Select-Object Name, InterfaceIndex, InterfaceMetric
Get-NetRoute -DestinationPrefix 192.168.56.0/24
route print -4 | Select-String '192.168.56'경로는 바뀌었는데 어댑터 메트릭은 그대로라면 클라이언트가 경쟁 경로를 설치한 것이다. 메트릭이 바뀌었다면 클라이언트가 어댑터 순서를 바꾼 것이다. 둘 다 고칠 수 있고, 고치는 위치가 다르다.
게스트의 NAT 범위가 충돌일 때
VirtualBox NAT는 기본으로 10.0.2.0/24를 쓰고, 같은 범위를 밀어 넣는 터널은 게스트가 그 트래픽을 실제 목적지 대신 자신의 NAT 게이트웨이로 보내게 만든다. 패킷은 호스트를 떠나지 않으므로 반대편 방화벽 로그에는 절대 나타나지 않는다. Docker Machine도 호스트 전용 계획에서 같은 종류의 충돌이 있으며, 그 계획을 바꾸려면 머신과 인증서를 다시 만들어야 할 수 있다.
대체 범위는 터널이 이미 광고하는 것, 그다음 사무실 네트워크가 쓰는 것, 그다음 이 호스트의 모든 가상 어댑터가 주장한 것을 나열해 고른다. 라우팅을 깨는 것은 겹침이며, 비슷하게 생겼는지는 무관하다. 한 범위가 다른 범위 안에 완전히 들어앉아 있으면서도 언뜻 전혀 닮지 않을 수 있다.
새 범위는 머신을 만들 때 정하거나, 바꾸고 다시 로드한 뒤 실패하는 연결을 게스트에서 다시 시험한다. 중요한 것은 게스트 자신의 테이블이다.
VBoxManage modifyvm devbox --natnet1 10.77.0.0/24
vagrant reload devbox --provision
vagrant ssh devbox -c 'ip route get 10.20.0.15'클라이언트와 싸우지 않고 경로를 되돌린다
모든 플랫폼에 호스트 전용 프리픽스를 다시 앞으로 끌어오는 방법이 있다. macOS에서는 호스트 전용 인터페이스로 가는 정적 경로가 다음 연결까지 유효하다. 윈도우에서는 가상 어댑터의 인터페이스 메트릭을 낮추면 계속 우선된다. 리눅스에서는 교체 작업이 프리픽스 하나를 덮는다. 셋 다 임시방편이다. 경로를 다시 주장하는 클라이언트가 그것을 되돌리기 때문이다.
부팅 시 무작정 재연결하는 대신 검사를 스크립트로 만든다. 연결할 때마다 게스트 프리픽스의 경로를 출력하는 작은 스크립트가 수수께끼를 로그 한 줄로 바꾼다.
프로필이 전체 터널이라면 네트워크 소유자에게 분할 터널링이나 문서화된 예외를 요청한다. 보안 정책을 우회하는 경로를 조용히 추가하는 것은 수정이 아니라, 나중에 감사인과 함께 오는 두 번째 문제다.
수정을 양쪽에서 확인한다
변경 후 세 경로를 검증한다. 호스트에서 게스트로, 게스트에서 기업 호스트로, 게스트에서 인터넷으로. 하나를 되살리고 다른 하나를 깨는 수정은 수리를 가장한 구성 변경이다. 비교가 같은 조건이 되도록 변경 전에 모은 것과 같은 출력을 뜬다.
바뀐 인터페이스, 메트릭, 경로를 시각과 함께 기록해 다음 발생이 재구축이 아니라 조회가 되게 한다. 그 메모는 긴 티켓 스레드보다 값지다.
ip -4 route get 192.168.56.10
traceroute -n -m 4 10.20.0.15
curl -sS -o /dev/null -w '%{http_code}\n' https://example.com호스트가 다시 게스트에 닿고 게스트가 LAN에 닿으면, 시작했던 경로를 되찾은 것이다. 둘 중 하나만 동작한다면 남은 결함은 다른 소유자의 영역에 있고, 차이가 어느 영역인지 알려 준다.