동시에 도는 두 VPN 클라이언트는 중첩 터널을 만들지 않고, 만드는 것은 두 개의 터널과 경로를 둘러싼 말다툼이다. 중첩 터널은 안쪽 클라이언트가 자기 서버로 가는 연결 자체를 바깥 터널이 나를 때 존재하며, 그것은 의도해서 짜는 배치다. 잘 되면 안쪽 서버는 바깥 서버의 주소를 보지만, 잘못되면 한 클라이언트가 다른 쪽을 조용히 우회해 다시 연결한다. 중첩이 진짜인지 우연인지는 세 가지 조건이 정한다.

세 가지 조건이 중첩을 정한다

첫째는 어느 종단점이 어느 경로를 필요로 하는가다. 안쪽 서버의 주소를 적고, 바깥 서버의 주소를 적고, 안쪽 서버는 바깥 터널을 통해서만 닿는다고 분명히 밝힌다. 나머지 모든 것은 그 문장에서 따라 나오며, 어떤 경로가 어느 표에 속하는지도 포함된다.

둘째는 각 계층에서 경로를 볼 수 있는가다. 특정 목적지가 어떤 경로를 쓸지 커널에 물을 수 없다면, 마지막 출구 IP에서 연쇄를 추론하는 셈이고, 그것이 바로 중첩과 우연을 구별하지 못하는 증거다.

셋째는 바깥 터널이 끊길 때 무슨 일이 일어나는가다. 안쪽 터널은 함께 멈출 수도, 평범한 네트워크로 다시 연결할 수도, 바깥 경로가 돌아올 때까지 막힌 채 있을 수도 있고, 셋 다 옹호할 수 있는 정책이다. 같은 정책이 아니며, 대부분 클라이언트의 기본 동작은 두 번째다. 연결이 건강하다고 표시하면서 물리 네트워크로 종단점을 다시 연결하는 클라이언트가, 의도한 연쇄가 조용히 무관한 두 터널이 되는 가장 흔한 방식이다.

조건 하나: 어느 종단점이 어느 경로를 필요로 하는가

ip route get 203.0.113.10 은 그 질문에 곧바로 답하며, 경로, 출발지 주소, 그리고 커널이 지금 그 목적지에 쓸 인터페이스를 출력한다.

안쪽 클라이언트가 시작되기 전에 안쪽 서버에서 한 번, 시작한 뒤에 다시 한 번 실행해 비교한다. 답이 물리 인터페이스에서 바깥 터널의 인터페이스로 바뀌면 그 시점에 중첩은 진짜다. 바뀌지 않으면 패널이 무슨 말을 하든 안쪽 클라이언트는 직접 연결하고 있다. 바깥 서버의 주소에 대해서도 반복해야 하는데, 그 주소는 여전히 물리 인터페이스로 풀려야 하며, 두 종단점을 재귀적으로 붙잡는 경로 가 기계를 네트워크에서 완전히 떼어내는 고장이기 때문이라는 점이다.

조건 둘: 각 계층에서 경로를 살핀다

현대 클라이언트에서 경로 선택은 주 표만이 아니다. 정책 규칙은 표시가 붙은 패킷을 다른 표로 보낼 수 있고, 클라이언트는 자기 소켓을 인터페이스에 묶을 수 있고, 컨테이너나 네임스페이스는 자기 표를 따로 가진다. ip rule 과 ip route show table all 이 그중 무엇이 작동 중인지 알아내는 방법이다.

자기 소켓에 SO_MARK 를 붙이는 클라이언트나 특정 장치에 묶이도록 설정된 클라이언트는, 당신이 정리했다고 생각한 기본 경로를 우회한다. 이것은 결함이 아니라 기능이며, 믿을 수 있는 확인은 클라이언트와 같은 네임스페이스에서 도는 것뿐이라는 뜻이다. 클라이언트가 컨테이너에서 돈다면 호스트가 아니라 그 컨테이너 안에서 확인을 실행한다.

조건 셋: 바깥 터널이 끊길 때 무슨 일이 일어나는가

장애 시 동작에는 기본값이 아니라 결정이 필요하다. 바깥 터널이 사라질 때 안쪽 터널이 어떻게 되어야 하는지 적고, 그대로 클라이언트가 하게 만든다.

선택지는 구체적이다. 바깥 경로가 사라질 때 안쪽 클라이언트를 멈추면 깨끗한 연쇄와 분명한 장애가 남는다. 그대로 직접 다시 연결하게 두면 가용성은 얻지만 연쇄가 노렸던 성질은 조용히 사라진다. 바깥 경로가 돌아올 때까지 막는 것은 가장 엄격하고 운영하기에도 가장 성가신데, 바깥 터널의 흔들림이 모두 눈에 보이는 사고가 되기 때문이다.

설정을 읽는 것만으로는 어느 쪽인지 알 수 없으므로 무해한 트래픽과 의도한 바깥 장애로 셋 다 시험한다. 바깥 터널을 끊고 안쪽 클라이언트가 무엇을 하는지 보며, 끊긴 동안 경로를 다시 확인한다. 그다음 바깥 터널을 되살리고, 안쪽 클라이언트를 그사이 고른 직접 경로에 남겨 두지 않고 연쇄가 다시 짜이는지 확인한다.

연쇄가 주지 않는 것

계층을 더하면 종단점과 키, 고장 유형이 늘어나지만 익명성 보장은 늘지 않고 바깥 운영자가 터널의 존재를 보지 못하게 만들지도 못한다. 중첩이 무엇을 지키는가라는 주장은 반드시 어느 관찰자로부터 지키는지를 밝혀야 한다.

산출물은 돌아가는 연결이 아니라, 어느 종단점이 어느 경로를 쓰는지, 바깥 장애 때 무엇이 일어나는지, 현재 상태를 보여 주는 세 명령을 적은 짧은 문서다. strongSwan의 전달 문서는 Linux 호스트에서 터널 트래픽이 인터페이스 사이로 어떻게 전달되는지 알아보는 데 유용한 참고다. 당신의 연쇄를 만든 기본값은 계약이 아니므로 클라이언트를 업데이트할 때마다 확인을 다시 돌린다. 점검할 수 없는 중첩 터널은 상태등이 달린 소문일 뿐이다.

관련 글