僅以特定使用者身份重新啟動 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 有不同的方法,但我不確定。
$$ UPDATE $$2019-01-27 4:40pm
感謝您對 Thomas 和 Perlduck 的全面回答。它幫助我提高了我對 systemd 的了解。
根據在沒有密碼提示的情況下啟動服務的方法,我很抱歉我沒有足夠強調真正的問題:
實際上,對我來說最重要的是,除了 techops 之外,沒有其他使用者應該停止或啟動該服務。但至少前兩種方法我仍然可以執行
service publicapi stop
並且我再次得到提示==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===
。當我選擇預設使用者並知道密碼時,我可以停止所有服務。我想拒絕這個使用者這樣做,即使他有密碼。重要的背景資訊,以更好地理解為什麼這對我來說更重要:預設使用者是唯一暴露於 ssh 的使用者,但該使用者不能做任何其他事情(如果您擁有這些其他使用者的密碼,則更改為其他使用者除外) . 但此時,他可以啟動或停止服務,但該使用者不得這樣做。
如果有人得到defaultuser的密碼並通過ssh登錄,那麼他現在可以停止所有服務。這就是我所說的“我希望只有技術人員可以重新啟動服務”的意思。抱歉,我最初的問題並不那麼準確。我認為對 techops 使用者進行 sudo 可能會繞過這個問題,但事實並非如此。問題本身不是在沒有密碼提示的情況下執行命令。(當我剛剛執行時,我可以很容易地以 techops 使用者的身份做到這一點
/home/techops/publicapi start
)。問題本身是阻止預設使用者啟動這些服務。我希望任何解決方案都能做到這一點。
我從托馬斯的方法開始。當我按照說明執行命令時,不想被詢問使用者 techops 的密碼時,使用 sudo 的方法有效,例如
sudo systemctl start publicapi.service sudo systemctl stop publicapi.service
第二種方法對我還不起作用。我無法在沒有密碼提示的情況下啟動服務,
==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===
並且當我擁有該使用者的密碼時,我可以以預設使用者身份登錄。使用第三種方法,服務甚至不再在啟動過程中啟動,所以我不確定這種方法是否適合我。我什至無法使用它,
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
或systemctl stop publicapi
使用 defaultuser 時,如果我有密碼,我可以停止服務。但我的目標是完全阻止預設使用者啟動或停止服務。
為了實現使用者無需提供密碼
techops
即可控制服務,您有不同的可能性。publicapi.service
哪一個適合您無法回答,因為您必須自己選擇。經典
sudo
方法可能是最常用的,因為它已經存在了很長時間。您必須按如下方式創建例如該文件。請注意,插入目錄僅在中設置
/etc/sudoers.d
時才處於活動狀態。但是,如果您使用的是現代 Ubuntu 發行版,情況就應該如此。作為執行:#includedir /etc/sudoers.d``/etc/sudoers``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
第二種方法是使用PolKit(從PolicyKit重命名)來允許使用者
techops
控制systemd
服務。根據 的版本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
到您的單元文件以使用非特權使用者帳戶執行該程序。