관리 도구의 접근 제한을 점검하다가 허용 규칙이 다섯 줄 적혀 있는 것을 봤다. 사무실과 개인 접속과 서버 대역이 CIDR 표기로 차례로 나열돼 있었다. 그런데 목록 끝에 나머지를 막는 줄이 없었다.
Table of contents
Open Table of contents
원인 — 매칭 실패 시의 동작
접근 제어 목록은 위에서부터 순회하며 요청 IP 와 맞는 CIDR 를 찾고 맞으면 그 규칙의 동작을 따른다. 그러면 끝까지 갔는데 맞는 것이 하나도 없을 때 무엇이 되는지가 문제였고 그 답이 기본 정책이다.
기본이 deny 라면 이 목록은 제대로 된 허용 목록이 된다. 기본이 allow 라면 이 다섯 줄은 아무것도 막지 못하고 그냥 장식이 된다. 문서에는 설정 항목 설명과 규칙 문법만 있고 미매칭일 때 무엇이 되는지는 어디에도 없었다.
검색으로는 갈리지 않았다
기본 정책이 무엇인지 문서와 자료를 찾아봤는데 설명이 엇갈렸다. 어떤 자료는 deny라고 하고 다른 자료는 allow라고 했다.
판이나 배포판에 따라 다를 수도 있는 부분이었다. 검색 결과가 갈리면 그것은 근거가 아니라 확인해야 할 물음이 된다. 그래서 그 소프트웨어의 소스를 직접 열어 보기로 했다.
소스가 준 답변
공개된 구현체가 있어서 grep 으로 IP 를 받아 동작을 정하는 함수를 찾아 읽었다.
for each rule in rules:
if match(rule, address):
return rule.action
return ACTION_TYPE_ALLOW
마지막 줄이 답이었다. 반복문이 rules 를 다 돌고도 match 가 없으면 ACTION_TYPE_ALLOW 를 돌려준다. 즉 이 목록은 아무것도 차단하지 못하는 상태였다.
사무실에서 오든 밖에서 오든 전부 return rule.action 에 안 걸리고 ACTION_TYPE_ALLOW 로 빠지므로 다섯 줄을 지워도 동작이 똑같았다. 고치는 것 자체는 한 줄이어서 목록 맨 끝에 0.0.0.0/0 을 deny 하는 규칙을 붙였고 그제서야 앞의 다섯 줄이 의미를 가졌다.
육안으로 구분되지 않는다
이 형태가 위험한 것은 틀린 설정이 맞는 설정과 똑같이 생겼기 때문이다. CIDR 다섯 줄은 어느 쪽이든 동일하고 목록 끝의 deny 한 줄이 있고 없고가 전부다.
그 줄이 없는 상태가 오히려 자연스러워 보인다 — 막을 대상을 안 적었으니 다 막힌 것 같다. 있는 것은 보이지만 없는 것은 안 보이므로 목록을 볼 때 끝을 먼저 보는 습관이 필요했다.
검토 순서
이 경험으로 접근 제어를 볼 때의 순서를 정했다. 기본 정책을 먼저 확인하고 목록 끝의 deny 여부를 보고 그다음에 CIDR 규칙을 읽는다.
CIDR 부터 읽으면 그것이 무엇을 뜻하는지 판단할 근거가 없는 상태에서 읽게 된다. 이번 건은 앞단 장비가 포트를 열어 주는 조건이 따로 있어서 그것이 실질적인 방어선이었고 도구의 목록은 두 번째 층이었다. 층이 둘이면 각각이 실제로 무엇을 막는지 따로 확인해야 한다.
정리
- 매칭 실패 시 동작이 그 설정의 성격을 결정한다
- 기본이
allow면CIDR규칙만으로는 아무것도 못 막는다 - 같은 설정이 정반대 성격을 가질 수 있다
- 검색 결과가 갈리면 그것은 근거가 아니다
- 문서가 엇갈리면
grep으로 구현체의match분기를 읽는다 - 맞는 설정과 틀린 설정이 겉모습이 같다
- 있는 것은 보이고 없는 것은 안 보인다
- 기본 정책과 목록 끝의
0.0.0.0/0deny를 먼저 보고CIDR를 읽는다