CentOS systemdは、`user.slice`(`system.slice`の代わりに)に`sudo`で始まるサービスサブプロセスを配置します。

CentOS systemdは、`user.slice`(`system.slice`の代わりに)に`sudo`で始まるサービスサブプロセスを配置します。

systemdサービスを使用して作成されたサブプロセスはsudoに配置されますuser.slice。この動作はCentOS 8(x86_64 20230606)でのみ観察され、そのサブプロセスが配置されているUbuntu 20.04.5 LTSでは観察されませんsystem.slice

これは、主要なサービスプロセスが異なるcgroupにあり、生成されたサブプロセスがsudo別のcgroupにあるため、大きな問題です。したがってsystemctl stop、サービスを呼び出すと、生成された子プロセスではなく基本サービスプロセスのみが停止するため、sudo最終的に中断されます。

コピーステップ:

  1. 非rootユーザー(権限を含む)としてsudoログインします。
$ ssh centos@{ADDR}
  1. script.sh次のコンテンツを含むbashスクリプトを作成します。
#!/bin/bash
sudo sleep 1000
  1. スクリプトを実行可能にします。
$ chmod +x script.sh
  1. スクリプトをシステムサービスとして実行します。
$ sudo systemd-run ./script.sh
Running as unit: run-r16ed2fef94d442b5800035653bcbbe01.service
  1. ヘルスチェック:
$ sudo systemctl status run-rf4fe2865d42240c1a95f1ed497575494.service
● run-rf4fe2865d42240c1a95f1ed497575494.service - /home/centos/./script.sh
   Loaded: loaded (/run/systemd/transient/run-rf4fe2865d42240c1a95f1ed497575494.service; transient)
Transient: yes
   Active: active (running) since Wed 2023-11-15 10:01:49 UTC; 1min 1s ago
 Main PID: 10587 (script.sh)
    Tasks: 1 (limit: 97480)
   Memory: 1.7M
   CGroup: /system.slice/run-rf4fe2865d42240c1a95f1ed497575494.service
           └─10587 /bin/bash /home/centos/./script.sh

結果cgroupにサブプロセスまたはサブプロセスの両方がリストされていないことを確認できますsudosleepPID 10587を参照してください。

  1. 睡眠プロセスがあることを確認してください。
$ ps aux | grep sleep
root       10588  0.0  0.0 333172  8140 ?        S    10:01   0:00 sudo sleep 1000
root       10591  0.0  0.0 217092   848 ?        S    10:01   0:00 sleep 1000
centos     10687  0.0  0.0 221940  1164 pts/0    S+   10:03   0:00 grep --color=auto sleep

sudo生成されたsystemdプロセスを停止しても、これら2つのプロセスsleep(それぞれPID 10588と10591)は終了しません。

  1. これらのプロセスが属するシステムスライスを確認してください。
  • 基本システムサービスプロセス(10587、systemctl status上記参照):
$ cat /proc/10587/cgroup | grep name=
1:name=systemd:/system.slice/run-rf4fe2865d42240c1a95f1ed497575494.service
  • サブsudoプロセス(10588):
$ cat /proc/10588/cgroup | grep name=
1:name=systemd:/user.slice/user-0.slice/session-c37.scope
  • サブプロセスsleep(10591)」
$ cat /proc/10591/cgroup | grep name=
1:name=systemd:/user.slice/user-0.slice/session-c37.scope

メインスクリプトプロセスはに属しsystem.slice、サブプロセスはに属していることがわかりますuser.slice

Ubuntu 20.04.5 LTSで同じ手順を使用すると、すべての子プロセスが次の場所にある同じcgroupに配置されますsystem.slice

$ sudo systemd-run ./script.sh
Running as unit: run-r09332b0da31a4dd198286a87a917e55f.service
ubuntu@ip-10-0-0-92:~$ sudo systemctl status run-r09332b0da31a4dd198286a87a917e55f.service
● run-r09332b0da31a4dd198286a87a917e55f.service - /home/ubuntu/./script.sh
     Loaded: loaded (/run/systemd/transient/run-r09332b0da31a4dd198286a87a917e55f.service; transient)
  Transient: yes
     Active: active (running) since Wed 2023-11-15 10:06:55 UTC; 7s ago
   Main PID: 1729 (script.sh)
      Tasks: 3 (limit: 18627)
     Memory: 1.4M
     CGroup: /system.slice/run-r09332b0da31a4dd198286a87a917e55f.service
             ├─1729 /bin/bash /home/ubuntu/./script.sh
             ├─1730 sudo sleep 1000
             └─1731 sleep 1000

したがって、サービスを停止すると、すべての子プロセスが終了します。

それでは、CentOSでは何が起こっているのでしょうか? systemdがUbuntuと同じように機能するようにするにはどうすればよいですか?子プロセスを同じcgroupに強制的に配置できますかsystem.slice

CentOSで生成されたサービスのsystemdパラメータを確認してみると、実際にUbuntuと同じです。特に、このSliceパラメータは次のように設定されますsystem.slice

$ sudo systemctl show run-rf4fe2865d42240c1a95f1ed497575494.service | grep Slice=
Slice=system.slice

答え1

Systemd サービス構成は、子プロセスの作成を引き継ぐことはなく、子プロセスを別の場所に移動することもありません。これはsudo不必要に呼び出されるPAM設定自体によって行われますpam_systemd(望ましくない結果を得るために故意に呼び出された場合、またはユーザーがrootとしてGUIアプリケーションを実行しようとしたときにターゲットユーザーにXDG_RUNTIME_DIRを設定しようとすることもあります。)わからない)。

PAMモジュールはsystemd-logindセッションを作成します。これにより、logindは呼び出しプロセスを「セッション」cgroupに移動し、独自のシェルプロセスはsshd.serviceから移動します。[Eメール保護]ログインするとき。

/etc/pam.d/sudoこのモジュールを無効にするには編集してください。ただし、他のPAM構成ではこれを無効にしないように注意してください。ファイルに/etc/pam.d/system-auth(コンソールおよびSSHログインにも使用されます)が含まれている場合は、代わりにpam_systemdを残す必要があります。挿入するpam_succeed_ifPAMをだましてスキップしてください。

session [success=1 default=ignore] pam_succeed_if.so service = sudo
session whatever                   pam_systemd.so

(pam_succeed_ifがPAM_SUCCESSを返す場合、「success = 1」は次の1つのモジュールをスキップし、「default = ignore」は他のすべての結果を無視します。)

関連情報