보안 정책 검토 중에 퇴사한 사람의 계정이 Jenkins 에 남아 있는 것을 발견했다. 계정이 시스템마다 따로 있어서 나갈 때 여러 곳을 각각 지워야 하는 구조였다.
Table of contents
Open Table of contents
증상 — 시스템마다 따로 있던 계정
관리 화면과 Jenkins 와 GitLab 과 DB 접속 계정과 서버 ssh 에 각각 계정이 있었다. 다섯 곳을 다 지워야 하는데 지운 기록이 남지 않으니 어디를 지웠는지도 몰랐다.
빠뜨렸다는 사실 자체가 드러나지 않는 구조였다. 그래서 남아 있는 것을 세는 방법부터 만들어야 했다.
검증 — 남아 있는 것을 세는 방법
각 시스템의 계정 목록을 뽑아 인사 재직자 목록과 comm -23 으로 대조하는 방식으로 셌다. 시스템마다 돌리니 열두 건이 나왔고 그중 셋은 몇 해 전에 나간 사람이었다.
세어 보기 전에는 몇 건이 남아 있는지 아무도 몰랐다. 대조 한 번이 그 상태를 숫자로 만들었다.
조치 — 위임과 못 옮긴 것
두 가지 방법이 있었다. 퇴사 절차서에 다섯 곳을 나열하고 사람이 지우게 하는 것과, OpenLDAP 한 곳에 계정을 두고 각 시스템이 인증을 위임하게 바꾸는 것이다. 뒤쪽을 골랐다. 이유는 절차서는 이미 있었는데도 열두 건이 남았기 때문이다. 대신 LDAP 서버가 서비스 전체의 로그인을 쥐는 단일 지점이 되는 것을 감수했다.
Jenkins 는 LDAP 플러그인으로, 관리 화면은 Spring Security 의 LdapAuthenticationProvider 로, 서버는 sssd 로 위임하니 slapd 에서 끄면 대부분이 막혔다. 다만 LDAP 연동을 지원하지 않는 DB 관리 도구와 NCloud 콘솔 둘이 남았다. 못 옮긴 것은 목록에 적고 퇴사 절차에 수동 단계로 넣었다. 절차를 적어도 사람이 빠뜨리므로 재직자 목록과 대조하는 확인 스크립트를 월 한 번 cron 으로 돌리게 했다.
막는 것과 지우는 것을 나눈다
바로 지우면 그 계정이 만든 커밋과 문서와 Jenkins 작업이 주인 없는 상태가 된다. 그래서 로그인을 막는 것과 계정을 지우는 것을 나눴다.
첫날에 pwdAccountLockedTime 으로 로그인을 차단하고 몇 주 안에 소유물을 넘긴 뒤에 지우는 순서로 두니 접근은 즉시 끊기면서 기록은 살아 있었다. 공용 계정도 이때 없애서 개인 계정으로 나누고 배포용 계정은 사람이 로그인할 수 없게 했다.
주의 — 한 곳이 죽을 때의 대비
계정을 한 곳으로 모으면 그곳이 죽었을 때 아무도 못 들어간다. slapd 를 고치러 서버에 들어가야 하는데 들어갈 방법이 없는 상황이 생긴다.
그래서 서버마다 키로만 붙는 비상용 로컬 계정을 남기고 그 키는 따로 관리했다. 평소에 안 쓰면 안 되는 것도 모르므로 분기마다 실제로 붙어 보게 했고, slapd 도 OpenLDAP 2.4 관리자 매뉴얼의 syncrepl 로 두 대를 서로 복제하게 뒀다.
정리
- 계정이 시스템마다 따로면 나갈 때 하나가 남는다
- 빠뜨렸다는 사실 자체가 드러나지 않는다
- 재직자 목록과 대조해 남은 것을 숫자로 만든다
LDAP한 곳에서 관리하고 각 시스템이 위임하게 한다- 못 옮긴 것은 적고 절차에 수동 단계로 넣는다
- 절차를 적어도 빠뜨리므로 확인을 정기적으로 돌린다
- 막는 것과 지우는 것을 나눠야 소유물이 주인을 안 잃는다
- 한 곳으로 모으면 그곳이 죽을 때의 비상 경로를 남기고
syncrepl로 두 대를 둔다