web-dev-qa-db-ja.com

特定のユーザーとしてのみsystemdサービスを再起動しますか?

基本的に機能するsystemdサービスをいくつか作成しました。

ロケーション:

/etc/systemd/system/multi-user.target.wants/publicapi.service

コンテンツ:

[Unit]
Description=public api startup script

[Service]
Type=oneshot
RemainAfterExit=yes
EnvironmentFile=-/etc/environment
WorkingDirectory=/home/techops
ExecStart=/home/techops/publicapi start
ExecStop=/home/techops/publicapi stop

[Install]
WantedBy=multi-user.target

コマンドラインでtechopsユーザーとしてサービスを再起動しようとすると、次の出力が表示されます。

==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===
Authentication is required to start 'publicapi.service'.
Multiple identities can be used for authentication:
 1.  Myself,,, (defaultuser)
 2.  ,,, (techops)
Choose identity to authenticate as (1-2):

Techopsのみがサービスを再起動できるようにしたいのですが、techopsとしてログインしているときにこのプロンプトが表示されないようにしたいのですが。どうやってやるの?

Polkit-1やsudoersにはさまざまなアプローチがあることを読みましたが、よくわかりません。

[更新] 2019-01-27 16:4
トーマスとパールダックへのこの包括的な回答に感謝します。 systemdの知識を向上させるのに役立ちました。

パスワードなしでサービスを開始するアプローチによると、私は本当の問題を十分に強調しなかったことをお詫びしたいと思います:

実際、私にとって最も重要なことは、techops以外のユーザーがサービスを停止または開始しないことです。しかし、少なくとも最初の2つのアプローチでは、service publicapi stopを実行でき、プロンプト==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===が再び表示されます。 defaultuserを選択してパスワードを知っていると、すべてのサービスを停止できます。 このユーザーがパスワードを持っている場合でも、それを拒否します。これが私にとってより重要な部分である理由をよりよく理解するための重要な背景情報:
defaultuserがsshに公開される唯一のユーザーですが、このユーザーは他に何もできません(他のユーザーのパスワードを持っている場合に他のユーザーに変更することを除きます)。しかし、現時点では、サービスを開始または停止できますが、このユーザーはこれを実行してはなりません。
誰かがdefaultuserのパスワードを取得し、ssh経由でログインした場合、その時点ですべてのサービスを停止する可能性があります。これは私が「技術者だけがサービスを再開できるようにしたい」という意味です。申し訳ありませんが、私は最初の質問ではそれほど正確ではありませんでした。私はtechopsユーザーをsudoすることでこの問題を回避できると思いましたが、そうではありません。問題自体は、パスワードプロンプトなしでコマンドを実行しないことです。 (/home/techops/publicapi startを実行するだけで、techopsユーザーとして簡単に実行できます)。問題自体は、defaultuserがこれらのサービスを開始できないようにすることです。

そして、どのソリューションでもそれが可能であることを望みました。

私はトーマスのアプローチから始めました。説明されているようにコマンドを実行するときに、ユーザーtechopsのパスワードの入力を求められない場合は、Sudoによるアプローチが機能します。

Sudo systemctl start publicapi.service
Sudo systemctl stop publicapi.service

2番目のアプローチはまだ機能しません。パスワードプロンプト==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===がないとサービスを開始できず、このユーザーのパスワードを持っていると、defaultuserとしてログインできなくなります。

3番目のアプローチでは、サービスが起動プロセスから開始されなくなっただけなので、このアプローチが私にとって適切かどうかはわかりません。 systemctl enable publicapi.serviceでもできません。次のエラーが発生します。

Failed to enable unit: Unit file mycuisine-publicapi.service does not exist.

すべてのサービスを/ etc/systemd/system /に戻し、systemctl enable publicapi.serviceを実行してもエラーは発生しません。その後、サービスは起動時に再び開始されます。

これらのアプローチはすべて、techopsユーザーのパスワードプロンプトをバイパスするのに多少役立ちますが、defaultuserでservice publicapi stopまたはsystemctl stop publicapiを実行すると、パスワードがあればサービスを停止できます。しかし、私の目標は、defaultuserがサービスを開始または停止しないようにロックアウトすることです。

9
Bevor

ユーザーtechopsがパスワードを指定せずにサービスpublicapi.serviceを制御できるようにするには、さまざまな可能性があります。あなたが自分で選択しなければならないので、どちらがあなたに適しているかは答えられません。


古典的なSudoアプローチは、長い間存在しているため、おそらく最も使用されています。作成する必要があります。次のようにファイル。
ドロップインディレクトリ/etc/sudoers.dは、#includedir /etc/sudoers.d/etc/sudoersで設定されている場合にのみアクティブになることに注意してください。しかし、最新のUbuntuディストリビューションを使用している場合はそうなります。 rootを実行すると:

cat > /etc/sudoers.d/techops << Sudo
techops ALL= NOPASSWD: /bin/systemctl restart publicapi.service
techops ALL= NOPASSWD: /bin/systemctl stop publicapi.service
techops ALL= NOPASSWD: /bin/systemctl start publicapi.service
Sudo

これで、コマンドにsystemctlを付加することにより、パスワードを指定しなくても、ユーザーtechopsとしてSudoコマンドを実行できるようになります。

Sudo systemctl start publicapi.service
Sudo systemctl stop publicapi.service
Sudo systemctl restart publicapi.service

