중첩 IPsec은 두 계층이 서로 다른 장비에서 종료될 때 이해하기 쉽다. 게이트웨이 네 대, 터널 두 개, 그리고 설계가 동작하는지를 결정하는 한 가지 질문: 내부 터널이 패킷 처리를 끝냈을 때 외부 터널은 실제로 무엇을 보는가? 여기에 답하면 셀렉터, 경로, 문제 해결 순서가 따라온다. 틀리면 기술적으로는 살아 있는 터널을 하루 종일 디버깅하게 된다.

네 개 게이트웨이 모델

외부 게이트웨이 A와 B가 두 사이트 사이에 첫 터널을 만든다. A 뒤에는 전송 주소10.60.0.2를 가진 내부 게이트웨이 C가, B 뒤에는 전송 주소10.70.0.2를 가진 내부 게이트웨이 D가 있다. 애플리케이션 네트워크는 C와 D 뒤에 있고, 예제의 모든 주소는 의도적으로 겹치지 않는다.

application net -> C -> A == outer IPsec == B -> D -> application net
                       \---------- inner IPsec ----------/

C transit: 10.60.0.2      D transit: 10.70.0.2
A and B:    underlay addresses only

계층을 네 호스트로 나누면 각 장비가 경계 하나를 강제한다. 두 계층을 한 호스트에서 실행하면 한 장비에서 두 세트의 정책, 두 개의 라우팅 테이블, 두 가지 장애 모드를 조화시켜야 하며, 가능은 하지만 관찰하기는 훨씬 어렵다.

각 계층은 자기 보호만 제거한다

C는 D를 위해 애플리케이션 패킷을 암호화한다. 결과는 C에서 D로 주소 지정되며, 그것이 A에 도달한다. 이후의 모든 것은 그 재작성에 달려 있다.

A는 그것을 B를 위해 다시 암호화한다. B는 외부 계층을 복호화하고, C에서 D로 가는 패킷을 보고, 여전히 암호화된 채로 전달한다. D는 내부 보호를 제거하고 애플리케이션 패킷을 전달한다.

따라서 A와 B는 내부 엔드포인트와 그 메타데이터를 보지만, 애플리케이션 페이로드를 복호화하는 당사자는 아니다. 이것은 설계의 실제 속성이며, C, D 또는 애플리케이션 호스트를 신뢰한다는 주장이 아니다.

외부 셀렉터는 내부 게이트웨이를 지목한다

여기에서 이런 구성의 대부분이 실패한다. 정책 기반 외부 터널에서는 협상하는 셀렉터에 A와 B가 실제로 다루는 주소가 들어 있어야 한다:10.60.0.2/32그리고10.70.0.2/32, 올바른 로컬 및 원격 순서로.

최종 애플리케이션 서브넷을 외부 셀렉터에 넣는 것은 동작하지 않는다. 패킷이 A에 도달할 때쯤이면 내부 캡슐화가 A가 보호해야 할 대상을 이미 다시 써 두었기 때문이다. 그러면 외부 정책은 아무것과도 일치하지 않고, 터널은 데이터를 나르지 않은 채 올라온다.

외부 허용을 UDP 500으로 좁히지도 마라. 내부 연결에는 자체 데이터 경로가 있고, 협상한 것에 따라 ESP 또는 UDP 캡슐화를 사용하므로 외부 정책이 그 프로토콜을 허용해야 한다.

각 게이트웨이에서swanctl --list-sas로 결과를 확인하고,자식 보안 연관이 의도한 주소를 보고하는지, 가정한 주소가 아닌지 확인하라. 목록에 애플리케이션 서브넷이 보이면 외부 정책이 잘못된 계층에 대해 작성된 것이다. 라우팅을 디버깅하기 전에 셀렉터를 고쳐라. 라우팅은 정상으로 보이지만 카운터는 움직이지 않을 것이다.

포워딩과 재귀의 함정

셀렉터는 라우팅을 대체하지 않는다. A와 B는 C와 D 사이의 트래픽을 양방향으로 포워딩해야 하며, 이는 IP 포워딩 활성화, 터널을 가리키는 경로, 반대편에 존재하는 반환 경로를 뜻한다.

외부 터널이 XFRM 인터페이스를 사용하면 경로는 인터페이스를 선택하고, 협상된 정책은 여전히 그것이 나르는 것을 제한한다. 인터페이스는 보호 범위를 넓히지 않는다. 커널이 패킷을 집어 올리는 방식만 바꾼다.

함정은 재귀다. B의 외부 엔드포인트로 가는 A의 경로는 A가 구축 중인 터널이 아니라 언더레이를 따라야 한다. 그렇지 않으면 캡슐화가 자기 안을 여행하려 하고 연결은 끝내 완료되지 않는다.

계층을 추가하기 전에 변환을 살펴라

다른 무엇을 조정하기 전에 A와 B의 모든 소스 NAT을 보라. IPsec 정책이 적용되기 전에 C의 주소를 다시 쓰는 규칙은 합의된 셀렉터를 깨뜨릴 수 있고, 반대편에서 D가 받는 것을 바꿀 수도 있다.

넓은 매스커레이드는 계층이 둘이라고 더 안전해지지 않는다. 원격이 어떤 주소를 보는지를 숨기며, 터널은 살아 있는데 애플리케이션이 동작하지 않을 때 바로 그 정보가 필요하다.

NAT 규칙이 정말 필요하다면 각 측이 어느 주소와 대화한다고 믿는지 적어 두라. 그 한 줄이 터널 탓인지 변환 탓인지에 대한 논쟁 대부분을 해결한다. 일 년 뒤 규칙을 제거할 때 다음 엔지니어가 어디를 봐야 하는지도 알려 준다. ping은 그중 아무것도 하지 못한다.

fail-closed를 증명하고 MTU를 확인하라

경로가 사라지는 것 자체가 fail-closed 정책은 아니다. 다른 테이블, 기본 경로 또는 정책 규칙이 조용히 대체 경로를 제공할 수 있고, 아는 유일한 방법은 외부 터널을 내리고 애플리케이션 트래픽이 어떻게 되는지 관찰하는 것이다. 사고로 발견하기보다 유지보수 창에서 의도적으로 하라.

세 가지 상태를 시험하라: 외부 터널 중지, 내부 터널 중지, 둘 다 돌아온 뒤 복구.각 게이트웨이에서 정책 카운터를 사용하라. 설정된 IKE 세션 두 개는 제어 평면 협상이 성공했다는 것만 증명한다.

두 캡슐화를 모두 예산에 넣어라. 동작하는 IKE는 작은 패킷의 결과이고, 전체 크기 애플리케이션 패킷은 헤더 두 개가 붙으면 여전히 실패할 수 있다. 숫자가 맞는다고 가정하지 말고 실제 경로에서 알려진 페이로드 크기로 시험하라. 계산은 쉽지만 경로는 그렇지 않다.

관련 글