Docker ๋ณด์•ˆ ๊ฒ€์‚ฌ ์œ ํ‹ธ๋ฆฌํ‹ฐ ๊ตฌํ˜„ ๋ฐฉ๋ฒ• ๋ฐ ์˜ˆ

Docker ๋ณด์•ˆ ๊ฒ€์‚ฌ ์œ ํ‹ธ๋ฆฌํ‹ฐ ๊ตฌํ˜„ ๋ฐฉ๋ฒ• ๋ฐ ์˜ˆ
ํ—ค์ด ํ•˜๋ธŒ๋ฅด!

ํ˜„๋Œ€ ํ˜„์‹ค์—์„œ๋Š” ๊ฐœ๋ฐœ ํ”„๋กœ์„ธ์Šค์—์„œ ์ปจํ…Œ์ด๋„ˆํ™”์˜ ์—ญํ• ์ด ์ฆ๊ฐ€ํ•จ์— ๋”ฐ๋ผ ์ปจํ…Œ์ด๋„ˆ์™€ ๊ด€๋ จ๋œ ๋‹ค์–‘ํ•œ ๋‹จ๊ณ„ ๋ฐ ์—”ํ„ฐํ‹ฐ์˜ ๋ณด์•ˆ์„ ๋ณด์žฅํ•˜๋Š” ๋ฌธ์ œ๊ฐ€ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๋ฌธ์ œ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. ์ˆ˜๋™ ๊ฒ€์‚ฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์€ ์‹œ๊ฐ„์ด ๋งŽ์ด ๊ฑธ๋ฆฌ๋ฏ€๋กœ ์ตœ์†Œํ•œ ์ด ํ”„๋กœ์„ธ์Šค๋ฅผ ์ž๋™ํ™”ํ•˜๊ธฐ ์œ„ํ•œ ์ดˆ๊ธฐ ๋‹จ๊ณ„๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

์ด ๊ธฐ์‚ฌ์—์„œ๋Š” ์—ฌ๋Ÿฌ Docker ๋ณด์•ˆ ์œ ํ‹ธ๋ฆฌํ‹ฐ๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ๋ฏธ๋ฆฌ ๋งŒ๋“ค์–ด์ง„ ์Šคํฌ๋ฆฝํŠธ์™€ ์ด ํ”„๋กœ์„ธ์Šค๋ฅผ ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์œ„ํ•ด ์ž‘์€ ๋ฐ๋ชจ ์Šคํƒ ๋“œ๋ฅผ ๋ฐฐํฌํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์ง€์นจ์„ ๊ณต์œ ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์ž๋ฃŒ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Dockerfile ์ด๋ฏธ์ง€ ๋ฐ ์ง€์นจ์˜ ๋ณด์•ˆ์„ ํ…Œ์ŠคํŠธํ•˜๋Š” ํ”„๋กœ์„ธ์Šค๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‹คํ—˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ์‚ฌ๋žŒ์˜ ๊ฐœ๋ฐœ ๋ฐ ๊ตฌํ˜„ ์ธํ”„๋ผ๊ฐ€ ๋‹ค๋ฅด๋‹ค๋Š” ๊ฒƒ์€ ๋ถ„๋ช…ํ•˜๋ฏ€๋กœ ์•„๋ž˜์—์„œ๋Š” ๋ช‡ ๊ฐ€์ง€ ๊ฐ€๋Šฅํ•œ ์˜ต์…˜์„ ์ œ๊ณตํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๋ณด์•ˆ ๊ฒ€์‚ฌ ์œ ํ‹ธ๋ฆฌํ‹ฐ

