은행 원화 입출금 API 쪽에 등록해 둔 허용 IP 가 열몇 개인데 절반은 어디에 쓰는지 아무도 몰랐다. 안 쓰는 것부터 지우기로 하고 각 주소의 접속 빈도를 뽑아 근거로 삼기로 했다.
Table of contents
Open Table of contents
증상 — 목록에 섞여 있던 내부 주소
목록을 보다가 등록된 것 중 몇 개가 10.0.x.x 대역의 내부 서버 주소인 것을 발견했다. 그 서버들은 외부로 나갈 때 NAT Gateway 를 거치는 구성이었다.
그러면 그 주소가 상대에게 보일 일이 없는데 왜 목록에 있는지가 먼저 풀려야 했다. 그리고 그것들의 접속 빈도를 어떻게 뽑을지도 문제였다.
원인 — 게이트웨이 뒤는 상대에게 안 보인다
RFC 3022 가 정의한 대로 NAPT 는 여러 내부 주소와 포트를 하나의 외부 주소와 포트로 바꾸므로, 나가는 패킷의 출발지가 NAT Gateway 의 공인 IP 로 바뀐다. 은행 쪽 서버가 기록에 남길 수 있는 것은 그 하나뿐이다.
뒤에 몇 대가 있든 어느 대가 얼마나 자주 부르든 상대는 관측할 방법이 없다. 상대편 목록의 항목과 우리 쪽 서버가 일대일로 대응하지 않는 구조였다.
빈도를 근거로 못 쓰는 이유
우리 access.log 에는 wallet-svc·notify-svc 별 호출 횟수가 남지만 그 숫자는 상대편 목록과 아무 관계가 없다. 반대로 NAT Gateway 주소는 나가는 시점에 붙는 값이라 애플리케이션 로그에 별도 항목으로 안 잡힌다.
빈도가 높은 것은 상대가 모르고 상대가 아는 것은 빈도가 안 잡힌다. 접속 빈도로 삭제 대상을 고르려던 계획이 여기서 성립하지 않게 됐다.
판단 기준 — 기준을 코드 경로로 바꾼 뒤
내부 주소가 등록돼 있다는 사실 자체가 단서였는데 과거 어느 시점에는 그 주소가 상대에게 직접 보였다는 뜻이다. 그때는 NAT Gateway 를 안 거치는 경로가 있었을 것이다.
두 가지 방법이 있었다. 은행 쪽에 접속 기록을 요청해 실제로 들어온 주소를 받는 것과, 기준을 경유하지 않는 직접 호출 경로가 코드에 살아 있는가로 바꾸는 것이다. 뒤쪽을 골랐다. 이유는 은행 쪽 기록은 분기 단위로만 나오고 그것도 요청 뒤 몇 주가 걸려서다. 대신 코드 밖 경로를 놓칠 수 있는 것을 감수했다. grep -rn bank-api 로 보니 대부분은 이미 squid 프록시를 타게 바뀌어 있었고 두 곳만 아직 직접 호출이라 그에 해당하는 주소만 남겼다.
검색으로 없음과 실제 없음
후보로 분류한 것도 바로 지우지는 않았다. 코드 검색으로 직접 호출이 없다는 것과 실제로 그 주소로 나가는 트래픽이 없다는 것은 다르기 때문이다.
application.yml 을 거치거나 다른 저장소에 있는 호출은 한 번에 안 잡히고 가끔 도는 cron 배치는 코드에 있어도 최근 기록이 없다. 그래서 지워도 될 것으로 보인다까지만 적고 실제 삭제는 은행 담당과 일정을 맞춰 한 번에 하기로 했다.
정리
NAT Gateway뒤의 주소는 상대편 기록에 남지 않는다- 상대가 보는 것은 게이트웨이 주소 하나뿐이다
- 그래서 뒤쪽 서버의 빈도를 상대편 목록의 근거로 쓸 수 없다
- 빈도가 높은 것은 상대가 모르고 아는 것은 빈도가 안 잡힌다
- 판단 기준은 직접 호출 경로가 코드에 살아 있는가로 바꾼다
- 목록에 남아 있다는 사실이 과거 경로의 단서가 된다
grep으로 없음과 실제 트래픽 없음은 다르다- 각 항목에 어느 경로가 쓰는지와 확인 시점을 적어 둔다