systemd: Concede uma permissão de usuário sem privilégios para alterar um serviço específico

11

Eu estou executando um servidor de jogo privado em uma caixa de Linux sem cabeça. Porque eu não sou um idiota, disse que o servidor está sendo executado como seu próprio usuário sem privilégios, com os mínimos direitos de acesso necessários para baixar atualizações e modificar o banco de dados mundial.

Eu também criei um arquivo de unidade systemd para iniciar, parar e reiniciar corretamente o servidor quando necessário (para as atualizações mencionadas, por exemplo).

No entanto, para realmente chamar systemctl ou service <game> start/stop/restart , ainda preciso fazer login como usuário root ou com capacidade para sudo .

Existe uma maneira de dizer ao systemd que, para o serviço <game> , o usuário sem privilégios gamesrv tem permissão para executar os comandos start / stop / restart?

    
por Shadur 28.03.2017 / 19:24

3 respostas

21

Posso pensar em duas maneiras de fazer isso:

Uma é tornando o serviço um serviço de usuário em vez de um serviço de sistema.

Em vez de criar uma unidade do sistema, a unidade do systemd será colocada no diretório inicial do usuário do serviço, em $HOME/.config/systemd/user/daemon-name.service . O mesmo usuário pode então gerenciar o serviço com systemctl --user <action> daemon-name.service .

Para permitir que a unidade de usuário inicie na inicialização , a raiz deve ativar o linger da conta, ou seja, sudo loginctl enable-linger username . A unidade também deve ser WantedBy=default.target .

A outra maneira é permitir que o usuário acesse para gerenciar a unidade do sistema via PolicyKit. Isso requer o systemd 226 ou superior (e PolicyKit > = 0.106 para os arquivos JavaScript rules.d - verifique com pkaction --version ).

Você criaria um novo arquivo de configuração do PolicyKit, por exemplo, /etc/polkit-1/rules.d/57-manage-daemon-name.rules , que verifica os atributos que você deseja permitir. Para exemplo :

// Allow alice to manage example.service;
// fall back to implicit authorization otherwise.
polkit.addRule(function(action, subject) {
    if (action.id == "org.freedesktop.systemd1.manage-units" &&
        action.lookup("unit") == "example.service" &&
        subject.user == "alice") {
        return polkit.Result.YES;
    }
});

O usuário nomeado pode então gerenciar o serviço nomeado com systemctl e sem usar sudo .

    
por 29.03.2017 / 00:07
8

sudo é feito para isso. Edite seu arquivo /etc/sudoers com visudo para adicionar Cmd_alias para os comandos que você deseja que o usuário sem privilégios possa usar:

# game server commands
Cmnd_Alias GAME_CMDS = /usr/bin/systemctl start <game service>, /usr/bin/systemctl stop <game service>

e adicione uma linha para permitir que o usuário sem privilégios use os comandos definidos com o alias como este:

unprivileged_user ALL=(ALL) NOPASSWD: GAME_CMDS

Leia mais algumas documentação sobre o tópico para os vários parâmetros do comando sudo.

Pode ser necessário instalar o sudo package para ter sudo disponível no seu sistema.

    
por 28.03.2017 / 19:36
1

Você pode associar sudo ao fornecimento de acesso equivalente a root , mas também pode ser usado para permitir um acesso de usuário root específico para um conjunto específico e limitado de comandos.

Como isso já foi respondido no Server Fault, em [ acesso de um conjunto de comandos a um usuário não-root sem sudo) .

O uso do PolicyKit ainda é incomum. Usar um systemd "user unit" deve funcionar bem, mas historicamente seu objetivo foi atingido muitas vezes usando a capacidade de sudo permitir que um usuário execute comandos específicos como root.

    
por 29.03.2017 / 15:09