ちょっとした確認で使えるHTTPS ProxyをDockerで作る

2019/11/13に公開

ContentSecurityPolicyの導入やCookieのsecure属性付与、URLに含まれるスキーマの確認等、HTTPSを使って確認したくなるシーンが最近増えてきたのでサクッと使えるHTTPS ProxyをDockerで作ってみる。

最初nginx-proxyを使ってみようかと思ったけど、いちいち証明書を作るのも面倒だし、docker.sockを渡したくなかったのでサクッと作ってみることにした。

前提としてアプリやDB等が記載された docker-compose.yml があるものとする。

まずDockerfileを作る。アプリのものと混同しないためにファイル名を Dockerfile.ngix としている。

Dockerfile.nginx
FROM nginx:latest
 
ARG VIRTUAL_HOST="localhost"
ENV VIRTUAL_HOST ${VIRTUAL_HOST}

ARG APP_HOST="http://app:3000"
ENV APP_HOST ${APP_HOST}

RUN mkdir -p /etc/nginx/certs

RUN apt-get update -qq && \
    apt-get install -y -qq openssl ssl-cert && \
    apt-get clean -qq && \
    rm -rf /var/lib/apt/lists/*

RUN echo "server {\n\tlisten 443 ssl;\n\tserver_name _;\n\tssl_certificate certs/ssl.pem;\n\tssl_certificate_key certs/ssl.key;\n\tlocation / {\n\t\tproxy_set_header X-Forwarded-Proto \$scheme;\n\t\tproxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;\n\t\tproxy_set_header Host \$http_host;\n\t\tproxy_set_header X-Real-IP \$remote_addr;\n\t\tproxy_redirect off;\n\t\tproxy_pass ${APP_HOST};\n\t}\n}\n" > /etc/nginx/conf.d/default.conf

RUN openssl req -batch -new -x509 -newkey rsa:2048 -nodes -sha256 \
      -subj /CN=${VIRTUAL_HOST} -days 3650 \
      -keyout /etc/nginx/certs/ssl.key \
      -out /etc/nginx/certs/ssl.pem

次に上記のDockerfileをdocker-composeに組み入れる

docker-compose.yml
version: "3.7"

services:
  ### ここから ###
  web:
    build:
      context: .
      dockerfile: Dockerfile.nginx
      #args:
      #  VIRTUAL_HOST: localhost
      #  APP_HOST:     http://app:3000
    ports:
      - 443:443
    depends_on:
      - app
  ### ここまで ###

  app:
    build:
### 後略 ###

この状態で docker-compose を立ち上げ、 https://localhost にアクセスすると、 docker-composeに記述された appサービスの 3000番ポートにプロキシされます。(証明書が自己署名証明書なのでセキュリティ警告は出ますが。)

もしアクセスするドメインをlocalhost以外に変更したい場合は docker-compose の VIRTUAL_HOST を、 バックエンドのサービスを app:3000以外に変えたい場合は同様に APP_HOST を書き換えてbuildしなおすことでドメインやバックエンドを切り替えて確認することができます。

docker-compose.yml
version: "3.7"

services:
  ### ここから ###
  web:
    build:
      context: .
      dockerfile: Dockerfile.nginx
      args:
        VIRTUAL_HOST: 127.0.0.1.xip.io
        APP_HOST:     http://app2:8080
    ports:
      - 443:443
    depends_on:
      - app2
  ### ここまで ###

  app:
    build:
### 後略 ###

ビルドのたびに証明書の組み直しは走るものの、ちょっと確認するにはちょうどいい規模のものになったかな。

Discussion