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モードを使う
関連記事: