Khởi động lại dịch vụ systemd chỉ là một người dùng cụ thể?


9

Tôi đã tạo một số dịch vụ systemd về cơ bản hoạt động:

vị trí:

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

Nội dung:

[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

Khi tôi cố gắng khởi động lại dịch vụ với tư cách là người dùng techops trong dòng lệnh, tôi nhận được kết quả đầu ra sau:

==== 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):

Tôi muốn rằng chỉ có techops mới có thể khởi động lại dịch vụ và tôi muốn rằng dấu nhắc này không xuất hiện khi đăng nhập với tên techops. Làm thế nào tôi có thể làm điều đó?

Tôi đọc rằng có nhiều cách tiếp cận khác nhau với polkit-1 hoặc sudoers, nhưng tôi không chắc chắn.

[CẬP NHẬT] 2019-01-27 4:40 chiều
Cảm ơn câu trả lời toàn diện này cho Thomas và Perlduck. Nó giúp tôi nâng cao kiến ​​thức về systemd.

Theo cách tiếp cận để bắt đầu dịch vụ mà không cần nhắc mật khẩu và tôi muốn xin lỗi rằng tôi đã không nhấn mạnh đủ vấn đề thực sự:

Trên thực tế, điều quan trọng nhất đối với tôi là không người dùng nào khác ngoài techops nên dừng hoặc bắt đầu dịch vụ. Nhưng ít nhất với hai cách tiếp cận đầu tiên tôi vẫn có thể chạy service publicapi stopvà tôi lại nhận được lời nhắc ==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===. Khi tôi chọn người dùng mặc định và biết mật khẩu, tôi có thể dừng tất cả các dịch vụ. Tôi muốn từ chối người dùng này làm điều đó, ngay cả khi anh ta có mật khẩu . Thông tin cơ bản quan trọng để hiểu rõ hơn lý do tại sao đây là phần quan trọng hơn đối với tôi:
Trình mặc định là người dùng duy nhất tiếp xúc với ssh nhưng người dùng này không thể làm gì khác (ngoại trừ thay đổi cho người dùng khác nếu bạn có mật khẩu của những người dùng khác) . Nhưng hiện tại, anh ta có thể bắt đầu hoặc dừng các dịch vụ, nhưng người dùng này không được làm điều này.
Nếu ai đó lấy được mật khẩu của defaultuser và đăng nhập qua ssh, thì anh ta có thể dừng tất cả các dịch vụ vào lúc này. Đây là điều tôi muốn nói với "Tôi muốn rằng chỉ có kỹ thuật viên mới có thể khởi động lại dịch vụ". Xin lỗi, rằng tôi không chính xác với câu hỏi ban đầu của tôi. Tôi nghĩ rằng sudoing người dùng techops có thể bỏ qua vấn đề này, nhưng nó không. Vấn đề là không chạy lệnh mà không có mật khẩu nhắc. (Tôi có thể dễ dàng làm điều đó với tư cách là người dùng techops khi tôi thực hiện /home/techops/publicapi start). Vấn đề là khóa hệ thống mặc định khỏi việc khởi động các dịch vụ này.

Và tôi hy vọng rằng bất kỳ giải pháp nào cũng có thể làm được điều đó.

Tôi bắt đầu với những cách tiếp cận của Thomas. Cách tiếp cận với sudo hoạt động khi tôi không muốn được hỏi mật khẩu cho các kỹ thuật viên người dùng khi tôi thực hiện các lệnh như được giải thích, ví dụ:

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

Cách tiếp cận thứ hai không hiệu quả với tôi. Tôi không thể khởi động dịch vụ mà không có mật khẩu nhắc ==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===và tôi có thể đăng nhập với tư cách là người dùng mặc định khi tôi có mật khẩu của người dùng này.

Với cách tiếp cận thứ ba, dịch vụ thậm chí không bắt đầu ở quá trình khởi động nữa nên tôi không chắc cách tiếp cận này có phù hợp với tôi không. Tôi thậm chí không thể làm được điều systemctl enable publicapi.serviceđó dẫn đến lỗi sau:

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

