2025/4/26 Updated by 
Docker GustOSのカスタムイメージを作成する
ubuntu 24.04LTS, sshd
[Up]

実験環境
- ubuntu24.04LTS 上に docker-desktop がインストールされている。
- docker のゲストOSとして、ubuntu 24.04LTS を動かす。
- sshd を自動起動する
- F5 VPN (f5fpc) が動作可能か試す。
docker の基本概念と操作
Docker Image
- OS や アプリケーションとメタデータを一つのファイルにまとめたもの。
- Container (実行環境)を作成する元になるデータであり、
Image 自体が動作するわけではない。
- オブジェクト指向におけるクラスに相当する。
(操作)Image の一覧を表示する
$ docker image ls
Docker Container
- Image を、ホストOSや他のゲストOSとは独立した仮想環境で動作するように、実体化したもの。
- Image を read-only でマウントし、書き込み可能なファイルシステムを追加することで、Container を生成する。
- 書き込み可能なファイルシステムは実行中のコンテナ単位で管理されるので、Image は影響を受けない。
- Container は「実行中」と「停止中」という2種類の状態を持つ。
- オブジェクト指向における、インスタンス(オブジェクト)に相当する。
(操作) Container の一覧を表示する
$ docker container ls -a
(操作) 動作中のContainer の一覧を表示する
$ docker container ls
- Docker Image ... OS や アプリケーションとメタデータを一つのファイルにまとめたもの。
Container (実行環境)を作成する元になるデータであり、
Image 自体が動作するわけではない。
オブジェクト指向におけるクラスに相当する。
(操作)Image の一覧を表示する
$ docker image ls
Docker Container ... Image を、ホストOSや他のゲストOSとは独立した仮想環境で動作するように、実体化したもの。
Image を read-only でマウントし、書き込み可能なファイルシステムを追加することで、Container を生成する。
書き込み可能なファイルシステムは実行中のコンテナ単位で管理されるので、Image は影響を受けない。
Container は「実行中」と「停止中」という2種類の状態を持つ。
オブジェクト指向における、インスタンス(オブジェクト)に相当する。
(操作) Container の一覧を表示する
$ docker container ls -a
(操作) 動作中のContainer の一覧を表示する
$ docker container ls
カスタムな Image を作成する
カスタムな docker Image を生成するには、新しいフォルダを作成し、その中に Dockerfile を置いて build 作業を行う。
以下では、Image を生成するタイミングを build 時、Imageからコンテナを作成するタイミンを run時と呼ぶ。
Dockerfile 中で ARG で宣言した変数は、build 時にのみ有効。
Dockerfile 中で ENV で宣言した変数は、build 時だけではなく、run 時にも有効となる。
Dockerfile 中の RUN 命令は、build時に実行される。
グで実行したいコマンドは entrypoint.sh のような
シェルスクリプトを用意して、その中で設定文を実行する。
sshd が自動起動する ubuntu24.04LTS の docker Image を生成する(1)
UIDやGIDは指定しない場合。
$ mkdir -p ~/doc/docker/ubuntu24_sshd
$ cd ~/doc/docker/ubuntu24_ssdimage
作業用フォルダの中に Dockerfile を作成する。Dockerfile中の パスワード の部分は、推測されにくい文字列に必ず変更すること。
Dockerfile |
FROM ubuntu:24.04
ENV UNAME=guest
ENV UID=3000
ENV GID=3000
ENV PASS=パスワード
# 必要なパッケージのインストール
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y \
sudo \
openssh-server \
supervisor \
&& rm -rf /var/lib/apt/lists/*
# guestユーザー追加+パスワード設定+sudo権限
RUN useradd -m ${UNAME} && \
echo "${UNAME}:${PASS}" | chpasswd && \
adduser guest sudo
# SSH 設定: パスワード認証を有効化
RUN sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config && \
sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin no/' /etc/ssh/sshd_config && \
mkdir /var/run/sshd
# supervisord 設定ファイル設置
RUN mkdir -p /var/log/supervisor
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
# ポート開放
EXPOSE 22 80
#CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
# Add User and start Supervisord in entrypoint.sh
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"] |
作業用フォルダの中に supervisord.conf を作成する
supervisord.conf |
[supervisord]
nodaemon=true
[program:sshd]
command=/usr/sbin/sshd -D
|
作業用フォルダの中に entrypoint.sh を作成する
entrypoint.sh |
#!/bin/bash
set -e
# ${UNAME} ユーザーのパスワードを再設定
if [ -n "${PASS}" ]; then
echo "${UNAME}:${PASS}" | chpasswd
fi
# supervisord start (background)
/usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf &
# Execute Commands in CMD
if [ "$#" -gt 0]; then
exec "$@"
else
wait
fi
|
build する。
$ docker build -t ubuntu24-sshd .
...
成功
生成したイメージを確認する
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu24-apache2-sshd latest aa2786c0514a 16 minutes ago 428MB
コンテナに永続的なファイルシステムを提供するために、1777 のパーミッションでフォルダを作る。
$ sudo mkdir -p /home/docker ← ディレクトリを作成する
$ sudo chmod 1777 /home/docker ← 誰でもファイルを作成できるが、作成した本人にしか消去できないモードに設定する
$ ls -ld /home/docker ← ディレクトリのsticky bit が on になっていることを確認する。
drwxrwxrwt 3 root root 4096 4月 26 15:47 /home/docker
image から container を起動する。
$ docker run --name ubuntu24-vpn --restart always -e PASS=新しいパスワード -p 13322:22 -v /home/docker/sshd:/home/guest/doc -it ubuntu24-sshd
起動オプション
- 仕様する image は ubuntu24-apache2-sshd
- container の名前は httpd
- ホストOSの /home/docker/httpd がゲストOSからは/root/doc として見える。
- ホストOSのポートへのアクセスが、ゲストOSのポートにforwardされる。
ホストOSのポート | ゲストOSのポート |
20022 | 22 |
20080 | 80 |
20443 | 443 |
/home/docker/httpd が存在しない場合は、 "docker run" を実行したユーザの権限で作成される。
$ ls -ld /home/docker/httpd
drwxr-xr-x 2 nitta nitta 4096 4月 26 15:47 /home/docker/httpd
docker が動作しているマシンから http://localhost:20080/ にアクセスすると、httpdにアクセスできた。
docker の外部のマシンから http://192.168.12.3:20080/ にアクセスすると、httpdにアクセスできなかった。
firewall が効いているようなので、20080 番ポートを開けると外部からアクセスできた。
$ sudo ufw allow 20080 ← ホストOSの20080番ポートを開ける
$ sudo ufw status ← ホストOSのファイアウォール設定状況を調べる
状態: アクティブ
To Action From
-- ------ ----
...
20080 ALLOW Anywhere
...
20080 (v6) ALLOW Anywhere (v6)
セキュリティ対策
ホストOSから ssh でゲストOSの guest ユーザにアクセスして、パスワードを変更する。
(ホストOSのターミナルから)
$ ssh -p 20022 guest@localhost ← ホストOSから自分の 20022番ポートへ ssh アクセスすると、ゲストOSの22番ポートへforwardされる。
guest@localhost's password: パスワード ← Dockerfile で指定したguest のパスワード
(ゲストOS上のシェルにアクセスできた)
Welcome to Ubuntu 24.04.2 LTS (GNU/Linux 6.10.14-linuxkit x86_64)
Last login: Week Month Day Hour:Minitue:Second Year from XXX.XXX.XXX.XXX
$ passwd ← ゲストOS上でパスワードを変更する
Current password: パスワード ← Dockerfile で指定したguest のパスワード
New password: 新しいパスワード ← 新しいパスワード(推測されにくい文字列を使うこと)
Retype new password: 新しいパスワード ← 再度入力する
ゲストOSの自動起動
Docker Desktop において、ホストOSが再起動すると自動的にゲストOSが起動するように設定する方法は2通りある。
- コンテナ作成時に
docker run --restart
オプションで設定する。
(使用例)
$ docker run --name コンテナ名 --restart always -it イメージ名
- 既に作成済みのコンテナに対して
docker update --restart
オプションで設定する。
(使用例)
$ docker update --restart always コンテナ名
--restart オプションで指定できる値
値 | 説明 |
no | 自動起動しない (default) |
always | ホスト再起動後も自動起動 |
unless-stopped | 手動停止しない限り自動起動 |
on-failure | 異常終了したときのみ自動起動 |
VPN関連の設定
F5 VPN ソフトウェアををインストールする
その他
$ apt update
$ apt install -y vim
guest ユーザのログインシェルが /bin/sh なので、/bin/bash に変更する。
$ chsh
Password: ← パスワード入力(エコーバックなし)
Changing the login shell for guest
Enter the new value, or press ENTER for the default
Login Shell [/bin/sh]: /bin/bash
bash の対話環境で Control-hを「1文字消去」に設定する。
~/.bashrc の最後に追加する。
if [[ $- == *i* ]]; then
stty erase ^H
fi
rsync をインストールする
$ sudo apt update
$ sudo apt install rsync
sshd が自動起動する ubuntu24.04LTS の docker Image を生成する(2)
UIDやGIDを指定する場合。
Dockerfile |
FROM ubuntu:24.04
ENV UNAME=guest
ENV GNAME=${UNAME}
ENV UID=3000
ENV GID=3000
ENV PASS=guestpass
# 必要なパッケージのインストール
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y \
sudo \
openssh-server \
supervisor \
&& rm -rf /var/lib/apt/lists/*
## ${UNAME} ユーザー追加+パスワード設定+sudo権限
#RUN useradd -m ${UNAME} && \
# echo "${UNAME}:${PASS}" | chpasswd && \
# adduser ${UNAME} sudo
# SSH 設定: パスワード認証を有効化
RUN sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config && \
sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin no/' /etc/ssh/sshd_config && \
mkdir /var/run/sshd
# supervisord 設定ファイル設置
RUN mkdir -p /var/log/supervisor
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
# ポート開放
EXPOSE 22
#CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
# Add User and start Supervisord in entrypoint.sh
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
CMD []
|
supervisord.conf |
[supervisord]
nodaemon=true
[program:sshd]
command=/usr/sbin/sshd -D
|
entrypoint.sh |
#!/bin/bash
set -e
# ${UNAME} ユーザーのパスワードを再設定
if [ -n "${PASS}" ]; then
if ! id ${UNAME} &>/dev/null; then
groupadd -g ${GID} ${GNAME} || true
useradd -m -u ${UID} -g ${GNAME} ${UNAME}
adduser ${UNAME} sudo
fi
echo "${UNAME}:${PASS}" | chpasswd
fi
# supervisord start (background)
/usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf &
# Execute Commands in CMD
if [ "$#" -gt 0 ]; then
exec "$@"
else
wait
fi
|
$ docker build -t ubuntu24-sshd-user .
docker run --name ubuntu24-vpn-user --restart always -e PASS=PASS -e UNAME=nitta -e GNAME=nitta -e GID=3000 -e UID=3000 -p 13322:22 -v /home/docker/sshd:/home/nitta/doc -it ubuntu24-sshd-user