2026年8月20日

2026年8月20日

Dockerのソケット(/var/run/docker.sock)を安全に使う方法|権限・マウント・リモート接続

/var/run/docker.sock は、Dockerデーモン(dockerd)がAPIを受け付けるUNIXドメインソケットです。docker コマンドは、このソケットを通じてデーモンにコンテナの作成や削除を依頼しています。

このソケットに書き込める人やプログラムは、Dockerデーモンに何でも指示できます。デーモンはrootで動いているので、ソケットへのアクセス権は実質的にホストのroot権限と同じです。この記事では、その前提を確認したうえで、ソケットを安全に扱う方法を説明します。内容は2026年10月時点のDocker公式ドキュメント(docs.docker.com)に合わせています。

なぜソケットへのアクセスがroot相当なのか

ソケットに接続できれば、たとえば次のようにホストの / をマウントしたコンテナを起動できます。

docker run --rm -it -v /:/host alpine chroot /host sh

このコンテナの中では、ホストのファイルシステム全体をrootとして読み書きできます。Dockerの公式ドキュメントでも、ホストの / をコンテナの /host にマウントすると、コンテナから制限なくホストのファイルシステムを変更できると説明しています。また、Linuxのインストール後の手順のページには「docker グループはユーザーにroot相当の権限を与える」という警告があります。

つまり、守るべきものは「ソケットに誰が接続できるか」です。

現在のソケットの権限を確認する

ls -l /var/run/docker.sock

通常は次のように、所有者が root、グループが docker、権限が srw-rw---- になっています。

srw-rw---- 1 root docker 0 Oct 20 09:00 /var/run/docker.sock

多くのLinuxディストリビューションでは /var/run は /run へのシンボリックリンクなので、実体は /run/docker.sock です。権限が srw-rw-rw- のように「その他」に書き込みが付いている場合は、サーバー上の全ユーザーがroot相当になっているので、すぐに戻します。

sudo chown root:docker /var/run/docker.sock
sudo chmod 660 /var/run/docker.sock

ソケットはデーモンの起動時に作り直されるので、権限が変わっていた原因(起動スクリプトや手作業の chmod 666 など)も取り除いてください。

dockerグループに入れるユーザーを絞る

sudo なしで docker コマンドを使うために、ユーザーを docker グループに追加する手順が公式ドキュメントにあります。

sudo groupadd docker
sudo usermod -aG docker $USER
newgrp docker

これは便利ですが、追加したユーザーにroot相当の権限を渡す操作です。次の点を守ります。

  • docker グループに入れるのは、そのサーバーでrootを渡してよい人だけにする
  • Webアプリケーションの実行ユーザー(www-data など)やCIのジョブ用のユーザーを docker グループに入れない
  • 定期的にメンバーを確認する
getent group docker

rootを渡したくない利用者がいる場合は、docker グループに入れる代わりに、後で説明するRootlessモードを使うか、sudo で実行させて記録を残す方法を検討します。

コンテナにソケットをマウントしない

監視ツールやリバースプロキシ、CIのエージェントなどで、次のようにソケットをコンテナにマウントする例をよく見かけます。

docker run -v /var/run/docker.sock:/var/run/docker.sock some-image

こうすると、そのコンテナ(とコンテナ内で動くプログラムの脆弱性を突いた攻撃者)がホストのroot相当の権限を持ちます。Dockerの公式ドキュメントでも、APIのエンドポイントにコンテナから到達できると権限昇格につながりやすいと注意しています。

  • 本当に必要なコンテナ以外にはマウントしない
  • マウントするのは、信頼できる配布元の、必要な機能が明確なイメージに限る
  • :ro(読み取り専用)を付けてもAPIの呼び出しは制限できない。ro はソケットのファイル自体の変更を防ぐだけで、ソケット経由でコンテナを作成する操作は通る

どうしてもコンテナからDockerの情報を読ませたい場合は、ソケットとコンテナの間に、許可したAPIだけを通すプロキシを置く方法があります。ただし、プロキシの設定が許可範囲そのものになるので、何を許可しているかを確認したうえで使ってください。

現在ソケットをマウントしているコンテナは、次のコマンドで確認できます。

docker ps -q | xargs -r docker inspect --format '{{.Name}} {{range .Mounts}}{{.Source}} {{end}}' | grep docker.sock

何も表示されなければ、動いているコンテナにソケットをマウントしたものはありません。

