Método adequado para adquirir acesso root nos aplicativos Linux for Qt

Dia bom

Fundo:

Estou criando um aplicativo de wrapper OpenVPN para sistemas Linux que está quase completo. Eu encontrei um pequeno problema.

O OpenVPN requer acesso root para modificar tabelas de roteamento (adicionar e remover rotas). Aqui é onde as coisas ficam um pouco vagas e confusas.

Felizmente, estendendoessa questão, algumas respostas e soluções padrão do setor podem ser compartilhadas.

Documentação:

Então, depois de várias horas pesquisando, compilei uma lista de métodos possíveis para obter acesso root, no entanto nenhum parece ser oficial nem nenhuma orientação realmente sólida fornecida para adquirir esse privilégio de SU.

Vamos considerar os seguintes métodos.

1. Usando pkexec e polkits

Por favor, encontre oficialdocumentação do freedesktop polkit aqui eaqui para obter algumas informações sobre práticas recomendadas

Existem alguns tutoriais encontrados on-line usando pkexec e polkits -aqui, isso me ajudou a criar meu arquivo polkit. -Tópico SO - e umadorável pequeno tutorial para aplicativos Qt

Para dar uma breve explicação (do meu entendimento) sobrepkexec epolkits:

polkits:

polkits consistem em ações e regras (consulte a documentação para uma leitura e explicação mais aprofundadas). Ele define ações de um aplicativo e as regras associadas a ele. As regras podem ser definidas como um usuário pertencente a um grupo específico, pelo qual a ação consulta a regra, conseguiu passar a regra, o usuário é autenticado automaticamente (sem solicitação de senha pop-up), caso contrário, é necessário que você entre com um administrador senha

pkexec:

um aplicativo usado para interagir com as ações do polkit e autenticar um aplicativo para adquirir acesso root.

Isso requer a adição de uma ação ao/usr/share/polkit-1/actions/ e/usr/share/polkit-1/rules.d/ (entre outros diretórios, consulte a documentação para todos os locais)

Este método parece ser bem usado (mas requer um pouco mais de explicação para ser entendido facilmente, imo)

nota: existemqt-polkit bibliotecas disponibilizadas para uso, consulte seusrepositório github

Para uma versão simples TL; DR, consulteesta

O arquivo polkit que eu criei (observe que isso pode não estar correto, mas funciona para mim):

Local onde pode ser encontrado / adicionado (também existem outros)

/usr/share/polkit-1/actions

Nome do arquivo do Policy Kit: com.myappname.something.policy // the.policy É necessário

Nota:

com.myappname.something

é referenciado como o espaço para nome da política (lendo a documentação, isso não ficará claro)

Conteúdo do Kit de Políticas

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE policyconfig PUBLIC "-//freedesktop//DTD polkit Policy Configuration 1.0//EN"
"http://www.freedesktop.org/software/polkit/policyconfig-1.dtd">
<policyconfig>
  <vendor>My App Name</vendor>
  <vendor_url>http://myappurl.com/</vendor_url>

  <action id="com.myappname.something.myaction-name">
    <description>Run the polkit for My App which requires it for X usage</description>
    <message>My App requires access to X, which requires root authentication, please let me have su access</message>
    <icon_name>myappname</icon_name>
    <defaults>
      <allow_any>auth_admin_keep</allow_any>
      <allow_inactive>auth_admin_keep</allow_inactive>
      <allow_active>auth_admin_keep</allow_active>
    </defaults>
    <annotate key="org.freedesktop.policykit.exec.path">/usr/bin/myappname</annotate>
    <annotate key="org.freedesktop.policykit.exec.allow_gui">true</annotate>
  </action>

</policyconfig>

Notas sobre o meu arquivo de políticas (os bits importantes)

Este é apenas um exemplo, consulte a documentação para exemplos e descrições oficiais:<vendor>My App Name</vendor> é o nome do aplicativo, ele pode ter espaços

<action id="com.myappname.something.myaction-name"> qualquer nome de ação aqui.

NOTA! O nome do arquivo ->com.myappname.something.policy e aaction id ->com.myappname.something.myaction-name deve ter o mesmo espaço para nome

O nome do ícone deve estar de acordo com as últimas especificações do ícone freedesktop encontradasaqui

