특정 사용자로만 시스템 서비스를 다시 시작하시겠습니까?

특정 사용자로만 시스템 서비스를 다시 시작하시겠습니까?

기본적으로 작동하는 일부 시스템 서비스를 만들었습니다.

장소:

/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 오후 4시 40분
포괄적인 답변을 주신 Thomas와 Perlduck에게 감사드립니다. systemd에 대한 지식을 향상시키는 데 도움이 되었습니다.

비밀번호 프롬프트 없이 서비스를 시작하는 관행에 따라 실제 문제를 충분히 강조하지 못한 점 사과드립니다.

사실 저에게 가장 중요한 것은 테크옵스 외에 다른 사용자가 서비스를 중지하거나 시작해서는 안 된다는 것입니다. 그러나 적어도 처음 두 가지 방법을 사용하면 여전히 실행 service publicapi stop하고 다시 메시지를 받을 수 있습니다 ==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===. 기본 사용자를 선택하고 비밀번호를 알면 모든 서비스를 중지할 수 있습니다.이 사용자가 비밀번호를 알고 있더라도 이 작업을 수행하는 것을 거부하고 싶습니다.. 이것이 나에게 더 중요한 이유를 더 잘 이해하기 위한 중요한 배경 정보:
defaultuser는 ssh에 노출된 유일한 사용자이지만 해당 사용자는 다른 작업을 수행할 수 없습니다(다른 사용자의 비밀번호를 가지고 있거나 다른 사용자로 변경하지 않는 한). 그러나 이때 그는 서비스를 시작하거나 중지할 수 있지만 사용자는 그렇게 할 수 없습니다.
누군가 defaultuser의 비밀번호를 알고 ssh를 통해 로그인하면 이때 모든 서비스를 중지할 수 있습니다. 이것이 바로 "기술자만이 서비스를 다시 시작할 수 있기를 바랍니다"라는 의미입니다. 죄송합니다. 원래 질문이 정확하지 않았습니다. 나는 sudoing techops 사용자가 이 문제를 해결할 수 있을 것이라고 생각했지만 그렇지 않습니다. 문제 자체는 암호 프롬프트 없이 명령을 실행하지 않는 것입니다. (실행할 때 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 사용자의 비밀번호 프롬프트를 우회하는 데 어느 정도 도움이 되지만 defaultuser를 실행하거나 사용할 때 service publicapi stop비밀번호 systemctl stop publicapi 가 있으면 서비스를 중지할 수 있습니다. 하지만 내 목표는 기본 사용자가 서비스를 시작하거나 중지하는 것을 완전히 방지하는 것입니다.

답변1

techops사용자가 비밀번호를 제공하지 않고 서비스를 제어할 수 있도록 하는 방법 에는 여러 가지가 있습니다. publicapi.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

두 번째 방법은 다음과 같습니다.폴킷(이름을 다음으로 바꿉니다.정책 툴킷) 사용자가 서비스를 techops제어할 수 있도록 합니다 . systemd버전에 따라 polit일반 사용자가 시스템 장치를 제어하도록 할 수 있습니다.
확인이 필요하다폴킷버전이면 그냥 실행하세요 pkaction --version.

  • 그리고폴킷 버전 0.106 이상, 사용자가 특정 시스템 단위를 제어하도록 허용할 수 있습니다.
    이를 위해 규칙을 생성할 수 있습니다 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 이하: 사용자가 시스템 단위를 제어하도록 허용할 수 있습니다. 불행하게도 여기에는 원하지 않는 모든 시스템 단위가 포함됩니다. 버전 0.105 이하의 특정 시스템 단위에 대한 액세스를 제한하는 방법이 있는지 확실하지 않지만 다른 사람이 명확히 할 수 있습니다.
    이 기능을 활성화하려면 다음과 같이 파일을 생성하면 됩니다 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모든 시스템 장치를 제어할 수 있습니다.


세 번째 옵션은 서비스를 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

앞서 언급했듯이 서비스/프로세스 자체가 루트 권한 없이 실행될 수 있다면 User=techops권한이 없는 사용자 계정을 사용하여 프로세스를 실행하도록 유닛 파일에 추가하는 것을 고려해야 합니다.

답변2

첫째, 유닛 파일을 디렉토리에 넣지 마십시오 /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

나머지 두 개는 비밀번호를 제공하지 않습니다. 파일에 제공된 대로 명령과 인수를 정확하게 입력해야 합니다( sudoers축약된 부분 제외)./bin/systemctlsystemctl

예를 들어 sudo /bin/systemctl start publicapi(none .service)은 비밀번호를 묻습니다.

관련 정보