Lỗi không xảy ra khi tôi chuyển tất cả các dịch vụ trở lại vào / etc / systemd / system / và thực thi systemctl enable publicapi.service. Sau đó, dịch vụ bắt đầu lại khi khởi động.

Tất cả các cách tiếp cận này sẽ ít nhiều giúp bỏ qua lời nhắc mật khẩu cho người dùng techops nhưng khi tôi chạy service publicapi stophoặc systemctl stop publicapi với defaultuser, tôi có thể dừng các dịch vụ nếu tôi có mật khẩu. Nhưng mục tiêu của tôi là khóa người dùng mặc định khỏi việc bắt đầu hoặc dừng dịch vụ.


1
Đối với cách tiếp cận thứ ba, bạn phải chạy systemctl --user ...như người dùng techopskhông phải là root. Không đề nghị của tôi cũng không phải là một trong những @PerlDuck cho bất kỳ sudoquyền của bạn defaultuser nhưng chỉ trong techops người dùng.
Thomas

1
defaultuser được cấu hình là sudo? Trong trường hợp đó, bạn nên xóa người dùng khỏi các nhóm thứ cấp và kiểm tra /etc/sudoerstệp của bạn nếu có tài liệu tham khảo cho người dùng đó.
Thomas

@Thomas Ah, vậy thôi. Nó hoạt động như mong đợi bây giờ. Cảm ơn.
Bevor

Câu trả lời:


17

Để đạt được điều đó, người dùng techopscó thể kiểm soát dịch vụ publicapi.servicemà không cần cung cấp mật khẩu, bạn có khả năng khác nhau. Cái nào phù hợp với bạn không thể được trả lời khi bạn phải tự chọn.


Phương sudopháp cổ điển có thể được sử dụng nhiều nhất, vì nó tồn tại trong một thời gian dài. Bạn sẽ phải tạo ví dụ như tập tin như sau.
Lưu ý rằng thư mục thả vào /etc/sudoers.dchỉ hoạt động khi #includedir /etc/sudoers.dđược đặt /etc/sudoers. Nhưng đó là trường hợp nếu bạn đang sử dụng bản phân phối Ubuntu hiện đại. Khi rootthực hiện:

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

Bây giờ bạn sẽ có thể chạy các systemctllệnh như người dùng techopsmà không cần cung cấp mật khẩu bằng cách thêm vào sudocác lệnh.

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

Phương pháp thứ hai sẽ là sử dụng PolKit (được đổi tên từ PolicyKit ) để cho phép người dùng techopskiểm soát systemdcác dịch vụ. Tùy thuộc vào phiên bản của polit, bạn có thể cung cấp cho người dùng bình thường quyền kiểm soát các đơn vị systemd.
Để kiểm tra phiên bản polkit , chỉ cần chạy pkaction --version.

  • với phiên bản polkit 0.106 trở lên , bạn có thể cho phép người dùng kiểm soát các đơn vị systemd cụ thể.
    Để làm như vậy, bạn có thể tạo một quy tắc như 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
    
  • với phiên bản polkit 0.105 trở xuống : bạn có thể cho phép người dùng kiểm soát các đơn vị systemd. Điều này không may bao gồm tất cả các đơn vị systemd và bạn có thể không muốn làm điều này. Không chắc chắn nếu có một cách để giới hạn quyền truy cập vào các đơn vị systemd cụ thể với phiên bản 0.105 trở xuống, nhưng có lẽ ai đó có thể làm rõ.
    Để kích hoạt tính năng này, bạn có thể tạo một tệp như 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
    

Trong cả hai trường hợp, bạn có thể chạy systemctl [start|stop|restart] publicapi.servicenhư người dùng techopsmà không cần cung cấp mật khẩu. Trong trường hợp sau (polkit <= 0.105), người dùng techopscó thể điều khiển bất kỳ đơn vị systemd nào.


