본문 바로가기
docker

[Docker] Docker 간단정리 & pwnable 문제 deploy (with docker-compose)

by snwo 2021. 7. 22.

 


container VS vm

 

컨테이너를 사용하는 도커

기존에 있던 VirtureMachine 은 하드웨어를 가상화 해서, 한 머신에서 여러 서버를 구동시킬 수 있다.

hypervisor 에서 여러 머신을 구동할 수 있게 해주기 때문에다.

근데 머신에 사용되는 각각의 os image 를 올리기 때문에, 메모리, 저장장치에서 overhead 를 추가시킨다.

 

이런 VM 과는 달리, container 는 호스트 os, 커널 , 바이너리, 라이브러리를 공유해서

vm 과는 다르게, 가볍고 빠르다. 프로세스의 실행환경을 격리하기 때문이다

host 커널과 container 의 커널이 달라도, 다른 부분만 패키징 해서 커널이 다른 container 도 쓸 수 있다.

 

하지만, 가볍다고 장점만 있는 것은 아니다. container 은, host os 를 가상화해서 올리고, 커널을 공유하게 되는데, 

이 때, 완전히 격리된 상태가 아니기 때문에, host 커널이 보안에 취약해질 수 있다.

 


docker

docker 는 , 컨테이너형 가상화를 지원하는 플랫폼이다.

 

docker 설치 

 

curl -s https://get.docker.com | sudo sh

https://get.docker.com 에는 알아서 도커를 설치해주는 쉘 스크립트가 있다. 

이 스크립트를 파이프를 통해 sh 로 넘겨주면, 도커가 설치가 된다.

 

근데 이런 형태의 명령은, 사이트에 있는 쉘 스크립트를 그대로 실행시켜주기 때문에,

안전한 사이트가 아니면 저런 형태의 명령어를 사용하는 것은 비추한다.

 

docker 는 앞에 sudo 를 붙여 관리자 권한으로 실행해야 하는데,

sudo usermod -aG docker $USER
sudo su - $USER

docker 그룹에 지금 사용자를 추가하면, sudo 없이도 사용할 수 있다고 한다.

 

docker 실행과정

docker image 준비

 

docker 은 vm 과 마찬가지로 image 를 이용해 컨테이너를 생성한다.

docker image 는 docker 에서 공식적으로 제공되는 UBUNTU, DEBIAN, MYSQL 등의 이미지가 있고,

사람들이 이런 base image 를 이용해 만든 다른 이미지파일을 docker hub 에 올리기도 한다.

 

하지만 이런 생 이미지를 다운받아 컨테이너로 사용한다면, 사용해야할 각종 툴들도 설치해야 하는데,

컨테이너는 휘발성이다. 그래서 사람들은 Dockerfile 을 이용해 base image 에 세팅을 한 뒤, 

이미지로 빌드해 사용하곤 한다.

 

FROM MAINTAINERRUN CMD LABEL EXPOSEENV ADDCOPY ENTRYPOINT VOLUME USER WORKDIR ARG ONBUILD SHELL ... 등의 명령어로 이루어져 있다.

 

docker 컨테이너 실행

 

docker run <이미지> 를 이용해 컨테이너를 생성할 수 있다.

-it 옵션은 터미널과 상호작용하기 위한 옵션,

-v 현재경로:컨테이너경로, 디렉터리를 마운트해서 호스트와 컨테이너가 폴더를 공유할 수 있다.

-d 백그라운드 모드

--name 컨테이너 이름 설정

 

docker-compose

ctf 에 문제를 낼 때는, 보통 한 개가 아니라 여러개를 내게 된다.

이 때, 도커를 하나하나 설정하는 것이 아니라, docker-compose 를 이용해 한꺼번에 키고 끌 수 있다.

 

service 명, build 경로, ports 를 지정해주는 docker-compose.yml 파일을 작성하고,

(Dockerfile 에서 ARG 를 사용한다면, docker-compose.yml 에서 넘겨줄 수 있다)

 

docker-compose up ( -d 백그라운드 ) ( --build 바뀐점 빌드 )

docker-compose down 

 

이렇게 닫고 열 수 있다.

 


pwnable 문제 deploy

 

간단하게 race condition 기초 pwnable 문제를 deploy 해보장.

 

폴더구조는 다음과 같다. 소스파일과 익스파일은 현재 경로에 놔두고,

문제서버에 필요한 바이너리파일, flag 는 share 폴더에 놔둔다.

 

settings/race.xinetd

기본적인 구조를 가지고 있다. 유저는 waylab 이고, 서버는 run.sh 인데, docker 파일에서 만드는 파일이다.

 

Dockerfile

급하게 짜느라 조잡하게 했다.

xinetd 를 설치하고, TERM 환경변수를 xterm 으로 설정해준다. (안쓰면 에러남)

 

user waylab 과 홈디렉터리를 만들고, share 에 있는 바이너리와 플레그를 옮긴 뒤

바이너리 timeout 을 설정해주는 run.sh 를 만든다.

권한도 설정해주고, 아까 settings/race.xinetd 을 /etc/xinetd.d/race 로 옮겨준다.

 

현재 폴더의 이름은 race 이다.

 

상위 폴더에 docker-compose.yml 파일을 다음과 같이 작성해주고,

docker-compose up -d --build 명령어로 도커들을 실행시켜주면

 

잘 실행된다. 외부접속도 잘 된다.

 

https://www.n1net4il.kr/posts/how-to-run-docker-for-ctf

 

n1net4il 님의 도커파일을 보면, 미러서버도 설정해주고 하는 것을 볼 수 있다.

ARG 를 통해 인자를 이용하므로 docker-compose.yml 파일을 통해 dockerfile 을 편하게 수정할 수 있다.

 

!!주의사항

포너블 문제를 낼 때, 드림핵과 같이 setvbuf 함수로 버퍼를 설정해줘야 메시지가 바로 출력된다.

(리눅스 기본 버퍼링설정때문)

 

설정하지 않으면 메시지가 안 뜨고 입력만 받게된다. (setvbuf(stdin/stdout,0,2,0)

python 으로 문제파일을 낼 때도, 버퍼링 설정을 해줘야한다. 

 

또한, 아까 말했다싶이 Dockerfile 에 ENV TERM xterm 을 명시해줘야한다.


참고

docker 

 

https://blog.netapp.com/blogs/containers-vs-vms/#:~:text=Virtual%20machines%20and%20containers%20differ,to%20run%20multiple%20OS%20instances.

https://subicura.com/2017/01/19/docker-guide-for-beginners-1.html

https://medium.com/@darkrasid/docker%EC%99%80-vm-d95d60e56fdd

https://www.44bits.io/ko/post/easy-deploy-with-docker

https://subicura.com/2017/01/19/docker-guide-for-beginners-1.html

https://blog.d0ngd0nge.xyz/docker-dockerfile-write/