핑 감시자는 끊긴 터널과 정상 터널을 구분하지 못한다
인터넷으로 보내는 핑은 보이는 것보다 적은 것을 증명한다. 터널을 안쪽에서 점검하고, 행동하기 전에 실패를 세고, 서버 전환은 별도의 결정으로 다루라.
감시자가 도움이 되는지 해가 되는지는 조사가 무엇을 구분할 수 있는지, 몇 번의 연속 실패가 행동을 정당화하는지, 그 행동이 재연결인지 전환인지의 세 가지 조건이 결정한다. 공개 주소로 핑을 보내는 cron 한 줄은 이 중 어느 것에도 잘 답하지 못한다. 정상인 터널을 다시 연결하고 끊긴 터널은 그대로 두며, 둘 다 기록 없이 한다. 지킬 가치가 있는 설계는 이 세 가지 선택을 명시한다.
조사가 나머지 모든 것을 결정하는 부분이다.
인터넷으로 보내는 핑이 실제로 증명하는 것
공개 리졸버로 핑을 보내면 로컬 인터넷 경로가 살아 있음을 보여 준다. 터널이 트래픽을 나른다는 것을 증명하지는 않으며, 전체 터널 프로필에서는 핑 자체가 터널을 지나가므로 정상 응답과 끊긴 터널이 동시에 존재할 수 있고 클라이언트는 여전히 패킷을 전달한다. 프로필이 이름 조회를 터널로 보낸다면 DNS 실패는 죽은 연결로 읽혀 아무것도 고칠 수 없는 재연결을 시작한다.
오류의 두 방향 중 어느 것도 종료 코드에 나타나지 않는다. 그 신호 위에 세운 감시자는 cron 일정표를 가진 동전 던지기일 뿐이다.
터널 뒤에 사는 무언가를 점검하라
ip -brief addr show tun0 ip route get 10.100.20.10 nc -z -w3 10.100.20.10 443
안쪽에서 점검하되 가장 싼 확인을 먼저 한다. 인터페이스가 있으면 터널이 올라와 있고, 알려진 내부 주소로의 경로 조회는 트래픽이 그리로 들어갈 것임을, 반대편 호스트로의 TCP 점검은 무언가가 실제로 응답함을 알려 준다. echo 요청만으로는 속는데, 내부 호스트 다수는 TCP에는 기꺼이 응답하지만 ICMP는 버리므로 핑에 기댄 감시자는 한 번도 멈춘 적 없는 터널을 계속 다시 연결한다.
조사에 시간 한도를 두고 별도의 종료 상태를 주어라. 삼십 초 동안 매달리는 조사는 감시자를 지연이 내장된 장애 감지기로 바꾼다.
한 줄과 루프 중에서 고르라
* * * * * nc -z -w5 10.100.20.10 443 || myvpn reconnect
cron 항목은 기억이 없는 한 줄이라 추가 재연결에 비용이 없는 노트북에 어울린다. 감시 아래의 루프는 카운터를 유지하고 몇 번 놓친 뒤에만 움직이므로 불안정한 회선이 재연결 폭풍을 일으키지 못하게 한다. 어느 쪽이든 크래시를 견디고 저널에 쓰도록 감독자 아래에서 실행하라. 어느 판이 더 짧은지가 아니라 쓸데없는 재연결이 문제인지로 고르라.
failures=0 while sleep 30; do if nc -z -w5 10.100.20.10 443; then failures=0 else failures=$((failures+1)); fi if [ $failures -ge 3 ]; then myvpn reconnect; failures=0; fi done
그 루프는 창구간 비율이 아니라 연속 실패를 센다. 창에는 시계와 표본 기억이 필요하고, 손으로 만든 감시자의 버그 대부분은 그 산술에 산다.
전환은 다른 결정이다
서버 전환은 재연결과 다르다. 먼저 옛 연결을 끊어라, 첫 클라이언트가 아직 주소를 쥐고 있는데 두 번째가 시작하면 충돌하기 때문이다. 전환 전에 연속 실패를 세고 시도에 상한을 두며, connect 명령의 종료 상태를 믿는 대신 새 연결이 올라온 뒤 다시 점검하라. 잘못된 설정이 루프로 모든 서버를 돌아서는 안 된다.
전체 터널 안에서 VPN 서버 자체의 공개 주소를 점검하지 마라. 그 확인은 자기가 시험하는 것에 의존하며, 검증해야 할 경로가 사라진 뒤에도 성공을 보고한다.
어떤 조사가 돌았는지, 무엇을 돌려주었는지, 어떤 행동이 이어졌는지 기록하라. 그 기록이 수수께끼 같은 재연결을 진단 가능한 사건으로 바꾼다.