Como executar o serviço init.d no systemd sem autenticação root (atualizado)

5

Minha empresa configurou alguns softwares que desenvolve para executar como um serviço usando o init.d em uma versão mais antiga do SLES. Recentemente, criamos a criação de um novo ambiente em uma instância do SLES 12 no EC2 da Amazon e descobrimos que o SLES 12 agora usa o systemd em vez do init.d. No entanto, parece que os serviços definidos nos scripts init.d (ou seja, em /etc/init.d) ainda podem ser iniciados normalmente porque o systemd executa alguma mágica em segundo plano para lidar com scripts init.d pré-existentes, o que é ótimo. / p>

No entanto, não queremos executar nosso serviço como o usuário raiz. Em vez disso, criamos um novo usuário para executar nosso serviço. O problema é que, quando tentamos iniciar nosso serviço como usuário não-root, o que quer que o systemd faça para se preparar para executar uma autenticação de raiz de solicitações de serviço init.d antigo que não achamos que deva ser necessária. No ambiente SLES mais antigo (usando o init.d atual) podemos iniciar o serviço como o usuário não root sem problemas. Tanto quanto eu posso dizer que nossas permissões de usuário não root e propriedades de arquivo são as mesmas em ambos os ambientes.

A razão pela qual eu acho que isso está no manuseio por baixo do material initd antigo do systemd é que o script para iniciar nosso serviço ecoa uma linha de texto imediatamente antes do comando real para iniciar / parar o serviço, mas essa linha não é produzida, ou seja, estamos sendo solicitados para a autenticação root antes da instrução echo. A autenticação é necessária para um determinado pacote / módulo enterrado no systemd, mas não me lembro de seu nome no momento.

Observe que gostaríamos de evitar a criação de um arquivo .service específico do serviço para nosso serviço, se possível - queremos continuar com o script init.d que temos e apenas executá-lo como usuário não raiz. Além disso, gostaríamos de executar o serviço sem o uso de sudo (não precisamos de sudo no ambiente antigo).

Desculpas pela falta de detalhes nesta questão - atualizarei com detalhes mais específicos assim que eu voltar ao escritório e puder pegar os detalhes específicos etc. Isso parece ser um problema comum, então eu Espero que alguém possa esclarecer isso.

Especificamente: queremos executar um serviço definido com um script init.d antigo como um usuário não-root usando o systemd no SLES 12.

(atualização 1) O resultado exato de tentar executar nosso script /etc/init.d/my_service stop é:

/etc/init.d/my_service stop
redirecting to systemctl stop electrum-gateway-main.service
==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units === Authentication is required to stop 'my_service.service'.
Authenticating as: root
Password:

O serviço não estava em exibição quando tentamos interrompê-lo, mas isso não é relevante para o problema de autenticação.

Eu fiz um pouco mais de digitação em nosso script e o script atinge a seguinte linha antes de pedir autorização:

. /etc/rc.status

Então é aí que está o problema. Alguém precisa de privilégios de root para chamar o /etc/rc.status?

    
por user5860663 16.11.2016 / 06:34

2 respostas

6

No systemd (e em outros sistemas init modernos), a inicialização do serviço é estritamente separada em duas etapas:

  1. Ferramentas do usuário (por exemplo, systemctl) solicitam remotamente ao init (pid 1) para iniciar um serviço específico.
  2. O Init lê a configuração do serviço, configura o ambiente (incluindo alternar para a conta de usuário desejada) e executa o executável.

Devido a essa indireção, os serviços sempre terão o mesmo ambiente, independentemente de quem e como eles foram iniciados. (Anteriormente, o ambiente do usuário como contexto de localidade, caminho ou SELinux vazando em serviços costumava ser um problema comum.)

(Para scripts init.d, o arquivo lsb-functions da distribuição contém os redirecionamentos mágicos para 'systemctl start', então eles também recebem a mesma indirecção.)

Isso também significa que você não pode iniciar um serviço "como o mesmo usuário" - você deve configurar um nome de usuário específico no arquivo systemd .service relevante (e se não houver nenhum, você deve escrever) um).

A chamada de 'start service' é normalmente privilegiada, mas você pode escrever uma regra de polkit que permita por usuário ou por serviço (se a versão do systemd for recente o suficiente):

/* /etc/polkit-1/rules.d/allow-whatever.rules */

polkit.addRule(function(action, subject) {
    if (action.id == "org.freedesktop.systemd1.manage-units") {
        var verb = action.lookup("verb");
        var unit = action.lookup("unit");
        if (subject.user == "manager"
            && unit == "app.service"
            && (verb == "start" || verb == "stop" || verb == "restart"))
        {
            return polkit.Result.YES;
        }
    }
});

Como alternativa, pode ser possível desativar a indireção no script init.d, mas você também perderá o rastreamento do serviço do systemd completamente - seu daemon parecerá um processo normal do usuário.

    
por 16.11.2016 / 09:12
0

A execução de seus serviços como usuário não raiz é uma boa ideia. Além da sugestão do Polkit na outra resposta, há algumas maneiras mais convencionais de iniciar um serviço não como root:

  1. Use o sudo . Uma regra sudo pode permitir que um usuário específico execute os comandos start e restart para um determinado serviço, mas não execute ações como raiz, fornecendo o mesmo tipo de privilégio limitado.
  2. Use o modo user systemd . O systemd oferece aos usuários a capacidade de gerenciar serviços sob o controle do usuário com uma instância systemd por usuário, permitindo que os usuários iniciem, interrompam, ativem e desativem suas próprias unidades.

Acho que o modo de usuário systemd pode existir mais com os casos de uso de desktop em mente. Para um servidor, recomendo permitir usar a solução sudo . No arquivo systemd .service , você também pode definir a diretiva User= para especificar o usuário que o serviço executa como - possível o mesmo usuário em que você foi capaz de iniciá-lo.

A solução "polkit" é uma solução de ação à distância - parece difícil perceber o que permite ao usuário iniciar o serviço. No entanto, com sudo você está chamando claramente de chamar sudo e com systemd user mode , você está usando esse recurso claramente.

Se eu fosse um ambiente em que a solução Polkit estivesse configurada, eu não teria nenhuma pista para descobrir por que iniciar o serviço estava funcionando, a menos que um colega de trabalho deixasse alguma documentação sobre isso.

    
por 16.11.2016 / 16:19