Usar o CmndAlias ALLnunca será seguro
Existem 1000 maneiras de executar service network restartsem fazer sudo service network restart. Aqui está um exemplo do que um usuário malcriado pode tentar:
$ echo "service network restart" > /tmp/hax
$ chmod a+x /tmp/hax
$ sudo /tmp/hax
Se você fornecer aos usuários o ALLalias de comando e tentar criar uma lista negra, eles sempre poderão encontrar uma maneira de contorná-la. Blacklist bash, e eles usarão python. Lista negra de python e eles usarão o Perl. Blacklist Perl, e eles usarão PHP. Ninguém quer isso!
Se você realmente não quer que alguém faça alguma coisa, você deve fazer como Thomas diz, e criar uma lista branca de coisas que eles estão autorizados a fazer.
Configurando uma lista branca com uma exceção
Um exemplo de uma pequena lista branca com uma exclusão pode ser encontrada na parte inferior de man sudoers:
pete HPPA = /usr/bin/passwd [A-Za-z]*, !/usr/bin/passwd root
The user pete is allowed to change anyone's password except for root on the HPPA
machines. Note that this assumes passwd(1) does not take multiple user names
on the command line.
(De fato, este exemplo da página de manual não é seguro e pode ser explorado para alterar a senha do root! Veja os comentários abaixo para saber como.)
Podemos tentar adaptar isso ao seu caso, para oferecer todos os servicecomandos ao grupo de funcionários, mas excluir os service networkcomandos que lhe dizem respeito:
%staff ALL = /usr/sbin/service *, \
! /usr/sbin/service *network*, \
! /usr/sbin/service *NetworkManager*
(O ALLnessa posição refere-se ao Host_Alias, não ao Cmnd_Alias - confuso, não é?)
O usuário não poderá executar sudo bashou sudo teeou sudo wgetou sudo /path/to/malicious_script. Você pode colocar na lista branca mais comandos de administração para seus usuários, se você for cuidadoso. Seja específico!
Nota: eu adicionei a *palavra networkanterior antes, caso uma bandeira inofensiva seja adicionada à serviceferramenta no futuro. Vamos imaginar que um --verbosesinalizador foi adicionado no futuro, então os usuários poderão executar o seguinte:
$ sudo service --verbose network restart
Portanto, precisamos *consumir qualquer sinalizador antes do nome do serviço. A única desvantagem é que isso pode bloquear outros serviços dos quais você não se importa de executar, por exemplo, um serviço chamado safe-networkou network-monitorque também seria rejeitado.
Permitir que os usuários editem um arquivo usando permissões de grupo
Abaixo, você pode encontrar várias tentativas utilizando rnanomeio sudopara permitir aos usuários editar um arquivo ou arquivos. Mas, na verdade, eles são mais complexos e mais perigosos do que deveriam ser.
Uma solução muito mais simples e segura é alterar as permissões de grupo nos arquivos específicos para os quais você deseja abrir os direitos de edição. Aqui estão alguns exemplos:
### Give steve the ability to edit his nginx config:
$ chgrp steve /etc/nginx/sites-available/steves_dodgy_project
$ chmod g+rw /etc/nginx/sites-available/steves_dodgy_project
### Let all members of the staff group edit the group_website config:
$ chgrp staff /etc/nginx/sites-available/group_website
$ chmod g+rw /etc/nginx/sites-available/group_website
Se você precisar de um controle mais refinado (por exemplo: acesso para apenas 3 usuários, mas não todos os membros da equipe), poderá criar um novo grupo usando o addgroupcomando e adicionar apenas alguns usuários.
Permita que os usuários editem um arquivo através de sudo
O restante desta resposta tornou-se uma investigação sobre como é fácil deixar buracos na sua sudoconfiguração ao tentar oferecer flexibilidade aos seus usuários. Eu não recomendaria fazer o seguinte!
Se você deseja conceder aos usuários acesso para editar um arquivo específico, tente usar rnano:
%staff ALL = /bin/rnano /etc/nginx/sites-available/host
rnanosó permitirá que eles editem o arquivo especificado. Isso é importante para impedir que um usuário mal-intencionado edite um serviço diferente (por exemplo /etc/init.d/urandom) e adicione uma linha a ele que seria executada service network restart.
Infelizmente, não encontrei uma maneira de restringir o rvimsuficiente (o usuário ainda pode abrir qualquer arquivo usando :e), por isso estamos presos nano.
Infelizmente, permitir que os usuários editem vários arquivos é muito mais difícil ...
Permita que os usuários editem vários arquivos (muito mais difícil do que deveria ser)
1. Abordagens inseguras
Cuidado com curingas! Se você oferecer muita flexibilidade (ou qualquer flexibilidade), ela poderá ser explorada:
%staff ALL = /bin/rnano /etc/nginx/sites-available/* # UNSAFE!
Nesse caso, um usuário mal-intencionado poderá editar qualquer outro script de serviço inicial e executá-lo:
$ sudo rnano /etc/nginx/sites-available/../../../any/file/on/the/system
(Na verdade, o Sudo impede .e ..amplia o comando, mas infelizmente não os argumentos.)
Eu esperava que algo assim pudesse funcionar, mas ainda é inseguro:
%staff ALL = /bin/rnano /etc/nginx/sites-available/[A-Za-z0-9_-]* # UNSAFE!
Como sudoatualmente oferece apenas padrões glob , isso *corresponderá a qualquer coisa - não é uma expressão regular!
(Edit: Eu considerei se você poderia se dar bem com o acima exposto na sua situação, porque não há subpastas abaixo sites-available. Exigimos que um caracter seja correspondido após a pasta e /..deve falhar após um nome de arquivo. No entanto, este não é um solução viável, porque rnanoaceita vários argumentos. E, de qualquer maneira, isso ainda seria inseguro em uma pasta que tinha subpastas!)
Mesmo se não tivermos subpastas e excluirmos quaisquer linhas que contenham /../, a regra que oferece uma *glob ainda poderá ser explorada, porque rnanoaceita vários argumentos (alternando entre eles <C-X>e o espaço é aceito com prazer pela *glob.
$ rnano /etc/nginx/sites-available/legal_file /then/any/file/on/the/system
2. Empurrar o envelope (também inseguro)
E se rejeitarmos qualquer linha que contenha espaços ou tentarmos alcançá-lo /..? Em seguida, uma solução final viável pode ser a seguinte:
# I tried hard to make this safe, but in the end I failed again.
# Please don't use this unless you are really smart or really stupid.
%staff ALL = /bin/rnano /etc/nginx/sites-available/*, \
! /bin/rnano */..*, \
! /bin/rnano /etc/nginx/sites-available/, \
! /bin/rnano */., \
! /bin/rnano * *
# CONCLUSION: It is still NOT SAFE if there are any subfolders, due to
# the bug in rnano described below.
Aceitamos qualquer coisa "embaixo" da pasta, mas também rejeitamos qualquer chamada para rnanose /..ou /.ou somos passadas, ou se a pasta é direcionada diretamente. (Tecnicamente, a /.exclusão torna a /..exclusão redundante, mas deixei os dois por uma questão de clareza.)
Encontrei a pasta e as /.exclusões eram necessárias porque, caso contrário, o usuário poderia segmentar a própria pasta. Agora você pode pensar rnanoem bloquear se apontado para uma pasta, mas você estaria errado. Na verdade, minha versão (2.2.6-1ubuntu1) inicia com um aviso moderado e um arquivo vazio; depois, <C-X>solicita que eu insira qualquer nome de arquivo que eu gostaria de salvar, abrindo um novo vetor de ataque! Bem, pelo menos, se recusou a substituir um arquivo existente (no teste que eu fiz). De qualquer forma, como não há como colocar as subpastas na lista negra com o sudo, devemos concluir que essa abordagem é novamente insegura. Desculpe usuários!
Essa descoberta me fez duvidar da minuciosidade do nanomodo "restrito" de. Eles dizem que uma corrente é tão forte quanto seu elo mais fraco. Estou começando a sentir a combinação da sudomagia negra da lista negra e rnanopode não ser mais seguro do que uma cadeia de margaridas.
3. Abordagens seguras, mas limitadas
Os globos são muito restritos - eles não nos permitem combinar uma classe de personagem várias vezes. Você pode oferecer várias edições de arquivo, se todos os seus nomes de arquivos tiverem o mesmo tamanho (nesse caso, hostseguido por um único dígito):
%staff ALL = /bin/rnano /etc/nginx/sites-available/host[0-9] # SAFE
Mas se você deseja conceder ao usuário acesso para editar vários arquivos, pode ser necessário especificar explicitamente cada arquivo:
%staff ALL = /bin/rnano /etc/nginx/sites-available/hothost \
/bin/rnano /etc/nginx/sites-available/coldhost \ # SAFE
/bin/rnano /etc/nginx/sites-available/wethost \
/bin/rnano /etc/nginx/sites-available/steves_dodgy_project
Não fique tentado a usar um*a qualquer momento. Consulte as seções 1. e 2. acima para saber o porquê! Lembre-se: um pequeno deslize pode comprometer toda a conta do superusuário e todo o sistema.
4. Escreva seu próprio verificador de argumentos (a segurança agora é de sua responsabilidade)
Espero que eles adicionem suporte a regexp sudono futuro; poderia resolver muitos problemas se usado corretamente. Mas também podemos precisar da capacidade de verificar as propriedades dos argumentos (para permitir apenas arquivos, apenas pastas ou apenas determinados sinalizadores).
Mas há uma alternativa para criar flexibilidade no sudo. Passar a bola:
%staff ALL = /root/bin/staffedit *
Em seguida, escreva seu próprio staffeditscript ou executável para verificar se os argumentos transmitidos pelo usuário são legais e somente execute a solicitação se forem.
networkingenetwork-manager? Além disso, por que seus usuários têmsudoacesso? Eles não devem, a menos que você queira que eles tenham privilégios de root completo.