티스토리 뷰

728x90
반응형

서론

DevSecOps란 개발, 보안, 운영이라는 세가지 중요한 측면을 원활하게 수행하기 위한 방식 또는 조직을 의미한다. DevOps에서 확장된 개념이라 볼 수 있다. 이는 전체 어플리케이션 라이프 사이클을 공동 책임으로 관리한다는 조직관리 관점에서 확장된 것이지만, 사실 확장이라는 개념에 어울리지 않게, 그간 우리는 보안이라는 요소를 기술의 Sub System 정도로 취급해 왔던 것이 사실이다. 특히 컨테이너 기술에 대한 이해가 높지 않은 상황에서 보안을 논의하기 보다는 기술의 완성도를 높이는데에만 집중해 오지 않았나 싶다.

최근 프로젝트에서 DevSecOps가 논의된 적이 있다. 당시 마이크로서비스를 설계하는 아키텍처 입장에서 나부터 보안에 대한 고려가 깊지 않았다는 생각을 하게 됐다. 이제는 그 생각의 전환이 필요한 시점이 아닌가 싶다. 보안이라는 진입점이 때로는 굉장히 높아 보인다는 문제가 있지만 컨테이너 보안은 더 이상 괄시하고 넘어갈 수 없는 상황이 되었다. 보안 침해 사고로부터 안전한 소프트웨어와 어플리케이션을 만들기 위해 많은 기업들이 여전히 고민하고 노력해 오고 있지만, 끊임없이 보안 사고는 발생하고 있으며, 그 파장은 엄청나다는 것을 알고 있다.

어플리케이션의 라이프사이클을 공통 책임으로 함께 관리해 나가기 위해서는 조직, 문화, 프로세스에 대한 변화와 자동화 체계 그리고 이를 뒷받침하는 플랫폼 설계에 대한 또 다른 사고방식으로 접근해야 할 필요가 있다.


Gartner 정의

아래 이미지는 Gartner 리서치 기관에서 정의한 DevSecOps의 연관 관계도이다. 이를 먼저 번역해 보면서 DevSecOps에 대해 고찰을 진행해 보자.

1) Plan : 보안을 담당하는 부서, DevSec Metrics 관리 방안, 보안 위협 모델링 수립, 보안 관련 플랫폼 교육 등의 보안 관련 문제를 해결해 나가기 위한 계획 수립

2) Create : 통합 개발환경에 보안 관련 요소 적용

3) Verify : SAST(Static Application Security Testing - 정적 어플리케이션 보안 테스트)/DAST(Dynamic Application Security Testing - 동적 어플리케이션 보안 테스트)/IAST(Interactive Application Security Testing - 상호작용 어플리케이션 보안테스트)/SCA(Software Composition Analysis - 원점 분석 / 소프트웨어 구성 분석)

4) Preprod : Chaos Monkey(카오스 몽키 테스트 - 발생 가능한 장애를 발생 시켜 정상 상태와 비교하는 테스트), Input Fuzzing(퍼징 테스트 - 예상치 않은 또는 무작위 데이터를 입력하여 결과를 확인하는 테스트), Integration Test(통합테스트 - 단위 테스트 결과를 기반으로 모듈 단위를 묶어 테스트를 진행하는 통합테스트) 또는 서비스를 가속화하고, 실행 중인 컨테이너에 자동화된 penetration bots을 배치하여 실제 어떻게 동작되는지 확인하는 과정을 거침

5) Release : 적용되는 소프트웨어 또는 어플리케이션에 대한 서명 진행

6) Prevent : 서명에 대한 확인, Checksum 등 무결성 검사, 심층 방어 조치 수립

7) Detect : RASP(Runtime Application Self-Protection - 런타임 어플리케이션 자가 보안, 실행중인 소프트웨어 내부의 정보를 활용하여 보안 공격을 탐지하고 차단하는 기술), UEBA(User Behavior Analytics - 사용자 행동 분석, 내부 위협, 표적 공격 및 금융 사기 탐지)

8) Respond : 보안 요건 재검토 및 조정, RASP/WAF(Web application Firewall) 등 런타임 환경에서의 보안 위협 차단

