web-dev-qa-db-ja.com

Sudo -iがターゲットユーザーのXDG_RUNTIME_DIRを設定しないのはなぜですか?

XDG_RUNTIME_DIRが機能するには、systemctl --userが必要です。

Systemdユーザーセッションを実行するようにubuntuサーバー16.04を設定しました。現在、それらを管理しようとすると、Sudo -u $user -iまたはsu - $userを介してユーザーを変更する場合、環境にXDG_RUNTIME_DIRが設定されていないため、systemctl --userが機能しません。ただし、そのユーザーに直接sshすると、正しく設定されます。

ドキュメントを正しく理解していれば、ユーザーセッションの作成時にlibpam-systemdによって設定されているはずです。 XDG_RUNTIME_DIRが指すディレクトリ(/run/users/$uid)が存在するため、ユーザースライスは正しく開始されます。 .bash_profileのようにハードコードするのは躊躇しています。

もちろん、sudoersXDG_RUNTIME_DIRenv_keepに追加することもできますが、これはsudoingユーザーの環境を保持するだけであり、私が望むものではありません。 targetユーザーの環境が必要です。

しかし、私が本当に疑問に思っているのは、セッションがsshまたはSudo -iではなくsuで正しく設定されるのはなぜですか?

14
mkaito

この問題をFedora 25システムで再現しました。

ソースコードに非常に疑わしい状態が見つかりました。 https://github.com/systemd/systemd/blob/f97b34a/src/login/pam_systemd.c#L439 通常のSudoを念頭に置いて記述されているように見えますが、 Sudo -u non-root-userではありません。

machinectl Shell --uid=non-root-userはリクエストどおりに機能しました。

systemd-runは、machinectlのドキュメントで参照されているにもかかわらず、期待どおりに機能していないようです。

現時点でSELinuxを有効にしている場合、一部のmachinectlコマンドは機能せず、これらの特定のコマンドは、setenforce 0を実行するまで機能しませんでした。しかし、私はmachinectlをSELinuxで希望どおりに機能させるための回避策を試行している最中なので、私の手作業が原因である可能性があります。タイムアウトするmachinectl Shell

編集:このコードは このディスカッション の後に導入されたと思います。そして、明らかにsu -/Sudo -iを機能させることはできますが、誰も実装していません(まだ)。

9
sourcejedi

しかし、私が本当に疑問に思っているのは、セッションがsshで正しく設定されているのに、suまたはSudo -iでは正しく設定されていないのはなぜですか?

https://github.com/systemd/systemd/issues/7451#issuecomment-346787237

申し訳ありませんが、「su」は、ユーザーIDと他のほとんどのプロセス資格情報を一時的に変更するためのツールです。まったく新しいログインセッションを開くためのツールではありません。新しいログインセッションには、他のセッションから何も継承しない、明確に定義された手付かずの設定がありますが、これは "su" uidの変更には当てはまりません。実行環境のほとんどは、数多くの非自明な形で継承されます方法、たとえば、MACコンテキスト、監査コンテキスト、cgroupコンテキスト、名前空間コンテキスト、スケジューリング、タイマーの粒度、…

完全に新しいセッションが必要な場合は、「machinectl login」や「machinectl Shell」などを使用します。これにより、完全にクリーンな独立したデタッチ環境が得られ、呼び出し先から隠されたプロセスプロパティがリークすることはありません。

ログインしたセッションは、ほとんどが監査セッションの概念に拘束され、監査セッションは「su」の影響を受けません。実際、「封印」されるように定義されています。つまり、プロセスが一度セッションに入ると、常に残ります。つまり、その子も同様です。つまり、新しいセッションを取得する唯一の方法は、PID 1(または類似の何か)からフォークして、セッションの一部になったことがないようにすることです。

または別の言い方をすると、 "su"を介して呼び出したものは "loginctl"で正常に表示されますが、元のセッションの一部であり、最初にログインしました。これは、元のセッションのID(echo $ XDG_SESSION_IDで確認できます)で「loginctl status」を呼び出すことで確認できます。

3
sourcejedi