IPsec 트래픽 셀렉터: 무엇을 덮고 무엇을 덮지 않는가
셀렉터는 협상된 정책이며 경로도 권한도 아니다. 양쪽 끝에서 읽고, 응답자가 어떻게 좁히는지 지켜본 다음, 목적지 하나를 끝까지 따라가라.
트래픽 셀렉터는 IPsec 합의가 보호하는 내부 트래픽에 이름을 붙이며, 그 쌍은 가정이 아니라 협상으로 정해진다. 두 끝점은 서로를 완벽하게 인증할 수 있으면서도 어떤 패킷이 터널 안에 속하는지에 대해 여전히 의견이 다를 수 있다. 그 불일치는 연결 상태에 보이지 않으며, 상태는 대개 정상 터널을 보고한다. 셀렉터를 양쪽 끝에서 읽은 뒤 목적지 하나를 따라가면 어떤 정책 편집보다도 빨리 그것을 찾아낸다.
양쪽 끝에서 읽어라
각 끝점은 자기 쪽을 로컬로, 다른 쪽을 원격으로 기술한다. 그래서 같은 프리픽스 쌍이 두 구성에서 뒤바뀐 채 나타나며, 그것은 옳은 것이지 모순이 아니다. 동작하는 합의가 종이 위에서 틀려 보일 때 가장 먼저 할 일은 관점을 뒤집는 것이다. 두 파일을 서로 바꾸지 않고 나란히 비교하면 존재하지 않는 불일치가 생긴다.
값이 항상 단일 서브넷인 것은 아니다. IKEv2 셀렉터는 주소 범위, 프로토콜 번호, 포트 범위를 실을 수 있고, 그렇게 해서 정책은 네트워크 전체 대신 하나의 서비스를 보호한다. 의도한 트래픽보다 좁은 셀렉터는 일부 목적지만 나르고 나머지는 조용히 배제하는 터널을 만든다.
무엇이든 바꾸기 전에 양쪽을 하나의 표에 적어라. 이 연습은 보통 구성 파일을 건드리지 않고도 문제를 정리한다.
좁히는 것은 응답자의 판단이다
개시자가 제안하고, 응답자는 부분집합만 받아들일 수 있다. IKEv2는 응답자가 제안된 트래픽 셀렉터를 좁히도록 허용하며, 실제로 설치되는 것은 좁혀진 결과다. 따라서 개시자 구성을 읽는 것은 합의가 아니라 제안을 설명한다.
그래서 클라이언트에 추가한 서브넷이 새 목적지를 여전히 거부하는 동작하는 터널을 만들 수 있다. 서버는 자기 정책이 허용하는 만큼 제안을 좁혔고, 클라이언트 파일은 여전히 더 넓은 범위를 나열한다. 협상된 상태만이 진실을 보여주며, Linux에서는 ip xfrm policy와 strongSwan의 IKEv2 문서에 있는 child SA 목록이 요청된 것이 아니라 설치된 것을 보고한다. 둘이 어긋날 때 바꿔야 하는 것은 응답자의 정책이다.
거부된 제안은 좁혀진 제안과 다른 증상이다. 거부는 협상 로그에 나타나며 child 연관을 전혀 남기지 않는다.
목적지 하나를 처음부터 끝까지 따라가라
클라이언트가 그 목적지에 쓸 실제 목적지와 출발지 주소를 고른 다음, 그 쌍을 세 가지 독립적인 결정에 통과시켜라. 경로가 길을 고르고, 셀렉터가 그 길이 보호되는지 결정하며, 방화벽이 패킷이 허용되는지 결정한다. 각각은 따로 실패할 수 있고, 넓은 셀렉터는 나머지 어느 것도 고치지 못한다.
ip route get 10.20.30.41
ip xfrm policy list
swanctl --list-sas
경로 조회는 패킷을 나를 인터페이스와 출발지 주소를 알려준다. 정책 목록은 그 쌍에 맞는 터널 정책이 있는지, 그 방향과 수준까지 포함해 보여준다. SA 목록은 협상된 child 셀렉터를 카운터와 함께 보여주므로, 트래픽을 시도한 뒤 패킷이 없는 child 연관은 보내는 것을 배제하는 셀렉터의 특징이다. 세 개의 명령, 세 가지 다른 답, 그리고 조용한 드롭을 설명하는 것은 그중 하나뿐이다.
애플리케이션이 계속 실패하는데 child 카운터가 움직인다면 문제는 터널 너머에 있다. 그것은 조사를 셀렉터가 아니라 원격 호스트의 리스너나 방화벽으로 옮긴다.
두 목표를 분리하라
사무실 서브넷을 보호하는 것과 모든 브라우징을 원격 출구로 보내는 것은 서로 다른 셀렉터를 가진 다른 요구 사항이다. 하나를 위해 만든 프로필이 다른 하나에 맞는 경우는 드물고, 둘을 섞으면 유출이거나 깨진 분할이 된다. 보호 범위를 넓히는 것은 양쪽 끝과 그 전달 정책을 바꾸는 일이며, 한쪽만 바꾸면 거부된 제안이 되기 때문이다. 작은 편집 뒤에 동작하던 터널이 동작을 멈추는 가장 흔한 경로가 이것이다.
셀렉터는 암호학적 적용 범위를 기술하고, 경로는 길을 고르며, 애플리케이션은 자체 권한을 강제한다. 모든 것을 덮는 터널도 loopback에 묶인 서비스에는 닿지 못하고, 터널로 들어가는 경로에도 목적지를 포함하는 셀렉터가 필요하다. 같은 시험 요청에 대해 셋을 모두 확인하면, 불일치가 스스로 이름을 말할 것이다.