9) Predict : IoC(Indicator of Compromise - 네트워크 또는 운영체제에서 관찰된 침입 흔적), TI(Threat Intelligence - 사이버 공간에서 유해한 이벤트를 완화하는데 도움이 되는 위협 및 위협 행위자에 대한 정보), STIX(Structured Thread Information Expression - 사이버 위협 정보 표현 규격), TAXII(Trusted Automated Exchange of Intelligence Information - 사이버위협 정보 전송 규격) 등 예상 가능한 위협 정보 등을 예측

10) Adapt : 보안을 담당하는 부서, 보안 위협에 대해 대응


DevSecOps 적용 범위

DevOps 과정에 적용되는 요건은 이렇게 다양하게 적용할 수 있다. 물론 위와 같이 굉장히 복잡해 보이는 보안 요소 특히 하나하나는 각 분야의 전문가의 도움 없이는 사실 적용 자체가 어려운 요건들이 많이 있다. 어떤 요소는 국가 단위, 어떤 요소는 대기업 수준의 보안 침해 대응팀에서나 다룰 수 있는 전문 분야 요건들이 많기에 우리는 이 모든 부분을 반영할 수는 없을 것이다.

따라서 우리가 초점을 맞춰야 하는 부분은 바로 2) Create, 3) Verify, 4) Preprod이다. 통합 개발환경에 적용한다는 점은 코드 기반 보안성 검토가 이뤄지는 코드를 개발하고, 정적/동적/상호/원점 분석이 가능한 검증도구를 CI/CD 파이프라인에 적용하며, 침해를 가정한 대응 테스트를 진행하는 것이 바로 DevSecOps 조직의 Srcutiry가 담당하는 역할이라 정의할 수 있을 것이다.

마이크로서비스를 구현하는 조직에 보안 전문가가 배치되는 것은 굉장히 중요한 일이다. 하지만, 보안 전문가는 급격한 컨테이너 기술의 성장과 맞물려 그 수요가 부족하여 모든 조직에 배치되는 것은 굉장히 어려운 일이다. 특히 보안 전문가 양성까지의 시간이 많이 걸리고, 새로운 보안 침해 사고들이 지속적으로 발생하는 현 시점에 보안 전문 회사가 아닌 이상 이러한 전문가가 모든 조직에 포함되기에는 사실상 불가능한 상황이다.

이는 근본적으로 해소가 불가능한 일이며, 따라서 DevSecOps 조직에서는 보안 침해로부터 보안 위협을 해결해 나가는 것 보다는 보안 위협이 발생했을때 얼마나 빠르게 보안 전문가에게 이를 전달해 줄 수 있는지를 고려해야 할 것이다. 보안 전문가는 때로는 사람이 될수 있겠지만, 대부분 보안을 해결해 주는 플랫폼이 될 것이다.


파이프라이닝

지금부터는 이를 기준으로 효과적인 DevSecOps를 적용하는 방법에 대해 알아보자.

DevSecOps를 구현함에 있어 가장 중요한 요소는 바로 자동화이다. 보안에 대한 프로세스 역시 DevOps를 수행하는 조직과 마찬가지로 하나의 파이프라인 안에서 수행하도록 구현하는 것이 바람직하다.

이는 매번 소스를 개발하고 배포함에 있어 발생하는 일련의 과정과 함께 동작하여 추가적인 작업 없이 보안 요건을 추출하도록 관리할 수 있게된다.

각 영역은 보안을 위한 주요 Stage를 포함한다.

1) 설계

공격 침해 사건은 대부분 잘못된 구성으로 부터 발생한다. 잘못된 구성은 잘못된 설계에서부터 파생되기 때문에 무엇보다 설계에 많은 시간을 투자하게 된다. 파이프라인의 첫 단계를 설계과정으로 잡은 이유이기도 하다. 우리는 설계 단계를 통해 침해 사건을 사전에 방비할 수 있는 시스템 취약 요소를 판별하고 확인하도록 한다.

a. 공격 루트 최소화

