게이트웨이 열이 비어 있을 때마다 라우팅 테이블을 고장으로 오독하기 쉽지만, 그 줄은 보통 그 자체로 완전합니다. via 필드는 커널이 패킷을 다음 홉 주소로 넘길 때만 나타나며, 인터페이스에 연결된 경로는 대신 링크 계층 해석이나 지점 간 피어를 통해 목적지에 도달합니다. 열을 왼쪽에서 오른쪽으로 읽으면 어느 경우인지 알 수 있고, 그 읽기는 누군가 기본 경로를 편집하기 전에 이루어져야 합니다. 게이트웨이가 없다는 티켓의 대부분은 이 구분에서 끝납니다.

경로 줄을 열마다 읽기

각 항목은 목적지와 그 접두사 길이로 시작하고, 이어서 고정된 어휘로 수정자를 덧붙입니다: via, dev, proto, scope, src, metric. 198.51.100.0/24 dev tun0 proto kernel scope link src 198.51.100.2 같은 줄은 빽빽하지만 완전히 명시되어 있습니다. 빠진 것은 없으며 라우터 주소도 함축되지 않습니다.

흥미로운 부분은 via의 부재입니다. 다음 홉이 없으면 커널은 지정된 인터페이스에서 목적지를 직접 해석하며, 터널의 경우 이는 프레임을 터널 장치에 넘기고 캡슐화가 거기서부터 처리하게 하는 것을 뜻합니다. proto kernel는 주소가 할당될 때 항목이 자동으로 설치되었음을 기록하며, 관리자가 입력한 것이 아닙니다. scope link은 그 링크에서 라우터를 거치지 않고 목적지에 도달할 수 있음을 말하고, src은 일치하는 트래픽의 소스로 커널이 선호할 주소를 지명합니다.

이제 기본 경로도 같은 방식으로 읽어 보십시오: default via 192.0.2.254 dev eth0 proto static metric 100. 여기서 via이 있는 것은 패킷이 실제로 다음 홉을 필요로 하기 때문이며, 그 홉 자체도 eth0에서 도달 가능해야 합니다. 두 줄은 서로의 변형이 아니라 트래픽이 어디로 가는지에 대한 서로 다른 질문에 답합니다.

서로 혼동되는 두 가지 경로 형태

터널 서브넷 경로와 기본 경로는 스크린샷에서 비슷해 보이지만 전혀 다르게 동작합니다. 아래 표를 필드를 읽는 보조 수단으로 사용하고, 안내서의 예시를 믿는 대신 디버그하는 머신에서 실제 숫자를 확인하십시오.

Piece of the lineWhat it settlesWhat it says nothing about
The destination and maskWhich packets are eligible to matchWhere those packets leave the host
via plus its addressWhich next hop receives them, and therefore that a router is involvedWhether that router is reachable or sane
devWhich interface carries the encapsulated or raw packetWhether the interface is up or has a carrier
proto and scopeWho installed the entry and how far the destination is considered to beWhether a firewall later drops the traffic

표가 말해 줄 수 없는 것은 의도입니다. 터널을 통해 사설 범위로 가는 직접 경로는 의도적인 분할 터널 설계이며, 모든 것을 VPN으로 보내야 하는 호스트에 같은 형태가 나타나는 것은 증상입니다. 의도는 그 항목을 만든 구성에 살아 있으므로, 커널이 뭔가 잘못했다고 결론 내리기 전에 그것을 설치한 도구를 보십시오.

마찬가지로 게이트웨이가 없다고 해서 하나를 지어내도 된다는 뜻은 아닙니다. 경로에 정말로 다음 홉이 필요하다면, 그 홉은 그것을 운반하는 인터페이스에서 도달 가능해야 하며, 지점 간 터널에서는 피어 주소가 로컬 주소와 같은 객체가 아닙니다. 로컬 터널 주소를 이더넷 라우터로 취급하는 것은 올바르게 보이지만 아무것도 전달하지 않는 경로를 만드는 흔한 방법입니다.

커널에 실제로 어느 줄을 사용할지 물어보기

표를 읽는 것은 조회를 수행하는 것과 다르며, 커널은 답하기 전에 정책 규칙, 여러 테이블, 캐시된 항목을 참조하기 때문입니다. 실제 조회를 수행하는 동사는 ip route get이며, 해당 속성을 가진 패킷이 택할 경로를 출력합니다.

ip route get 203.0.113.37 from 198.51.100.2 iif tun0

일반적인 로컬 조회는 전달되는 클라이언트와 다른 경로를 고를 수 있으므로, 정말로 관심 있는 목적지로 바꾸고, 트래픽이 소스 기준으로 선택되거나 전달될 때 from 또는 iif를 추가하십시오. 응답은 인터페이스, 선택된 소스 주소, 그리고 모든 다음 홉을 지명하며, 이는 그 순간 패킷이 라우팅될 정보와 같습니다.

응답이 놀랍다면 무엇이든 바꾸기 전에 규칙을 출력하십시오: ip -4 rule show은 우선순위 순으로 나열하며, 자체 테이블이나 표시된 패킷용 규칙을 설치하는 VPN 클라이언트는 기본 테이블에 전혀 나타나지 않습니다. 모든 테이블을 나열하면 그 틈이 메워집니다.

ip -4 route show table all | grep -E 'tun|default'

기본 경로를 바꾸기 전에 하부망을 확인하십시오

터널 자체의 패킷은 원격 엔드포인트에 도달해야 하며, VPN이 올라오기 전에 존재하던 경로를 사용해 물리 인터페이스를 통해 그렇게 합니다. 그 엔드포인트를 고정하지 않고 기본 경로 전체를 바꾸면 캡슐화된 패킷이 자신들이 만들어야 할 터널 안으로 들어가고 연결이 무너집니다. 먼저 엔드포인트 주소만으로 조회해 엔드포인트 경로를 확인하십시오.

변경할 때 세 가지를 분리해 두십시오: 물리 인터페이스에 남아야 하는 엔드포인트 경로, 터널로 들어가야 하는 사설 범위, 그리고 나머지 전부를 결정하는 기본 경로입니다. 그 순서로 나누고 한 번에 하나씩 적용하며 각 단계 후에 조회를 다시 실행하십시오. 나중에 핑이 실패해도, 권한, 응답 라우팅, DNS, 서비스 자체가 모두 올바른 경로의 하류에 있으므로 그 자체로는 거의 아무것도 증명하지 못합니다.

편집 전에 그 줄이 준 네 가지 값을 적어 두십시오: 목적지, 다음 홉 또는 그 부재, 장치, 선택된 소스. 나중의 변경이 그중 하나를 움직인다면 어떤 결정이 실제로 바뀌었는지 알 수 있고, 전체 테이블을 추측하는 대신 항목 하나를 복원할 수 있습니다.

관련 글