Tùy chọn thứ ba sẽ làm cho dịch vụ trở thành dịch vụ người dùng, không cần sudohoặc polkitcấu hình. Điều này đặt mọi thứ dưới sự kiểm soát của người dùng và chỉ hoạt động nếu dịch vụ thực tế của bạn được bắt đầu có /home/techops/publicapi startthể chạy mà không có rootđặc quyền.

Trước tiên, bạn phải kích hoạt kéo dài cho người dùng techops. Điều này là cần thiết để khởi động dịch vụ người dùng khi khởi động. Khi rootthực hiện:

loginctl enable-linger techops

Tiếp theo bạn phải di chuyển systemdtệp đơn vị vào techopsthư mục người dùng. Khi người dùng techopsthực hiện các lệnh như sau.

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

Lưu ý rằng WantedByphải có default.targetnhư multi-user.targettrong không có bối cảnh người dùng.

Bây giờ tải lại cấu hình và kích hoạt dịch vụ. Một lần nữa khi người dùng techopsthực hiện các lệnh.

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

Nói chung, bạn nên đặt các đơn vị systemd của bạn /etc/systemd/system/không trực tiếp trong /etc/systemd/system/multi-user.target.wants. Khi bạn thực hiện systemctl enable publicapi.servicemột liên kết tượng trưng sẽ được tạo trong etc/systemd/system/multi-user.target.wantshoặc bất kỳ mục tiêu nào được chỉ định cho đơn vị đó.

Như đã đề cập, nếu bản thân dịch vụ / quy trình có thể được chạy mà không có quyền root, bạn nên xem xét thêm User=techopsvào tệp đơn vị của mình để chạy quy trình với tài khoản người dùng không có đặc quyền.


Rất tốt. Bạn thậm chí đã nghĩ về mục tiêu WantedBy khác nhau cho các đơn vị người dùng. Rõ ràng, đây không phải là tệp đơn vị đầu tiên bạn đã viết :-)
PerlDuck

Xe tăng @PerlDuck. = 0)
Thomas

Cảm ơn vì đã trả lời. Điều này một phần trả lời câu hỏi của tôi, nhưng tôi vẫn có vấn đề ban đầu của tôi. (Tôi đã cập nhật câu hỏi)
Bevor

Xin lỗi, vì đã .pklakhông làm việc. Điều này cần một [section]mục. Cập nhật câu trả lời.
Thomas

5

Trước hết, bạn không đặt một tập tin đơn vị trong thư mục /etc/systemd/system/multi-user.target.wants. Thư mục này được duy trì bởi systemdvà các systemctllệnh. Đặt tệp đơn vị /etc/systemd/systemthay thế và sau đó kích hoạt nó với

sudo systemctl enable publicapi.service

Điều này sẽ tạo ra một liên kết tượng trưng bên dưới multi-user.target.wants(hoặc bất cứ nơi nào, systemctlbiết rõ hơn) để tôn vinh các dòng

[Install]
WantedBy=multi-user.target

trong đơn vị.

Tiếp theo, tạo một sudoerstập tin dưới đây /etc/sudoers.d:

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

với nội dung sau:

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

Không sử dụng trìnhsudo vim /etc/sudoers.d/techops chỉnh sửa thông thường (ví dụ ) để chỉnh sửa tệp đó vì nếu bạn đặt bất kỳ lỗi cú pháp nào trong đó, bạn sẽ không thể chạy sudolại. visudomặt khác kiểm tra cú pháp của tập tin trước khi rời khỏi trình chỉnh sửa.

Bây giờ người dùng techopscó thể chạy

sudo systemctl start publicapi.service

và hai cái còn lại mà không cung cấp mật khẩu. Lưu ý rằng bạn phải nhập lệnh và tham số chính xác như được đưa ra trong sudoerstệp (ngoại trừ /bin/systemctlphần có thể rút ngắn thành chỉ systemctl).

Chẳng hạn, sudo /bin/systemctl start publicapi(không có .service) sẽ yêu cầu nhập mật khẩu.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.