Docker - Security

INHEES·2025년 1월 10일

금일은 Docker Security 에 대해 알아보겠습니다.

목차

  • Docker 와 Cloud Native Application 보안
  • Docker Security
  • Docker 에서의 정보 관리

Docker 와 Cloud Native Application 보안

Cloud native application security

  • 컨테이너, 서버리스, 마이크로 서비스 등 다양한 클라우드 기반 기술을 활용하는 애플리케이션의 전체 생명 주기에 걸쳐 보안을 적용을 의미합니다.

  • 멀티 클라우드 환경에서의 데이터 보호, 동적 보안 정책 적용, 연속적인 보안 모니터링 등을 포함합니다.

예시로 lstio 를 들어보겠습니다. Docker 의 resource, scheduling 등을 관리하는 Orchestration 도구인 k8s 를 통해 service mesh 제품인 lstio 를 사용할 수 있습니다.

k8s 환경에 구성되어있는 outer architecture 에 포함되어 network, registry, gateway, router, configuration 정보를 관리해주는 제품이 lstio 이다.

lstio 를 사용하여 서비스간 tls 통신을 적용할 수 있습니다.

docker 보안

  • 컨테이너 수준에서의 보안 조치에 집중
  • 이미지와 컨테이너 취약점 관리에 초점
  • 컨테이너 런타임 시 보안 정보 사용
  • 이미지 보안과 컨테이너의 격리의 특징

Docker Security

  • docker daemon security
    - 컨테이너 실행을 위한 docker engine 에 대한 보안
  • container image security
    - 이미지에 대한 보안 취약성 문제점 확인
  • container isolation
    - 컨테이너의 실행이 다른 컨테이너나 host 에 영향을 주지 않는 독립적인 실행 환경
  • runtime security
    - 컨테이너 실행 동안 지속적인 모니터링과 관리

docker daemon security

  • docker daemon 은 root 권한을 가지고 실행되기 때문에 주의 깊은 보안 관리가 필요합니다.

    • limit root access
    • 일반 계정에 secure 권한을 주어야 합니다.
  • tls 활성화

    • url 을 통해 ssl/tls 인증서를 통한 보안
  • api access 제한

    • docker client 에 대한 요청 또는 docker api 접속을 차단

container image security

  • 컨테이너 이미지는 취약점에 민감한 레이어오 sw 로 구성되면 검증된 기본 이미지(base image) 를 사용합니다.

  • 보안 취약점 점검으로는 Clair, Trivy, docker Security Scanning 이 있습니다.

    • Clair, Trivy 등을 활용하여 정기적으로 도커 이미지의 취약점을 검사합니다.
  • 이미지 크기는 최소화 하면 alpine 이미지를 사용하기도 합니다.

  • docker scout

    • docker desktop 에서는 기본 제공되며, linux docker 에서는 설치가 필요합니다.
    • docker hub, docker cli, docker scout dashboard 와 상호 작용 가능한 독립한 서비스 플랫폼입니다.
      docker scout quickview <image_name>:<tag_name>
      docker scout recommendations <image_name>:<tag_name>
    • cvss score 로 0 ~ 10 점으로 나뉘며 low, medium, high, critical 로 나뉩니다.
  • Trivy

    • 컨테이너의 취약점 및 구성 문제를 쉽게 검색 가능한 보안 스캐너

    • 정확성이 높으며, 데이터베이스 설치를 위한 서전 요구 사항이 없음

    • os 패키지 및 언어별 패키지 를 검색합니다.

    • 포괄적인 취약점 감지(os, 미들웨어, app library)

    • 설치가 간단하고 ci/cd 파이프라인에 쉽게 통합 됩니다.

      docker pull aquasec/trivy:0.18.3
      docker run --rm -v /home/ec2-user/.cache/:/root/.cache/ aquasec/trivy:0.18.3 <image_name>:<tag_name>

docker scout command

해당 실습의 이미지는 docker hub 에 나와있는 edowon0623/docker:latest 를 사용하겠습니다.

실습 명령어외 scout 명령어는 --help 명령어를 통해 알아보시면 됩니다.

