Použití CmndAlias ALL
nikdy nebude v bezpečí
Existuje 1000 způsobů, jak spustit service network restart
bez provedení sudo service network restart
. Zde je příklad toho, co může nezbedný uživatel zkusit:
$ echo "service network restart" > /tmp/hax
$ chmod a+x /tmp/hax
$ sudo /tmp/hax
Pokud uživatelům poskytnete ALL
alias příkazu a poté se pokuste vytvořit černou listinu, vždy budou moci najít způsob, jak to obejít. Blacklist bash a budou používat python. Blacklist python a budou používat Perl. Blacklist Perl a budou používat PHP. To nikdo nechce!
Pokud opravdu nechcete, aby někdo něco udělal, měli byste udělat to, co říká Thomas, a vytvořit seznam povolených věcí, které jsou povoleno.
Nastavení bílé listiny s výjimkou
Příklad malé bílé listiny s vyloučením lze nalézt v dolní části 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.
(Ve skutečnosti je tento příklad z manuálové stránky nebezpečný a lze jej zneužít ke změně hesla roota! Jak na to, viz níže uvedené komentáře.)
Můžeme se to pokusit přizpůsobit vašemu případu a nabídnout všech service
příkazy skupině zaměstnanců, ale vyloučit service network
příkazy, které se vás týkají:
%staff ALL = /usr/sbin/service *, \
! /usr/sbin/service *network*, \
! /usr/sbin/service *NetworkManager*
(ALL
v této pozici odkazuje na Host_Alias, nikoli Cmnd_Alias - matoucí, že?)
Uživatel nebude moci spustit sudo bash
nebo sudo tee
nebo sudo wget
nebo sudo /path/to/malicious_script
. Pokud budete opatrní, můžete pro své uživatele přidat na seznam povolených více příkazů správce. Buďte konkrétní!
Poznámka:Přidal jsem *
před slovo network
výše, pro případ, že by se do service
někdy přidal neškodný příznak nástroj v budoucnu. Představme si --verbose
příznak byl přidán v budoucnu, pak by uživatelé mohli spouštět následující:
$ sudo service --verbose network restart
Potřebujeme tedy *
spotřebovat všechny příznaky před názvem služby. Jedinou nevýhodou je, že to může blokovat další služby, u kterých vám ve skutečnosti nevadí, že uživatelé spouštějí, např. službu s názvem safe-network
nebo network-monitor
bude také odmítnut.
Umožněte uživatelům upravovat soubor pomocí skupinových oprávnění
Níže naleznete různé pokusy pomocí rnano
až sudo
aby uživatelé mohli upravovat soubor nebo soubory. Ale ve skutečnosti jsou složitější a nebezpečnější, než by měly být.
Mnohem jednodušším a bezpečnějším řešením je změnit skupinová oprávnění u konkrétních souborů, pro které chcete otevřít práva k úpravám. Zde je několik příkladů:
### 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
Pokud potřebujete podrobnější kontrolu (například:přístup pouze pro 3 uživatele, ale ne pro všechny zaměstnance), můžete vytvořit novou skupinu pomocí addgroup
a přidejte k němu jen několik uživatelů.
Umožněte uživatelům upravovat soubor pomocí sudo
Zbytek této odpovědi se stal zkoumáním toho, jak snadné je zanechat díry ve vašem sudo
konfiguraci při snaze nabídnout uživatelům flexibilitu. Nedoporučoval bych dělat nic z následujícího!
Pokud chcete svým uživatelům udělit přístup k úpravám konkrétního souboru, můžete zkusit použít rnano
:
%staff ALL = /bin/rnano /etc/nginx/sites-available/host
rnano
pouze jim umožní upravit zadaný soubor. To je důležité, aby uživatel se zlými úmysly nemohl upravovat jinou službu pro začínající uživatele (například /etc/init.d/urandom
) a přidat k němu řádek, který by běžel service network restart
.
Bohužel jsem nenašel způsob, jak omezit rvim
dostatečně (uživatel může stále otevřít libovolný soubor pomocí :e
), takže jsme uvízli u nano
.
Bohužel umožnit uživatelům upravovat více souborů je mnohem těžší...
Umožněte uživatelům upravovat více souborů (je to mnohem obtížnější, než by mělo být)
1. Nebezpečné přístupy
Dejte si pozor na zástupné znaky! Pokud nabízíte příliš velkou flexibilitu (nebo jakoukoli flexibilitu), lze ji zneužít:
%staff ALL = /bin/rnano /etc/nginx/sites-available/* # UNSAFE!
V tomto případě by uživatel se zlými úmysly mohl upravit jakýkoli jiný počáteční servisní skript a poté jej spustit:
$ sudo rnano /etc/nginx/sites-available/../../../any/file/on/the/system
(Sudo ve skutečnosti zabraňuje .
a ..
rozšíření na příkaz, ale bohužel ne na argumenty.)
Doufal jsem, že něco takového by mohlo fungovat, ale stále je to nejisté:
%staff ALL = /bin/rnano /etc/nginx/sites-available/[A-Za-z0-9_-]* # UNSAFE!
Od sudo
aktuálně nabízí pouze glob vzory, to *
bude odpovídat čemukoli - to není regulární výraz!
(Edit:Zvažoval jsem, zda můžete ve vaší situaci se vyhněte výše uvedenému, protože pod sites-available
nejsou žádné podsložky . Požadovali jsme, aby za složkou odpovídal jeden znak a /..
by měl selhat po názvu souboru. Toto však není funkční řešení, protože rnano
přijímá více argumentů. A obecně by to stále bylo nebezpečné ve složce, která měla podsložky!)
I když nemáme žádné podsložky a vyloučíme všechny řádky obsahující /../
, pravidlo nabízející *
glob může být stále zneužito, protože rnano
přijímá více argumentů (cyklicky mezi nimi na <C-X>
a prostor je šťastně akceptován *
glob.
$ rnano /etc/nginx/sites-available/legal_file /then/any/file/on/the/system
2. Tlačení obálky (také v konečném důsledku nebezpečné)
Co když odmítneme všechny řádky obsahující mezery nebo pokusy o dosažení /..
? Pak může být konečné funkční řešení toto:
# 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.
Přijímáme cokoli "pod" složkou, ale také odmítáme jakékoli volání na rnano
pokud /..
nebo /.
nebo jsou předány, nebo pokud je složka přímo zacílena. (Technicky
/.
vyloučení dělá /..
vyloučení je nadbytečné, ale kvůli přehlednosti jsem ponechal obojí.)
Našel jsem složku a /.
výjimky byly potřeba, protože jinak by uživatel mohl cílit na samotnou složku. Nyní si možná myslíte rnano
by se zablokoval, pokud by ukázal na složku, ale mýlili byste se. Moje verze (2.2.6-1ubuntu1) se ve skutečnosti spustí s mírným varováním a prázdným souborem, poté na <C-X>
požádá mě o zadání jakéhokoli souboru, který se mi líbí uložit do, otevření nového útočného vektoru! Alespoň to odmítlo přepsat existující soubor (v jednom testu, který jsem udělal). Každopádně, protože neexistuje způsob, jak zakázat podsložky pomocí sudo, musíme dojít k závěru, že tento přístup je opět nebezpečný. Omlouváme se uživatelům!
Tento objev mě přiměl pochybovat o důkladnosti nano
„omezený“ režim. Říká se, že řetěz je tak silný, jak silný je jeho nejslabší článek. Začínám cítit kombinaci sudo
blacklist black-magic a rnano
nemusí být o nic bezpečnější než řetěz sedmikrásek.
3. Bezpečné, ale omezené přístupy
Globy jsou velmi omezené – neumožňují nám vícenásobně odpovídat třídě postavy. Mohli byste nabídnout více úprav souborů, pokud mají všechny vaše názvy souborů stejnou délku (v tomto případě host
následovaná jednou číslicí):
%staff ALL = /bin/rnano /etc/nginx/sites-available/host[0-9] # SAFE
Pokud však chcete uživateli poskytnout přístup k úpravám různých souborů, možná budete muset každý soubor explicitně specifikovat:
%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
Nenechte se v pokušení použít *
v kterémkoli bodě. Proč, viz sekce 1. a 2. výše! Pamatujte:jeden malý skluz může ohrozit celý účet superuživatele a celý systém.
4. Napište si vlastní kontrolu argumentů (bezpečnost je nyní vaší zodpovědností)
Doufám, že do sudo
přidají podporu regulárních výrazů v budoucnu; při správném použití by mohl vyřešit spoustu problémů. Ale můžeme také potřebovat možnost kontrolovat vlastnosti argumentů (povolit pouze soubory, pouze složky nebo pouze určité příznaky).
Existuje však jedna alternativa, jak vytvořit flexibilitu v sudo. Předávejte peníze:
%staff ALL = /root/bin/staffedit *
Pak napište svůj vlastní staffedit
skript nebo spustitelný soubor pro kontrolu, zda jsou argumenty předané uživatelem legální, a pouze v případě, že jsou, provede jejich požadavek.
Nejprve otevřete soubor sudoers s sudo visudo
. Přidání user ALL=!/usr/sbin/service
bude, IIRC, zakázat service
příkaz pro uživatele user
.
Zdroje:http://nixcraft.com/showthread.php/15132-Sudo-Exclude-Commands-And-Disable-sudo-su-Bash-Shell
Našel jsem řešení.
Otevřel jsem terminál a změnil jsem se na uživatele root s su -
pak jsem napsal visudo
upravit.
pak na konci jsem napsal řádky jako
user ALL=!/etc/init.d/NetworkManager restart
user ALL=!/etc/init.d/network restart
Poté jsem také uložil a zavřel a restartoval.
Nyní, když píšu jako service network restart
nebo service NetworkManager restart
pak mi to nedovoluje a dává chybu jako
Sorry user is not allowed to execute '/sbin/service NetowkrManager restart' as root on localhost.localdomain
a podobně pro service network restart
příkaz také.