基本的に機能する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がサービスを開始または停止しないようにロックアウトすることです。
ユーザー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番目の方法は、ユーザーがtechops
がsystemd
サービスを制御できるようにするためにPolKit(PolicyKitから名前が変更されました)を使用することです。 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
がないため、WantedBy
は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
をユニットファイルに追加して、権限のないユーザーアカウントでプロセスを実行することを検討してください。
まず、ユニットファイルを/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
以外)はパスワードを要求します。