[docker scout] 

docker scout quickview edowon0623/docker:latest
docker scout recommendations edowon0623/docker:latest

[trivy]
docker pull aquasec/trivy:0.18.3
docker run --rm -v $(pwd)/.cache/:/root/.cache/ aquasec/trivy:0.18.3 edowon0623/docker:latest

그림에서 recommadations 명령어를 통해 상태값을 확인해준 다음에 trivy 명령어 를 통해 분석 결과를 통해 패키지의 라이브러리의 문제점과 수정된 버전을 확인 할 수 있습니다.

이렇듯 registry 에서의 image 를 그대로 사용하기 보다는 해당 명령어를 통해 검사 후 수정이 필요하면 수정 후 실행하는 것이 좋을 것 같습니다.


container isolation

  • 컨테이너와 호스트는 기본적으로 격리되어 있습니다.

    • Namaspace Isolation : 프로세스, 네트워, 파일 시스템 격리
    • Control Groups (cgroups) : 리소스를 보호하기 위해 cpu, memory, i/o 리소스 를 제한
      docker run -it --coups=".5" --memory="512MB" <IMAGE_NAME>
  • 컨테이너 내의 사용자 ID를 호스트의 다른 사용자 ID 에 매핑하여 권한 상승 공격의 위험을 조정합니다.

    • User Namespace -> container Root 사용자를 Non-root 사용자와 매핑을 합니다.
    • linux 환경을 제외한 max, windows 환경에서는 docker desktop 에 관리하고 있기 떄문에 docker daemon 을 실행하는 dockerd 명령어를 사용할 필요는 없습니다.
  • 컨테이너 간의 트래픽을 제한하기 위해 네트워크 세분화 및 방화벽 규칙이 필요합니다.

    • 사용자 정의 브리지 네트워크를 생성하여 컨테이너 통신을 겨리

    • docker network 명령어 사용 합니다.

      docker network create --driver bridge isolated_network
      docker run --network=isolated_network <container images>
      
    • 두개의 서로 다른 db를 독립적인 환경에서 통신을 위해서는 컨테이너 실행 명령어에 isolate_network 를 적어주거나 아래와 같이 connect 명령어를 통해 묶어 주어야 합니다.

      그렇게 되면 mariadb2 번 db 에서 mariadb1 번으로 접속이 가능합니다.

      docker network connect isolated_network mariadb1
      
      [mariadb2 bash]
      maariadb -h<mariadb1 ip adress> -uroot -p

runtime security

  • 실행 중인 컨테이너 보안 강화 및 지속적인 모니터링
    • Security Profiles 는 보안 정책으로 Apparmor, SELinux, seccomp profiles 등을 사용합니다.
      docker run --security-opt seccomp=/path/to/seccomp-profile.json <Image_name>
  • 컨테이너를 최소 권한으로 실행
    • Linux Capabilities 는 작업의 명시로 root 슈퍼 유저의 권한을 세분화하여 부분적으로 권한을 허용하는 역할을 만듭니다.

      root 유저의 권환 명령어로는 chown, dac_override, dkill, net_raw, mknod ... 등이 있고 아래 명령어를 통해 제어가 가능합니다.

      docker run --cap-drop=ALL --cap-add=SETGID \
      --cap-add=SETUID --cap-add=CHOIWN \
      --cap-add=DAC_OVERRIDE --cap_add=FOWNER \
      FIRST-IMAGE:0.1 bash
      
  • Dockerfile 에서의 권한 조정
    • Dockerfile 로 이미지를 빌드할 때는 높은 권한으로 실행되기 때문에 제한이 필요없습니다.

    • 컨테이너 이미지를 이용하여 컨테이너를 실행할 때 제한이 필요합니다.

    • Dockerfile 에서 USER d지시어를 사용하여 컨테이너를 root 가 아닌 사용자로 실행하도록 지정할 수 있습니다.

      FROM nginx:latest
      RUN adduser -D nonrootuser
      USER nonrootuser
      adduser : /home 디렉토리 아래에 사용자 디렉토리가 생성
      useradd : 디렉토리가 생성되지 않는다. 
  • Capabilities Command 실습
    [권한 필요 에러 발생]
    docker run -it --cap-drop=ALL first-image:0.1 bash
    apt-get update
    
    exit
    docker rm [container_id]
    
    [권한 부여 명령어]
    docker run -it run --cap-drop=ALL --cap-add=SETGID --cap-add=SETUID --cap-add=CHOWN --cap-add=DAC_OVERRIDE --cap-add=FOWNER first-image:0.1 bash
    apt-get update