TL; DR (ou não deseja): os locais dos ícones são:

 1. /home/yourusername/.icons (sometimes not there)
 2. /home/yourusername/.local/share/icons
 2. /usr/share/icons

desde que estejam em conformidade com os tamanhos e sejam.png, você pode passar apenas o nome do arquivo (omitindo o formato)

Very Important:

<annotate key="org.freedesktop.policykit.exec.path">/usr/bin/myappname</annotate>
<annotate key="org.freedesktop.policykit.exec.allow_gui">true</annotate>

Ao ligarpkexec <myappname>, e NÃO tendo essas linhas(Sinceramente, não tenho certeza do propósito deles), ocorrerá um erro semelhante a este:

2017-12-19 12::58:24 Fatal: QXcbConnection: Could not connect to display  ((null):0, (null))

Aborted (core dumped)

Nota: mantenha okey o mesmo, no entanto, você pode e provavelmente deve alterar oexec.path chave para o local do seu aplicativo.

Como os kits de políticas funcionam?

Em suma, se você rever a adorávelexemplo mencionado anteriormente (e pule todos os nomes de arquivos muito semelhantes), fica claro.

Quando alguém roda:

pkexec <myappname> 

isso chama o agente de autenticação local para executar o aplicativo (no nosso caso) como root.

Isso é tratado peloactions (o kit de políticas mencionado acima). Além disso, as regras utilizam oaction id para executar consultas adicionais, etc., que podem ser visualizadas nos exemplos fornecidos acima.

Depois que a senha do administrador for inserida, dependendo das 'configurações' inseridas nos padrões (consulteaqui), temos:

auth_admin_keep

Como auth_admin, mas a autorização é mantida por um breve período (por exemplo, cinco minutos).

Assim, o usuário pode (no meu aplicativo OpenVPN) conectar-se a uma conexão OpenVPN pelos próximos 5 minutos, até que a senha seja solicitada novamente.

2)Sudo (/ etc / sudoers):

Esse parece ser o método go to para a maioria dos usuários que exigiram acesso root, no entanto, não é recomendado:

por exemplo. Verifique o acesso root antes de executar o aplicativo principal chamando um singleShotQProcess com argumentos:

/bin/sh -c sudo -v

resultará no código de saída de1 em várias distribuições Linux (fazendo com que eu busque alternativas)

3. setuid ():

Um muito bomexemplo pode ser encontrado aqui, infelizmente, não parece funcionar nas distros modernas do Linux, por ser uma brecha na segurança que pode ser facilmente explorada.

Em suma, o processo requer um para:

chmod +x <executable>

e verificando se os bit é definido no aplicativo usandogetuid() para obter o ID do usuário egetgid() para obter o ID do grupo do usuário.

Essas funções podem ser encontradas nos cabeçalhos do Linux definidos por:

<sys/types.h> // defines structs
<unistd.h>    // defines methods

No entanto, isso não parece funcionar com os sistemas Linux modernos. Aqui está a saída da execução de um aplicativo de propriedade raiz com os conjunto de bits, execute como um usuário normal (sem privilégios):

2017-12-19 12::21:08 Fatal: FATAL: The application binary appears to be running setuid, this is a security hole. ((null):0, (null))

Aborted (core dumped)

Despedida,setuid()

4. Outros métodos:

PAM

para ler mais, consulte

página de manualtutorial / explicação

A Fórum QT pergunta sobre a integração entre plataformas do PAM

QT usermode Qt fornece umapequena implementação para adquirir acesso root, mas está disponível apenas para distribuições Linux usandoyum gerenciador de pacotes.

Uma pergunta seguida sobre isso, consulteesta pergunta do fórum QT

Problema:

Acima, podem incluir apenas uma pequena parte dos métodos disponíveis para adquirir acesso root, no entanto, considerando que alguns aplicativos são usados globalmente, eles geralmente são atacados ou separados ou até comprometidos.

Depois de fazer essa pesquisa, ele ampliou meus conhecimentos, mas não me deu um método seguro, recomendado, mas apenas sugestões.

Pergunta, questão:

Qual método acima é preferido na indústria, ou seja, quando devo usar um sobre o outro (PAM vs polkits vs simple sudo) e se houver outros métodos disponíveis, eles são preferidos?

questionAnswers(2)

yourAnswerToTheQuestion