最近、誰かがPodman.ioで問題をオープンしました:Dockerfile USERはpodmanにとって意味がありますか?ユーザーは、Postgresqlコンテナを非rootとして実行するようにコンテナを設定しようとしていました。彼は自分のホームディレクトリにPostgresqlデータベースのディレクトリを作成し、それをコンテナにボリュームマウントしたいと考えていました。
$ podman run -it **-v "$PWD"/html:/output:Z** schemaspy/schemaspy:snapshot -u postgres -t pgsql11 -host 192.168.4.1 -port 5432 -db anitya
...
INFO - Starting Main v6.1.0-SNAPSHOT on 9090a61652af with PID 1 (/schemaspy-6.1.0-SNAPSHOT.jar started by java in /)
INFO - The following profiles are active: default
INFO - Started Main in 2.594 seconds (JVM running for 3.598)
INFO - Starting schema analysis
**ERROR - IOException**
**Unable to create directory /output/tables**
INFO - StackTraces have been omitted, use `-debug` when executing SchemaSpy to see them
ルートレスPodmanを非ルートとして実行することは意味がありますか?
彼が抱えていた問題は、彼がホームディレクトリに作成したディレクトリ$PWD/html
でした。 彼のUIDによって所有されていました。このUIDはroot
のように見えます コンテナ内で、コンテナ内のPostgresqlプロセスはrootとして実行されません:postgres
として実行されます ユーザー(-u postgres
)。したがって、Postgresqlプロセスはディレクトリに書き込むことができません。
この問題の簡単な解決策は、html
をchownすることです。 Postgresqlがコンテナ内で実行するUIDと一致するディレクトリ。ただし、ユーザーがファイルをchownしようとした場合:
chown postgres:postgres $PWD/html
chown: changing ownership of '/home/dwalsh/html': Operation not permitted
彼らは許可を拒否されます。この結果は、ユーザーがシステムのrootではなく、ファイルをランダムなUIDにchownすることを許可されていないためです。
$ grep postgres /etc/passwd
postgres:x:26:26:PostgreSQL Server:/var/lib/pgsql:/bin/bash
ユーザーがsudo
を追加した場合 ディレクトリをchownすると、同様のエラーが発生します。現在、ディレクトリはUID 26によって所有されていますが、UID 26はコンテナにマップされておらず、Postgresがコンテナ内で実行されるのと同じUIDではありません。ユーザー名前空間に関する以前の記事を思い出してください。Podmanはユーザー名前空間内でコンテナーを起動します。このコンテナーは、/etc/subuid
でユーザーに定義されたUIDの範囲にマッピングされます。 および/etc/subgid
。
私のシステムでは、次のユーザー名前空間で実行しています:
$ podman unshare cat /proc/self/uid_map
0 3267 1
1 100000 65536
この結果は、UID 0が私のUID3267にマップされ、UID 1が100000にマップされ、UID2が100001にマップされることを示しています。この結果は、コンテナ内でUID26がUID100025として実行されることを意味します。
すばらしい、試してみましょう:
$ chown 100025:100025 $PWD/html
chown: changing ownership of '/home/dwalsh/html': Operation not permitted
まあ、それもうまくいきませんでした。問題は、私のユーザーアカウントがこれらのマッピングを使用してユーザー名前空間を実行できるにもかかわらず、現在ユーザー名前空間にいないことです。 podman unshare
を使用する必要があります コマンドを使用すると、rootless Podmanが使用するのと同じユーザー名前空間に移動するため、unshare
の場合はまったく同じように見えます。 ルートレスの場合と同じように:
$ podman unshare chown 100025:100025 $PWD/html
chown: changing ownership of '/home/dwalsh/html': Invalid argument
Error: exit status 1
まだ正しくありません。現在の問題は、chown
ユーザー名前空間内で発生しているため、chown
マップされたUIDではなく、元のUIDを使用する必要があります:
$ podman unshare chown 26:26 $PWD/html
ユーザー名前空間の外では、この結果は次のようになります。
$ ls -ld $PWD/html
drwxrwxr-x. 2 100025 100025 4096 Sep 13 07:14 /home/dwalsh/html
これで、ユーザーがコンテナーを実行すると、成功します。コンテナ内のPostgresqlプロセスは、コンテナ内(および外部100025)のUID26として実行されます。
しかし、元の質問に戻りましょう。「ルートレスPodmanを非ルートとして実行することは意味がありますか?」すでにコンテナを非ルートとして実行している場合、PodmanコンテナでPostgresqlを別の非ルートとして実行する必要があるのはなぜですか?
デフォルトでは、rootなしのPodmanはコンテナ内でrootとして実行されます。このポリシーは、コンテナ内のプロセスに名前空間機能のデフォルトリストがあることを意味します。 これにより、プロセスはユーザー名前空間内でルートのように動作できます。これには、UIDの変更や、ユーザー名前空間にマップされている別のUIDへのファイルの変更が含まれます。コンテナをPostgresqlユーザーとして実行する場合は、このアクセスを防止する必要があります。
この設定は、コンテナ内のプロセスがユーザーのUIDとして実行されていることも意味します。コンテナプロセスがコンテナをエスケープした場合、プロセスはUIDの分離に基づいて、ホームディレクトリ内のファイルに完全にアクセスできます。 SELinuxは引き続きアクセスをブロックしますが、一部の人々はSELinuxを無効にする 。そうすることは、エスケープされたプロセスが~/.ssh
のようなホームディレクトリのシークレットを読み取る可能性があることを意味します および~/.gpg
、またはコンテナがアクセスできないようにするその他の情報。
ただし、コンテナ内のプロセスを別の非ルートUIDとして実行する場合、それらのプロセスはそのUIDとして実行されます。コンテナをエスケープすると、ホームディレクトリのコンテンツにのみアクセスできます。これらのディレクトリのコンテンツを操作するには、podman unshare
を実行する必要があることに注意してください。 コマンドを実行するか、UID(コンテナ内のroot)が所有するディレクトリのグループ所有権を設定します。
Podmanでは、ユーザーが選択した場合、ユーザーが任意のコンテナーレジストリで任意のコンテナーイメージを非rootとして実行できるようにする必要があります。また、セキュリティ上の理由から、コンテナを非ルートとして実行することが常に最優先事項であると私は信じています。
[Red Hat Enterprise Linuxを試してみませんか?今すぐ無料でダウンロードしてください。]