메시지가 나타나는 지점부터 시작하세요. 클라이언트가 연결되고 터널이 올라오면, 로그는 Linux의 경로 추가 명령이 File exists와 함께 실패했다고 보고합니다. 그 문장 어디에도 인증서, 키, 구성 파일에 대한 언급은 없지만 단어는 그렇게 암시합니다. 커널이 자신의 라우팅 테이블을 설명하는 것이며, 설치를 요청한 프리픽스에는 이미 항목이 있습니다.

클라이언트 자체의 순서를 따르세요: 무엇을 요청했는지, 테이블에 이미 무엇이 있었는지, 그 항목을 누가 넣었는지, 그리고 나서야 무엇을 바꿀지. 각 단계마다 가능한 소유자 하나가 제거됩니다.

클라이언트가 실제로 요청한 것

실패 전에 클라이언트는 추가하려는 경로를 보통 목적지, 넷마스크, 게이트웨이, 때로는 메트릭이나 테이블로 기록합니다. 그 줄이 요청입니다. 뒤따르는 오류는 커널의 답이며, 둘은 나란히 읽어야 합니다.

journalctl -u openvpn-client@office -b --no-pager | grep -nE 'route|File exists'
openvpn --config /etc/openvpn/client/office.ovpn --verb 4 --log /tmp/ovpn.log

경로 도우미의 영이 아닌 종료 상태는 서로 다른 커널 응답이 영이 아닌 상태를 만들기 때문에 그 아래 텍스트보다 정보가 적습니다. 정확한 메시지를 보관하세요; 기존 항목과 도달할 수 없는 게이트웨이의 구분이 다음 절 중 어느 것이 적용되는지를 결정합니다.

기존 경로를 읽으세요 — 주소만 보지 마세요

테이블에서 같은 점 표기 사중주를 찾는 것만으로는 충분하지 않습니다. 경로 객체는 주소 패밀리, 테이블, 목적지 프리픽스, 메트릭, 프로토콜, 출력 장치로 식별되며, 프리픽스를 공유하는 항목들은 그 속성이 다를 때 정당하게 공존할 수 있습니다. 충돌하는 것은 텍스트가 아니라 객체 전체입니다.

ip -4 route show table all | grep -F '10.40.'
ip -4 route show match 10.40.0.0/16
ip -4 route get 10.40.0.5

마지막 명령은 무엇이 존재하는지가 아니라 커널이 그 목적지에 대해 지금 어떤 항목을 고를지라는, 앞의 두 명령과 다른 질문에 답합니다. 두 관점 모두 유용하며, 결론을 내리기 전에 비교할 가치가 있을 만큼 자주 어긋납니다. 둘 사이의 불일치가 흥미로운 사례이지 반올림 오류가 아닙니다.

실패한 요청 옆에 프리픽스, 테이블, 메트릭, 장치를 기록하세요. 기존 항목이 같은 속성과 같은 다음 홉을 가지고 있다면, 라우팅 문제가 아니라 중복된 지시입니다.

프리픽스가 가질 수 있는 네 가지 소유자

연결된 경로는 할당된 주소에서 생기며, 그 주소가 존재할 때마다 시스템이 다시 만듭니다. DHCP 클라이언트나 연결 관리자는 자신의 수명 주기의 일부로 경로를 설치합니다. 다른 VPN 클라이언트가 이미 같은 프리픽스를 갖고 있을 수 있습니다. 그리고 로컬 훅이나 스크립트가 다른 무엇도 모르는 경로를 추가할 수 있습니다.

소유자마다 다른 수정이 필요합니다. 연결된 경로는 지울 것이 아니며, 그것을 제거하면 터널이 쓸 수 있게 되기 전에 로컬 접근이 끊길 수 있고 커널이 다시 넣습니다. 관리자 소유 경로는 그 관리자를 통해 바꿔야 하며, 다음 재연결이 되돌리는 수동 ip route del가 아닙니다.

유지되는 인터페이스는 같은 혼란을 쉽게 만듭니다. 터널 장치가 재연결 후에도 남으면 사용자 설정 코드가 설치한 경로가 두 번째 실행에도 남아 있을 수 있어, 깨끗한 상태를 가정한 스크립트는 두 번째에 실패하고 첫 번째에는 동작합니다. 오래된 항목을 의도적으로 지우거나 설정 코드를 멱등하게 만드세요.

block-local은 다른 질문에 답한다

프로필이 모든 트래픽을 터널로 보내면, 클라이언트는 로컬 네트워크를 어떻게 할지 결정해야 합니다. block-local 플래그는 로컬 LAN을 터널로 라우팅하면서 LAN 게이트웨이에 대한 문서화된 예외를 유지하여 그 결정을 바꿉니다 — 이는 도달 가능성에 눈에 보이는 결과를 낳는 트래픽 정책 선택입니다.

이것은 경로 추가가 왜 기존 항목 오류를 반환했는지 설명하지 않으며, 이를 보편적 수리로 받아들이면 실제 충돌이 정책 변경 뒤로 숨습니다. 프로필을 편집한 뒤 로컬 리소스에 접근할 수 없다면 이 플래그는 먼저 확인할 것 중 하나입니다; 경로 추가가 실패한다면 이것이 답은 아닙니다.

어떤 목적지가 로컬로 남을지에 대한 결정으로 다루고, 의도적으로 정해 기록하세요. 로그가 불안해 보일 때 시험해 볼 스위치가 아닙니다.

루프를 닫으세요 — 중복을 원천에서 제거하세요

어느 소유자가 항목을 갖고 있는지 알았다면, 지시가 정의된 곳에서 중복 지시를 제거하세요. 프로필의 route 줄, 서버에서 오는 push, 더 이상 실행할 필요가 없는 훅일 수 있습니다.

ip -4 route show match 10.40.0.0/16
ip -4 route get 10.40.0.5
journalctl -u openvpn-client@office -b --no-pager | tail -n 15

그런 다음 다시 연결하고 세 가지를 확인하세요: 터널이 올라오고, 의도한 목적지가 원하는 경로로 해석되며, 실패가 사라지고 그 자리에 새로운 실패가 나타나지 않아야 합니다. 경로 선택이 잘못된 채로 로그만 깨끗한 것은 수리가 아닙니다.

프리픽스가 한쪽에서는 로컬 LAN을, 다른 쪽에서는 원격 네트워크를 뜻한다면, 문제는 중복이 아니라 주소 겹침이며, 어떤 삭제도 두 의미를 동시에 참으로 만들지 못합니다. 그 경우 두 네트워크 중 하나에 다른 계획이 필요합니다. 둘 중 어느 쪽에 닿기 전에 어느 쪽의 번호를 다시 매길지 정하세요.

관련 글