2021 POXX 해킹대회 문제 제작할때 최종적으로 Dockerfile과 docker-compose를 이용해 이미지를 만들어야 했다.
특히 웹해킹 문제같은 경우에는 자동화를 위해 docker-compose파일도 필수적으로 만들어야 했다.
따라서 이번 포스트에서는 DB가 없는 문제와 DB가 있는 문제 두 경우에 대해 작성하고자 한다.
DB가 없는 문제
DB 없는 문제 같은 경우에는 구축하기 쉬웠다.
#Dockerfile
FROM ubuntu:18.04
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update -y
RUN apt-get install apache2 -y
RUN apt-get install php -y
RUN apt-get install php7.2-xml -y
RUN apt-get install php-xmlrpc -y
RUN apt-get install libapache2-mod-php -y
COPY ./transcript /etc
COPY ./php.ini /etc/php/7.2/php.ini
RUN rm /var/www/html/index.html
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
WORKDIR /var/www/html/
EXPOSE 3000
CMD ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]
- FROM : 이미지를 생성할 때 사용할 기반 이미지를 지정한다. ubuntu:18.04 이미지를 사용한다.
- ENV DEBIAN_FRONTEND=noninteractive : 설치시 사용자 입력을 요구하지 않는 설정이다. 꼭 필요하다
- RUN: 이미지를 생성할 때 실행할 코드를 지정한다. apache와 php가 필요하기 때문에 apahce와 php 및 그와 관련된 것들을 설치한 것을 확인할 수 있다.
- COPY: 파일이나 폴더를 이미지에 복사한다. 변경한 설정 파일등을 COPY를 이용하여 지정한 폴더에 복사해 주었다.
- ENV : 이미지에서 사용할 환경 변수 값을 지정한다.
- WORKDIR : RUN, CMD, ENTRYPOINT의 명령이 실행될 디렉터리를 설정한다.
- EXPOSE: 포트 설정해준다.
- CMD : 명령어를 실행시킨다.
#docker-compose.yml
version: "3"
services:
main:
build: .
container_name: pepero_theif
volumes:
- "./src:/var/www/html"
ports:
- 3000:80
restart: always
- build : dockerfile 위치를 써준다
- volumes : 패스와 볼륨으로써 마운트한다. 옵션으로써 호스쪽의 경로를 지정한다. (호스트:컨테이너)
- ports: 포트를 공개(expose)한다. 호스트와 포트를 지정한다. (호스트:컨테이너)
db없는 것에 대해서는 어렵게 구축할 필요 없고 인터넷에 돌아다니는 도커파일과 docker-compose를 이용하여 충분히 작성할 수 있다.
DB 있는 문제
#Dockerfile
FROM php:7.4-apache
RUN docker-php-ext-install mysqli
- php:7.4-apache 이미지를 사용했다
- mysql을 사용하기 때문에 docker-php-ext-install mysqli 를 이용하여 php 컨테이너에 mysqli 플러그인을 설치해주었다. 이와 관련된 자세한 것은 Docker hub에 찾아보면 나와있다
#docker-compose.yml
version: "3.1"
services:
php:
build:
context: .
dockerfile: Dockerfile
container_name: ${APP_NAME}
depends_on:
- db
ports:
- 4000:80
volumes:
- ./src:/var/www/html
db:
image: mysql:5.6
command: --default-authentication-plugin=mysql_native_password
restart: always
container_name: ${APP_NAME}-db
environment:
MYSQL_ROOT_PASSWORD: "111111"
MYSQL_DATABASE: "users"
volumes:
- ./db/init.sql:/docker-entrypoint-initdb.d/init.sql
- .env 파일을 따로 만들어서 APP_NAME을 지정해 줄 수 있다.
- depends_on: 특정 컨테이너에 대한 의존 관계를 나타내고,이 항목에 명시된 컨테이너가 먼저 생성되고 실행된다. DB가 필요하기 때문에 db 컨테이너를 써주었고 따라서 db 컨테이너가 먼저 실행된다.
- php 그외의 부분은 위에서 설명한거과 똑같으므로 넘어간다.
- db에서는 MYSQL에서 db를 구축할때 썼던 password 등등을 작성해줘야 한다. 이부분을 environment에 작성해준다.
- 문제를 실행할때 db가 이미 구축된 상태여야 한다. 따라서 sql파일을 만들어서 그것을 마운트 해줘야한다. 만든 sql파일을 db라는 폴더에 init이란 이름으로 만들어준다. 그리고 그것을 /docker-entrypoint-initdb.d/init.sql 에 마운트 해준다.
발생한 문제점
- wsl에서는 db 있을때는 정상적으로 동작하지 않았다. 그러나 우분투에서는 매우매우 정상적으로 동작했다. 왜그런지 모르겠으나 우분투에서 하는것이 좋은가보다
2022 poxx 문제 출제할 친구들에게 이 포스트가 도움이 되었길 바란다.