リモートから操作するときはSSHかTLSを使う

別のマシンからDockerを操作するために、デーモンをTCPで待ち受けさせる設定(-H tcp://0.0.0.0:2375 など)を見かけますが、暗号化も認証もない状態でポートを開けると、届いた人は誰でもホストのroot権限を取れます。Dockerの公式ドキュメントでは、HTTPでAPIを公開する場合は、HTTPSと証明書でエンドポイントを保護することを必須としています。

SSHで接続する(設定が簡単)

リモートのホストにSSHでログインでき、そのユーザーがソケットにアクセスできれば、デーモン側の設定変更なしで使えます。

# その場だけ接続先を切り替える
export DOCKER_HOST=ssh://docker-user@host1.example.com
docker ps

# コンテキストとして登録して切り替える
docker context create --docker host=ssh://docker-user@host1.example.com --description="Remote engine" my-remote-engine
docker context use my-remote-engine
docker context use default

通信はSSHで暗号化され、認証もSSHの鍵で行われます。SSHの鍵の管理(パスワード認証の無効化など)がそのままDockerの保護になります。

TLSで待ち受ける

SSHが使えない場合は、相互TLS認証で待ち受けます。公式ドキュメントの例では、デーモンを次のように起動し、ポートはTLS用の2376を使います。

dockerd --tlsverify --tlscacert=ca.pem --tlscert=server-cert.pem --tlskey=server-key.pem -H=0.0.0.0:2376

--tlsverify を付けると、指定したCAが署名したクライアント証明書を持つ接続だけを受け付けます。クライアント側は次のように接続します。

docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H=$HOST:2376 version

クライアントの鍵を持つ人はホストのrootと同じことができるので、公式ドキュメントでも鍵はrootのパスワードと同じように守るよう求めています。証明書の作り方は公式ドキュメントの「Protect the Docker daemon socket」の手順に従ってください。あわせて、ファイアウォールで2376番ポートに接続できる送信元を絞ります。

Rootlessモードでデーモン自体を一般ユーザーで動かす

Rootlessモードでは、Dockerデーモンとコンテナを一般ユーザーの権限で動かします。ソケットに接続できる人がいても、得られるのはそのユーザーの権限までです。

公式ドキュメントの主な前提と手順は次のとおりです。

  • ホストに newuidmap と newgidmap が必要(Ubuntuでは uidmap パッケージ)
  • /etc/subuid と /etc/subgid に、そのユーザー用のサブIDが65,536個以上必要
  • Docker公式のDEB/RPMパッケージで入れた場合、dockerd-rootless-setuptool.sh は docker-ce-rootless-extras パッケージに含まれる
# 一般ユーザーで実行する
dockerd-rootless-setuptool.sh install

# ソケットは /run/user/<UID>/docker.sock になる
export DOCKER_HOST=unix:///run/user/$(id -u)/docker.sock

# デーモンの操作は systemd のユーザーサービスで行う
systemctl --user restart docker.service

# ログインしていなくても起動させる(管理者が実行)
sudo loginctl enable-linger <ユーザー名>

ネットワークやストレージの機能に一部制限があるので、使う機能が動くかを事前に試してください。

点検のチェックリスト

確認項目 コマンド・方法 望ましい状態
ソケットの権限 ls -l /var/run/docker.sock srw-rw----、所有者 root、グループ docker
dockerグループのメンバー getent group docker rootを渡してよい人だけ
ソケットをマウントしたコンテナ 上の docker inspect のコマンド 無い、または理由が説明できるものだけ
TCPでの待ち受け sudo ss -lntp で dockerd の行を見る 何も無い、または2376番でTLSのみ
デーモンの起動オプション /etc/docker/daemon.json とsystemdのユニット tcp:// の指定が無い、またはTLSの設定がある

まとめ

  • docker.sock に接続できることは、ホストのroot権限を持つことと同じ
  • ソケットの権限は 660(root:docker)に保ち、docker グループにはrootを渡してよい人だけを入れる
  • コンテナにソケットをマウントしない。:ro を付けても防げない
  • リモート操作はSSH(DOCKER_HOST=ssh://)か、相互TLS認証(2376番)で行い、暗号化なしのTCPは開けない
  • 権限を分けたい場合はRootlessモードを使う

関連記事:

お気軽にご相談ください

お見積りへ お問い合わせへ
▲