통합차단시스템 개발후기
통합차단시스템 개발 후기
지금은 많이 변한 초기 구성 화면이지만 이 형태에서 많이 달라지진 않았다.
대부분의 페이지가 검색창, 테이블, 모달 형태이다.
시스템 소개
용도 및 목적
네트워크를 담당하는 N팀과 보안 관제를 담당하는 M팀이 공통으로 사용할 차단 업무 플랫폼이 필요했다. 각기 다른 권한을 가진 두 팀의 업무는 대강 이런 식으로 이루어진다.
-
M팀이 특정 IP 등을 차단하기 위해 차단 사유, 영구차단 여부와 함께 N팀에 차단 신청을 함
-
방화벽 등에 대해 컨트롤 권한이 있는 N팀은 이를 받아 차단 입력을 함. 차단 입력은 여러 종류의 방화벽이나 다수의 솔루션이 될 수 있으며, 신청 내역에 따라 기간별 차단을 하거나 영구차단을 한다.
-
이 차단은 일정기간 이후 자동해지 되기도 하고, 요청에 따라 수동해지가 될 수도 있다.
이런 식으로 서로 다른 권한을 가진 팀이 차단 신청 - 차단 입력을 주고받을 공공지가 필요했으며, 동시에 모든 것은 차단 작업은 차단 사유와 함께 이력이 남아야 했다. 혹여나 이미 차단된 url등에 대해 문의가 들어올 시 증빙이 가능해야 했기 때문. 상세한 검색 기능이 요구되는 것은 당연했다.
기존 레거시에 대해
물론 기존에 쓰여지던 시스템이 있었다. 사용자들은 차단입력 후 그 내역을 전부 가져와서(엑셀로 export/import가 가능함) 일부러 차단 사유를 남기기 위해서 이 시스템을 사용하고 있었다.
그런데 이것이 완전한 레거시 그 자체였다. 내부 사정을 전부 이야기할 수는 없으나... 대부분의 인원이 친숙하지 않은 기술스택으로 이루어져 유지보수는 고사하고 기능추가도 힘든 시스템이었다. 덤으로 어지간한건 내부적으로 오픈소스 활용해서 만들자는 조직의 시스템 내재화에 대한 요구가 있는 상황에서 개발은 시작되었다.
프로젝트 시작 시 나와 주변 상황
- 업무 전환이 막 이루어져 방금 합류한 나(뭔가 보여주고 싶었다)
- 내가 진짜로 실사용될 웹을 만드는게 처음임
- 혼자 만들어야 함(다른 멤버들이 너무 빠듯했음)
- 그래도 조언은 구할 수 있음(굿 멤버들)
- 하지만 거시적인 조언을 구할 사람은 없음(시니어의 부재, 기한을 잡거나 설계 등의 질문을 받아줄 사람이 없음)
- 하고싶은 걸 하게 해주는 자유롭고 따뜻한 팀 분위기
다행인 점?
- 사용자나 트래픽이 아주 많이 발생하지 않을 내부 시스템 개발이다.
- 잠재적인 미래의 사용자들이 관대하다. 아마 개선에 대한 희망이 가장 강한 분들이셔서 그러셨던 것 같다. 내 손에서 나오는 잔실수들을 너그럽게 이해해 주셨다.
부담스러운 점?
- 이미 사용중인 시스템을 마이그레이션 해야함. 제가요...?
사용 기술스택
- Backend: Spring boot
- Frontend: Vue.js
기존에 파트 내에서 사용되던 백엔드는 node.js, 프론트는 vue.js였다. 노드는 개인적으로 간단하게 웹 형태가 필요할 일이 있을때 몇번 다루어본 경험이라도있었다. 반면 프론트를 다루는 것은 완전히 처음이었다. 프로젝트를 시작하면서 개인 혹은 팀 차원에서 새로운 기술스택을 하나 가져가고자 했는데, 리액트를 해보고 싶었지만 내가 조금 겁을 냈다. 이 욕심을 내자니 나는 프론트 지식이 전무한 상태였기 때문이다. 뷰를 선택한다면 그래도 참고할 코드가 있는데, 리액트를 선택하는 순간 맨땅에 헤딩이 되어 내 목이 부러질 것 같았다...
대신에 나와 파트에게는 새로운 백엔드 기술스택인 스프링부트를 선택했다. 내가 백엔드 개념은 있었고, 외부에서 많이 사용되는 만큼 레퍼런스도 많을 거란 계산도 있었다. 그리고 지겨울 정도로 많이 쓰인다는데 왜 이렇게 싫어하는 개발자들이 많을지에 대한 개인적인 호기심도 해결하고 싶었다.
추가기능에 관해
기존 통합이력관리 시스템의 사용자들의 공통적인 니즈는 다음과 같았다.
- 각종 방화벽/솔루션 모두 연동해서 단 한번 입력으로 차단도 되고 이력도 남았으면 좋겠어요.
- 모두 연동하기 전에, 제발 입력 검증 시스템이 필요해요!
N팀 분들이 이 시스템과 방화벽을 연동할 수 있었다. 차단신청 내역의 특정 조건을 만족하는 row를 csv처럼 뽑아내는 특정 페이지를 만들어서, 방화벽으로 하여금 이 페이지를 주기적으로 크롤링하게 하고 자동차단까지 할 수는 있었다. 다만 문제는, 차단신청시에 입력값에 대한 검증기능은 존재하지 않는다는 것이었다. 그러니까 차단신청시에 루프백이든, 0.0.0.0이든, 심지어 숫자가 아닌 평문을 입력해도 그대로 입력값으로써 들어가게 되고, 이런 방법으로 바로 연동을 해버린다면 방화벽은 이를 충실히 긁어가서 차단을 진행할 것이라는 것이었다. 방화벽은 0.0.0.0같은 무서운 값이 입력되면 알아서 자동으로 뱉어내지 않나요? 라고 여쭤봤더니 경력이 많으신 어느 분이 한타래 썰을 풀기 시작하셨다. 때는 201X년이었죠. 제가 ㅇㅇ에 있을 때였는데... 로 시작하는 스릴러같은 이야기들을
아무튼 옮겨오는 기능이 아닌 순수히 추가해야 하는 기능들을 구체화하면 이러했다.
-
IP 검증
- IP 형식 여부 체크
- 루프백, 0.0.0.0 등 입력 불가하게 설정
- 서브넷 마스크 중에서 C클래스만 가능하게(요청사항)
-
차단 예외 리스트
이것도 IP검증의 맥락이긴 하지만 사이즈가 커서 분리해서 적었다. 타 운영성 팀들에게서 차단이 절대 되면 안되는 IP들을 입력받아 이것들이 차단 신청 시점에 입력이 방지되게끔 해야 한다. 이 기능은 있어야 당연하다고 생각되겠지만... 회사마다 운영 사정은 다른 법이다. 관리해야 하는 서비스들이 산재된 환경에서 서비스 운영과 보안 관련 팀, 그리고 관제를 담당하는 팀이 유관 정보를 올바른 형태로 적재적시에 주고받으며 여기에 자동화까지 가져가는 것은 각잡고 가내수공업을 하지 않는 이상 탄생하기가 쉽지 않을 수도 있다고 생각했다.
차단 예외 리스트에서 비롯되는 추추가기능:
- 회원가입/승인 기능(사원정보 참조)
- 권한!(차단 신청하는 페이지에는 유관 팀 외에는 접근되면 안된다.)
-
방화벽/각종 솔루션 연동
입력과 동시에 차단되게 해야 함. 방화벽은 N팀 분들이 하셨지만 기타 다른 솔루션들은 내가 직접 연동해야 했다. 이 솔루션들은 각기 입력받는 방식이 달랐다. REST API를 활용하는 것도 있고 DB에 직접 꽂아야 하는 것도 있고 다양하게 존재했다.
옮겨와야 하는 기능들을 재구현하는 것도 만만치 않았다.
-
아주 상세한 검색 기능
-
각 차단 메뉴 별 차단신청이 들어올 때마다 메일 발송
-
엑셀 export/import
-
기본적인 CRUD 등
개발 중에 고민했던 것들
-
엑셀 export/import 기능을 굳이 옮겨올 필요가 있을까?
엑셀기능은 왜 있을지 궁금했었다. 대량입력을 위해 존재할 것 같다는 추측을 하고 있었는데(기존 시스템에 대량입력이나 일괄입력같은 기능이 없었음) 내부적으로 또 다르게 쓰일지도 모르는 일이었다. 그래서 여쭤봤더니 그저 대량입력을 위해 존재하는게 맞긴 했었다. 그렇다면 웹에서 대량입력이 가능하게 하면 엑셀기능은 없어도 되지 않나? 같은 고민을 잠깐 했었다.
그런데 결론적으로는 두가지 다 만들었다. 이미 다수의 사용자들이 이렇게 사용하고 계셨고, 결국에 나중에는 새로 만든 시스템으로 반강제적으로 옮겨오게 될텐데, 거기에다 내가 그분들의 업무하는 방식까지 강제하는 것은 뭔가... 아니라고 생각했었다. 내가 할일이 더 생기더라도 일단 둘다 만들어 두고, 엑셀 업로드는 모두 웹에서 가능하게끔 서서히 길게 보고 바꿔나가는 편이 낫다고 생각했다.
-
엑셀 내 검증 및 사용자 일람 시스템
웹에서 업로드를 하면 프론트에서 바로 검증해 줄 수 있었다.(vee-validate를 아주 잘 활용했다.) 입력값 무엇이 어떻게 잘못되었다고 사용자에게 바로 알려줄 수 있었는데 엑셀로 업로드 시에는 그럴 수가 없었다. 심지어 엑셀 업로드는 있던 기능인데... 기존 사용자들이 엑셀로 차단신청 올리는 것을 머릿속에서 시뮬레이션을 돌려 봤었다.
-
1단계
1000 row를 엑셀 업로드를 하려 하는데 그중에 차단되면 안되는 IP가 존재할 수 있다.
-> 백엔드에서도 IP 검증기능/차단예외리스트 대조해주는 함수 파서 자동으로 비교 후 입력하게 만든다.
-
2단계
검증 기능을 거친 후 입력이 되어 이제는 안전하게 차단 신청이 된다. 그런데 3000row를 입력했는데 2997row만 입력되었다. 3개는 무엇인지도 모르고 왜 입력되지 않았는지도 모른다.
-> !
사용자는 개발자처럼 에러 로그를 볼 수 없다. 이런 식으로 입력이 잘못되면 확인이 가능한 창구가 어떤 형태로든 필요하다고 생각했다. 그래서 이것을 위한 페이지를 별도로 만들었다.
-
-
검색을 어떻게 할 것인가?
검색은 기존에도 있던 아주 기본적인 기능이었다. 그러나 막상 구현하려 하니 생각할 것들이 꽤 있었다. 클라이언트 사이드에서 검색할 것인가? 서버 사이드에서 검색할 것인가? 결론적으로는 강제적으로 서버사이드 검색을 선택하게 되었다. 핸들링할 데이터가 만 단위가 넘어가기 때문에 프론트에 뿌려지는 화면은 pageable로 1차적으로 가져온 데이터였다. 때문에 그 안에서 클라이언트 사이드 검색을 하면 안된다는게 첫번째였고, 두번째는 row별로 strict한 검색이 요구되기 때문이었다. 성능 문제도 있었지만 이는 서버-DB 쪽에서 Pageable 처리를 하고 넘겨지면서 해결되었다.
ip 검색이 주가 되기 때문에 이후에 정규식 검색도 가능하게 만들면 좋을 것 같다.
배운 점
기술적인 면에서
-
스프링 부트는 좋은 프레임워크이다.
그리고 싫어하는 사람은 왜 싫어하는지도 알 것 같다.
스타트업 등지에서 서비스 오픈 시에 node 등으로 개발하고, 나중에 스프링 부트로 옮겨가는듯한 양상을 꽤 본 것 같다. 왜 그런지에 대해서도 어느정도 이해했다. 결과물을 빨리 구현해서 보여주는 데에는 노드가 좀더 적합한 것처럼 느껴졌다. 스프링 부트는 견고하고, 이미 만들어진 무언가들이 많아서 정말로 비즈니스 로직만 생각하면 되었다. 단, 명세서를 작성하는 듯한 기분이 들었다. 이미 짜여진 튼튼한 틀 안에 내 로직을 맞추어 적는 느낌... 다른 언어 다른 프레임워크를 사용하던 사람들이 갑갑하다는 인상을 받는다는 느낌을 이해했다. 그리고 이렇게 명세서...에 작성해야 하는 것이 많으니, 빨리 무언가를 보여줘야 하는 상황에서는 적합하지 않을 수도 있겠다는 생각이 들었다.
하지만 나는 이 프레임워크의 수혜를 톡톡하게 받았다고 생각한다. 사실 구현 중에 적지 않은 문제들이 생겼었는데, 그 문제들의 대부분은 순수하게 내 비즈니스 로직 문제였다. 환경에 대한 문제라거나, 웹의 구조적인 구현으로 인해 발생하는 문제는 굉장히 적었다고 느꼈다.
초심자가 상당히 복잡한 시스템을 가내수공업을 했는데 다른 프레임워크로 이렇게 짰다면 다른 문제들을 해결하느라 구현 시간이 훨씬 오래 걸렸을 것 같다.
-
사용 중인 시스템의 마이그레이션
처음부터 새로 만드는 시스템이 아닌 기존에 있던 걸 옮겨옴과 동시에 플러스 알파를 구현해야 한다는 것을 너무 쉽게 여겼던 것 같다... 사실 무지가 불러온 용기이자 만용이었다. 라이브 마이그레이션까지는 하지 못했지만(이것도 그럴만한 바탕이 만들어져 있어야 가능할 것 같다), 최대한 순단을 덜 가져가려고 노력했다. 이것도 이해해주신 분들께 정말 감사하다.
덕분에 이중화나 시스템을 잘게 쪼개어 구현하는 MSA 등에 대해 관심을 가지게 되었다. 내부에서 소수가 사용중이지만 중요도가 꽤 높은 시스템이 되어버려서... 그리고 개발 중에 알게 된 내 성향을 따라서도 아주 튼튼하고 안정적인 시스템을 만들고 싶어졌다.
인간적인 면에서
-
위에서 언급했던, 자동화를 진행하며 타 팀의 업무 프로세스에 손을 대는 면에 있어서 조심스럽게 접근한 것도 잘했던 것 같다.
온전히 모두가 개발자 집단이 아닌 곳은 이렇게 다른 업무를 하는 사람들과 의견을 조율하고 협업하는 일이 많을 것이다. 넓게 보면 구성원 모두가 개발자인 집단은 생각보다 드물 것 같다는 생각이 들었다. 나는 지금 환경도 그렇지만 미래에 다른 회사나 다른 집단에 속하게 되어도 비개발자나 다른 전문 인력들과 커뮤니케이션 할 때 이런 부분을 섬세하게 생각하고 전달하는 감각을 계속 가져가야 할 것 같다는 생각을 했다.
-
생각보다 자동화를 필요로 하는 곳은 많다.
솔루션을 사서 바르기에는 너무나 그 회사 그 업무의 특성을 타는 문제가 있어서 도입하기 부담스러운 케이스가 꽤 많다. 그리고 100개의 회사가 있다면 100개의 특성이 존재한다(인하우스 개발자들이 요구되던 이유라고 생각한다). 그리고 거기엔 신경을 세우고 실수없이 반복업무를 해야 하는 수많은 상황들이 존재한다. 내부에서 비개발자인 분들과 같이 무언가를 만들다 보니 자동화에 대해 생각할 거리, 그리고 개발할 거리가 정말 많이 있었다. 소중한 경험이기도 했지만 이런 것들이 스무스하게 이루어질 수 있는 환경을 동경하게 되기도 했다.
자아성찰적 면에서
-
보수적으로 접근하는 마인드와 뭔가 해보자는 개척자로써의 마인드 사이에서 균형을 잘 잡을 필요가 있다. 이번엔 너무 사렸던 것 같다. 한가지 예를 들면... DB를 그대로 가져갔다. 이왕 옮겨가는거 다른 DB로 바꾸는 것도 괜찮지 않았을까 싶지만 후회는 남지 않았다.
-
기발한 것을 만드는 것보다 필요한 것을 만드는 걸 확실히 선호하는 것 같다. 존재하는 문제를 소프트웨어적으로 해결하는 과정을 꽤 즐겼던 것 같다.
-
보안/운영 경험이 있어서 그런지 성향 때문인지는 모르겠는데, 나는 튼튼하고 안정적인 시스템을 만드는 것에 확실히 관심이 보였다. 솔직히 코드 짜면서도 최악의 상황 시뮬레이션이 머리에 그려졌다. 이대로 짜면 어떤 상황에 장애나기 쉬울 것 같다/ 또는 공격 집어넣기 딱 좋겠다 같은 생각들... 장기적으로는 좋을 수도 있겠으나, 처음부터 이 모든것을 생각하면서 개발하면 막막해지기 쉬웠다. 사고가 끝도 없이 확장되는 것을 의식적으로 차단하고 기능 구현 하는걸 우선순위를 높게 가져가려 했고 그게 맞았던 것 같다.
-
처음 혼자 개발한 것 치고는 나름 괜찮게 한 것 같다.
앞으로 더 배우거나 하고 싶은 것들
- DB(이중화 구성, 효율적인 백업 등)
- 메시징 할 때 Kafka 도입