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


9

基本的に機能する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:40
トーマスとパールダックへのこの包括的な答えをありがとう。systemdの知識を向上させるのに役立ちました。

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

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


1
3番目のアプローチでは、root systemctl --user ...としてではtechopsなく、ユーザーとして実行する必要があります。どちらも私の提案も@PerlDuckの一つは、任意の与えないsudoあなたの権利defaultuserだけにtechopsのユーザーを。
Thomas

1
defaultuserは sudoとして構成されていますか?その場合は、セカンダリグループからユーザーを削除し、/etc/sudoersそのユーザーの参照があるかどうかファイルを確認する必要があります。
Thomas

@トーマスああ、それだけです。現在、期待どおりに動作します。ありがとう。
Bevor

回答:


17

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


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

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ユーザーとしてコマンドを実行できるようになります。techopssudo

sudo systemctl start publicapi.service
sudo systemctl stop publicapi.service
sudo systemctl restart publicapi.service

2番目の方法は、PolKitPolicyKitから名前が変更されました)を使用して、ユーザーtechopssystemdサービスを制御できるようにすることです。のバージョンによっては、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
    

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


第三の選択肢は、サービスは必要ありませんユーザーサービス、作ることであろう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

ことに注意してくださいWantedByしないために持っているdefault.target何があるので、multi-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、非特権ユーザーアカウントでプロセスを実行するためにユニットファイルに追加することを検討する必要があります。


とても良い。ユーザーユニットのさまざまなWantedByターゲットについても考えました。明らかに、これはあなたが書いた最初のユニットファイルではありません:-)
PerlDuck

タンク@PerlDuck。= 0)
Thomas

お返事をありがとうございます。これは私の質問に部分的に答えますが、私はまだ最初の問題を抱えています。(質問を更新しました)
Bevor

申し訳ありませんが、動作して.pklaいません。これには[section]エントリが必要です。回答を更新しました。
Thomas

5

まず、ユニットファイルをディレクトリに配置しません /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

ユニット内。

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

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ファイルに指定されているとおりに正確に入力する必要があることに注意してください(/bin/systemctl短縮して短縮できる部分を除くsystemctl)。

たとえば、sudo /bin/systemctl start publicapi(whithoutなしで.service)パスワードを要求します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.