使用Docker的docker-compose实现容器之间的SSH通信

我不知道是第几次尝试了,但是既然已经努力学习了,所以我搭建了一个简单的环境,可以在容器之间进行SSH通信。

策略

只需使用docker compose up,我希望能够轻松地验证SSH通信。
我想要进行验证,而不会弄乱主机的~/.ssh等文件。
由于是SSH协议,我希望以安全的方式进行验证。

image.png

实施

    ディレクトリ構成
% 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
广告
将在 10 秒后关闭
bannerAds