1.5. root または root 以外のユーザーとしてコンテナーの実行

スーパーユーザー特権 (root ユーザー) を持つユーザーとして podmanskopeobuildah などのコンテナーツールを実行すると、コンテナーが、システムで利用できる機能に完全にアクセスできるようにするのが最善の方法です。ただし、RHEL 8.1 以降で一般的に利用可能な「ルートレスコンテナー」と呼ばれる機能を使用すると、コンテナーを一般ユーザーとして使用できます。

Docker などのコンテナーエンジンでは、通常の (root 以外の) ユーザーとして docker コマンドを実行できますが、これらの要求を実行する docker デーモンは root として実行されます。そのため、通常のユーザーは、コンテナーを介してシステムに害を及ぼす要求を行うことができますが、要求を行ったユーザーを明確にする必要はありません。ルートレスコンテナーユーザーを設定することにより、システム管理者は、一般ユーザーからのコンテナーアクティビティーに損害を与える可能性を制限しながら、それらのユーザーが自分のアカウントで多くのコンテナー機能を安全に実行できるようにします。

本セクションでは、コンテナーツール (Podman、skopeo、および Buildah) を使用して、root 以外のユーザー (ルートレス) としてコンテナーを操作するように設定する方法を説明します。また、一般ユーザーアカウントは、コンテナーの実行に必要なすべてのオペレーティングシステム機能に完全にアクセスできないため、発生する可能性のある制限についても説明します。

1.5.1. ルートレスコンテナーの設定

root 以外のユーザーでコンテナーツールを使用できるように、RHEL システムを設定する必要があります。

  1. RHEL のインストール - RHEL 8.1 をインストールするか、RHEL 8.0 から RHEL 8.1 にアップグレードします。この手順に必要な機能は、以前の RHEL 7 バージョンにはありません。RHEL 7.6 以前のバージョンからアップグレードする場合は、この手順を行った後に「ルートレスコンテナーへのアップグレード」に進みます。
  2. podman および slirp4netns のインストール - podman パッケージおよび slirp4netns パッケージがインストールされていない場合はインストールします。

    # yum install slirp4netns podman -y
  3. ユーザーの名前空間を増やす - カーネルのユーザー名前空間の数を増やすには、次のコマンドを実行します。

    # echo "user.max_user_namespaces=28633" > /etc/sysctl.d/userns.conf
    # sysctl -p /etc/sysctl.d/userns.conf
  4. 新規のユーザーアカウントの作成 - 新規のユーザーアカウントを作成し、そのアカウント (例: joe) のパスワードを追加するには、次のコマンドを実行します。

    # useradd -c "Joe Jones" joe
    # passwd joe

    ユーザーは、ルートレスな podman を使用できるように自動的に設定されます。

  5. podman コマンドを試用 - 設定したばかりのユーザーとして直接ログインし (正しい環境変数が設定されていないため、su または su - を使用しないでください)、イメージをプルして実行します。

    $ podman pull registry.access.redhat.com/ubi8/ubi
    $ podman run registry.access.redhat.com/ubi8/ubi cat /etc/os-release
    NAME="Red Hat Enterprise Linux"
    VERSION="8.1 (Ootpa)"
    ...
  6. ルートレス設定の確認 - ルートレス設定が正しく設定されていることを確認するには、podman unshare コマンドで変更したユーザー名前空間内でコマンドを実行できます。ルートレスユーザーとして次のコマンドを実行すると、uid がユーザーの名前空間にどのようにを割り当てられるかを確認できます。

    $ podman unshare cat /proc/self/uid_map
             0       1001       1
             1      65537   65536

1.5.2. ルートレスコンテナーへのアップグレード

RHEL 7 からアップグレードした場合は、ルートレス Podman を使用できる既存のユーザーに対して、subuid 値および subgid 値を手動で設定する必要があります。

