使用Docker的docker-compose实现容器之间的SSH通信
我不知道是第几次尝试了,但是既然已经努力学习了,所以我搭建了一个简单的环境,可以在容器之间进行SSH通信。
策略
只需使用docker compose up,我希望能够轻松地验证SSH通信。
我想要进行验证,而不会弄乱主机的~/.ssh等文件。
由于是SSH协议,我希望以安全的方式进行验证。
实施
- ディレクトリ構成
% tree
.
├── compose.yml
├── local-volume
│ ├── local_config
│ ├── local_id_rsa
│ ├── local_id_rsa.pub
│ └── local_known_hosts
├── ssh-client
│ └── Dockerfile
└── ssh-server
└── Dockerfile
- Compose.yml
# networksについて
# bridgeならデフォルトで設定されるため省略でも問題ないが、subnet適用の挙動確認のため記載している
# version表記は現在は非推奨の模様
# version: "3"
services:
ssh_server:
build:
context: .
dockerfile: ./ssh-server/Dockerfile
container_name: ssh_server
hostname: master
privileged: true # /sbin/initを特権モード(Dockerデーモンへのアクセス)で実行するために必要
command: /sbin/init
volumes:
- ./local-volume/local_id_rsa.pub:/home/ssh-man01/.ssh/authorized_keys
expose:
- "2222" # コンテナ間通信のみ実現させたいのportsではなくexposeでOK
networks:
ssh_network:
ipv4_address: 192.168.10.2
ssh_client:
build:
context: .
dockerfile: ./ssh-client/Dockerfile
container_name: ssh_client
hostname: slave
tty: true # コンテナの起動状態を継続させる
volumes:
- ./local-volume/local_known_hosts:/root/.ssh/known_hosts
- ./local-volume/local_id_rsa:/root/.ssh/id_rsa
- ./local-volume/local_config:/root/.ssh/config
networks:
ssh_network:
ipv4_address: 192.168.10.3
networks:
ssh_network:
driver: bridge
ipam:
driver: default
config:
- subnet: 192.168.10.0/24
- Dockerfile(ssh-client)
FROM ubuntu:20.04
RUN apt -y update && \
apt clean all && \
apt -y install openssh-client && \
mkdir -m 700 ~/.ssh
- Dockerfile(ssh-server)
FROM ubuntu:20.04
RUN apt -y update && \
apt clean all && \
apt -y install openssh-server && \
sed -ri 's/^#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config && \
sed -ri 's/^#Port 22/Port 2222/' /etc/ssh/sshd_config && \
useradd -m ssh-man01 && \
install -m 700 -o ssh-man01 -d /home/ssh-man01/.ssh
- local_config
Host master
HostName master
User ssh-man01
Port 2222
IdentityFile ~/.ssh/id_rsa
ServerAliveInterval 60
ServerAliveCountMax 5
验证
准备好事前。
使用ssh-keygen -t rsa命令生成密钥,并将公钥和私钥放置在local-volume目录中,并分别将它们的权限更改为600。
% ls -l local-volume
total 32
-rw-r--r--@ 1 user staff 148 9 20 12:44 local_config
-rw-------@ 1 user staff 2602 9 19 20:30 local_id_rsa
-rw-------@ 1 user staff 564 9 19 20:15 local_id_rsa.pub
-rw-r--r--@ 1 user staff 444 9 20 14:40 local_known_hosts
容器启动
% docker compose up -d
[+] Running 3/3
✔ Network ssh_network Created 0.0s
✔ Container ssh_client Started 0.3s
✔ Container ssh_server Started
确认网络架构
・确认已经使用指定的network名称和子网进行了构建
・确认已经分配指定的IPv4地址给每个容器,并且它们属于指定的网络
% docker network inspect ssh_network
[
{
"Name": "ssh_network",
"Id": "e21a0a50a33a5c6b69f752f4f6114adaac471df40447b329ce80b9135cfefc4e",
"Created": "2023-09-20T05:58:58.725362953Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "192.168.10.0/24"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"7be6980344c041e01f0b8fb64d77b86ff8e02836710e16cab91f4765f6f0340a": {
"Name": "ssh_server",
"EndpointID": "9fe9aaa47cd88b9dbd895a9da08f98af9b9bfdbcc0c6b2c3dbfc42ebea7847f4",
"MacAddress": "02:42:c0:a8:0a:02",
"IPv4Address": "192.168.10.2/24",
"IPv6Address": ""
},
"9b517b7fb1130382bc11b392a792a76294b49025c4cfd9e6e4a4e3850eed16b1": {
"Name": "ssh_client",
"EndpointID": "e93a15cf99024c764bc0e7104acb2a49d2507989f4652cab77aa5b5a6788e5d8",
"MacAddress": "02:42:c0:a8:0a:03",
"IPv4Address": "192.168.10.3/24",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {
"com.docker.compose.network": "ssh_network",
"com.docker.compose.project": "docker-compose-test",
"com.docker.compose.version": "2.20.2"
}
}
]
登录到slave侧的容器
% docker exec -it ssh_client bash
root@slave:/#
将主机侧的SSH连接到master。
确认使用ssh-man01用户名能够登录到master侧的ssh。
# ~/.ssh/configを設定しているため下記コマンドで公開鍵認証が可能です
root@slave:/# ssh master
The authenticity of host '[master]:2222 ([192.168.10.2]:2222)' can\'t be established.
ECDSA key fingerprint is SHA256:DQSQdUdNphmtnOPpzKDEl/XMNCO+KN+Pz5sIEBzVGwo.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
-- (中略) --
Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.
$ whoami
ssh-man01
$
从主机通过 ssh 进行连接
确认从主机上无法解析SSH服务器的主机。
(paraphrased in Mandarin Chinese)
% ssh -i ./local-volume/local_id_rsa -oPort=2222 ssh-man01@192.168.10.2
ssh: connect to host 192.168.10.2 port 2222: Operation timed out
总结
-
- DockerよりもLinuxサーバーやネットワークの勉強した方がよさそう…(Dockerはここらへんの基礎がしっかりあっての応用という感じがした)
-
- とはいえ、あまり複雑な構成でなければ割とハードル低く使っていけそう
- 今回はローカルマシン汚さずにssh検証することができたので、Dockerの良さを少し感じることができた
附加议论
写这段文字时我虽然写得很轻松,但其实花了很多时间…(._.)
一开始我完全不知道如何启动SSH服务器。
我努力尝试启动sshd,尝试使用Dockerhub的openssh-server等等,但都没有成功,经过一番努力试错后才被下面的文章所帮助解决了问题。
privilegedは
・Dockerデーモン実行したい時
・ホストのハードウェアに直接アクセスしたい時
に使う特権モードのようです。(今回のケースは前者ですかね)
ホストコンピュータのルート権限を持つことと同義のようで、セキュリティ的な危険性が発生するようです。
今回はローカルで閉じた環境なので気にしなくていいですが、業務で使う際は十分気をつけないといけないですね。
请参照
-
- https://zenn.dev/akhmgc/articles/52c90fe6100eaf
-
- https://docs.docker.jp/compose/toc.html
-
- https://www.udemy.com/share/109eIi3@V90_P314cpKcCxH5Tm1w78iWeugFigCOir2n73wrMli62ZMwkR4I9ylXZWRV6KVFCA==/
-
- https://josysnavi.jp/2020/tmsb_21jan20_docker-in-docker
-
- https://utouto97.hatenablog.com/entry/2022/03/15/092924
- https://qiita.com/mountcedar/items/43157ff1225c56500655