1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

SSHのたびにDockerコンテナを立ち上げる

Posted at

TCPでDockerの標準入出力を提供したい - Qiita

↑は失敗。真面目にdocker killとかやらないとダメかなと考えていたけれど、そもそもやりたいことは接続ごとにコンテナをリセットすることで、ncでなくても良かった。シェルを提供するならSSHを使うほうが良いよね。ということで、SSH接続があったら、コンテナを立ち上げ、そのコンテナを渡す方法。

SSHサーバーを立ち上げるDockerfile。

FROM centos

RUN \
  dnf -y install openssh-server passwd && \
  dnf -y clean all

RUN \
  ssh-keygen -t rsa -N "" -f /etc/ssh/ssh_host_rsa_key && \
  ssh-keygen -t ecdsa -N "" -f /etc/ssh/ssh_host_ecdsa_key && \
  ssh-keygen -t ed25519 -N "" -f /etc/ssh/ssh_host_ed25519_key

RUN \
  adduser user && \
  echo p@ssw0rd | passwd --stdin user

# これを消さないと一般ユーザーはログインできない
RUN rm /run/nologin

CMD ["/usr/sbin/sshd", "-D"]

nologinを消さないとroot以外はログインできない。

このDockerfileだとssh-keygenのところで生成しているサーバー鍵がキャッシュされるので注意。例えば、後半を書き換えて別のイメージを作り、そのイメージを他人に渡すと、自分の手元のコンテナのサーバー鍵と同じサーバー鍵を他人が持っていることになるので、中間者攻撃とかをされてしまう。これで作ったイメージ自体を公開するのもダメ。

ビルド。

$ docker build -t ssh_server .

シェルスクリプトを用意。

ssh_server.sh
# コンテナを立ち上げ、
cid=$(docker run --rm -d ssh_server)
# IPアドレスを取得し、
ip=$(docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' ${cid})
# 標準入出力を${ip}:22に繋ぐ
timeout 3m socat - TCP:${ip}:22
# タイムアウトするか標準入出力が切断されたら、コンテナを終了
docker stop ${cid}

このシェルスクリプトは、標準入出力を新しく立ち上げたコンテナのポート22に繋ぐ。

あとはホストの適当なポートで接続を待ち受けて、このシェルスクリプトの標準入出力に渡せば良い。この部分はxinetdでも良い。

$ socat TCP-LISTEN:2222,reuseaddr,fork 'SYSTEM:sh ssh_server.sh'
$ ssh user@ssh-server.example.com -p 2222
user@ssh-server.example.com's password:
[user@a73d4676f399 ~]$ echo "hoge" > hoge
[user@a73d4676f399 ~]$ ls -al
total 28
drwx------ 1 user user 4096 Feb 25 15:13 .
drwxr-xr-x 1 root root 4096 Feb 25 15:05 ..
-rw-r--r-- 1 user user   18 Jul 21  2020 .bash_logout
-rw-r--r-- 1 user user  141 Jul 21  2020 .bash_profile
-rw-r--r-- 1 user user  376 Jul 21  2020 .bashrc
-rw-rw-r-- 1 user user    5 Feb 25 15:13 hoge
[user@a73d4676f399 ~]$ exit
logout
Connection to ssh-server.example.com closed.

$ ssh user@ssh-server.example.com -p 2222
user@ssh-server.example.com's password:
[user@0e2465485f42 ~]$ ls -al
total 20
drwx------ 2 user user 4096 Feb 25 15:05 .
drwxr-xr-x 1 root root 4096 Feb 25 15:05 ..
-rw-r--r-- 1 user user   18 Jul 21  2020 .bash_logout
-rw-r--r-- 1 user user  141 Jul 21  2020 .bash_profile
-rw-r--r-- 1 user user  376 Jul 21  2020 .bashrc
[user@0e2465485f42 ~]$ exit
logout
Connection to ssh-server.example.com closed.

$ ssh user@ssh-server.example.com -p 2222
user@ssh-server.example.com's password:
[user@62bc4f4c36ed ~]$ Bad packet length 1237871916.
ssh_dispatch_run_fatal: Connection to xxx.xxx.xxx.xxx port 2222: Connection corrupted

新しいファイルを追加しても繋ぎ直したらリセットされているし、接続して放置していると(上記のシェルスクリプト中のtimeoutで)3分で強制切断されるし、どうなってもサーバー側にDockerのコンテナが残ることはない :ok_hand:

1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?