- 운영체제 기반 이미지의 크기가 크면 다양한 도구가 포함되기 마련이다.
- 그러나 이들 도구는 실제 컴퓨터에서는 유용할지 모르지만 컨테이너에서는 보안상의 허점이 되기 쉽다.
- 예를 들어 운영체제 기반 이미지에 curl이 설치돼 있다면, 애플리케이션 컨테이너에 침입한 공격자가 curl을 사용해 악의적인 소프트웨어를 컨테이너로 내려받거나 자신의 서버로 여러분의 데이터를 전송할 수도 있다.
표 17-1 도커 허브에서 게시된 자바 11 버전 이미지 간의 이미지 크기 차이 | | :11-jdk | :11-jre | :11-jre-slim | :11-jre-nanoserver-1809 | | -- | -- | -- | -- | -- | | 리눅스 | 296MB | 103MB | 69MB | | | 윈도 | 2.4GB | 2.2GB | | 277MB |
- 애플리케이션에 사용할 때는 크기가 작은 변종 이미지부터 검토해야 한다.
- 참고 사항이지만 리눅스 컨테이너에는 알파인 리눅스 또는 데비안 슬림 이미지를 기반 이미지로 추천하며, 윈도 컨테이너는 나노 서버(윈도 서버의 모든 기능 을 갖춘 원도 서버 코어의 대체품이다)를 기반 이미지로 사용하는 것이 좋다.
- 이미지 크기는 비단 디스크 용량에만 관계된 것이 아니며, 디스크 활용과도 관계가 깊다.
- 크기가 가장 큰 OpenjDK 이미지는 자바 SDK 전체가 들어 있다.
- 따라서 누군가가 컨테이너에 침입했다면 그다음 공격을 이어 나갈 좋은 수단으로 이를 이용할 수 있다.
- 컨테이너 파일 시스템에서 자바로 코드를 작성한 다음 SDK를 사용해 이를 컴파일하고, 컨테이너 보안을 멋대로 헤집는 애플리케이션을 실행할 수도 있다.
실습 이번 장의 실습 문제 중에는 기본 JDK 이미지를 사용하는 자바 애플리케이션이 있다. 이 애플리케이션은 항상 true를 반환하는 간단한 REST API를 제공한다.
➜ cd ch17/exercises/truth-app
# 이미지 빌드 - 베이스 이미지로 :11-jdk 태그가 쓰인다
➜ docker image build -t diamol/ch17-truth-app .
[+] Building 46.1s (19/19) FINISHED
=> exporting to image 0.0s
=> => naming to docker.io/diamol/ch17-truth-app 0.0s
# 애플리케이션을 실행하고 테스트한다
➜ docker container run -d -p 8010:80 --name truth diamol/ch17-truth-app
89c66663501d127a3881b53da74cc0f7809f742d5ace9aa4207e8bd1a7634c07
➜ curl http://localhost:8010/truth
true%
- 지금 실행한 컨테이너는 자바 REST API를 제공한다.
- 하지만 이외에도 다른 자바 애플리케이션을 컴파일할 수 있는 모든 도구가 함께 이미지에 포함돼 있다.
- 공격자가 애플리케이션 내부로 침입해 컨테이너에서 명령을 실행할 수 있게 됐다면, 자신이 원하는 코드를 무엇이든 실행할 수 있다.
실습 셀로 API 컨테이너에 접속해 공격자를 가정해 보자. 그리고 JDK를 사용해 테스트 코드를 실행한 다음 애플리케이션의 동작을 다시 확인해 보자.
# 셸로 API 컨테이너에 접속하기
➜ docker container exec -it truth sh
$ ls
FileUpdateTest.java truth-app-0.1.0.jar truth.txt
# 컨테이너 내부에서 자바 테스트 코드를 컴파일하고 실행한다
$ javac FileUpdateTest.java
$ java FileUpdateTest
$ exit
# 컨테이너에서 로그아웃한 후 API를 다시 호출한다
➜ curl http://localhost:8010/truth
false%
- 기반 이미지가 애플리케이션 실행에 필요한 모든 것을 갖춰야 하지만, 빌드에 필요한 도구를 포함시켜서는 안 된다는 것이다
- 골든 이미지는 이러한 문제를 피할 수 있는 한 가지 방법이다.
- 직접 만든 골든 이미지는 업데이트 주기를 스스로 결정할 수 있고 골든 이미지 빌드 후에 바로 이어서 애플리케이션 빌드를 진행할 수도 있다.
- 또한, 앤코어(Anchore) 같은 서드파티 도구를 골든 이미지에 삽입해 빌드 중에 보안 검사를 할 수 있다는 것도 장점이다.
실습 앤코어는 오픈 소스 도커 이미지 분석 도구다. 앤코어의 분석 모듈은 도커 컨테이너에서 실행되는데, 아쉽게도 아직 다중 아키텍처를 지원하지 않는다. 인텔 프로세서 에서 리눅스 컨테이너를 사용 중이라면 앤코어를 사용할 수 있다. 만약 지원 대상이 아니라면, Play with Docker 세션을 사용해 이 책의 예제 코드 저장소를 복제한 후 실 습을 진행하기 바란다.
001) $ cd ch17/exercises/anchore/
002)
003) # 엔코어의 모든 구성요소를 실행한다
004) $ docker-compose up -d
005) $ docker ps
006) CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
007) 578b010fc07c anchore/anchore-engine:v0.5.2 "/docker-entrypoint.…" 5 minutes ago Up 5 minutes (healthy) 0.0.0.0:8228->8228/tcp anchore-engine-api-1
008) a95e1e52b5b4 anchore/anchore-engine:v0.5.2 "/docker-entrypoint.…" 5 minutes ago Up 5 minutes (healthy) 8228/tcp anchore-engine-analyzer-1
009) 92625fc63251 anchore/anchore-engine:v0.5.2 "/docker-entrypoint.…" 5 minutes ago Up 5 minutes (healthy) 8228/tcp anchore-engine-simpleq-1
010) 9461314d237e anchore/anchore-engine:v0.5.2 "/docker-entrypoint.…" 5 minutes ago Up 5 minutes (healthy) 8228/tcp anchore-engine-policy-engine-1
011) ef6d2e564b09 anchore/anchore-engine:v0.5.2 "/docker-entrypoint.…" 5 minutes ago Up 5 minutes (healthy) 8228/tcp anchore-engine-catalog-1
012) 2fe84582ceaf postgres:9 "docker-entrypoint.s…" 5 minutes ago Up 5 minutes 5432/tcp anchore-anchore-db-1
013)
014) # 앤코어가 데이터베이스를 내려받는 데 15분 정도가 걸린다
015) # 여기서부터는 새 터미널 창을 열어 진행하기 바란다
016) $ docker exec anchore-engine-api-1 anchore-cli system wait
017)
018) # 나의 자바 골든 이미지 Dockerfile 스크립트를 컨테이너로 복사한다
019) $ docker container cp "$(pwd)/../../../images/openjdk/Dockerfile" anchore-engine-api-1:Dockerfile
020) Successfully copied 2.05kB to anchore-engine-api-1:Dockerfile
021)
022) # 그리고 이미지와 Dockerfile을 앤코어로 분석한다
023) $ docker container exec anchore-engine-api-1 anchore-cli image add diamol/openjdk --dockerfile /Dockerfile
024) Image Digest: sha256:6b39ed34b004ea3a9cc26985129bc76cea4006d1af45e15fb33b7353488ef222
025) Parent Digest: sha256:bc11278602c48a60f71ea01031c54a73878d19db4803f7dd8705aa77bab89808
026) Analysis Status: not_analyzed
027) Image Type: docker
028) Analyzed At: None
029) Image ID: ace3932f8772e8a78327bf00e25a704e4a09e672d64538bb84db3bb5b47be566
030) Dockerfile Mode: Actual
031) Distro: None
032) Distro Version: None
033) Size: None
034) Architecture: None
035) Layer Count: None
036)
037) Full Tag: docker.io/diamol/openjdk:latest
038) Tag Detected At: 2023-08-05T15:09:43Z
039)
040) # 분석 결과를 기다린다
041) $ docker container exec anchore-engine-api-1 anchore-cli image wait diamol/openjdk
042) Status: analyzing
043) Waiting 5.0 seconds for next retry.
044) Status: analyzing
045) Waiting 5.0 seconds for next retry.
046) Status: analyzing
047) Waiting 5.0 seconds for next retry.
048) Status: analyzing
049) Waiting 5.0 seconds for next retry.
050) Image Digest: sha256:6b39ed34b004ea3a9cc26985129bc76cea4006d1af45e15fb33b7353488ef222
051) Parent Digest: sha256:bc11278602c48a60f71ea01031c54a73878d19db4803f7dd8705aa77bab89808
052) Analysis Status: analyzed
053) Image Type: docker
054) Analyzed At: 2023-08-05T15:10:19Z
055) Image ID: ace3932f8772e8a78327bf00e25a704e4a09e672d64538bb84db3bb5b47be566
056) Dockerfile Mode: Actual
057) Distro: debian
058) Distro Version: 10
059) Size: 231352320
060) Architecture: amd64
061) Layer Count: 5
062)
063) Full Tag: docker.io/diamol/openjdk:latest
064) Tag Detected At: 2023-08-05T15:09:43Z
- 023: 도커 허브 혹은 전용 레지스트리에 저장된 특정 이미지나 리포지터리 전체를 분석 대상으로 삼을 수 있다. 대상 이미지를 스캔하고 보안 취약점이나 정책 위반 사항을 찾아낸다.
- 026: 응답 내용에서 이미지가 분석 대상에는 포함됐지만, 분석 과정은 백그라운드에서 돌아가며 아직 분석이 끝나지 않은 상태임을 알 수 있다.
-
041: 이 부분은 대개 C/CD 파이프라인에서 실행하는 방식이지만, 앤코어의 wait 명령으로 분석이 끝날 때까지 터미널 세션을 막아 놓는 기능을 보이고자 여기서 사용했다.
-
앤코어 분석이 끝나면 이미지에 포함된 다양하고 많은 문제점을 지적해 준다.
- 이미지에 사용된 오픈 소스 소프트웨어의 라이선스부터 운영체제와 애플리케이션 플랫폼에 대한 상세 정보, 이미지에 포함된 바이너리 파일의 보안 문제까지 알 수 있다.
- 이렇게 발견된 문제점으로 업데이트된 기반 이미지의 품질을 평가할 수도 있다.
실습 앞의 실습에서 wait를 포함한 명령 실행이 끝나면 이미지 분석이 완료된 것이다. 애플리케이션 플랫폼 및 이미지에서 어떤 보안 취약점이 발견됐는지 확인해 보자
- 앤코어는 젠킨스 같은 CI/CD 도구용 플러그인을 제공한다.
- 이를 사용해 원하는 정책을 파이프라인에 포함시킬 수 있다.
- 분석 결과는 앤코어 API 컨테이너에 직접 쿼리로 문의할 수 있다.
001) # 이미지에서 사용된 자바 컴포넌트를 확인한다
002) $ docker container exec anchore-engine-api-1 anchore-cli image content diamol/openjdk java
003) Package Specification-Version Implementation-Version Location
004) jrt-fs 11 11.0.10 /usr/local/openjdk-11/lib/jrt-fs.jar
005)
006) # 이미지에서 발견된 보안 취약점을 확인한다
007) $ docker container exec anchore-engine-api-1 anchore-cli image vuln diamol/openjdk all
008)
- 002~004: 앤코어는 주요 애플리케이션 플랫폼을 분석할 수 있다. 이 이미지에서 자바 런타임을 찾아내고 그 상세 정보(버전, 설치 경로)를 파악했다.
- 007: 현재 시점에서는 보안취약점이 발견되지 않았다(교재 집필 시점에는 보안취약점이 발견되었었다)