はじめに
皆さん開発ではgitをよく使われると思います。
近年githubでは二段階認証が義務化されたことにより、今までpush等をするときにパスワードを打っていたけどssh key等に頼リ始めた人も多いと思います。
しかし、ssh接続を用いた認証で困るのはDockerで開発中のアプリのコンテナを作成したときです。
なぜなら、sshキーがコンテナ内に無いのでgitでpush等するときに毎回クソめんどくさい二段階認証をする必要があるからです。
本記事ではdockerでgithubに接続するための二段階認証をssh-agentを用いて安全に自動化する方法について解説します。
使用するOSはWindows 11 Homeです。
ssh-agentとは
Dockerのコンテナ内でgithubのssh認証を最も手っ取り早く使う方法はコンテナ内にsshキーをコピーして使うことです。(実際そういう風に指導している記事も結構あります)
しかし、imageの中にsshキーのファイルをコピーしてしまうと、imageをDocker hub等で公開したときや、他人にimageを共有した時に、ssh keyが漏洩してしまう危険があります。
そこで、コンテナ内にssh keyをコピーするのでは無く、ssh-agentというSSHキーの管理と認証を効率的に行うためのツールを用いてより事故が起こらない様にします。
そこで本記事ではアプリを作成するコンテナとssh-agentでssh keyを管理するコンテナを分けることによってssh keyを開発環境にコピーすること無くssh認証が出来るようにします。
開発用のコンテナで作業している時に、ssh keyを管理するコンテナがssh-agentを貸し出し、githubとのssh接続を可能とします。
本記事ではアプリ用のコンテナはpythonで作るものとします。
Step 1: ssh keyをgithubに登録しよう
まず二段階認証を行うためには、githubにssh keyを登録する必要があります。
これについてはとてもわかりやすい記事があるので以下の記事を参考にしてください。
Step 2:docker-compose.ymlを書こう
まず、アプリ用のDockerfileとssh-agent用のDockerfileをどのように関連付けるかを定義するためにdocker-compose.ymlを書きます。
ディレクトリ構成は以下のようにしてください。
workspace/
│
┣ ─ docker-compose.yml
│
┣ ─ requirements.txt
│
┣ ─ app/
│ │
│ ┣ ─ Dockerfile
│
│
┣ ─ ssh/
│
┣ ─ Dockerfile
│
┣ ─ init.sh
docker-compose.ymlは以下のようなファイルにしてください。
version: '3.10'
services:
web:
build:
context: ./
dockerfile: /app/Dockerfile
tty: true
ports:
- "8000:8000"
#sshコンテナと通信できるようにする
networks:
- ssh_net
ssh:
build: ./ssh
#web containerが立ち上がるのと同時に立ち上がるようにする
depends_on:
- web
tty: true
# ssh keyをマウント
volumes:
- type: bind
source: ~/.ssh
target : /root/.ssh
#web containerと通信できるようにする
networks:
- ssh_net
networks:
ssh_net:
これによって、sshコンテナはwebコンテナと共に立ち上がるようになりました。
appディレクトリのDockerfileを以下のように書いてください。
FROM python:3.10.11
RUN apt-get update
RUN apt-get -y install locales && \
localedef -f UTF-8 -i ja_JP ja_JP.UTF-8
RUN apt-get -y install git
ENV LANG ja_JP.UTF-8
ENV LANGUAGE ja_JP:ja
ENV LC_ALL ja_JP.UTF-8
ENV TZ JST-9
ENV TERM xterm
#ssh serverを立ち上げる為のライブラリをインストール
RUN apt-get install -y openssh-server
# SSHの設定
RUN mkdir /var/run/sshd
RUN echo 'root:Docker!' | chpasswd
RUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
RUN pip install --upgrade pip==23.2.1
RUN pip install --upgrade setuptools
WORKDIR /root/workspaces
COPY . .
#ssh接続用のポート
EXPOSE 22
#アプリ用のポート
EXPOSE 8000
RUN pip install -r requirements.txt
#ssh serverを立ち上げ
CMD ["/usr/sbin/sshd", "-D"]
これにより、22番ポートでssh接続をwebコンテナは受け付けるようになります。
RUN echo 'root:Docker!' | chpasswd
の部分は適時変更してください。
次にsshディレクトリのDockerfileを以下のようにしてください
FROM ubuntu:latest
RUN apt-get update
RUN apt-get -y install locales && \
localedef -f UTF-8 -i ja_JP ja_JP.UTF-8
ENV LANG ja_JP.UTF-8
ENV LANGUAGE ja_JP:ja
ENV LC_ALL ja_JP.UTF-8
ENV TZ JST-9
ENV TERM xterm
#ssh接続用のライブラリをインストール
RUN apt-get install -y openssh-server
COPY . root/sh
#shell scriptを起動
ENTRYPOINT ["root/sh/init.sh"]
これによって、sshコンテナが起動するたびにsshディレクトリのinit.shが実行されるようになりました。
次に、sshコンテナが起動したときに、webコンテナにssh-agentを転送するために、init.shを以下のようにしてください
#!/bin/bash
PASSWORD = "Docker!"
#ssh agentを起動
eval "$(ssh-agent)"
#初めてのコンテナ起動の時
if [ -z "$first_flag" ]; then
export first_flag=0
#ssh-agentにssh keyの登録
ssh-add
#ssh keyの権限変更
chmod 600 /root/.ssh/*
chmod 600 /root/.ssh/id_rsa
#ssh接続
echo "yes" "$PASSWORD"| ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -A web
else
#ssh接続
echo "PASSWORD" | ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -A web
fi
これによってssh-agentがwebコンテナへとssh接続で転送されるようになります。
PASSWORD = "Docker!"
の部分は適時変更してください。
Step 3:コンテナを立ち上げる。
Powershellに
docker-compose up
と打てば、webコンテナとsshコンテナが起動し、自動的にsshコンテナがssh-agentをwebコンテナへと転送します。
これによってwebコンテナ内でgithubのssh認証が使えるようになりました。
おわりに
OSがLinuxやMacであれば、環境変数SSH_AUTH_SOCKをコンテナにコピーするだけでssh-agentをコンテナに移植することができるのですが、Windowsでは厄介なことにSSH_AUTH_SOCKを使用せずにssh-agentが動いているのでその方法をとることが出来ませんでした。
Dockerを使えば環境の差を埋めることが出来ますが、完全に消せるわけでは無いって事を痛感しました