TL;DR
Packageのinstall
RUN apk add --no-cache openssh openrc
sshdの起動
RUN rc-update add sshd && rc-status
RUN mkdir -p /run/openrc/ && touch /run/openrc/softlevel
Port Forwardingの設定
RUN sed -i 's/^AllowTcpForwarding no/AllowTcpForwarding yes/g' /etc/ssh/sshd_config
RUN sed -i 's/^GatewayPorts no/GatewayPorts yes/g' /etc/ssh/sshd_config
RUN sed -i 's/^X11Forwarding no/X11Forwarding yes/g' /etc/ssh/sshd_config
ユーザーの作成、Password付与(パスワードないと、なぜかpublicKeyでもloginできない)
RUN adduser -D ssh-user
# It will cause an ssh login error if user has no password
RUN echo "ssh-user:ssh-pass" | chpasswd
# If need sudo
RUN apk add --no-cache sudo
RUN echo "ssh-user ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
公開秘密鍵の作成&導入
RUN mkdir $HOME/.ssh
RUN ssh-keygen -m PEM -t rsa -b 1024 -C "ssh-user@example.com" -N "" -f $HOME/.ssh/id_rsa
RUN cat $HOME/.ssh/id_rsa.pub >> $HOME/.ssh/authorized_keys
はじめに
先日、筆者は『SSHポートフォワーディングのプチ魔術』という記事を書きました。
当時はAWS EC2を一台借りでSSHの実験をしましたが、どうももったいないと思いました。
実は昔からVagrantでSSHの実験をしましたが、今回はあえてDockerで同じことできるようにします。
Dockerfile
このようなDockerfileを作成しました。一番サイズが小さいと言われるalpine
を使いました。筆者の都合でnode
のコンテナを選びましたが、alpineのみでも結構です。
FROM node:10.15.3-alpine
LABEL maintainer="Iuliana Augusta <iuliana.augusta@gmail.com>"
RUN set -x && apk update && apk upgrade \
&& apk add --no-cache openssh openrc
# For debug
# RUN apk add --no-cache bash vim
RUN rc-update add sshd && rc-status
RUN mkdir -p /run/openrc/ && touch /run/openrc/softlevel
# Enable Port Forwarding
RUN sed -i 's/^AllowTcpForwarding no/AllowTcpForwarding yes/g' /etc/ssh/sshd_config
RUN sed -i 's/^GatewayPorts no/GatewayPorts yes/g' /etc/ssh/sshd_config
RUN sed -i 's/^X11Forwarding no/X11Forwarding yes/g' /etc/ssh/sshd_config
RUN adduser -D ssh-user
# It will cause an ssh login error if user has no password
RUN echo "ssh-user:ssh-pass" | chpasswd
# If need sudo
# RUN apk add --no-cache sudo
# RUN echo "ssh-user ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
USER ssh-user
RUN mkdir $HOME/.ssh
RUN ssh-keygen -m PEM -t rsa -b 1024 -C "ssh-user@example.com" -N "" -f $HOME/.ssh/id_rsa
RUN cat $HOME/.ssh/id_rsa.pub >> $HOME/.ssh/authorized_keys
USER root
RUN cp /home/ssh-user/.ssh/id_rsa $HOME/ssh-user.pem
CMD /etc/init.d/sshd start && tail -f /dev/null
Docker Compose
前述したDockerfile
をそのまま起動しても構いませんが、docker-compose.yml
を作成すれば、より省力化できると思います。
version: '3.7'
services:
ssh-test:
# image: node:10.15.3-alpine
container_name: ssh-test
build:
context: ./
dockerfile: ./Dockerfile
working_dir: /root
volumes:
- ./share:/root/share
ports:
- "20080:80"
- "20443:443"
- "20022:22"
- "23000:3000"
- "23030:3030"
- "28000:8000"
- "28080:8080"
command: /bin/sh -c "/etc/init.d/sshd start && tail -f /dev/null"
よく使われる80, 443, 22, 3000, 3030, 8000, 8080
を全部開放しました。
わかりやすくするために、全部のポートをプラス20000
のポートを、ホストに割り当てます。
これで準備が完了しました、docker-compose build
でコンパイルしてみれば、本体が85.1MBでベースのnode:10.15.3-alpine
を併せても、150MBくらいしかありません。
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ssh_test_ssh-test latest 13b7daa0eaad 29 minutes ago 85.1MB
node 10.15.3-alpine 94f3c8956482 3 weeks ago 71MB
SSH接続
上記Dockerfile
が書いたように、秘密鍵が/root/ssh-user.pem
にコピーされたので、それをホストマシーンに持って行けばOKです。
$ docker exec ssh-test cat /root/ssh-user.pem > ssh-user.pem
$ chmod 600 ssh-user.pem
早速ポートフォワードで試してみましょう。
# localhost:3030 にサーバーが動いているとして
$ ssh -R 8080:localhost:3030 -i ssh-user.pem ssh-user@localhost -p 20022
こうすれば、localhost:3030
のサーバーがlocalhost:28080
でアクセスできるようになります。
参考
https://wiki.alpinelinux.org/wiki/Setting_up_a_ssh-server
https://blog.adachin.me/archives/4177