시스템을 보호하기 위한 가장 기본적인 방법이자 중요한 접근 방식은 바로 시스템이나 소프트웨어의 공격 루트를 줄이는 것이다. 공격 루트를 줄이기 위한 기본 전략은 다음과 같다.

  • 실행 중인 코드양 최소화
  • 신뢰할 수 없는 사용자가 접근할 수 있는 진입점 최소화 (ex - bastion 서버를 통해 접근하도록 하고, 모든 서버는 Private Subnet에 위치하여 접근을 차단)
  • 상대적으로 소수의 사용자가 요청한 서비스 제거

b. 권한 설계

IAM(ID and Access Management)은 개별 사용자, 그룹 또는 시스템 컴퓨팅 리소스에 대한 액세스를 허용하거나 제한하는 프로세스이다. 보안으로부터의 침해 사고를 예방하기 위해 사용자, 그룹 또는 리소스에 따라 세분화된 IAM Role을 부여하도록 한다.

c. 네트워크 설계

네트워크는 외부 침해 루트로 부터 보호하기 위해 다양한 구성 요소를 검토해야 한다. 다음은 필수 사항은 아니지만, 권고하는 주요 네트워크 보안 구성 방안이다.

  • VM은 Private Subnet 내 Private IP만 사용하여 배포
  • Cloud NAT로 안전한 아웃바운드 인터넷 연결 구성
  • Public LoadBalancer를 구성하고, 웹 애플리케이션 방화벽(WAF)와 DDoS 완화 서비스(Cloud Armor) 활성화
  • 서버, 리소스 및 VPC에 대한 세분화된 네트워킹 정책 적용
  • 필요한 IP 대역 및 포트만 오픈

d. 시스템 설계

근본적으로 서버 보안을 강화하는 것은 가장 기초가 되는 보안 침해를 방지하는 방안이다. Kubernetes와 같은 컨테이너를 기반으로 서비스를 하더라도 Kubernetes가 설치되는 인프라 보안도 함께 보장되어야 한다.

e. 쿠버네티스 설계

서비스 기반 Kubernetes 클러스터를 사용 중이고 Worker Node만 관리한다고 가정한다. 마스터 노드를 관리하는 경우 Kube-bench를 사용하여 관리한다.

또한, Worker Node 이미지 보안에 대해 고려해야 한다.

  • Secrets - 암호화되어 있고 RBAC가 적용되어 있는지 확인
  • 네트워크 정책 - Zero Trust(기본적으로 모든 것을 차단)로 시작하고 필요한 경우에만 허용 규칙 추가. 가장 좋은 방법은 Service Mesh(Linkerd 또는 Istio와 같은)를 적용하여 관리하는 방법. 서비스 메시를 구현하지 않을 경우 강력한 네트워크 정책 관리 및 액세스 제어 목록(ACL)을 지원하기 위한 오버레이 네트워크 사용
  • OPA(Gatekeeper), Kyverno 등을 사용하여 각 네임스페이스에는 서비스 메시 태그 정책을 적용함

파이프라인 내에 포함되어야할 Stage는 다음과 같다.

▶ 오픈소스 라이선스 관리 및 보안 취약점 점검 (Blackduck, Protex 등)

웹 취약점 분석 (AppScan, Arachni 등)

소스코드 정적분석 (SonarQube, Sparrow 등)

소스코드 종속성 검사 (Maven, Python Plug-In 등)

이미지 취약점분석 수행 (Anchore, Clair 등)

이중 이미지 취약점의 경우 아직 정형화 되어 있는 검증 방식들이 없어 아래와 같은 사항에는 반드시 유의하여 작성하는 것을 권고한다.

 빌드 시 확인할 도커 Base 이미지의 Whitelist를 생성한다.

 암호화된 방식으로 서명된 Base 이미지를 가져오는지 확인한다.

 나중에 확인할 수 있도록 푸시된 이미지의 메타데이터를 암호화된 방식으로 서명한다.

 컨테이너에서는 패키지 관리자의 보안 기능을 사용하여 패키지의 무결성을 확인하는 Linux 배포만 적용한다.

 3rd Party Dependency을 수동으로 가져올 경우 HTTPS만 허용하고, 반드시 Checksum의 유효성을 확인한다.

 HostPath 볼륨은 가능한 접근을 차단한다. 부득이하게 HostPath 볼륨을 PV로 연결해야 할 경우에는 /dev와 같은 중요한 Path에는 접근하지 못하도록 접근을 제한해야 한다.

