OpenVPN 경로가 strongSwan XFRM 정책에 지는 이유
특정 OpenVPN 경로는 XFRM 정책을 덮어쓰지 않습니다. 경로와 정책 선택자를 읽고, 좁히거나 예외를 두거나 XFRM 인터페이스로 옮기십시오.
패킷은 OpenVPN 경로를 따라가면서도 IPsec 정책에 붙잡힐 수 있고, 그 조합은 올바른 각도만 빼면 어느 각도에서 봐도 라우팅 버그처럼 보입니다. Linux는 경로를 해석한 다음 별도의 보안 정책 데이터베이스를 조회하므로, 더 구체적인 목적지 경로가 일치하는 XFRM 정책을 밀어내지 않습니다. 눈에 보이는 증상은 호스트를 떠나 영원히 도착하지 않는 트래픽이며, 두 터널은 모두 스스로 건강하다고 보고합니다. 해결책은 세 가지이고, 어느 것을 고를지는 두 경로 중 어느 쪽이 그 프리픽스를 나르도록 의도되었는지에 달려 있습니다.
두 가지 결정, 하나가 아니다
경로 선택은 좁은 질문에 답합니다. 어떤 다음 홉과 소스 주소가 이 패킷을 나를 것인가. 보안 정책 데이터베이스는 다른 질문에 답합니다. 이 패킷에 IPsec 보호가 필요한가, 필요하다면 어느 선택자 아래에서인가. 둘 다 같은 패킷에 대해 실행되며, 첫 번째를 만족해도 두 번째에 대해서는 아무것도 말해 주지 않습니다. 그래서 메트릭을 바꾸거나 정적 경로를 추가해도 증상이 그대로일 수 있습니다.
넓은 IPsec 선택자가 흔한 원인입니다. 172.16.0.0/12를 보호하는 정책은 172.20.8.0/24도 덮으며, 관리자는 오히려 OpenVPN 터널로 그곳에 도달하려 했을 수 있습니다. 의도는 라우팅 테이블에만 존재하고, 정책 데이터베이스는 그것을 알지 못했습니다.
이것을 두 메트릭의 경쟁이 아니라 설정된 두 보호 경로 사이의 충돌로 보십시오. 수정은 잘못된 범위로 설정된 구성 요소에 속합니다.
커널이 실제로 고르는 경로를 읽으십시오
커널이 수행하는 조회부터 시작하되, 소스 주소와 패킷을 다른 테이블로 우회시킬 수 있는 모든 정책 규칙을 포함하십시오. 이전 규칙이 다른 테이블을 고르면 메인 테이블의 경로는 조회되지 않을 수 있고, 최장 프리픽스 일치는 규칙이 고른 테이블 안에서만 적용됩니다.
ip rule show
ip route show table all
ip route get 172.20.8.20 from 10.44.7.15
마지막 명령이 핵심입니다. 선택된 경로와 커널이 사용할 소스 주소를 함께 출력하기 때문입니다. 그 출력을 IPsec 정책이 일치하는 선택자와 비교하십시오. 경로가 OpenVPN 인터페이스를 가리키고 정책이 여전히 같은 쌍과 일치한다면, 추측 없이 충돌을 재현한 것입니다.
티켓에 오르기 전에 덤프에서 무관한 주소를 걷어내십시오. 운영 호스트의 라우팅 테이블은 내부 토폴로지를 담고 있으므로, 질문에 답하는 줄만 붙여 넣을 가치가 있습니다.
함께 적용되는 정책도 읽으십시오
정책 목록은 방향, 선택자, 그리고 일치하는 패킷을 어떻게 처리할지 결정하는 템플릿을 보여 줍니다. 먼저 나가는 방향을 읽고, 다음으로 돌아오는 트래픽을 위해 들어오는 쪽을 읽으십시오. 한 방향짜리 예외는 시작만 하고 끝나지 않는 연결을 만들기 때문입니다.
ip -s xfrm policy
swanctl --list-sas
목록의 선택자를 연결이 협상한 프리픽스와 비교하십시오. strongSwan의 경로 설치를 끄더라도 그 정책은 사라지지 않고, 메트릭을 바꿔도 정책이 어느 소스-목적지 쌍을 보호하는지는 달라지지 않습니다. 이 두 가지 헛수고는 일찍 배제할 가치가 있습니다. 사람들이 가장 먼저 시도하는 것이기 때문입니다.
목록에 기대한 프리픽스에 대한 정책이 없다면 문제는 다른 곳에 있고 라우팅 테이블이 아마 사실을 말하고 있을 것입니다. 그 프리픽스를 덮는 더 넓은 정책이 있다면 가로채기를 찾은 것입니다.
두 경로가 모두 정당할 때의 세 가지 선택
넓은 프리픽스가 요구 사항이 아니라 편의였다면 IPsec 선택자를 좁히는 것이 가장 깔끔한 선택입니다. 원격 트래픽 선택자를 정말로 IPsec 뒤에 속한 서브넷으로 줄이면 모든 호스트의 충돌이 한 번에 사라지고, 비용은 새 구성 요소가 아니라 키 재협상입니다.
넓은 선택자를 유지해야 한다면 통과 예외가 외과적 선택입니다. strongSwan은 child가 pass 모드를 쓰는 별도 연결을 지원하며, 이는 일치하는 트래픽을 IPsec이 처리해서는 안 된다고 커널에 알립니다. 루프백 원격 주소는 그 연결이 들어오는 피어에 선택되지 않게 하고, 선택자는 전부가 아니라 실제 승인된 쌍을 서술해야 합니다.
connections {
openvpn-exception {
remote_addrs = 127.0.0.1
children {
openvpn-exception {
local_ts = 10.44.7.0/24
remote_ts = 172.20.8.0/24
mode = pass
start_action = trap
}
}
}
}
strongSwan 구성 예제 는 이 정책 유형과 루프백 피어 관례를 문서화합니다. 세 번째 선택은 XFRM 인터페이스를 쓰는 경로 기반 설계 이며, 정책을 전역 선택자가 아니라 이름 붙은 인터페이스를 통해 라우팅되는 트래픽에 묶습니다. 이는 조정이 아니라 이전이며, 트래픽은 여전히 협상된 선택자를 만족해야 합니다.
| Option | Use it when | Cost |
|---|---|---|
| Narrow the selector | The broad prefix was convenience | A rekey and a policy review |
| Passthrough child | The broad selector must stay | One exception per intended pair |
| XFRM interface | Policy should follow routing | A design migration |
나머지를 약화시키지 않고 예외를 증명하십시오
변경을 적용한 뒤 예외와 보호된 채로 남아야 할 일반 목적지를 시험하십시오. 양방향을 확인한 다음 OpenVPN 터널을 내리고 예외 트래픽이 어떻게 되는지 확인하십시오. 터널이 내려갔을 때 그 프리픽스를 조용히 평문으로 보내는 예외는 사고 중에 발견할 일이 아니라 의도적으로 결정해야 할 정책 판단입니다.
어느 프리픽스가 어느 경로를 쓰고 왜 그런지 기록하십시오. 그렇지 않으면 넓은 선택자를 본 다음 엔지니어가 같은 조사를 다시 열 것이고, 답은 아무도 읽지 않는 commit 메시지에 남아 있을 것입니다.