Não é possível obter o serviço upstart para honrar as capacidades (7)

1

Estou desenvolvendo um daemon iniciado por upstart (Ubuntu 14.04) que precisa ser executado como um usuário não privilegiado (por segurança), mas vincule a porta 443 com privilégios.

Estou usando setcap para definir o recurso CAP_NET_BIND_SERVICE para o executável (não é um script). Estou configurando-o em conjuntos Permitted, Effective e Inherited ( setcap 'cap_net_bind_service+eip' EXEC ).

Eu posso su para o usuário não privilegiado e executá-lo diretamente, e ele funciona perfeitamente. Ele vincula corretamente a porta e /proc/PID/status mostra as máscaras de recursos adequadas com 0x400 bit set.

Mas quando inicio o serviço por meio de upstart , ele não é executado com os recursos especificados para o binário e o bind() falha ( EPERM ). /proc/PID/status mostra que as máscaras de recursos são todas 0.

Alguma idéia?

    
por BobDoolittle 04.08.2014 / 21:38

2 respostas

1

Agora estou pensando que isso é um bug e relacionado à maneira como o upstart inicia serviços com "expect daemon" (ou seja, serviços que são bifurcados duas vezes na inicialização). Percebo que, se eu usar strace em um processo que está usando recursos (7), os recursos também serão ignorados. Eu suspeito que o upstart, a fim de determinar o PID para esperar, rastreia um serviço especificado com "esperar daemon" tempo suficiente para obter o PID, e isso está causando o mecanismo de capacidades do kernel para falhar. Portanto, o bug está no modo como os recursos interagem com o rastreio do processo e o fato de que o upstart usa o rastreio do processo ao iniciar um serviço com o "espere daemon" (isso é suposição).

Como um teste simples:

  1. Escreva um pequeno C PROGRAM para ligar à porta 443 (você não pode usar uma linguagem interpretada como python com recursos (7)).
  2. Execute-o como não-raiz e veja se ele não é vinculado devido à falta de privilégio.
  3. Defina o recurso CAP_NET_BIND_SERVICE para seu PROGRAM (como a execução raiz setcap 'cap_net_bind_service+epi' PROGRAM )
  4. Execute como não-raiz e veja que agora é bem-sucedido.
  5. Agora, execute-o com strace e veja que agora ele falha.

(observe que na etapa 3, estritamente falando, o conjunto de recursos herdados ( i flag) não precisa ser modificado para este teste, mas para um processo que forks() , como meu daemon).

Vou registrar um bug contra o kernel sobre isso, já que nada na página do manual capabilities (7) diz que ele não deve funcionar com o rastreio do processo.

    
por 05.08.2014 / 15:34
1

Uma alternativa é não usar o fork expect ou expect, e apenas tornar seu daemon em um processo em primeiro plano. Então o Upstart não irá rastreá-lo.

    
por 07.08.2014 / 01:28