Docker ์ธํ”„๋ผ์˜ ๋‹ค์–‘ํ•œ ์ธก๋ฉด์„ ๊ฒ€์‚ฌํ•˜๋Š” ๋‹ค์–‘ํ•œ ๋„์šฐ๋ฏธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ์ค‘ ์ผ๋ถ€๋Š” ์ด๋ฏธ ์ด์ „ ๊ธฐ์‚ฌ์—์„œ ์„ค๋ช…ํ–ˆ์Šต๋‹ˆ๋‹ค(https://habr.com/ru/company/swordfish_security/blog/518758/#docker-security), ์ด ์ž๋ฃŒ์—์„œ๋Š” ๊ฐœ๋ฐœ ํ”„๋กœ์„ธ์Šค ์ค‘์— ๊ตฌ์ถ•๋œ Docker ์ด๋ฏธ์ง€์— ๋Œ€ํ•œ ๋ณด์•ˆ ์š”๊ตฌ ์‚ฌํ•ญ์˜ ๋Œ€๋ถ€๋ถ„์„ ๋‹ค๋ฃจ๋Š” ์„ธ ๊ฐ€์ง€์— ์ค‘์ ์„ ๋‘๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์ด ์„ธ ๊ฐ€์ง€ ์œ ํ‹ธ๋ฆฌํ‹ฐ๋ฅผ ํ•˜๋‚˜์˜ ํŒŒ์ดํ”„๋ผ์ธ์— ์—ฐ๊ฒฐํ•˜์—ฌ ๋ณด์•ˆ ๊ฒ€์‚ฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์˜ˆ๋„ ๋ณด์—ฌ ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

ํ•˜๋Œ๋ฆฐํŠธ
https://github.com/hadolint/hadolint

์ฒซ ๋ฒˆ์งธ ๊ทผ์‚ฌ์น˜๋กœ Dockerfile ์ง€์นจ์˜ ์ •ํ™•์„ฑ๊ณผ ์•ˆ์ „์„ฑ์„ ํ‰๊ฐ€ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋˜๋Š” ๋งค์šฐ ๊ฐ„๋‹จํ•œ ์ฝ˜์†” ์œ ํ‹ธ๋ฆฌํ‹ฐ์ž…๋‹ˆ๋‹ค(์˜ˆ: ์Šน์ธ๋œ ์ด๋ฏธ์ง€ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ๋งŒ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ sudo ์‚ฌ์šฉ).

Docker ๋ณด์•ˆ ๊ฒ€์‚ฌ ์œ ํ‹ธ๋ฆฌํ‹ฐ ๊ตฌํ˜„ ๋ฐฉ๋ฒ• ๋ฐ ์˜ˆ

๋„ํด
https://github.com/goodwithtech/dockle

์ด๋ฏธ์ง€(๋˜๋Š” ์ด๋ฏธ์ง€์˜ ์ €์žฅ๋œ tar ์•„์นด์ด๋ธŒ)์™€ ํ•จ๊ป˜ ์ž‘๋™ํ•˜๋Š” ์ฝ˜์†” ์œ ํ‹ธ๋ฆฌํ‹ฐ๋กœ ํŠน์ • ์ด๋ฏธ์ง€์˜ ์ •ํ™•์„ฑ๊ณผ ๋ณด์•ˆ์„ ํ™•์ธํ•˜๊ณ  ๋ ˆ์ด์–ด์™€ ๊ตฌ์„ฑ(์ƒ์„ฑ๋œ ์‚ฌ์šฉ์ž, ์‚ฌ์šฉ๋œ ์ง€์นจ, ๋ณผ๋ฅจ์ด ๋งˆ์šดํŠธ๋˜์–ด ์žˆ๋Š”์ง€, ๋นˆ ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ์žˆ๋Š”์ง€ ๋“ฑ d. ์ง€๊ธˆ๊นŒ์ง€ ํ™•์ธ ํšŸ์ˆ˜๋Š” ๊ทธ๋ฆฌ ๋งŽ์ง€ ์•Š์œผ๋ฉฐ ์ž์ฒด ํ™•์ธ ๋ฐ ๊ถŒ์žฅ ์‚ฌํ•ญ ์ค‘ ์ผ๋ถ€๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค. CIS(์ธํ„ฐ๋„ท ๋ณด์•ˆ ์„ผํ„ฐ) ๋ฒค์น˜๋งˆํฌ ๋„์ปค์šฉ.
Docker ๋ณด์•ˆ ๊ฒ€์‚ฌ ์œ ํ‹ธ๋ฆฌํ‹ฐ ๊ตฌํ˜„ ๋ฐฉ๋ฒ• ๋ฐ ์˜ˆ

์‚ฌ์†Œํ•œ
https://github.com/aquasecurity/trivy

์ด ์œ ํ‹ธ๋ฆฌํ‹ฐ๋Š” OS ๋นŒ๋“œ ๋ฌธ์ œ(Alpine, RedHat(EL), CentOS, Debian GNU, Ubuntu์—์„œ ์ง€์›)์™€ ์ข…์†์„ฑ ๋ฌธ์ œ(Gemfile.lock, Pipfile.lock, Composer.lock, ํŒจํ‚ค์ง€)๋ผ๋Š” ๋‘ ๊ฐ€์ง€ ์œ ํ˜•์˜ ์ทจ์•ฝ์ ์„ ์ฐพ๋Š” ๊ฒƒ์„ ๋ชฉํ‘œ๋กœ ํ•ฉ๋‹ˆ๋‹ค. -lock.json, ์›์‚ฌ.์ž ๊ธˆ, ํ™”๋ฌผ.์ž ๊ธˆ). Trivy๋Š” ์ €์žฅ์†Œ์˜ ์ด๋ฏธ์ง€์™€ ๋กœ์ปฌ ์ด๋ฏธ์ง€๋ฅผ ๋ชจ๋‘ ์Šค์บ”ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, Docker ์ด๋ฏธ์ง€๋กœ ์ „์†ก๋œ .tar ํŒŒ์ผ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์Šค์บ”ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

Docker ๋ณด์•ˆ ๊ฒ€์‚ฌ ์œ ํ‹ธ๋ฆฌํ‹ฐ ๊ตฌํ˜„ ๋ฐฉ๋ฒ• ๋ฐ ์˜ˆ

์œ ํ‹ธ๋ฆฌํ‹ฐ ๊ตฌํ˜„ ์˜ต์…˜

๊ฒฉ๋ฆฌ๋œ ํ™˜๊ฒฝ์—์„œ ์„ค๋ช…๋œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹œํ—˜ํ•ด ๋ณด๊ธฐ ์œ„ํ•ด ๋‹ค์†Œ ๋‹จ์ˆœํ™”๋œ ํ”„๋กœ์„ธ์Šค๋กœ ๋ชจ๋“  ์œ ํ‹ธ๋ฆฌํ‹ฐ๋ฅผ ์„ค์น˜ํ•˜๋Š” ์ง€์นจ์„ ์ œ๊ณตํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์ฃผ์š” ์•„์ด๋””์–ด๋Š” ๊ฐœ๋ฐœ ์ค‘์— ์ƒ์„ฑ๋œ Dockerfile ๋ฐ Docker ์ด๋ฏธ์ง€์˜ ์ž๋™ ์ฝ˜ํ…์ธ  ํ™•์ธ์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ฃผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ฒ€์‚ฌ ์ž์ฒด๋Š” ๋‹ค์Œ ๋‹จ๊ณ„๋กœ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค.

  1. linter ์œ ํ‹ธ๋ฆฌํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Dockerfile ๋ช…๋ น์˜ ์ •ํ™•์„ฑ๊ณผ ์•ˆ์ „์„ฑ ํ™•์ธ ํ•˜๋Œ๋ฆฐํŠธ
  2. ์œ ํ‹ธ๋ฆฌํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ตœ์ข… ๋ฐ ์ค‘๊ฐ„ ์ด๋ฏธ์ง€์˜ ์ •ํ™•์„ฑ๊ณผ ์•ˆ์ „์„ฑ ํ™•์ธ ๋„ํด
  3. ์œ ํ‹ธ๋ฆฌํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ธฐ๋ณธ ์ด๋ฏธ์ง€ ๋ฐ ์—ฌ๋Ÿฌ ์ข…์†์„ฑ์— ๊ณต๊ฐœ์ ์œผ๋กœ ์•Œ๋ ค์ง„ ์ทจ์•ฝ์ (CVE)์ด ์žˆ๋Š”์ง€ ํ™•์ธ ์‚ฌ์†Œํ•œ

์ด ๊ธฐ์‚ฌ์˜ ๋’ท๋ถ€๋ถ„์—์„œ๋Š” ์ด๋Ÿฌํ•œ ๋‹จ๊ณ„๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•œ ์„ธ ๊ฐ€์ง€ ์˜ต์…˜์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
์ฒซ ๋ฒˆ์งธ๋Š” GitLab์„ ์˜ˆ์‹œ๋กœ ์‚ฌ์šฉํ•˜์—ฌ CI/CD ํŒŒ์ดํ”„๋ผ์ธ์„ ๊ตฌ์„ฑํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค(ํ…Œ์ŠคํŠธ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ํ”„๋กœ์„ธ์Šค์— ๋Œ€ํ•œ ์„ค๋ช… ํฌํ•จ).
๋‘ ๋ฒˆ์งธ๋Š” ์‰˜ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์„ธ ๋ฒˆ์งธ๋Š” Docker ์ด๋ฏธ์ง€๋ฅผ ์Šค์บ”ํ•˜๊ธฐ ์œ„ํ•ด Docker ์ด๋ฏธ์ง€๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
๊ท€ํ•˜์—๊ฒŒ ๊ฐ€์žฅ ์ ํ•ฉํ•œ ์˜ต์…˜์„ ์„ ํƒํ•˜๊ณ  ์ด๋ฅผ ์ธํ”„๋ผ๋กœ ์ „์†กํ•œ ํ›„ ํ•„์š”์— ๋งž๊ฒŒ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•„์š”ํ•œ ๋ชจ๋“  ํŒŒ์ผ๊ณผ ์ถ”๊ฐ€ ์ง€์นจ๋„ ์ €์žฅ์†Œ์— ์žˆ์Šต๋‹ˆ๋‹ค. https://github.com/Swordfish-Security/docker_cicd

GitLab CI/CD์— ํ†ตํ•ฉ

์ฒซ ๋ฒˆ์งธ ์˜ต์…˜์—์„œ๋Š” GitLab ์ €์žฅ์†Œ ์‹œ์Šคํ…œ์„ ์˜ˆ๋กœ ๋“ค์–ด ๋ณด์•ˆ ๊ฒ€์‚ฌ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—์„œ๋Š” ๋‹จ๊ณ„๋ฅผ ๊ฑฐ์ณ ์ฒ˜์Œ๋ถ€ํ„ฐ GitLab์„ ์‚ฌ์šฉํ•˜์—ฌ ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ์„ ์„ค์น˜ํ•˜๊ณ , ์Šค์บ” ํ”„๋กœ์„ธ์Šค๋ฅผ ๋งŒ๋“ค๊ณ , ํ…Œ์ŠคํŠธ Dockerfile ๋ฐ ์ž„์˜ ์ด๋ฏธ์ง€(JuiceShop ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜)๋ฅผ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•œ ์œ ํ‹ธ๋ฆฌํ‹ฐ๋ฅผ ์‹œ์ž‘ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ด…๋‹ˆ๋‹ค.

GitLab ์„ค์น˜
1. ๋„์ปค๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค:

sudo apt-get update && sudo apt-get install docker.io

2. sudo๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ ๋„ docker๋กœ ์ž‘์—…ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ˜„์žฌ ์‚ฌ์šฉ์ž๋ฅผ docker ๊ทธ๋ฃน์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

sudo addgroup <username> docker

3. ๊ท€ํ•˜์˜ IP๋ฅผ ์ฐพ์œผ์‹ญ์‹œ์˜ค:

ip addr

4. ์ปจํ…Œ์ด๋„ˆ์— GitLab์„ ์„ค์น˜ํ•˜๊ณ  ์‹คํ–‰ํ•˜์—ฌ ํ˜ธ์ŠคํŠธ ์ด๋ฆ„์˜ IP ์ฃผ์†Œ๋ฅผ ์‚ฌ์šฉ์ž ๊ณ ์œ ์˜ IP ์ฃผ์†Œ๋กœ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.

docker run --detach 
--hostname 192.168.1.112 
--publish 443:443 --publish 80:80 
--name gitlab 
--restart always 
--volume /srv/gitlab/config:/etc/gitlab 
--volume /srv/gitlab/logs:/var/log/gitlab 
--volume /srv/gitlab/data:/var/opt/gitlab 
gitlab/gitlab-ce:latest

GitLab์ด ํ•„์š”ํ•œ ๋ชจ๋“  ์„ค์น˜ ์ ˆ์ฐจ๋ฅผ ์™„๋ฃŒํ•  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค(๋กœ๊ทธ ํŒŒ์ผ ์ถœ๋ ฅ: dockerlogs -f gitlab์„ ํ†ตํ•ด ํ”„๋กœ์„ธ์Šค๋ฅผ ๋ชจ๋‹ˆํ„ฐ๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค).

5. ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋กœ์ปฌ IP๋ฅผ ์—ด๊ณ  ๋ฃจํŠธ ์‚ฌ์šฉ์ž์˜ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๋ณ€๊ฒฝํ•˜๋ผ๋Š” ํŽ˜์ด์ง€๋ฅผ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.
Docker ๋ณด์•ˆ ๊ฒ€์‚ฌ ์œ ํ‹ธ๋ฆฌํ‹ฐ ๊ตฌํ˜„ ๋ฐฉ๋ฒ• ๋ฐ ์˜ˆ
์ƒˆ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์„ค์ •ํ•˜๊ณ  GitLab์œผ๋กœ ์ด๋™ํ•˜์„ธ์š”.

6. cicd-test์™€ ๊ฐ™์€ ์ƒˆ ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์‹œ์ž‘ ํŒŒ์ผ๋กœ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค. README.md:
Docker ๋ณด์•ˆ ๊ฒ€์‚ฌ ์œ ํ‹ธ๋ฆฌํ‹ฐ ๊ตฌํ˜„ ๋ฐฉ๋ฒ• ๋ฐ ์˜ˆ
7. ์ด์ œ ์š”์ฒญ ์‹œ ํ•„์š”ํ•œ ๋ชจ๋“  ์ž‘์—…์„ ์‹คํ–‰ํ•˜๋Š” ์—์ด์ „ํŠธ์ธ GitLab Runner๋ฅผ ์„ค์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
์ตœ์‹  ๋ฒ„์ „์„ ๋‹ค์šด๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค(์ด ๊ฒฝ์šฐ Linux 64๋น„ํŠธ์šฉ).

sudo curl -L --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64

8. ์‹คํ–‰ ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“œ์„ธ์š”:

sudo chmod +x /usr/local/bin/gitlab-runner

9. Runner์šฉ OS ์‚ฌ์šฉ์ž๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์„œ๋น„์Šค๋ฅผ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

sudo useradd --comment 'GitLab Runner' --create-home gitlab-runner --shell /bin/bash
sudo gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner
sudo gitlab-runner start

๋‹ค์Œ๊ณผ ๊ฐ™์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.

local@osboxes:~$ sudo gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner
Runtime platform arch=amd64 os=linux pid=8438 revision=0e5417a3 version=12.0.1
local@osboxes:~$ sudo gitlab-runner start
Runtime platform arch=amd64 os=linux pid=8518 revision=0e5417a3 version=12.0.1

10. ์ด์ œ GitLab ์ธ์Šคํ„ด์Šค์™€ ์ƒํ˜ธ ์ž‘์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก Runner๋ฅผ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค.
์ด๋ ‡๊ฒŒ ํ•˜๋ ค๋ฉด ์„ค์ •-CI/CD ํŽ˜์ด์ง€(http://OUR_IP_ADDRESS/root/cicd-test/-/settings/ci_cd)๋ฅผ ์—ด๊ณ  ์‹คํ–‰์ž ํƒญ์—์„œ URL๊ณผ ๋“ฑ๋ก ํ† ํฐ์„ ์ฐพ์œผ์„ธ์š”.
Docker ๋ณด์•ˆ ๊ฒ€์‚ฌ ์œ ํ‹ธ๋ฆฌํ‹ฐ ๊ตฌํ˜„ ๋ฐฉ๋ฒ• ๋ฐ ์˜ˆ
11. URL๊ณผ ๋“ฑ๋ก ํ† ํฐ์„ ๋Œ€์ฒดํ•˜์—ฌ Runner๋ฅผ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค.

sudo gitlab-runner register 
--non-interactive 
--url "http://<URL>/" 
--registration-token "<Registration Token>" 
--executor "docker" 
--docker-privileged 
--docker-image alpine:latest 
--description "docker-runner" 
--tag-list "docker,privileged" 
--run-untagged="true" 
--locked="false" 
--access-level="not_protected"

๊ฒฐ๊ณผ์ ์œผ๋กœ ์šฐ๋ฆฌ๋Š” ์œ ํ‹ธ๋ฆฌํ‹ฐ๋ฅผ ์‹œ์ž‘ํ•˜๊ธฐ ์œ„ํ•œ ์ง€์นจ์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•˜๋Š” ๊ธฐ์„ฑํ’ˆ ์ž‘์—… GitLab์„ ์–ป์Šต๋‹ˆ๋‹ค. ์ด ๋ฐ๋ชจ์—๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌ์ถ•ํ•˜๊ณ  ์ปจํ…Œ์ด๋„ˆํ™”ํ•˜๋Š” ๋‹จ๊ณ„๊ฐ€ ์—†์ง€๋งŒ ์‹ค์ œ ํ™˜๊ฒฝ์—์„œ๋Š” ์ด๋Ÿฌํ•œ ๋‹จ๊ณ„๊ฐ€ ์Šค์บ” ๋‹จ๊ณ„๋ณด๋‹ค ๋จผ์ € ์ˆ˜ํ–‰๋˜๊ณ  ๋ถ„์„์„ ์œ„ํ•œ ์ด๋ฏธ์ง€์™€ Dockerfile์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

ํŒŒ์ดํ”„๋ผ์ธ ๊ตฌ์„ฑ

1. ์ €์žฅ์†Œ์— ํŒŒ์ผ ์ถ”๊ฐ€ mydockerfile.df (์šฐ๋ฆฌ๊ฐ€ ํ™•์ธํ•  ํ…Œ์ŠคํŠธ Dockerfile์ž…๋‹ˆ๋‹ค) ๋ฐ GitLab CI/CD ํ”„๋กœ์„ธ์Šค ๊ตฌ์„ฑ ํŒŒ์ผ .gitlab-cicd.yml, ์Šค์บ๋„ˆ์— ๋Œ€ํ•œ ์ง€์นจ์ด ๋‚˜์—ด๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค(ํŒŒ์ผ ์ด๋ฆ„์˜ ์  ์ฐธ๊ณ ).

YAML ๊ตฌ์„ฑ ํŒŒ์ผ์—๋Š” ์„ ํƒํ•œ Dockerfile๊ณผ DOCKERFILE ๋ณ€์ˆ˜์— ์ง€์ •๋œ ์ด๋ฏธ์ง€๋ฅผ ๋ถ„์„ํ•˜๋Š” ์„ธ ๊ฐ€์ง€ ์œ ํ‹ธ๋ฆฌํ‹ฐ(Hadolint, Dockle ๋ฐ Trivy)๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•œ ์ง€์นจ์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ•„์š”ํ•œ ๋ชจ๋“  ํŒŒ์ผ์€ ์ €์žฅ์†Œ์—์„œ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. https://github.com/Swordfish-Security/docker_cicd/

๋ฐœ์ทŒ mydockerfile.df (์ด๊ฒƒ์€ ์œ ํ‹ธ๋ฆฌํ‹ฐ์˜ ์ž‘๋™์„ ๋ณด์—ฌ์ฃผ๊ธฐ ์œ„ํ•œ ์ž„์˜์˜ ๋ช…๋ น ์„ธํŠธ๊ฐ€ ํฌํ•จ๋œ ์ถ”์ƒ ํŒŒ์ผ์ž…๋‹ˆ๋‹ค.) ํŒŒ์ผ์— ๋Œ€ํ•œ ์ง์ ‘ ๋งํฌ: mydockerfile.df

mydockerfile.df์˜ ๋‚ด์šฉ

FROM amd64/node:10.16.0-alpine@sha256:f59303fb3248e5d992586c76cc83e1d3700f641cbcd7c0067bc7ad5bb2e5b489 AS tsbuild
COPY package.json .
COPY yarn.lock .
RUN yarn install
COPY lib lib
COPY tsconfig.json tsconfig.json
COPY tsconfig.app.json tsconfig.app.json
RUN yarn build
FROM amd64/ubuntu:18.04@sha256:eb70667a801686f914408558660da753cde27192cd036148e58258819b927395
LABEL maintainer="Rhys Arkins <[email protected]>"
LABEL name="renovate"
...
COPY php.ini /usr/local/etc/php/php.ini
RUN cp -a /tmp/piik/* /var/www/html/
RUN rm -rf /tmp/piwik
RUN chown -R www-data /var/www/html
ADD piwik-cli-setup /piwik-cli-setup
ADD reset.php /var/www/html/
## ENTRYPOINT ##
ADD entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
USER root

๊ตฌ์„ฑ YAML์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ํŒŒ์ผ ์ž์ฒด๋Š” ๋‹ค์Œ ์ง์ ‘ ๋งํฌ๋ฅผ ํ†ตํ•ด ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. .gitlab-ci.yml):

.gitlab-ci.yml์˜ ๋‚ด์šฉ

variables:
    DOCKER_HOST: "tcp://docker:2375/"
    DOCKERFILE: "mydockerfile.df" # name of the Dockerfile to analyse   
    DOCKERIMAGE: "bkimminich/juice-shop" # name of the Docker image to analyse
    # DOCKERIMAGE: "knqyf263/cve-2018-11235" # test Docker image with several CRITICAL CVE
    SHOWSTOPPER_PRIORITY: "CRITICAL" # what level of criticality will fail Trivy job
    TRIVYCACHE: "$CI_PROJECT_DIR/.cache" # where to cache Trivy database of vulnerabilities for faster reuse
    ARTIFACT_FOLDER: "$CI_PROJECT_DIR"
 
services:
    - docker:dind # to be able to build docker images inside the Runner
 
stages:
    - scan
    - report
    - publish
 
HadoLint:
    # Basic lint analysis of Dockerfile instructions
    stage: scan
    image: docker:git
 
    after_script:
    - cat $ARTIFACT_FOLDER/hadolint_results.json
 
    script:
    - export VERSION=$(wget -q -O - https://api.github.com/repos/hadolint/hadolint/releases/latest | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/1/')
    - wget https://github.com/hadolint/hadolint/releases/download/v${VERSION}/hadolint-Linux-x86_64 && chmod +x hadolint-Linux-x86_64
     
    # NB: hadolint will always exit with 0 exit code
    - ./hadolint-Linux-x86_64 -f json $DOCKERFILE > $ARTIFACT_FOLDER/hadolint_results.json || exit 0
 
    artifacts:
        when: always # return artifacts even after job failure       
        paths:
        - $ARTIFACT_FOLDER/hadolint_results.json
 
Dockle:
    # Analysing best practices about docker image (users permissions, instructions followed when image was built, etc.)
    stage: scan   
    image: docker:git
 
    after_script:
    - cat $ARTIFACT_FOLDER/dockle_results.json
 
    script:
    - export VERSION=$(wget -q -O - https://api.github.com/repos/goodwithtech/dockle/releases/latest | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/1/')
    - wget https://github.com/goodwithtech/dockle/releases/download/v${VERSION}/dockle_${VERSION}_Linux-64bit.tar.gz && tar zxf dockle_${VERSION}_Linux-64bit.tar.gz
    - ./dockle --exit-code 1 -f json --output $ARTIFACT_FOLDER/dockle_results.json $DOCKERIMAGE   
     
    artifacts:
        when: always # return artifacts even after job failure       
        paths:
        - $ARTIFACT_FOLDER/dockle_results.json
 
Trivy:
    # Analysing docker image and package dependencies against several CVE bases
    stage: scan   
    image: docker:git
 
    script:
    # getting the latest Trivy
    - apk add rpm
    - export VERSION=$(wget -q -O - https://api.github.com/repos/knqyf263/trivy/releases/latest | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/1/')
    - wget https://github.com/knqyf263/trivy/releases/download/v${VERSION}/trivy_${VERSION}_Linux-64bit.tar.gz && tar zxf trivy_${VERSION}_Linux-64bit.tar.gz
     
    # displaying all vulnerabilities w/o failing the build
    - ./trivy -d --cache-dir $TRIVYCACHE -f json -o $ARTIFACT_FOLDER/trivy_results.json --exit-code 0 $DOCKERIMAGE    
    
    # write vulnerabilities info to stdout in human readable format (reading pure json is not fun, eh?). You can remove this if you don't need this.
    - ./trivy -d --cache-dir $TRIVYCACHE --exit-code 0 $DOCKERIMAGE    
 
    # failing the build if the SHOWSTOPPER priority is found
    - ./trivy -d --cache-dir $TRIVYCACHE --exit-code 1 --severity $SHOWSTOPPER_PRIORITY --quiet $DOCKERIMAGE
         
    artifacts:
        when: always # return artifacts even after job failure
        paths:
        - $ARTIFACT_FOLDER/trivy_results.json
 
    cache:
        paths:
        - .cache
 
Report:
    # combining tools outputs into one HTML
    stage: report
    when: always
    image: python:3.5
     
    script:
    - mkdir json
    - cp $ARTIFACT_FOLDER/*.json ./json/
    - pip install json2html
    - wget https://raw.githubusercontent.com/shad0wrunner/docker_cicd/master/convert_json_results.py
    - python ./convert_json_results.py
     
    artifacts:
        paths:
        - results.html

ํ•„์š”ํ•œ ๊ฒฝ์šฐ .tar ์•„์นด์ด๋ธŒ ํ˜•์‹์œผ๋กœ ์ €์žฅ๋œ ์ด๋ฏธ์ง€๋ฅผ ์Šค์บ”ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค(๋‹จ, YAML ํŒŒ์ผ์—์„œ ์œ ํ‹ธ๋ฆฌํ‹ฐ์— ๋Œ€ํ•œ ์ž…๋ ฅ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ณ€๊ฒฝํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค).

์ฃผ์˜: Trivy๋ฅผ ์„ค์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. RPM ะธ ์ž์‹. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด RedHat ๊ธฐ๋ฐ˜ ์ด๋ฏธ์ง€๋ฅผ ์Šค์บ”ํ•˜๊ณ  ์ทจ์•ฝ์„ฑ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋Œ€ํ•œ ์—…๋ฐ์ดํŠธ๋ฅผ ๋ฐ›์„ ๋•Œ ์˜ค๋ฅ˜๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

2. ๊ตฌ์„ฑ ํŒŒ์ผ์˜ ์ง€์นจ์— ๋”ฐ๋ผ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ์— ํŒŒ์ผ์„ ์ถ”๊ฐ€ํ•œ ํ›„ GitLab์€ ์ž๋™์œผ๋กœ ๋นŒ๋“œ ๋ฐ ์Šค์บ” ํ”„๋กœ์„ธ์Šค๋ฅผ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. CI/CD โ†’ ํŒŒ์ดํ”„๋ผ์ธ ํƒญ์—์„œ ์ง€์นจ์˜ ์ง„ํ–‰ ์ƒํ™ฉ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ์ ์œผ๋กœ ๋„ค ๊ฐ€์ง€ ์ž‘์—…์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ์ค‘ XNUMX๊ฐœ๋Š” ์Šค์บ”์„ ์ง์ ‘ ์ฒ˜๋ฆฌํ•˜๊ณ , ๋งˆ์ง€๋ง‰ ํ•˜๋‚˜(๋ณด๊ณ ์„œ)๋Š” ์Šค์บ” ๊ฒฐ๊ณผ์™€ ํ•จ๊ป˜ ํฉ์–ด์ ธ ์žˆ๋Š” ํŒŒ์ผ์—์„œ ๊ฐ„๋‹จํ•œ ๋ณด๊ณ ์„œ๋ฅผ ์ˆ˜์ง‘ํ•ฉ๋‹ˆ๋‹ค.
Docker ๋ณด์•ˆ ๊ฒ€์‚ฌ ์œ ํ‹ธ๋ฆฌํ‹ฐ ๊ตฌํ˜„ ๋ฐฉ๋ฒ• ๋ฐ ์˜ˆ
๊ธฐ๋ณธ์ ์œผ๋กœ Trivy๋Š” ์ด๋ฏธ์ง€ ๋˜๋Š” ์ข…์†์„ฑ์—์„œ CRITICAL ์ทจ์•ฝ์ ์ด ๊ฐ์ง€๋˜๋ฉด ์‹คํ–‰์„ ์ค‘์ง€ํ•ฉ๋‹ˆ๋‹ค. ๋™์‹œ์— Hadolint๋Š” ํ•ญ์ƒ ์„ฑ๊ณต ์ฝ”๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ํ•ญ์ƒ ์ฃผ์„์ด ์ƒ์„ฑ๋˜์–ด ๋นŒ๋“œ๊ฐ€ ์ค‘์ง€๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

ํŠน์ • ์š”๊ตฌ ์‚ฌํ•ญ์— ๋”ฐ๋ผ ์ด๋Ÿฌํ•œ ์œ ํ‹ธ๋ฆฌํ‹ฐ๊ฐ€ ํŠน์ • ์ค‘์š”์„ฑ์˜ ๋ฌธ์ œ๋ฅผ ๊ฐ์ง€ํ•˜๋ฉด ๋นŒ๋“œ ํ”„๋กœ์„ธ์Šค๋„ ์ค‘์ง€ํ•˜๋„๋ก ์ข…๋ฃŒ ์ฝ”๋“œ๋ฅผ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ์˜ ๊ฒฝ์šฐ Trivy๊ฐ€ SHOWSTOPPER ๋ณ€์ˆ˜์— ์ง€์ •ํ•œ ์ค‘์š”๋„์˜ ์ทจ์•ฝ์ ์„ ๊ฐ์ง€ํ•œ ๊ฒฝ์šฐ์—๋งŒ ๋นŒ๋“œ๊ฐ€ ์ค‘์ง€๋ฉ๋‹ˆ๋‹ค. .gitlab-ci.yml.
Docker ๋ณด์•ˆ ๊ฒ€์‚ฌ ์œ ํ‹ธ๋ฆฌํ‹ฐ ๊ตฌํ˜„ ๋ฐฉ๋ฒ• ๋ฐ ์˜ˆ

๊ฐ ์œ ํ‹ธ๋ฆฌํ‹ฐ์˜ ๊ฒฐ๊ณผ๋Š” ๊ฐ ๊ฒ€์‚ฌ ์ž‘์—…์˜ ๋กœ๊ทธ, ์•„ํ‹ฐํŒฉํŠธ ์„น์…˜์˜ json ํŒŒ์ผ ๋˜๋Š” ๊ฐ„๋‹จํ•œ HTML ๋ณด๊ณ ์„œ์—์„œ ์ง์ ‘ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์ž์„ธํ•œ ๋‚ด์šฉ์€ ์•„๋ž˜ ์ฐธ์กฐ).
Docker ๋ณด์•ˆ ๊ฒ€์‚ฌ ์œ ํ‹ธ๋ฆฌํ‹ฐ ๊ตฌํ˜„ ๋ฐฉ๋ฒ• ๋ฐ ์˜ˆ

3. ์‚ฌ๋žŒ์ด ์ข€ ๋” ์ฝ๊ธฐ ์‰ฌ์šด ํ˜•์‹์œผ๋กœ ์œ ํ‹ธ๋ฆฌํ‹ฐ ๋ณด๊ณ ์„œ๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ์ž‘์€ Python ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์„ธ ๊ฐœ์˜ JSON ํŒŒ์ผ์„ ๊ฒฐํ•จ ํ‘œ๊ฐ€ ํฌํ•จ๋œ ํ•˜๋‚˜์˜ HTML ํŒŒ์ผ๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
์ด ์Šคํฌ๋ฆฝํŠธ๋Š” ๋ณ„๋„์˜ ๋ณด๊ณ ์„œ ์ž‘์—…์— ์˜ํ•ด ์‹œ์ž‘๋˜๋ฉฐ ์ตœ์ข… ๊ฒฐ๊ณผ๋ฌผ์€ ๋ณด๊ณ ์„œ๊ฐ€ ํฌํ•จ๋œ HTML ํŒŒ์ผ์ž…๋‹ˆ๋‹ค. ์Šคํฌ๋ฆฝํŠธ ์†Œ์Šค๋„ ์ €์žฅ์†Œ์— ์žˆ์œผ๋ฉฐ ํ•„์š”, ์ƒ‰์ƒ ๋“ฑ์— ๋งž๊ฒŒ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
Docker ๋ณด์•ˆ ๊ฒ€์‚ฌ ์œ ํ‹ธ๋ฆฌํ‹ฐ ๊ตฌํ˜„ ๋ฐฉ๋ฒ• ๋ฐ ์˜ˆ

์‰˜ ์Šคํฌ๋ฆฝํŠธ

๋‘ ๋ฒˆ์งธ ์˜ต์…˜์€ CI/CD ์‹œ์Šคํ…œ ์™ธ๋ถ€์—์„œ Docker ์ด๋ฏธ์ง€๋ฅผ ํ™•์ธํ•ด์•ผ ํ•˜๊ฑฐ๋‚˜ ํ˜ธ์ŠคํŠธ์—์„œ ์ง์ ‘ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ํ˜•์‹์˜ ๋ชจ๋“  ์ง€์นจ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ์— ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค. ์ด ์˜ต์…˜์€ ๊นจ๋—ํ•œ ๊ฐ€์ƒ(๋˜๋Š” ์‹ค์ œ) ๋จธ์‹ ์—์„œ ์‹คํ–‰๋  ์ˆ˜ ์žˆ๋Š” ๋ฏธ๋ฆฌ ๋งŒ๋“ค์–ด์ง„ ์‰˜ ์Šคํฌ๋ฆฝํŠธ๋กœ ๋‹ค๋ค„์ง‘๋‹ˆ๋‹ค. ์Šคํฌ๋ฆฝํŠธ๋Š” ์œ„์—์„œ ์„ค๋ช…ํ•œ gitlab-runner์™€ ๋™์ผํ•œ ์ง€์นจ์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

์Šคํฌ๋ฆฝํŠธ๋ฅผ ์„ฑ๊ณต์ ์œผ๋กœ ์‹คํ–‰ํ•˜๋ ค๋ฉด Docker๊ฐ€ ์‹œ์Šคํ…œ์— ์„ค์น˜๋˜์–ด ์žˆ์–ด์•ผ ํ•˜๋ฉฐ ํ˜„์žฌ ์‚ฌ์šฉ์ž๊ฐ€ docker ๊ทธ๋ฃน์— ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์Šคํฌ๋ฆฝํŠธ ์ž์ฒด๋Š” ์—ฌ๊ธฐ์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. docker_sec_check.sh

ํŒŒ์ผ ์‹œ์ž‘ ๋ถ€๋ถ„์—์„œ ๋ณ€์ˆ˜๋Š” ์Šค์บ”ํ•ด์•ผ ํ•  ์ด๋ฏธ์ง€์™€ Trivy ์œ ํ‹ธ๋ฆฌํ‹ฐ๊ฐ€ ์ง€์ •๋œ ์˜ค๋ฅ˜ ์ฝ”๋“œ์™€ ํ•จ๊ป˜ ์ข…๋ฃŒ๋˜๋„๋ก ํ•˜๋Š” ์ค‘์š”๋„ ๊ฒฐํ•จ์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰ ์ค‘์— ๋ชจ๋“  ์œ ํ‹ธ๋ฆฌํ‹ฐ๊ฐ€ ๋””๋ ‰ํ† ๋ฆฌ์— ๋‹ค์šด๋กœ๋“œ๋ฉ๋‹ˆ๋‹ค. docker_tools, ์ž‘์—… ๊ฒฐ๊ณผ๋Š” ๋””๋ ‰ํ† ๋ฆฌ์— ์žˆ์Šต๋‹ˆ๋‹ค. docker_tools/json, ๋ณด๊ณ ์„œ๊ฐ€ ํฌํ•จ๋œ HTML์ด ํŒŒ์ผ์— ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ.html.

์˜ˆ์ œ ์Šคํฌ๋ฆฝํŠธ ์ถœ๋ ฅ

~/docker_cicd$ ./docker_sec_check.sh

[+] Setting environment variables
[+] Installing required packages
[+] Preparing necessary directories
[+] Fetching sample Dockerfile
2020-10-20 10:40:00 (45.3 MB/s) - โ€˜Dockerfileโ€™ saved [8071/8071]
[+] Pulling image to scan
latest: Pulling from bkimminich/juice-shop
[+] Running Hadolint
...
Dockerfile:205 DL3015 Avoid additional packages by specifying `--no-install-recommends`
Dockerfile:248 DL3002 Last USER should not be root
...
[+] Running Dockle
...
WARN    - DKL-DI-0006: Avoid latest tag
        * Avoid 'latest' tag
INFO    - CIS-DI-0005: Enable Content trust for Docker
        * export DOCKER_CONTENT_TRUST=1 before docker pull/build
...
[+] Running Trivy
juice-shop/frontend/package-lock.json
=====================================
Total: 3 (UNKNOWN: 0, LOW: 1, MEDIUM: 0, HIGH: 2, CRITICAL: 0)

+---------------------+------------------+----------+---------+-------------------------+
|       LIBRARY       | VULNERABILITY ID | SEVERITY | VERSION |             TITLE       |
+---------------------+------------------+----------+---------+-------------------------+
| object-path         | CVE-2020-15256   | HIGH     | 0.11.4  | Prototype pollution in  |
|                     |                  |          |         | object-path             |
+---------------------+------------------+          +---------+-------------------------+
| tree-kill           | CVE-2019-15599   |          | 1.2.2   | Code Injection          |
+---------------------+------------------+----------+---------+-------------------------+
| webpack-subresource | CVE-2020-15262   | LOW      | 1.4.1   | Unprotected dynamically |
|                     |                  |          |         | loaded chunks           |
+---------------------+------------------+----------+---------+-------------------------+

juice-shop/package-lock.json
============================
Total: 20 (UNKNOWN: 0, LOW: 1, MEDIUM: 6, HIGH: 8, CRITICAL: 5)

...

juice-shop/package-lock.json
============================
Total: 5 (CRITICAL: 5)

...
[+] Removing left-overs
[+] Making the output look pretty
[+] Converting JSON results
[+] Writing results HTML
[+] Clean exit ============================================================
[+] Everything is done. Find the resulting HTML report in results.html

๋ชจ๋“  ์œ ํ‹ธ๋ฆฌํ‹ฐ๊ฐ€ ํฌํ•จ๋œ Docker ์ด๋ฏธ์ง€

์„ธ ๋ฒˆ์งธ ๋Œ€์•ˆ์œผ๋กœ ๋‘ ๊ฐœ์˜ ๊ฐ„๋‹จํ•œ Dockerfile์„ ์ปดํŒŒ์ผํ•˜์—ฌ ๋ณด์•ˆ ์œ ํ‹ธ๋ฆฌํ‹ฐ๊ฐ€ ํฌํ•จ๋œ ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•˜๋‚˜์˜ Dockerfile์€ ์ €์žฅ์†Œ์—์„œ ์ด๋ฏธ์ง€๋ฅผ ์Šค์บ”ํ•˜๊ธฐ ์œ„ํ•œ ์„ธํŠธ๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋˜๊ณ , ๋‘ ๋ฒˆ์งธ Dockerfile_tar๋Š” ์ด๋ฏธ์ง€๊ฐ€ ํฌํ•จ๋œ tar ํŒŒ์ผ์„ ์Šค์บ”ํ•˜๊ธฐ ์œ„ํ•œ ์„ธํŠธ๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค.

1. ์ €์žฅ์†Œ์—์„œ ํ•ด๋‹น Docker ํŒŒ์ผ๊ณผ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. https://github.com/Swordfish-Security/docker_cicd/tree/master/Dockerfile.
2. ์กฐ๋ฆฝ์„ ์œ„ํ•ด ์ถœ์‹œํ•ฉ๋‹ˆ๋‹ค.

docker build -t dscan:image -f docker_security.df .

3. ์กฐ๋ฆฝ์ด ์™„๋ฃŒ๋˜๋ฉด ์ด๋ฏธ์ง€์—์„œ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๋™์‹œ์— ๊ด€์‹ฌ ์žˆ๋Š” ์ด๋ฏธ์ง€ ์ด๋ฆ„๊ณผ ํ•จ๊ป˜ DOCKERIMAGE ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์ „๋‹ฌํ•˜๊ณ  ๋ถ„์„ํ•˜๋ ค๋Š” Dockerfile์„ ๋จธ์‹ ์—์„œ ํŒŒ์ผ๋กœ ๋งˆ์šดํŠธํ•ฉ๋‹ˆ๋‹ค. /๋„์ปคํŒŒ์ผ (์ด ํŒŒ์ผ์˜ ์ ˆ๋Œ€ ๊ฒฝ๋กœ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.):

docker run --rm -v $(pwd)/results:/results -v $(pwd)/docker_security.df:/Dockerfile -e DOCKERIMAGE="bkimminich/juice-shop" dscan:image


[+] Setting environment variables
[+] Running Hadolint
/Dockerfile:3 DL3006 Always tag the version of an image explicitly
[+] Running Dockle
WARN    - DKL-DI-0006: Avoid latest tag
        * Avoid 'latest' tag
INFO    - CIS-DI-0005: Enable Content trust for Docker
        * export DOCKER_CONTENT_TRUST=1 before docker pull/build
INFO    - CIS-DI-0006: Add HEALTHCHECK instruction to the container image
        * not found HEALTHCHECK statement
INFO    - DKL-LI-0003: Only put necessary files
        * unnecessary file : juice-shop/node_modules/sqlite3/Dockerfile
        * unnecessary file : juice-shop/node_modules/sqlite3/tools/docker/architecture/linux-arm64/Dockerfile
        * unnecessary file : juice-shop/node_modules/sqlite3/tools/docker/architecture/linux-arm/Dockerfile
[+] Running Trivy
...
juice-shop/package-lock.json
============================
Total: 20 (UNKNOWN: 0, LOW: 1, MEDIUM: 6, HIGH: 8, CRITICAL: 5)
...
[+] Making the output look pretty
[+] Starting the main module ============================================================
[+] Converting JSON results
[+] Writing results HTML
[+] Clean exit ============================================================
[+] Everything is done. Find the resulting HTML report in results.html

์กฐ์‚ฌ ๊ฒฐ๊ณผ

์šฐ๋ฆฌ๋Š” Docker ์•„ํ‹ฐํŒฉํŠธ๋ฅผ ๊ฒ€์ƒ‰ํ•˜๊ธฐ ์œ„ํ•œ ํ•˜๋‚˜์˜ ๊ธฐ๋ณธ ์œ ํ‹ธ๋ฆฌํ‹ฐ ์„ธํŠธ๋งŒ ์‚ดํŽด๋ณด์•˜๋Š”๋ฐ, ์ œ ์ƒ๊ฐ์—๋Š” ์ด๋ฏธ์ง€ ๋ณด์•ˆ ์š”๊ตฌ ์‚ฌํ•ญ์˜ ์ƒ๋‹น ๋ถ€๋ถ„์„ ๋งค์šฐ ํšจ๊ณผ์ ์œผ๋กœ ๋‹ค๋ฃจ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ๋™์ผํ•œ ๊ฒ€์‚ฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ณ , ๋ฉ‹์ง„ ๋ณด๊ณ ์„œ๋ฅผ ์ž‘์„ฑํ•˜๊ฑฐ๋‚˜, ์ˆœ์ „ํžˆ ์ฝ˜์†” ๋ชจ๋“œ์—์„œ ์ž‘์—…ํ•˜๊ณ , ์ปจํ…Œ์ด๋„ˆ ๊ด€๋ฆฌ ์‹œ์Šคํ…œ์„ ๋ณดํ˜ธํ•˜๋Š” ๋“ฑ์˜ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ์ˆ˜๋งŽ์€ ์œ ๋ฃŒ ๋ฐ ๋ฌด๋ฃŒ ๋„๊ตฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋„๊ตฌ์— ๋Œ€ํ•œ ๊ฐœ์š”์™€ ํ†ตํ•ฉ ๋ฐฉ๋ฒ•์€ ์กฐ๊ธˆ ๋‚˜์ค‘์— ๋‚˜ํƒ€๋‚  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. .

์ด ๋ฌธ์„œ์— ์„ค๋ช…๋œ ๋„๊ตฌ ์„ธํŠธ์˜ ์ข‹์€ ์ ์€ ๋ชจ๋‘ ์˜คํ”ˆ ์†Œ์Šค์ด๋ฉฐ ์ด๋Ÿฌํ•œ ๋„๊ตฌ์™€ ๊ธฐํƒ€ ์œ ์‚ฌํ•œ ๋„๊ตฌ๋ฅผ ์‹คํ—˜ํ•˜์—ฌ ์š”๊ตฌ ์‚ฌํ•ญ๊ณผ ์ธํ”„๋ผ์— ์ ํ•ฉํ•œ ๊ฒƒ์„ ์ฐพ์„ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ฌผ๋ก , ๋ฐœ๊ฒฌ๋œ ๋ชจ๋“  ์ทจ์•ฝ์ ์€ ํŠน์ • ์กฐ๊ฑด์—์„œ์˜ ์ ์šฉ ๊ฐ€๋Šฅ์„ฑ์— ๋Œ€ํ•ด ์—ฐ๊ตฌ๋˜์–ด์•ผ ํ•˜์ง€๋งŒ ์ด๋Š” ํ–ฅํ›„ ๋Œ€๊ทœ๋ชจ ๊ธฐ์‚ฌ์˜ ์ฃผ์ œ์ž…๋‹ˆ๋‹ค.

์ด ๊ฐ€์ด๋“œ, ์Šคํฌ๋ฆฝํŠธ ๋ฐ ์œ ํ‹ธ๋ฆฌํ‹ฐ๊ฐ€ ๊ท€ํ•˜์—๊ฒŒ ๋„์›€์ด ๋˜๊ณ  ์ปจํ…Œ์ด๋„ˆํ™” ๋ถ„์•ผ์—์„œ ๋ณด๋‹ค ์•ˆ์ „ํ•œ ์ธํ”„๋ผ๋ฅผ ๊ตฌ์ถ•ํ•˜๊ธฐ ์œ„ํ•œ ์ถœ๋ฐœ์ ์ด ๋˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€