Secrets Management

  • Secret은 보안이 필요한 민감한 데이터를 클러스터 단위에서 안전하게 관리하는 용도입니다.

    • docker swarm mode 에서 생성 된 service 에서 사용 가능합니다.
  • 도커 이미지나 컨테이너 환경에 비밀번호나 api 키와 같은 비밀을 저장하지 않도록 주의합니다.

    • docker secrets 또는 외부 비밀 관리자를 사용합니다.
    • create a docker secret
      key-value 형태로 만들어 집니다. 
      docker swarm init
      echo "mysecretdata" | docker secret create my_secret -
      echo qwer1234 | docker secret create my_db_password - 
  • secret 에 포함된 데이터는 해당 secret 이 삽입된 service 와 이에 속하여 구동 중인 task 의 container 에서만 접근이 가능하기 때문에 매우 중요한 정보는 조심할 필요가 있습니다.

  • docker swarm d의 secret 은 파일 형태로 컨테이너에 마운트 됩니다.

docker secrets 실습

secret 목록 조회

docker secret ls
docker secret inspect my_secret

서비스 실행 시 secret 사용

[redis service]
docker service create --name my-redis --secret my_secret redis:alpine
docker exec -it [container_id] sh

[redis container# ]
redis-cli set my_secret_key "$(cat /run/secrets/my_secret)"
redis-cli
GET my_secret_key


[mariaDB service]
docker service create --name my-db --replicas 1 \
        --secret source=my_db_password,target=mariadb_root_password \
        -e MARIADB_ROOT_PASSWORD_FILE="/run/secrets/mariadb_root_password" \
        -e MARIADB_DATABASE="mydb" mariadb:latest
        
docker exec -it [container_id] bash

[mariaDB container]
mariadb -h127.0.0.1 -uroot -p
qwer1234

위의 명령어는 docker swarm 환경에서 구성해야 되기 때문에 manager, worker 노드 환경을 사전에 구축 해놔야 한다. 전의 블로그에서 정리를 하였으니 참고하시길 바랍니다.

manager node 에서 echo 명령어를 통해 secrets 을 생성해줍니다.

manager node 에서 redis service 를 실행한 뒤에 sh, bash 명령어를 통해 컨테이너에 접속하게 되면 ls -al /run/secrets 에 저장되어 있는 것을 볼 수 있습니다.

mariadb 같은 경우도 동일한 방식입니다. 위의 명령어를 참고해주기시 바랍니다.

Logging and Monitoring

다음시간에 자세히 알아보겠습니다. 금일은 개념만 다루어 보겠습니다.

  • 로그를 유지 관리하여 보안 사고를 감지하고 문제를 해결하는 데 도움을 줍니다.

    • Docker Logging Driver 를 구성하여 로그를 안전하고 외부 시스템에 중앙 집중화 하여 분석
    • Syslog를 이용하여 컨테이너를 실행 (Linux 환경)
      아래의 명렁어는 일반적으로는 linux 환경에서 syslog 를 기본적으로 저장하게 되어있지만 컨테이너에 발생하는 로그도 저장하기 위해서는 아래와 같이 syslog 위치의 ipaddress 를 적어주어야 한다.
      docker run --log-driver syslog --log-opt syslog-address=udp://[ip address] <Image_name>
  • 도커 엔진, 이미지 및 호스트 운영 체제를 정기적으로 업데이트하여 최신 보안 패치를 적용해야 합니다.


참고자료

inflearn

profile
이유를 찾아보자

0개의 댓글