みおもん倶楽部 技術雑記

世界の片隅で、諜報活動と称して本を読んだりゲームをしたり

dockerでSSH接続可能なubuntuコンテナを立てる

dockerで立てたコンテナにsshでアクセスして開発を行いたいなと思いました。

N番煎じもいいところですが、ちょっとハマったので記録を残しておきます。

目指すもの

  • イメージはubuntu
  • 認証方式は公開鍵認証、パスワード認証はしない。
  • ~/.ssh/terminal~/.ssh/terminal.pubというキーペアを作成する
  • アクセス方法はssh localhost -p 2222 -i ~/.ssh/terminal
  • rootではなく作成したユーザでログインする(maclinuxでは$USERで現在のユーザを参照できますが、その値でユーザを作成します)
  • ポートは2222

ファイル構成

.
├── Dockerfile
├── docker-compose.yaml
└── setup.sh

Dockerfile

FROM ubuntu:latest

# ビルド時、new_userという引数を受け取る
ARG new_user

# ユーザを作成
RUN useradd -ms /bin/bash ${new_user}

# sshディレクトリを作成
RUN mkdir /home/${new_user}/.ssh

# 公開鍵をコピー(terminal.pubが存在している必要がある)
COPY terminal.pub /home/${new_user}/.ssh/authorized_keys

# sshサーバとsudoコマンドをインストール
RUN apt update && apt install -y openssh-server sudo && apt clean

# ひとまずパスワードを設定、あとで変えたほうがいい
RUN echo "${new_user}:password" | chpasswd

# sudoに追加
RUN gpasswd -a ${new_user} sudo

# ssh用のディレクトリを作成
RUN mkdir /var/run/sshd

# パスワードを使用したログインを許可しない
RUN sed -i -r 's/^#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config 

# 公開鍵認証を許可
RUN sed -i -r 's/#AuthorizedKeysFile/AuthorizedKeysFile/' /etc/ssh/sshd_config

# ポートを22から2222に変更
RUN sed -i -r 's/^#Port 22/Port 2222/' /etc/ssh/sshd_config 

RUN /usr/sbin/sshd

EXPOSE 2222

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

docker-compose.yaml

version: "3"
services:
  terminal:
    build:
      args:
        - new_user=${USER}
      context: .
      dockerfile: Dockerfile
    container_name: terminal
    privileged: true
    tty: true
    ports:
      - "2222:2222"

new_user=${USER}の部分では、ホスト側の環境変数を使用しています。 別の名前を使用したい場合はここを変更します。

ボリュームをマウントしたい場合、dnsを設定したい場合、他のコンテナを付け足したい場合、適宜改造してください。

setup.sh

手元ではコンテナが起動していたら止めるとか、キーペアが存在してたら中止するとかを付け加えていますが、その部分は省略して、エッセンスだけ抜粋します。

# キーペアの作成
ssh-keygen -t ed25519 -C "" -f ~/.ssh/terminal -N "" 

# 手元に公開鍵をコピー
cp ~/.ssh/terminal.pub .

# docker compose upを実行
docker compose up -d --build

# sshで接続
ssh localhost -p 2222 -i ~/.ssh/terminal

実行手順

上記記載済みですが、terminal.pubを用意してdocker compose upを実行すればOKです。

xxxxxxxx@yyyyyyyy zzzzzzzz % ./setup.sh                              
[+] Building 0.0s (15/15) FINISHED                                                                                                      docker:desktop-linux
 => [terminal internal] load build definition from Dockerfile                                                                                           0.0s
 => => transferring dockerfile: 880B                                                                                                                    0.0s
 => [terminal internal] load metadata for docker.io/library/ubuntu:latest                                                                               0.0s
 => [terminal internal] load .dockerignore                                                                                                              0.0s
 => => transferring context: 2B                                                                                                                         0.0s
 => [terminal  1/10] FROM docker.io/library/ubuntu:latest                                                                                               0.0s
 => [terminal internal] load build context                                                                                                              0.0s
 => => transferring context: 595B                                                                                                                       0.0s
 => CACHED [terminal  2/10] RUN useradd -ms /bin/bash xxxxxxxx                                                                                          0.0s
 => CACHED [terminal  3/10] RUN mkdir /home/xxxxxxxx/.ssh                                                                                               0.0s
 => CACHED [terminal  4/10] COPY terminal.pub /home/xxxxxxxx/.ssh/authorized_keys                                                                       0.0s
 => CACHED [terminal  5/10] RUN apt update && apt install -y openssh-server && apt clean                                                                0.0s
 => CACHED [terminal  6/10] RUN mkdir /var/run/sshd                                                                                                     0.0s
 => CACHED [terminal  7/10] RUN sed -i -r 's/^#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config                              0.0s
 => CACHED [terminal  8/10] RUN sed -i -r 's/#AuthorizedKeysFile/AuthorizedKeysFile/' /etc/ssh/sshd_config                                              0.0s
 => CACHED [terminal  9/10] RUN sed -i -r 's/^#Port 22/Port 2222/' /etc/ssh/sshd_config                                                                 0.0s
 => CACHED [terminal 10/10] RUN /usr/sbin/sshd                                                                                                          0.0s
 => [terminal] exporting to image                                                                                                                       0.0s
 => => exporting layers                                                                                                                                 0.0s
 => => writing image sha256:fbe41ddbf46c8601b2709640c58c66f311c66628c5cc53b0429877270bf0bad2                                                            0.0s
 => => naming to docker.io/library/zzzzzzzz-terminal                                                                                                    0.0s
[+] Running 1/2
 ⠙ Network zzzzzzzz_default  Created                                                                                                                    0.1s 
 ✔ Container terminal       Started                                                                                                                     0.1s 

xxxxxxxx@yyyyyyyy zzzzzzzz % ssh localhost -p 2222 -i ~/.ssh/terminal
Welcome to Ubuntu 22.04.1 LTS (GNU/Linux 6.6.16-linuxkit aarch64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

This system has been minimized by removing packages and content that are
not required on a system that users do not log into.

To restore this content, you can run the 'unminimize' command.

The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

xxxxxxxx@c264796d36c0:~$ 

以下の情報は置き換えています。

  • ログインユーザ名:xxxxxxxx
  • ホストPCのホスト名:yyyyyyyy
  • 作業ディレクトリ名:zzzzzzzz

Dockerfileとかdocker-compose.yamlは雰囲気で書いていますので、変な部分あるかもしれません。