두 VPN 풀을 위한 출발지 라우팅: 규칙이 놓치는 것
from 형태의 규칙은 SNAT가 다시 쓰기 전 클라이언트 주소와 매칭되고, 게이트웨이에서 한 시험은 둘 중 어느 것과도 매칭되지 않습니다. 풀마다 조회를 실행하고 대신 우선순위를 읽으십시오.
클라이언트 풀이 둘, 게이트웨이가 하나이고, 한 규칙은 첫 번째 풀을 빠른 업링크로 내보내고 다른 규칙은 두 번째 풀을 파트너 터널로 보내는 계획은 사소해 보입니다. 그런데 규칙을 넣어도 두 번째 풀은 여전히 기본 경로로 나갑니다. 규칙이 고장 난 것은 아닙니다. 패킷의 출발지는 조회가 일어나는 순간 작성자가 기대한 값이 아니며, 변환과 조회가 같은 패킷 여정의 서로 다른 지점에서 일어나고 그 순서가 대부분이 그리는 머릿속 그림과 반대이기 때문입니다.
조회는 출발지가 다시 쓰이기 전에 일어난다
VPN 클라이언트에서 전달되는 패킷에 대해 커널은 정해진 순서를 실행합니다. 패킷은 터널 인터페이스에 도착하고 conntrack과 DNAT이 있는 prerouting을 지나며, 다음으로 라우팅 결정이 내려지고, 다음으로 포워딩, 다음으로 SNAT이 마지막에 적용되는 postrouting을 지납니다. from 형태의 규칙은 바로 그 라우팅 결정 시점에 참조되므로, 클라이언트의 원래 주소를 보게 되고 변환된 주소는 보지 않습니다.
따라서 masquerade 규칙을 추가해도 나가는 흐름에 어떤 정책이 매칭되는지는 바뀌지 않습니다. 바뀌는 것은 반대편이 보는 내용, 따라서 어떤 되돌아오는 경로가 존재하는지입니다. 이 둘은 서로 다른 결과이고 변경 검토는 이 둘을 늘 혼동합니다. 이 둘을 분리하면 설계는 보통 금방 분명해집니다.
변환된 주소는 응답 방향에서 규칙에 나타납니다. 게이트웨이로 돌아오는 패킷은 변환된 주소를 목적지로 하며, 목적지나 패킷이 들어온 인터페이스를 기준으로 한 정책 규칙이 있다면 바로 그 값을 매칭하게 됩니다. 같은 연결이지만 방향마다 진실의 출처가 다릅니다.
| Stage | Source the kernel sees | What it means for your rule |
|---|---|---|
| Prerouting | Client address, 172.31.7.42 | Where marks and DNAT are applied |
| Routing decision | Still 172.31.7.42 | This is where from rules match |
| Postrouting | Becomes 198.51.100.9 | What the far end and its return route see |
따라서 출발지가 다른 두 풀에는 정말로 다른 테이블이 필요하고 설계는 타당합니다. 위의 표가 배제하는 것은 원격 사이트가 무엇을 받았는지 보고 규칙을 추론하는 지름길입니다.
게이트웨이에서 한 시험은 풀의 시험이 아니다
게이트웨이가 스스로 만든 트래픽은 인터페이스로 도착하지 않았으므로 prerouting을 절대 지나지 않습니다. 그것은 출력 경로에서 라우팅되고, 출발지는 게이트웨이 자신의 주소이며, 클라이언트 범위를 기준으로 한 from 규칙은 매칭되지 않습니다. 이 영역의 모든 티켓이 말하는 박스에서는 되는데 클라이언트에서는 안 된다는 것은 바로 그 사실의 반복입니다.
클라이언트를 근사하지 말고 모사하십시오: 라우팅 조회는 출발지와 입력 인터페이스를 주어 직접 물을 수 있습니다.
ip route get 198.51.100.9 from 172.31.7.42 iif tun0
ip route get 198.51.100.9 from 172.31.8.42 iif tun0
ip route show table 201
풀마다 한 번씩 실행하십시오. 두 명령이 같은 인터페이스를 반환하면 규칙이 풀을 분리하지 못하는 것이고, 이유는 빠진 규칙이거나 둘 다에 매칭되는 더 높은 우선순위 규칙입니다. 서로 다른 인터페이스를 반환하는데도 클라이언트가 실패하면 장애는 조회 뒤에 있으므로 규칙을 더 볼 필요가 없습니다.
우선순위이지 파일에서의 위치가 아니다
규칙은 우선순위 오름차순으로 평가되며 중요한 것은 숫자이고 입력한 순서가 아닙니다. local 테이블은 우선순위 0, main 테이블은 32766, 기본 규칙은 32767에 있으므로 기본 우선순위로 추가한 규칙은 목록 끝 근처에 놓여 거의 모든 것에 집니다.
ip rule show
ip rule add from 172.31.8.0/24 lookup 201 priority 1000
ip -4 route show table 201
우선순위를 명시하면 의도한 순서가 파일에서도 검토에서도 보입니다. 또한 나중에 추가한 규칙이 기존 규칙을 조용히 앞지르는 것을 막는데, 이것이 무관한 변경 뒤에 동작하던 정책이 멈추는 가장 흔한 원인입니다.
일치하는 규칙이 불완전한 테이블을 가리키는 것이 다른 함정입니다. 테이블 201에 기본 경로는 있지만 목적지로 가는 경로가 없으면 패킷은 버려지거나 잘못된 곳으로 보내지고, 규칙만 보면 완벽하게 옳아 보입니다. 규칙이 아니라 테이블을 읽으십시오. 규칙은 포인터이고 빈 테이블은 아무것도 가리키지 않는 포인터입니다.
되돌아오는 경로는 여전히 있어야 한다
출발지 정책은 출구를 고릅니다. 되돌아오는 경로를 만들지는 않습니다. 두 번째 풀이 파트너 터널로 나간다면 파트너는 172.31.8.0/24에 어떻게 도달하는지 알아야 하며, 게이트웨이로 돌아가는 경로이거나 이미 알고 있는 변환된 주소를 받는 방식입니다.
둘 중 하나를 고르는 것은 눈에 보이는 결과가 있는 설계 결정입니다. 클라이언트 범위를 되돌려 라우팅하면 파트너 쪽에서 클라이언트별 정체성이 유지되고 파트너가 여러분의 프리픽스를 받아들여야 합니다. 변환은 풀을 하나의 주소 뒤에 숨기고 파트너가 그 주소만 받아들이면 되지만, 누가 접속했는지에 대해 양쪽 로그가 더 이상 일치하지 않는 비용이 따릅니다.
무엇을 고르든 풀 정의 옆에 적어 두십시오. 누군가의 기억에만 존재하는 되돌아오는 경로는 파트너가 방화벽을 바꿀 때까지 살아남고 그 뒤 재구성에 하루가 걸리는 바로 그런 물건입니다.
정책에서 게이트웨이 자신의 터널을 잡지 마십시오
클라이언트를 위해 쓴 규칙은 제외하지 않는 한 게이트웨이가 만드는 트래픽에도 적용됩니다. 마크나 출력 인터페이스를 기준으로 한 넓은 규칙은 게이트웨이 자신의 파트너 연결을 잡을 수 있고, 그러면 정책을 나르는 터널이 정책에 의해 라우팅됩니다. 이것은 공급자 장애처럼 보이는 루프나 단절을 만듭니다.
각 규칙을 출발지 프리픽스, 입력 인터페이스, 지원되는 경우 클라이언트 패킷만 지니는 마크까지 설계가 허용하는 만큼 좁히십시오. 그런 다음 규칙을 바꿀 때마다 게이트웨이 자신의 연결을 시험하십시오, 장애가 자기 참조적이라 클라이언트 시험에는 나타나지 않기 때문입니다.
ip-rule 매뉴얼 페이지는 선택자와 우선순위의 의미를 문서화합니다. 풀별 조회 시험과 결합하면 설계를 검증할 수 있게 되는데, 이것이 한 해를 버티는 정책 라우팅과 모두가 건드리기를 두려워하는 정책 라우팅의 차이입니다.