사실 파이프라인에 위에 제시한 5가지 +@가 모두 포함된다면 배포 속도는 굉장히 느려지게 될 것이다. Security의 확보는 굉장히 중요하지만 가능한 배포 품질을 저하 시키는 정도의 시간 낭비는 발생하지 않아야 한다. 따라서 우리는 1회성으로 적용해야 하는 대상 매번 배포시 마다 검증해야하는 대상을 정의해야 한다.

예를 들어 오픈소스 보안 취약점 점검의 경우 별도의 Stage로 관리되는 것이 효율적이다. 오픈소스는 새로운 버전으로 업그레이드하거나, 새로 다운로드 할 경우에만 해당 Stage를 통해 검토되도록 구성하고, 검토가 완료된 버전을 Local Repository에 저장 후 사용하는 것이 가장 적합한 방식이 될 것이다.

소스코드나 이미지의 경우 항상 재 검증이 필요하다. 소스코드의 변경은 결국 이미지의 변경을 의미하기 때문에 취약점 점검을 통해 문제를 검토해야 할 사항을 도출해 낼 수 있도록 Stage 작성해야 한다.

여기서는 정적분석과 이미지에 대한 내용만 논의했지만, 사실 보안에서 다뤄야 하는 분야는 훨씬 넓다. 동적분석, 상호연계분석 등은 물론 보안을 침해할 수 있는 환경을 구성하고 테스트하는 부분 이를 해결하고 적용하는 부분까지 모두 Security가 담당해야 할 분야라 볼 수 있다.

결론

다음은 digital.ai에서 만든 DevOps 주기율표이다.

(# 위 이미지는 digital.ai/periodic-table-of-devops-tools에서 확인할 수 있다.)

DevOps에 대해서는 그간 꾸준히 논의되어 왔고, 이를 적용하기 위해 많은 노력을 기울이고 있는 것이 사실이다. DevOps는 조직과 프로세스의 변화를 요구하는 동시 빠른 개발, 빠른 배포가 가능한 Agile 방법론을 적용하기 위한 필수적인 요건이기 때문이다.

이제는 보안이라는 요소가 포함되어야 한다. DevSecOps의 시작은 간단히 출발하는 것이 좋다. 소스코드 정적분석, 이미지 취약점 분석을 시작으로 앞서 논의된 수준으로 확대해 나가는 것이 좋을 것이다.

개인적인 의견이지만, Dev : Sec : Ops의 구성 비율은 초기 80 : 10 : 10 수준으로 진행하고, 이후 운영, 테스트, 적용 단계까지 보안 분야를 확대 적용할 경우 70 : 20 : 10 비율로 확대 구성하는 것이 좋아보인다.

지금까지 다룬 내용은 간단해 보이지만 사실 구현과정은 간단하지 않다. 다만 이와 같은 환경을 구성하고 단순화해 나가는 과정을 통해 도출되는 여러가지 보안 요건들을 적용하다보면 그 사례는 분명 하나의 PB 사례가 될 수 있지 않을까 싶다. 사실 DevSecOps를 반드시 적용해야 하는 이유는 단순히 운영조직에서 감당해야 할 운영 상 발생 가능한 보안 위협만의 일은 아니다. 개발조직 역시 심각한 보안 취약점으로 인해 수개월의 프로젝트 동안 개발한 모듈을 전체적으로 재개발해야 하는 일도 발생할 수 있다. 따라서 Sec 영역은 Dev와 Ops 모든 조직에 밀접하게 연관되어 있다는 점을 반드시 기억해야 한다.

개발과 운영 조직이 함께 DevOps의 안정성과 품질을 책임지는 것처럼 DevSecOps는 보안을 포함하여 완전한 팀을 구성할 수 있게 한다. 훌륭한 DevSecOps 체계가 구성되면 전체 어플리케이션을 배포하고 제공하는 프로세스의 효율성은 점진적으로 개선되고 안전한 서비스가 가능해 질 것이다.

728x90
반응형