既存のユーザー名およびグループ名 (jill など) を使用して、コンテナーに使用できるアクセス可能なユーザー ID とグループ ID の範囲を設定します。以下にいくつかの警告を示します。

  • この範囲には、ルート以外のユーザーの UID と GID を追加しないでください。
  • 複数のルートレスコンテナーユーザーを設定する場合は、ユーザーごとに一意の範囲を使用します。
  • 既存のコンテナーイメージとの互換性を最大限にするために、UID および GID の数を 65536 とすることが推奨されますが、この数を減らすことができます
  • 1000 未満の UID または GID を使用したり、既存のユーザーアカウントから UID または GID を再利用したりしないでください (デフォルトでは 1000 から開始します)。

    以下に例を示します。

    # echo "jill:165537:65536" >> /etc/subuid
    # echo "jill:165537:65536" >> /etc/subgid

    これにより、ユーザーまたはグループの jill は、165537~231072 の範囲から、65535 のユーザー ID とグループ ID が割り当てられます。そのユーザーは、コンテナーを操作するコマンドの実行を開始できるはずです。

1.5.3. ルートレスに関する特別な考慮事項

コンテナーを root 以外のユーザーとして実行する場合に考慮すべき事項を次に示します。

  • 非 root コンテナーユーザーとして、コンテナーイメージは、/var/lib/containers ではなく、ホームディレクトリー ($HOME/.local/share/containers/storage/) の下に保存されます。
  • ルートレスコンテナーを実行するユーザーには、ホストシステムでユーザー ID およびグループ ID の範囲として実行する特別な権限が付与されます。ただし、これを行わないと、ホストのオペレーティングシステムに root 権限がありません。
  • ルートレスコンテナー環境を設定する必要がある場合は、ホームディレクトリー内の設定ファイル ($HOME/.config/containers) を編集します。設定ファイルには、storage.conf (ストレージ設定用) および libpod.conf (さまざまなコンテナー設定用) が含まれます。また、registries.conf ファイルを作成し、podmanを使用してイメージをプル、検索、または実行する時に利用可能なコンテナーレジストリーを識別することもできます。
  • ルートレスアカウントで root として実行しているコンテナーは、独自の名前空間内で特権機能を有効にできます。ただし、ホスト上で保護された機能にアクセスするための特別な特権は提供されません (追加の UID および GID が必要です)。以下は、有効ではないルートレスアカウントから作業する可能性があるコンテナーアクションの例です。

    • ホストからマウントされたディレクトリーからアクセスするすべての内容には、コンテナーを実行している UID、またはそのコンポーネントへのアクセス要求にアクセスできない必要があります。
    • 特権なしでは変更できないシステム機能もいくつかあります。たとえば、コンテナー内で SYS_TIME 機能を設定し、ネットワークタイムサービス (ntpd) を実行するだけでは、システムクロックを変更できません。次のような機能を有効にするためには、そのコンテナーを root として実行し、ルートレスコンテナー環境は回避して root ユーザーの環境を使用する必要があります。

      $ sudo podman run -d --cap-add SYS_TIME ntpd

      この例では、ntpd がコンテナー内だけでなく、システム全体の時間の調整を行うことができることに注意してください。

  • ルートレスコンテナーは、1024 未満のポートにアクセスすることができません。たとえば、コンテナーの httpd サービスからポート 80 を公開するサービスを開始しますが、名前空間外からはアクセスできません。

    $ podman run -d httpd

    ただし、そのポートをホストシステムに公開するには、コンテナーには root ユーザーのコンテナー環境を使用するルート権限が必要です。

    $ sudo podman run -d -p 80:80 httpd
  • ワークステーションの管理者は、ユーザーが 1024 未満のサービスを公開できるように構成できますが、セキュリティーへの影響を理解する必要があります。たとえば、一般ユーザーは、公式のポート 80 で Web サーバーを実行し、外部ユーザーが管理者により構成されていると信じ込ませることができます。通常、これはワークステーションでは問題ありませんが、ネットワークにアクセス可能な開発サーバーでは実行できない可能性があり、実稼働サーバーでは実行しないでください。ユーザーがポート 80 にバインドできるようにするには、次のコマンドを実行します。

    # echo 80 > /proc/sys/net/ipv4/ip_unprivileged_port_start
  • root 権限がない状態で podman および関連ツールの実行することの短所は、「Shortcomings of Rootless Podman」を参照してください。