7
6

More than 1 year has passed since last update.

Fargate で構築した Laravel と WordPress の コンテナを 読み取り専用(ReadOnly)にする

Last updated at Posted at 2022-07-10

はじめに

Fargate で Laravel や WordPress を構築後、セキュリティを高める方法として、読み取り専用(readonlyRootFilesystem) を有効にする方法があります。
この設定を行なうと、コンテナ内のファイルやディレクトリが読み取り専用となり、マルウェア等に対してセキュリティーが高めることができます。

ただし、全てを読み取りにはできず、一時的に書き込みが必要なディレクトリがサーバー内にありますので、一部のディレクトリを読み書き可能なボリュームとしてマウントし、残りは読み込み専用にすることが必要です。

今回は、Fargate で構築した Laravel と WordPress を読み取り専用にする方法について方法を記載します。

ちなみに、読み取り専用(readonlyRootFilesystem) を有効にすると、Fargate Execが使用できないデメリットがあります。

事前構築

  • 下記の記事でwordpressをfargateで構築
  • ソースはDockerfileのみ

wordpressのDockerfile
FROM wordpress:6.0.0-php8.1-apache

RUN set -ex; \
  apt-get update && apt-get install -y --no-install-recommends \
  unzip \
  wget \
  && apt-get clean \
  && rm -rf /var/lib/apt/lists/*

# /usr/src/wordpress/wp-content/plugin にプラグインを置いておくと、ビルド時、ドキュメントルートに設置する
WORKDIR /usr/src/wordpress/wp-content/plugins

# プラグイン[WP Offload Media Lite for Amazon S3]をインストール
RUN set -ex; \
  wget -q -O amazon-s3-and-cloudfront.zip https://downloads.wordpress.org/plugin/amazon-s3-and-cloudfront.1.4.3.zip \
  && unzip -q -o '*.zip' -d /usr/src/wordpress/wp-content/plugins \
  && chown -R www-data:www-data /usr/src/wordpress/wp-content/plugins \
  && rm -f *.zip

# 所有者の変更
RUN chown -R www-data:www-data /var/www/html

WORKDIR /var/www/html
  • 下記の記事でlaravelをfargateで構築
  • ソースも添付(ブランチは、mainを使用してください)

マウントタイプ

読み取り専用にするにあたり、/var/runなどの一時的に書き込みが必要なディレクトリがあるため、その部分のみ書き込みを許可する必要があります。
Dockerでよく用いられるマウントを行い、一部書き込みを許可します。

Fargateでマウントする方法は、3つあります

  1. VolumeをDockerfileに記載し、マウントする
  2. タスク定義のBind mountでマウントする
  3. EFSを利用して、マウントする
    • EFSは、新たにリソースを作成する手間がある、EFSだと永続的に一時ファイルが保存される、という理由で今回は利用しません。

それぞれ説明します。

VolumeとBind mountの違い

  • Bind mount はホストマシン OS のディレクトリ構造に依存しますが、Volumeは完全に Docker によって管理されます。
  • Volumeを作成しマウントすると、書き込まれるファイルシステムはDockerで管理され、ホストマシンからは見えません。
    • ホストマシンのディレクトリ構成を実行中のコンテナから分離することができます。

調べたところセキュリティー的には、Volumeでマウントする方がよいようです。

wordpressのコンテナを読み取り専用

DockerfileにVolumeを追加、タスク定義のreadonlyRootFilesystemtrueにします。

Dockerfileの一部のディレクトリにVolumeでマウント

ソースは、Dockerfileのみです。
wordpress (fargate) では、下記の2つのディレクトリ内に一時ファイルが作成されるため、Volumeでマウントします

  • /var/run/apache2
  • /tmp
wordpressのDockerfile
FROM wordpress:6.0.0-php8.1-apache

RUN set -ex; \
  apt-get update && apt-get install -y --no-install-recommends \
  unzip \
  wget \
  && apt-get clean \
  && rm -rf /var/lib/apt/lists/*

# /usr/src/wordpress/wp-content/plugin にプラグインを置いておくと、ビルド時、ドキュメントルートに設置する
WORKDIR /usr/src/wordpress/wp-content/plugins

# プラグイン[WP Offload Media Lite for Amazon S3]をインストール
RUN set -ex; \
  wget -q -O amazon-s3-and-cloudfront.zip https://downloads.wordpress.org/plugin/amazon-s3-and-cloudfront.1.4.3.zip \
  && unzip -q -o '*.zip' -d /usr/src/wordpress/wp-content/plugins \
  && chown -R www-data:www-data /usr/src/wordpress/wp-content/plugins \
  && rm -f *.zip

# 所有者の変更
RUN chown -R www-data:www-data /var/www/html

WORKDIR /var/www/html

+ VOLUME ["/var/run/apache2", "/tmp"]

タスク定義のreadonlyRootFilesystemtrueに修正

タスク定義の読み取り専用ルートファイルシステムにチェックマークをつけるだけです。
スクリーンショット 2022-07-10 19.01.14.png

これでデプロイすると、/var/run/apache2/tmpを除いて、読み取り専用になりました。

laravelのコンテナを読み取り専用

DockerfileにVolumeを追加、タスク定義のreadonlyRootFilesystemtrueにします。
また、タスク定義のコマンドを変更します。

ソースは、以下のmainブランチを使用します。

Dockerfileの一部のディレクトリにVolumeでマウント

phpのDockerfile修正

phpのDockerfileでは、下記の4つのディレクトリを、Volumeでマウントします

  • /var/www/html/bootstrap/cache
  • /var/www/html/storage/framework
  • /var/www/html/storage/logs
  • /tmp
.docker/php/Dockerfile
FROM php:8.1-fpm-bullseye

# timezone environment
ENV TZ=Asia/Tokyo \
  # locale
  LANG=ja_JP.UTF-8 \
  LANGUAGE=ja_JP:ja \
  LC_ALL=ja_JP.UTF-8 \
  # composer environment 
  COMPOSER_ALLOW_SUPERUSER=1 \
  COMPOSER_HOME=/composer

COPY --from=composer:2.3 /usr/bin/composer /usr/bin/composer

RUN apt-get update \
  && apt-get -y install --no-install-recommends \
    git \
    libzip-dev \
    libicu-dev \
    libonig-dev \
    locales \
    unzip \
    vim \
  && apt-get clean \
  && rm -rf /var/lib/apt/lists/* \
  && locale-gen ja_JP.UTF-8 \
  && localedef -f UTF-8 -i ja_JP ja_JP.UTF-8 \
  && docker-php-ext-install \
    bcmath \
    intl \
    pdo_mysql \
    zip \
  && composer config -g process-timeout 3600 \
  && composer config -g repos.packagist composer https://packagist.org

COPY ./src /var/www/html
COPY ./docker/php/php.ini /usr/local/etc/php/php.ini

+ VOLUME ["/var/www/html/bootstrap/cache", "/var/www/html/storage/framework", "/var/www/html/storage/logs", "/tmp"]

RUN composer install -q -n --no-ansi --no-dev --no-scripts --no-progress --prefer-dist \
+ && chown -R www-data:www-data /var/www/html \
  && chmod -R 775 storage bootstrap/cache \
  && php artisan optimize:clear \
  && php artisan optimize \
  && php artisan cache:clear \
  && php artisan config:clear \
  && php artisan route:clear \
  && php artisan view:clear 

Volumeを使用すると、所有者がrootになったため、&& chown -R www-data:www-data /var/www/htmlも追加しています。

phpのDockerfile修正

phpのDockerfileでは、下記の3つのディレクトリを、Volumeでマウントします

  • /var/cache/nginx
  • /var/run
  • /etc/nginx/conf.d
.docker/php/Dockerfile
FROM nginx:1.20-alpine
COPY ./docker/nginx/default.conf /etc/nginx/conf.d/default.conf
COPY ./docker/nginx/nginx.conf /etc/nginx/nginx.conf
COPY ./src /var/www/html
ENV TZ=Asia/Tokyo
EXPOSE 80
+ VOLUME ["/var/cache/nginx", "/var/run", "/etc/nginx/conf.d"]

タスク定義のコマンドを修正

コマンドは、以下の記事に記載しておりました。

  • 変更前
    php artisan config:cache && php artisan view:cache && php artisan route:cache && php artisan migrate --force && chmod -R 777 storage/* && php-fpm && composer install --optimize-autoloader --no-dev

  • 変更後
    php artisan config:cache && php artisan view:cache && php artisan route:cache && php artisan migrate --force && php-fpm && composer install --optimize-autoloader --no-dev

読み取り専用にすると、権限変更がエラーになりましたので、chmod -R 777 storage/*を削除しました。
必要であれば、Dockerfileに追記するとよいです。

タスク定義のreadonlyRootFilesystemtrueに修正

先程と同様に、タスク定義の読み取り専用ルートファイルシステムにチェックマークをつけるだけです。

これでデプロイすると、4つのディレクトリを除いて、読み取り専用となります。

laravelの/tmpのパスを変更してみる

phpコンテナでは、/tmpをVolumeでマウントしましたが、/tmpは予想がつきマルウェア等に狙われやすいため、/fuga/tmpパスを変更してみたいと思います。

やることは以下の2点です。

  • phpのDockerfileを修正
  • タスク定義の環境変数にTMPDIRを追加

phpのDockerfileを修正

.docker/php/Dockerfile
FROM php:8.1-fpm-bullseye

# timezone environment
ENV TZ=Asia/Tokyo \
  # locale
  LANG=ja_JP.UTF-8 \
  LANGUAGE=ja_JP:ja \
  LC_ALL=ja_JP.UTF-8 \
  # composer environment
  COMPOSER_ALLOW_SUPERUSER=1 \
  COMPOSER_HOME=/composer

COPY --from=composer:2.3 /usr/bin/composer /usr/bin/composer

RUN apt-get update \
  && apt-get -y install --no-install-recommends \
    git \
    libzip-dev \
    libicu-dev \
    libonig-dev \
    locales \
    unzip \
    vim \
  && apt-get clean \
  && rm -rf /var/lib/apt/lists/* \
  && locale-gen ja_JP.UTF-8 \
  && localedef -f UTF-8 -i ja_JP ja_JP.UTF-8 \
  && docker-php-ext-install \
    bcmath \
    intl \
    pdo_mysql \
    zip \
  && composer config -g process-timeout 3600 \
  && composer config -g repos.packagist composer https://packagist.org

COPY ./src /var/www/html
COPY ./docker/php/php.ini /usr/local/etc/php/php.ini
+ WORKDIR /fuga/tmp
+ VOLUME ["/var/www/html/bootstrap/cache", "/var/www/html/storage/framework", "/var/www/html/storage/logs", "/fuga/tmp"]

RUN composer install -q -n --no-ansi --no-dev --no-scripts --no-progress --prefer-dist \
  && chown -R www-data:www-data /var/www/html \
  && chmod -R 775 storage bootstrap/cache \
  && php artisan optimize:clear \
  && php artisan optimize \
  && php artisan cache:clear \
  && php artisan config:clear \
  && php artisan route:clear \
  && php artisan view:clear 

/fuga/tmpディレクトリを作成し、Volumeにもマウントさせます。

タスク定義の環境変数にTMPDIRを追加

envファイル、もしくは、タスク定義に以下を追記します。

TMPDIR=/fuga/tmp

スクリーンショット 2022-07-10 19.45.45.png

/tmpではなく、/fuga/tmpに一時ファイルが保存されるようになりました。

Codebuildでビルドする場合

Codebuildでビルドする場合、DockerfileにVolume権限変更のコマンドが効かなかったため、タスク定義のコマンドに追加しました。

タスク定義のコマンドを追加

  • 変更前
    php artisan config:cache && php artisan view:cache && php artisan route:cache && php artisan migrate --force && php-fpm && composer install --optimize-autoloader --no-dev

  • 変更後
    php artisan config:cache && php artisan view:cache && php artisan route:cache && php artisan migrate --force && chown -hR www-data:www-data /var/www/html/bootstrap/cache /var/www/html/storage/framework /var/www/html/storage/logs /fuga/tmp && php-fpm && composer install --optimize-autoloader --no-dev

その他のfargateに関するtips

その他のfargateに関するtipsを記事としてまとめていますので、こちらを参考にしてください。

参考記事

7
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
6