2番目の方法は、ユーザーがtechopssystemdサービスを制御できるようにするためにPolKitPolicyKitから名前が変更されました)を使用することです。 politのバージョンによっては、systemdユニットを通常のユーザーが制御できるようにすることができます。
polkitバージョンを確認するには、pkaction --versionを実行します。

  • polkitバージョン0.106以降を使用すると、特定のsystemdユニットをユーザーが制御できるようにすることができます。
    これを行うには、rootとしてルールを作成します。

    cat > /etc/polkit-1/rules.d/10-techops.rules << POLKIT
    polkit.addRule(function(action, subject) {
        if (action.id == "org.freedesktop.systemd1.manage-units" &&
            action.lookup("unit") == "publicapi.service" &&
            subject.user == "techops") {
            return polkit.Result.YES;
        }
    });
    POLKIT
    
  • polkitバージョン0.105以下を使用すると、ユーザーがsystemdユニットを制御できるようになります。残念ながら、これにはすべてのsystemdユニットが含まれており、これを実行したくない場合があります。バージョン0.105以下の特定のsystemdユニットへのアクセスを制限する方法があるかどうかはわかりませんが、おそらく他の誰かが明確にすることができます。
    これを有効にするには、rootとしてファイルを作成します。

    cat > /etc/polkit-1/localauthority/50-local.d/org.freedesktop.systemd1.pkla << POLKIT
    [Allow user techops to run systemctl commands]
    Identity=unix-user:techops
    Action=org.freedesktop.systemd1.manage-units
    ResultInactive=no
    ResultActive=no
    ResultAny=yes
    POLKIT
    

どちらの場合も、パスワードを入力しなくても、ユーザーtechopsとしてsystemctl [start|stop|restart] publicapi.serviceを実行できます。後者の場合(polkit <= 0.105)、ユーザーtechopsは任意のsystemdユニットを制御できます。


3番目のオプションは、サービスをユーザーサービスにすることです。Sudoまたはpolkit構成は必要ありません。これはすべてをユーザーの制御下に置き、/home/techops/publicapi startで開始された実際のサービスがroot特権なしで実行できる場合にのみ機能します。

まず、ユーザーtechopsの残存を有効にする必要があります。これは、起動時にユーザーサービスを起動するために必要です。 rootを実行すると:

loginctl enable-linger techops

次に、systemdユニットファイルをtechopsユーザーディレクトリに移動する必要があります。ユーザーtechopsとして、次のようにコマンドを実行します。

mkdir -p ~/.config/systemd/user

cat > ~/.config/systemd/user/publicapi.service << UNIT
[Unit]
Description=public api startup script

[Service]
Type=oneshot
RemainAfterExit=yes
EnvironmentFile=-/etc/environment
WorkingDirectory=/home/techops
ExecStart=/home/techops/publicapi start
ExecStop=/home/techops/publicapi stop

[Install]
WantedBy=default.target
UNIT

ユーザーコンテキストにはdefault.targetがないため、WantedBymulti-user.targetである必要があります。

次に、設定をリロードしてサービスを有効にします。再度、ユーザーtechopsとしてコマンドを実行します。

systemctl --user daemon-reload
systemctl --user enable publicapi.service
systemctl --user start publicapi.service

一般に、systemdユニットは/etc/systemd/system/に直接配置するのではなく、/etc/systemd/system/multi-user.target.wantsに配置する必要があります。 systemctl enable publicapi.serviceを実行すると、etc/systemd/system/multi-user.target.wantsまたはそのユニットに指定されているターゲットにシンボリックリンクが作成されます。

すでに述べたように、サービス/プロセス自体がroot権限なしで実行できる場合は、User=techopsをユニットファイルに追加して、権限のないユーザーアカウントでプロセスを実行することを検討してください。

17
Thomas

まず、ユニットファイルを/etc/systemd/system/multi-user.target.wantsディレクトリに配置しません。このディレクトリは、systemdおよびsystemctlコマンドによって維持されます。代わりにユニットファイルを/etc/systemd/systemに入れて、次のコマンドで有効にします。

Sudo systemctl enable publicapi.service

これにより、multi-user.target.wants(またはsystemctlの方が適切な場合)の下にシンボリックリンクが作成され、行が守られます

[Install]
WantedBy=multi-user.target

ユニット内。

次に、/etc/sudoers.dの下にsudoersファイルを作成します。

Sudo visudo -f /etc/sudoers.d/techops

次の内容で:

Cmnd_Alias HANDLE_PUBLICAPI = \
    /bin/systemctl start   publicapi.service \
    /bin/systemctl stop    publicapi.service \
    /bin/systemctl restart publicapi.service

techops ALL = (root) NOPASSWD: HANDLE_PUBLICAPI

通常のエディターを使用しないでください(例:Sudo vim /etc/sudoers.d/techops)でそのファイルを編集します。構文エラーがあると、Sudoを再度実行できなくなるためです。一方、visudoは、エディターを終了する前にファイルの構文をチェックします。

ユーザーtechopsが実行できるようになりました

Sudo systemctl start publicapi.service

残りの2つはパスワードを指定しません。 sudoersファイルで指定されているとおりにコマンドとパラメーターを正確に入力する必要があることに注意してください(systemctlだけに短縮できる/bin/systemctl部分を除く)。

たとえば、Sudo /bin/systemctl start publicapi.service以外)はパスワードを要求します。

5
PerlDuck