금일은 Docker Security 에 대해 알아보겠습니다.
컨테이너, 서버리스, 마이크로 서비스 등 다양한 클라우드 기반 기술을 활용하는 애플리케이션의 전체 생명 주기에 걸쳐 보안을 적용을 의미합니다.
멀티 클라우드 환경에서의 데이터 보호, 동적 보안 정책 적용, 연속적인 보안 모니터링 등을 포함합니다.
예시로 lstio 를 들어보겠습니다. Docker 의 resource, scheduling 등을 관리하는 Orchestration 도구인 k8s 를 통해 service mesh 제품인 lstio 를 사용할 수 있습니다.
k8s 환경에 구성되어있는 outer architecture 에 포함되어 network, registry, gateway, router, configuration 정보를 관리해주는 제품이 lstio 이다.
lstio 를 사용하여 서비스간 tls 통신을 적용할 수 있습니다.
docker daemon 은 root 권한을 가지고 실행되기 때문에 주의 깊은 보안 관리가 필요합니다.
tls 활성화
api access 제한
컨테이너 이미지는 취약점에 민감한 레이어오 sw 로 구성되면 검증된 기본 이미지(base image) 를 사용합니다.
보안 취약점 점검으로는 Clair, Trivy, docker Security Scanning 이 있습니다.
이미지 크기는 최소화 하면 alpine 이미지를 사용하기도 합니다.
docker scout
docker scout quickview <image_name>:<tag_name>
docker scout recommendations <image_name>:<tag_name>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 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 를 그대로 사용하기 보다는 해당 명령어를 통해 검사 후 수정이 필요하면 수정 후 실행하는 것이 좋을 것 같습니다.
컨테이너와 호스트는 기본적으로 격리되어 있습니다.
docker run -it --coups=".5" --memory="512MB" <IMAGE_NAME>컨테이너 내의 사용자 ID를 호스트의 다른 사용자 ID 에 매핑하여 권한 상승 공격의 위험을 조정합니다.
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
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 에서 USER d지시어를 사용하여 컨테이너를 root 가 아닌 사용자로 실행하도록 지정할 수 있습니다.
FROM nginx:latest
RUN adduser -D nonrootuser
USER nonrootuser
adduser : /home 디렉토리 아래에 사용자 디렉토리가 생성
useradd : 디렉토리가 생성되지 않는다.
[권한 필요 에러 발생]
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 updateSecret은 보안이 필요한 민감한 데이터를 클러스터 단위에서 안전하게 관리하는 용도입니다.
도커 이미지나 컨테이너 환경에 비밀번호나 api 키와 같은 비밀을 저장하지 않도록 주의합니다.
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 은 파일 형태로 컨테이너에 마운트 됩니다.
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 같은 경우도 동일한 방식입니다. 위의 명령어를 참고해주기시 바랍니다.
다음시간에 자세히 알아보겠습니다. 금일은 개념만 다루어 보겠습니다.
로그를 유지 관리하여 보안 사고를 감지하고 문제를 해결하는 데 도움을 줍니다.
docker run --log-driver syslog --log-opt syslog-address=udp://[ip address] <Image_name>도커 엔진, 이미지 및 호스트 운영 체제를 정기적으로 업데이트하여 최신 보안 패치를 적용해야 합니다.