興味深いユースケースがあります。テスト用の仮想マシンをシミュレートするためにコンテナでsystemdを実行しています。 systemdをうまく実行できますが、rootになるためにsudoを実行する前に、コンテナで実行されるすべての操作が正しいユーザーを取得できるように、デフォルトユーザーがroot以外のユーザーである必要があります。
私のENTRYPOINT
ことはsudo /usr/lib/systemd/systemd --system --unit=multi-user.target
、それがほとんどのことに効果があるということです。ただし、sudo
systemdは呼び出しによってPID 1を取得できず、一部のダウンストリームsystemdデバイスはPID 1に依存します。
文書によると:
プロセスモデル
sudoは、コマンドを実行するときにfork(2)を呼び出し、上記のように実行環境を設定し、サブプロセスでexecveシステムコールを呼び出します。デフォルトのsudoプロセスはコマンドが完了するのを待ち、コマンドの終了ステータスをセキュリティポリシーの閉じる機能に渡して終了します。 I / Oロギングプラグインが設定されている場合、またはセキュリティポリシーから明示的に要求された場合は、新しい擬似端末(「pty」)が作成され、2番目のsudoプロセスを使用して、ユーザーの既存のptyと新しいpty制御の間でタスクを渡します。シグナル pty がコマンドを実行しています。この追加プロセスにより、コマンドを一時停止して再開できます。これがないと、コマンドはPOSIX用語で「孤立プロセスグループ」に属し、ジョブ制御信号を受信できなくなります。特別な場合に、ポリシープラグインが閉じる機能を定義せずにptyを必要としない場合、sudoは最初にfork(2)を呼び出さずにコマンドを直接実行します。 sudoersポリシープラグインは、I / Oロギングが有効な場合、ptyが必要な場合、またはpam_sessionまたはpam_setcredオプションが有効になっている場合にのみシャットダウン機能を定義します。 PAM を使用するシステムでは、pam_session および pam_setcred がデフォルトで有効になっています。
Bashと同様に、sudoに実行中の子プロセスに自分自身を置き換えるように指示する方法はありますかexec
?他に良い方法がありますか?このコマンドに対して「ポリシープラグイン」を変更する必要があるようですが、どうすればよいかわかりません。
答え1
この問題を解決しました。エスカレーターと呼ばれる小さなRustアプリケーション。実行可能ビットを使用してsuid
ルートとして実行し、実際にルートになり、渡されたコンテンツを実行するsetuid
前に自分自身を子プロセスに置き換えます。setgid
答え2
コマンドラインを制御できる場合は、ENTRYPOINTコマンドで使用するのではなく、オプション(たとえば)を渡すことdocker run
を検討できます。--user
--user=0:0
sudo
この場合、ENTRYPOINTをに設定して/usr/lib/systemd/systemd --system --unit=multi-user.target
systemdをPID 1として実行し、USER設定をそのまま維持してコマンドに適用できますdocker exec
。
バラよりユーザーに到達docker run
リファレンスマニュアルにあります。
逆に、コマンドラインを制御できない場合は、コンテナ定義でUSERをルートとして残してコマンドをdocker run
渡すことができます。これには、オプションをすべての呼び出しに渡す必要があり、それを渡すuser:group(またはuid:gid)を見つける必要があるなど、いくつかの欠点があります(ルートは単純で常に0:0です)。--user
docker exec