1
0

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 1 year has passed since last update.

【Docker】docker-composeを使ってコンテナ間ssh通信

Last updated at Posted at 2023-09-20

何番煎じか分かりませんが、せっかく勉強したのでコンテナ間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構成確認

・「指定したnetwork名・sbunetで構築できていること」を確認
・「指定した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:/#

master側へssh

「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サーバのホストが解決できないこと」を確認

% 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デーモン実行したい時
・ホストのハードウェアに直接アクセスしたい時
に使う特権モードのようです。(今回のケースは前者ですかね)
ホストコンピュータのルート権限を持つことと同義のようで、セキュリティ的な危険性が発生するようです。
今回はローカルで閉じた環境なので気にしなくていいですが、業務で使う際は十分気をつけないといけないですね。

参考

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?