Linux root, nie root
Inspiracja niniejszego artykułu pochodzi niejako z Ubuntu. Cechą charakterystyczną tej dystrybucji jest pominięcie konta root'a. Nie usunięcie, tylko pominięcie ponieważ usunąć root'a z systemu się nie da. Zaletą takiego rozwiązania na pewno jest zwiększenie bezpieczeństwa od zewnątrz od strony tych którzy konta na serwerze nie mają, ale ma to też swoje wady, zmniejsza bezpieczeństwo od wewnątrz od strony tych, którzy to konto posiadają. Przelogowanie na konto administratora to wykonanie pojedynczej komendy 'sudo su -' i wpisanie hasła użytkownika. Oczywiście trudno odgadnąć z zewnątrz jaki login ma główny użytkownik. Za to łatwiej podejrzeć pracującego admina, gdy loguje się na swoje zwykle konto. Dochodzi niemożność odkrycia loginu, to prawie jak drugie hasło, ale za to z bliska, wystarczy podejrzeć tylko jedno hasło.
Dlaczego nie zrobić jednego i drugiego ? Chory login + hasło ?
Chciałem jedynie zaznaczyć, że to co opisuje jest przeznaczone dla serwerów małych, domowych, gdzie administrator nie ma kont osób nieznanych. Jest to również zabawa dla tych, którzy nie chcą używać konta 'root', a chcą mieć możliwość administrowania. Chyba, że na komputerze jest oprogramowanie, które pozwala zablokować dostęp do czytania '/etc/passwd' bez zablokowania jednocześnie możliwości logowania. Właściwie to chciałbym się sam dowiedzieć czy coś takiego istnieje (PAM ? czy to daje taką możliwość?)
No to jazda bez trzymanki ;]
. Tworzymy dwóch nowych użytkowników dajemy im hasło i katalog domowy.
Jeden użytkownik to będzie czysty figurant. Będzie to zwykły najzwyklejszy użytkownik pod słońcem, należacy do grupy 'users' i żadnych innych. Dajmy mu login 'looser'. Tworzymy go, a potem blokujemy login za pomocą polecenia
passwd -l looser
. Drugi użytkownik to nasz root. Będę go dalej zwał 'superuser'. Tworzymy go prawie dokładnie tak samo, z tym że jako główną grupę do której przynależy dajemy grupę 'root'. Katalog domowy tegoż użytkownika jest dokładnie taki sam jak katalog domowy użytkownika 'looser'. Co więcej, po stworzeniu tego użytkownika, przywracamy prawa własności do katalogu domowego użytkownikowi 'looser', jeśli nadpisaliśmy katalog domowy loosera. Dlaczego ? Żeby ukryć fakt że w tym katalogu znajduje się katalog administratora. Niech owner zgadza się z loginem, to w niczym nie przeszkodzi w działaniu, bo roota prawa i własności nie obowiązują, a raczej on jest właścicielem wszystkiego i ma do wszystkiego prawo. Zabawa ze zmienianiem ownera i w ogóle z całym dodatkowym użytkownikiem nie jest to konieczna, ponieważ każdy użytkownik, który zajrzy do /etc/passwd od razu się zorientuje, a każdy użytkownik potrzebuje praw do czytania tego pliku, choćby po to żeby się móc zalogować. Chyba, że na serwerze jest oprogramowanie, o którym wspomniałem na początku. Ważne jest natomiast, aby nie dać czytać z tego katalogu, bo to katalog administratora. Czyli nadajemy prawa 700. Zabawa z drugim użytkownikiem nie ma również sensu, gdy na katalog domowy użyjemy katalogu '/root' , z jasnych chyba względów.
: /etc/passwd
Edytujemy plik '/etc/passwd'. Zmieniamy id naszego 'superusera'. Co zmienić ? Tak np. może wyglądać linijka opisująca naszego nowego admina:
superuser:x:1234:0::/home/looser:/bin/bash
Pola oddzielone są ':', a każde z nich ma takie o to znaczenie:
login_name:hasło:UID:GID:imie_nazwisko:katalog:powłoka
Pierwsze pole to oczywiście login. Jeśli chcecie go zmienić to nie ma najmniejszego problemu, zmieniajcie tu, tylko że trzeba ten login zmienić również w pliku '/etc/shadow', bo inaczej w ogóle się potem nie zalogujecie. Druga pozycja wyszła chyba z użycia wieki temu i została zachowana dla kompatybilności. Chyba, bo nie mam zielonego pojęcia. w każdym razie we wszystkich znanych mi systemach hasła trzymane są w '/etc/shadow'. Trzecia pozycja jest pozycją która nas interesuje. Jest to identyfikator użytkownika, root ma ten identyfikator równy 0, więc i tu taki wpisujemy, Czwarta pozycja to grupa podstawowa, do której należy użytkownik. Standardowo identyfikator 0 to grupa 'root'. Wszystkie grupy, ich identyfikatory, hasła do nich oraz członkowie należący do tych grup są wypisani w '/etc/group' . Piąta pozycja ... Bez komentarza. Szósta: katalog domowy. Siódma: domyślna powłoka. Zmieńcie, jeśli chcecie. W pliku '/etc/shells' są wypisane powłoki jakie macie w systemie. Tak o to może wyglądać '/etc/passwd' po wykonaniu zadania:
root:x:0:0::/root:/bin/bash
superuser:x:0:0::/home/looser:/bin/bash
looser:x:5678:100::/home/looser:/bin/bash
:. Testy
Logujemy się na looser'a ... Nie da rady. Po szczegóły odsyłam do 'man passwd' zwłaszcza opcja '-l'.
Logujemy się na root'a, wykonujemy polecenie 'pwd' ...
root@host:~# pwd
/root
Logujemy się na superuser'a i wykonujemy po kolei polecenia:
root@host:~# pwd
/home/looser
root@host:~# whoami
root
Zdziwienie ? Czemu nie superuser ? Wyedytujcie znów '/etc/passwd' . Jest tak:
root:x:0:0::/root:/bin/bash
superuser:x:0:0::/home/looser:/bin/bash
Root jest przed superuser'em. Zamiencie kolejność linijek. Drobna uwaga. kolejność wpisów w tym pliku nie ma żadnego wpływu na pracę systemu. Możecie plik posortować, wymieszać, zrobic z kolejnością cokolwiek chcecie, system będzie działał prawidłowo.
superuser:x:0:0::/home/looser:/bin/bash
root:x:0:0::/root:/bin/bash
Poza tą konkretną sytuacją gdy dwóch użytkowników ma ten sam identyfikator nic się nie zmieni. Zapiszcie plik. Potem wylogujcie sie i znów zalogujcie kolejno na konta root'a i superuser'a.
Root:
superuser@host:~# pwd
/root
superuser@host:~# whoami
superuser
Superuser:
superuser@host:~# pwd
/home/looser
superuser@host:~# whoami
superuser
Z czego to wynika ? Ano 'whoami' i shell pokazujący prompta czytają '/etc/passwd' tylko do momentu napotkania identyfikatora, ktorego szukają. Użytkownik w systemie po nazwie jest identyfikowany tylko przy logowaniu. Stąd różnice w katalogu domowym. stąd tez zmiany rożne zapisy w pliku 'utmp' - polecenie 'who' oraz w pliku w pliku 'wtmp' - polecenie 'last'. Potem identyfikuje się go tylko po identyfikatorze. Dopiero przy wylogowaniu. Co do utmp: jeśli po wylogowaniu wykonanie polecenia who nadal pokazuje zalogowanego użytkownika, to po prostu plik 'utmp' został jakoś uszkodzony, należy wykonać
cat /dev/null > /var/run/utmp
Z tym że w różnych systemach różna może być tego pliku lokacja. Po wykonaniu tego polecenia. 'who' nie pokaże wam nic, bo będzie miało pustą bazę. Zacznie pokazywać dopiero nowozalogowanych.
Wracając do sprawy. To czy zostawicie sobie jako pierwszego superuser'a , czy root'a, to wasza broszka. Jednak po to było całe to zamieszanie w systemie, aby ukryć ze na roota logujemy się inaczej. tak więc oryginalna kolejności tych dwóch użytkowników byłaby bardziej wskazana.
:: Blokada
Skoro możemy się zalogować i wszystko (sprawdzić!) działa spod superusera, to możemy zablokować już login dla root'a
passwd -l root
::. su
Polecenie 'su -' jest jednoznaczne z wydaniem polecenia 'su - root'. Analogicznie 'su' to 'su root'. Chcemy, żeby zeby zamiast 'root' było 'superuser'. Chcemy.
Pierwsze co robimy, to przemianujemy plik 'su' do 'su.real'
mv 'which su' 'which su'.real
Potem tworzymy w tym samym katalogu plik 'su' i dajemy mu prawa do wykonania. Zazwyczaj w katalogu /bin. Polecenie 'which su.real' pokaże wam ten katalog.
touch /bin/su
chmod 755 /bin/su
Potem ten plik edytujemy.
#!/bin/sh
USER=superuser
JA=`whoami`
if [ "${1}" == "-" ] && [ "${2}" == "-" ] ; then
${0} `echo ${@} | sed "s/${1}//"`
else
if [ `whoami` == "${JA}" ] && [ "${1}" == "-" ] ; then
u="${USER}"
isuser=0
if [ "${2}" != "" ] ; then
users=`awk -F ':' '{printf($1" ")}' < /etc/passwd`
for i in ${users} ; do [ "${i}" == "${2}" ] && isuser=1 && break ; done
[ ${isuser} -gt 0 ] && u="${2}"
fi
p=${@}
if [ "${1}" != "" ] ; then
p=`echo ${@} | sed "s/${1}//"`
[ "${2}" != "" ] && [ ${isuser} -gt 0 ] && p=`echo ${p} | sed "s/${2}//"`
fi
su.real - ${u} ${p}
else
su.real ${@}
fi
fi
Kilka słów:
Po pierwsze tylko dla mnie bedzie zmieniane 'su -' na 'su - superuser'. Po drugie tylko 'su -'. Samo 'su' nie (o tym dalej). W skrypcie jest w tej chwili JA=`whoami`. W tym przypadku zadziała to dla każdego usera. Wystarczy żeby wpisać konkretny login (np. flabra, jozek, ktokolwiek) zeby opcja ta była dostępna tylko dla konkretnej osoby.
Po trzecie zmieniła się funcjonalność polecenia 'su'. Oryginalnie 'man su' pokazuje coś takiego:
su [-] [nazwa_użytkownika [argumenty]]
Co znaczy, że argumenty będą brane pod uwage przy jawnym podaniu loginu. A my staramy się to zmienić ukryć że root to nie root.
Skrypt można wywołać bez podania użytkownika
su [-] [nazwa_użytkownika] [argumenty]
Ale tylko wtedy, gdy wywołujemy 'su -'. Przy zwykłym 'su' trzeba zastosować login. Tak więc poprawne będą obydwie formy:
su - -c ls
su - superuser -c ls
Natomiast z poniższych tylko druga
su -c ls
su superuser -c ls
Jak i to rozszerzyć ? Wykonując linijkę 'alias su='su -'', bądź dopisując ją sobie do .bashrc/.bash_profile, czy jakiegokolwiek innego uruchamianaego przy logowaniu pliku. Za kazdym razem po wpisaniu z konsoli 'su' zostanie wykonane 'su -'. W przypadku wykonania 'su - innyuser' zostanie wykonane 'su - - innyuser'. Przed tym oryginalne 'su' nie było zabezpieczone i wywalało błędy. Skrypt jest. Po przyjrzeniu się skryptowi widać wywołanie rekurencyjne:
if [ "${1}" == "-" ] && [ "${2}" == "-" ] ; then
${0} `echo ${@} | sed "s/${1}//"`
To nic innego niż wywołanie samego siebie z pominięciem pierwszego parametru. Tak więc możecie nawsadzać i 10 '-' a skrypt zostanie wykonany poprawnie. Po prostu wywoła sam siebie 9 razy.
::: Co jeszcze ?
Możecie sobie stworzyć plik np. 'su-'
#!/bin/sh
su - superuser
Możecie również, jeśli wam to potrzebne podmienić plik 'whoami' na skrypt, który bedzie porównywał nie tylko UID, lecz również katalog domowy - '$HOME' w celu jednoznacznej identyfikacji loginu (o ile katalog domowy jest róźny od /root).
:::. Profity ?
Można zostawić możliwość bezpośredniego logowania na superusera w sshd, chociaż ftp juz nie, bo hasla są nieszyfrowane. Superuser może mieć własną stronę domową (wiem, żaden argument, root może wystawić nawet '/' jeśli zechce).
:::: Mankamenty
To o czym wspomniałem wcześniej. Utmp mi się cosik pokręcił. Poza tym midnight commander działa dziwnie, jak w debianie. Przy wychodzeniu z programu następuje powrót do katalogu domowego, niezależnie od tego w jakim zakończyłem mc. To z drobnych spraw. Część programów zapisuje konfigi nie w katalogu superusera, tylko w katalogu roota. Grubszych nie zauważyłem.
::::. Bezpiecznego użytkowania :)
Sprawdziłem i u mnie to działa. Z ciekawszych rzeczy podczas prób... Zablokowałem root'a, wyedytowałem /etc/passwd i zmieniłem login. Ale zapomniałem o /etc/shadow ;].
Nie mam ixów na tym komputerze, więc nie powiem jak działa 'uruchom jako inny użytkownik' spod okienek i czy w ogóle działa. Stąd ponawiam prośbe, abo wszystko dokładnie przetestować, zanim zdecydujecie sie na zablokowanie root'a.
Źródło: 4programmers.net. Treść udostępniona na zasadach licencji Creative Commons Attribution