Web Hacking

docker-compose, Dockerfile을 이용해 이미지 만들기

ankisile 2021. 11. 29. 04:10

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 문제 출제할 친구들에게 이 포스트가 도움이 되었길 바란다.