Niedawno zachwalałem VPS jako najfajniejszą formę hostingu. Ba - dla wielu osób odstraszająca jest konieczność samodzielnej administracji, zwłaszcza surowej, zdalnej maszyny. Stąd pomysł na cykl artykułów opisujących co właściwie trzeba na takim VPS zainstalować i jak skonfigurować. Potrzebnych aplikacji wcale nie jest wiele…
W tej części piszę o czynnościach do wykonania tuż po stworzeniu maszyny - czyli co zrobić, by móc się na nią zalogować przy kolejnych wizytach i ... by nie mieć niepotrzebnych gości.
Aha: z Linode nadal jestem bardzo zadowolony i szczerze je polecam.
Tworzenie maszyny
Sposób robienia nowego VPS zależy od firmy sprzedającej tą usługę. Najczęściej po prostu wybieramy plan (tj. ilość pamięci RAM i rozmiar dysku) oraz dystrybucję (Debian, Centos, Gentoo, Ubuntu, Fedora, ...) w trakcie rejestracji i po pewnym czasie dostajemy do dyspozycji gotową maszynę (tak działa choćby Slicehost). Polecane przeze mnie Linode ma dość bajerancką aplikację (formularze w przeglądarce) do konfigurowania VPSa, można tam min. popartycjonować dyski, wybrać dystrybucję, określić wersję jądra, zdecydować o ograniczeniu ilości RAMu, nawet stworzyć dwa warianty systemu do bootowania na zmianę.
W prostej wersji: wykorzystujemy całą przestrzeń dyskową, dzieląc ją na swap (około 2x ilość RAM) i właściwy dysk (reszta), używamy najnowszego z dostępnych jąder, bierzemy cały RAM i poprzestajemy na pojedynczej konfiguracji. Co do dystrybucji ... każdy wie, jaką lubi. Moją ulubioną jest Ubuntu.
Niektóre elementy dalszego opisu są specyficzne dla Debiana i Ubuntu, staram się jednak, by poradnik był przydatny i przy używaniu innych dystrybucji.
Pierwsze logowanie
Informacja o dostępności maszyny (zaprezentowana w ramach przeglądarkowej aplikacji administracyjnej albo podesłana mailem) będzie zawierała adres IP. Powinniśmy też otrzymać (o ile go nie ustawialiśmy sami) hasło roota. Pozostaje zrobić:
dom$ ssh root@217.99.128.56
(oczywiście podając właściwe IP), wpisać hasło i jesteśmy zalogowani na naszym VPS.
Sieć
Jak by nie została stworzona maszyna, gdy się uruchomi, będzie miała
poprawnie skonfigurowaną sieć i adres IP, nie powinno być potrzeby
czegokolwiek tu modyfikować. Większość providerów używa DHCP, dzięki
czemu VPSy dostają odpowiednie adresy IP i konfiguracje resolverów DNS
bez potrzeby ich wpisywania (cała konfiguracja sieci to iface eth0
inet dhcp
w /etc/network/interfaces
lub jakimś podobnym pliku).
Aktualizacje i uzupełnienia
Sprawdzamy, czy działa mechanizm sieciowej instalacji/aktualizacji
pakietów. To również na każdym porządnym VPSie powinno być domyślnie
dobrze skonfigurowane. Szczegóły zależą od dystrybucji (yum
,
emerge
, apt-get
, …), na Debianie/Ubuntu powinno poprawnie
działać:
# apt-get update
# apt-get upgrade
Tą - lub analogiczną - parę operacji warto później regularnie
powtarzać, by instalować ewentualne aktualizacje bezpieczeństwa. Jeśli
coś nie działa, weryfikujemy konfigurację aktualizacji (na
Debianie/Ubuntu - plik /etc/apt/sources.list
).
Ten sam mechanizm będzie służył do instalacji potrzebnych programów, na przykład:
# apt-get install zile
zile
to mały emacsopodobny edytor tekstu, jakiś tego typu edytor na pewno się przyda, może być teżvim
czy - chyba najprzyjaźniejsze dla niewprawionego -nano
.
Konta i dostęp
Zdalne logowanie na konto root-a nie jest rekomendowane, dlatego zakładamy zwykłe konto użytkownika. Na przykład:
# adduser tadeusz
Hasło skrzętnie zapisujemy lub zapamiętujemy. Następnie, konfigurujemy
logowanie ssh autoryzowane kluczem na to konto (tj. robimy - o ile go
nie mamy - klucz prywatny na maszynie domowej i dopisujemy klucz
publiczny do ~/.ssh/authorized_keys2
). Klucz prywatny równie
skrzętnie backupujemy.
Testujemy, czy wszystko działa:
dom$ ssh tadeusz@217.99.128.59
(powinniśmy się zalogować bez hasła). Następnie instalujemy i
konfigurujemy pakiet sudo
(ostatni raz przypomnę, że na
dystrybucjach innych niż Debian/Ubuntu, do instalacji będzie służył
yum
, emerge
czy inny zarządca pakietów, a nie apt-get
):
# apt-get install sudo
sudo
umożliwia wykonywanie poleceń z kont innych niż własne bez podawania haseł, niesłychanie ułatwiając administrację maszyną. Po skonfigurowaniu wykorzystujemy je (z konta użytkownika - tu, z naszego tadeusza - poleceniami takimi, jak:$ sudo apt-get install python $ sudo less /var/log/messages $ sudo vim /etc/environment
(wszystkie polecenia zostaną wykonane z uprawnieniami root-a) ale też
$ sudo -u postgres psql template1 $ sudo -u mysql mysqladmin
itp.
sudo
nigdy nie pyta o hasła do tych kont (mogą być w ogóle nie ustawione), od czasu do czasu jedynie o hasło uruchamiającego je użytkownika.W ramach
/etc/sudoers
można bardzo szczegółowo skonfigurować jacy użytkownicy jakie polecenia z jakich kont mogą wykonywać, co się przydaje przy maszynach współadministrowanych przez wiele osób. Poniższy przykład jest ekstremalnym uproszczeniem, nasztadeusz
może wszystko.
Po czym edytujemy plik /etc/sudoers
do następującej formy:
Defaults env_reset root ALL=(ALL) ALL # Jedno z poniższych: #tadeusz ALL=(ALL) NOPASSWD: ALL tadeusz ALL=(ALL) ALL
(oczywiście podając właściwego użytkownika). Domyślnie sudo
od czasu
do czasu pyta o nasze własne hasło (zabezpieczenie przed
pozostawieniem zalogowanej konsoli, utrudnienie eskalacji przywilejów
gdyby ktoś się włamał na nasze konto), w wariancie z NOPASSWD
nie
będzie tego robić. Balans między trochę większym bezpieczeństwem, a
wygodą.
Sprawdzamy czy wszystko działa: logujemy się z domu przez ssh na konto robocze, sprawdzamy, czy możemy przy pomocy sudo zyskiwać uprawnienia roota:
dom$ ssh tadeusz@217.99.128.59
$ sudo cat /etc/shadow
Jeśli jest dobrze, kończymy blokując możliwość zdalnego logowania ssh
na konto root
- edytujemy plik /etc/ssh/sshd_config
i przestawiamy
PermitRootLogin
na no
. Przy okazji warto przejrzeć inne ustawienia
w tym pliku - wyłączyć wszystkie metody logowania, których nie
potrzebujemy (można rozważać nawet zablokowanie
PasswordAuthentication
i pozostanie wyłącznie przy logowaniu się
kluczem prywatnym), włączyć separację przywilejów itp.
W trakcie rekonfigurowania ssh łatwo strzelić sobie w stopę i zablokować logowanie, dlatego warto trzymać z boku zalogowaną już sesję (reload serwera ssh nie dotyczy już nawiązanych połączeń), po każdej zmianie robić:
$ sudo /etc/init.d/ssh reload
i testować, czy dalej możemy się logować (z domu). Na dobrych VPS stres jest nieco mniejszy - Linode czy Slicehost dają awaryjną zewnętrzną konsolę realizującą logowanie bez ssh (przez swoistą symulację logowania konsolowego).
Firewall
Ostatni ważny krok to instalacja i konfiguracja firewalla.
Standardowym narzędziem służącym do tego celu są iptables
. Daje się
ich nauczyć ale … ręczne pisanie tych reguł jest niewygodne i
podatne na błędy. Co gorsza, już po ich napisaniu, bardzo trudno
ogarnąć, co właściwie robią. Dlatego rekomenduję użycie jakiegoś
wyższego poziomu narzędzia. Jest ich obecnie kilka, sam preferuję
Shorewalla.
Shorewall, podobnie jak wiele innych wygodnych firewalli dla Linuksa, po prostu generuje i wykonuje odpowiedni pakiet reguł
iptables
. Nie jest to żaden stale działający demon, po prostu program ten czyta swoją (czytelną i klarowną) konfigurację, generuje na jej bazie odpowiednią sekwencję poleceń iptables i wykonuje je. Resztą zajmuje się jądro - tak samo, jak przy ręcznym pisaniu regułek iptables.Przy tym, Shorewall jest silnym i rozbudowanym narzędziem o bardzo wielu możliwościach. Tutaj opisuję prostą i łatwą konfigurację służącą do zabezpieczenia pojedynczej maszyny - tej, na której działamy.
Instalacja:
$ apt-get install shorewall-perl
Istnienie pakietów shorewall i shorewall-perl to pewna zaszłość, oba robią obecnie to samo, tyle że w jednym wypadku parser plików konfiguracyjnych jest napisany w shellu, a w drugim - w perlu, docelowo ten pierwszy zapewne zniknie. Doradzam wariant perlowy, bo działa szybciej i ma lepszą diagnostykę błędów.
Konfiguracja shorewalla składa się z pakietu plików w katalogu
/etc/shorewall
. Są tu pewne różnice w sposobie paczkowania (w
Debianie/Ubuntu ten katalog jest pusty a przykłady do skopiowania i
edycji są dostępne w /usr/share/doc/shorewall-common/
, w innych
dystrybucjach przykłady mogą leżeć w /etc/shorewall
).
Tak czy siak, dla naszego prostego przypadku katalog powinien zawierać następujące pliki (pozostałe można usunąć):
shorewall.conf
(różne globalne ustawienia, od flagi czy startować po poziom logowania).interfaces
(wykaz interfejsów sieciowych kontrolowanych przez firewall)zones
(symboliczne nazwy stref - sposób na wprowadzenie nazw dla grup maszyn/adresów czy segmentów sieci)hosts
(przypisanie konkretnych maszyn do stref)policy
(domyślne ogólne reguły z której strefy do której ruch jest dopuszczany)rules
(szczegółowe reguły typu wpuść taki a taki adres na taki a taki port)
W katalogu należy też pozostawić (o ile był) plik Makefile
(nie
ruszając jego zawartości).
A … przykłady treści powinny wyjaśnić więcej niż powyższe omówienie.
Plik shorewall.conf
jest długi i nieciekawy, więc całości cytować
nie będę, trzeba zwrócić uwagę by na razie było STARTUP_ENABLED=No
(przestawimy to na Yes
dopiero po napisaniu całej konfiguracji, by
przypadkowy reboot w trakcie edycji nie odciął nas od maszyny) i
SHOREWALL_COMPILER=perl
Plik interfaces
powinien wyglądać tak (nic ciekawego, mamy jeden
interfejs, bardziej złożone konfiguracje bywają w prawdziwych
firewallach czyli maszynach o wielu kartach sieciowych):
#ZONE INTERFACE BROADCAST OPTIONS - eth0 detect tcpflags,nosmurfs,logmartians,routefilter #LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE
Plik zones
jest bardziej interesujący. Mój wygląda tak jak niżej -
wpis fw
jest obecny zawsze i oznacza maszynę, na której działa
shorewall, wpis net
to cała sieć, inne nazwy można wprowadzać lub
nie według upodobań - jeśli je wprowadzimy, będziemy mogli ich używać
przy konfigurowaniu co wolno a co nie zamiast gołych adresów IP
(dom
będzie oznaczać mój domowy adres a kol
adresy znajomych czy
rodziny, od których mogę się awaryjnie logować):
Przy konfiguracjach wielointerfejsowych wprowadzalibyśmy też osobne nazwy stref dla każdego segmentu sieci.
#ZONE TYPE OPTIONS IN OUT fw firewall dom ipv4 kol ipv4 net ipv4 #LAST LINE - ADD YOUR ENTRIES ABOVE THIS ONE - DO NOT REMOVE
Plik hosts
przypisuje konkretne maszyny do powyższych stref (kol
trochę tu udziwniłem, by pokazać jak podawać adresy grupowe i więcej
niż jeden adres):
#ZONE HOST(S) OPTIONS net eth0:0.0.0.0/0 dom eth0:211.66.49.193 kol eth0:61.88.73.128/27,195.113.10.118/25 #LAST LINE -- ADD YOUR ENTRIES BEFORE THIS LINE -- DO NOT REMOVE
Plik policy
to ogólne co wolno, a co nie, definiowane na poziomie
stref. Na przykład:
#SOURCE DEST POLICY LOG LIMIT:BURST fw all ACCEPT net all DROP info all all REJECT info #LAST LINE -- DO NOT REMOVE
Jak widać pozwalam na dowolny ruch z naszej maszyny w świat, po cichu
odrzucam połączenia z świata do naszej maszyny a głośno (z
informacją Server rejected connection) odrzucam resztę (co - w tym
wypadku - obejmie połączenia z domu i od kolegów do naszej
maszyny). Przy odrzucaniu połączeń loguję odpowiednią informację w
/var/log/messages
.
Niektórzy tną także ruch z firewalla w świat i dopuszczają wyłącznie
wybrane porty (wyżej zamiast ACCEPT
jest REJECT
), ale tego typu
zabezpieczenie (walczące z koniami trojańskimi) jest bardziej na
miejscu na desktopach.
Wreszcie, plik rules
to szczegółowe regułki. Może wyglądać tak
(celowo stosuję kilka zapisów by pokazać, jak wyglądają). Definiuję
wyłącznie sekcję NEW
(nowe połączenia), w prostym firewallu obsługa
sekcji ESTABLISHED
i RELATED
nie jest potrzebna.
#ACTION SOURCE DEST PROTO DEST #SECTION ESTABLISHED #SECTION RELATED SECTION NEW # DNS (przyjmujemy zapytania DNS) DNS/ACCEPT all fw # SSH (pozwalamy na logowanie SSH z domu i od znajomych) SSH/ACCEPT kol fw SSH/ACCEPT dom fw # WEB (cały świat może odwiedzać nasz serwer WWW na portach 80 i 443) HTTP/ACCEPT all fw HTTPS/ACCEPT all fw # Przykład zapisu explicite bez użycia makra. # Pozwalamy na połączenia z domu na port 4747 ACCEPT dom fw tcp 4747 # Przykład wpuszczania konkretnego hosta. Pozwalamy # maszynie kazik.delta.pl łączyć się z portem 5449. # Podobnie można podać adres IP lub netmaskę. ACCEPT net:kazik.delta.pl fw tcp 5449 # Poczta (przyjmujemy pocztę) SMTP/ACCEPT all fw SMTPS/ACCEPT all fw #LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE
Na tym etapie konfigurowania maszyny, z powyższego potrzebujemy tylko wejścia po SSH, resztę zacytowałem dla ilustracji. Dobra rutynowa metoda to zaglądanie tutaj po zainstalowaniu nowej aplikacji.
Znaczenie skrótowców (takich jak powyższe DNS czy SSH) definiują pliki w katalogu
/usr/share/shorewall
- na przykład/usr/share/shorewall/macro.DNS
. Wybór, czy pisaćHTTP/ACCEPT all fw
czy też
ACCEPT all fw tcp 80
jest wyłącznie kwestią gustu, efekt jest ten sam.
Uruchamiamy:
$ sudo shorewall check
i jeśli nie wykaże błędów, zaciskamy kciuki i wołamy (na
Debianie/Ubuntu sprawdziwszy jeszcze, czy w /etc/default/shorewall
jest ustawione startup=1
, a w każdym wypadku ustawiając
STARTUP_ENABLED=Yes
w shorewall.conf
):
$ sudo /etc/init.d/shorewall start
Po czym próbujemy się na nowo zalogować. Jeśli niechcący wyblokowaliśmy jednak dostęp z domu po SSH, zostaje awaryjna konsola, o której pisałem już wcześniej ;-)
Głównym miejscem na zrobienie tu pomyłki jest podanie niewłaściwego adresu źródłowego - powiedzmy - maszyny domowej. Jeśli nie mamy stałego IP, ustalenie z jakim adresem wychodzimy do sieci może być nieco kłopotliwe. Oczywiście można np. próbować robić zabronione połączenia i sprawdzać w logach, jaki adres został odrzucony - ale to nie daje zupełnej pewności. Bywa, że provider rotuje jakąś pulę adresów wyjściowych, nawet z zupełnie różnych sieci i po udanych logowaniach rano nie zdołamy zalogować się wieczorem. Bywa też, że np. SSH wychodzi z innego IP niż HTTP (ewentualne przeglądarkowe usługi sprawdź swoje IP są raczej mało przydatne).
Jeśli ta zagadka wygląda na złożoną, można machnąć ręką i dopuścić logowania ssh z całego świata (zwłaszcza, jeśli blokujemy logowanie identyfikatorem i hasłem, dopuszczając tylko autoryzację kluczem prywatnym). Albo z jakiegoś grubego nadzbioru faktycznie możliwych adresów.
Żadnego problemu nie ma, gdy korzystamy z stałego IP.
Przy późniejszych zmianach będziemy po prostu edytować
konfigurację (najczęściej - plik rules
) a następnie wołać:
$ sudo shorewall check
$ sudo /etc/init.d/shorewall restart
Podsumowanie
Nasz VPS jeszcze do niczego ciekawego nie służy, ale już jest naprawdę nasz. Możemy się zalogować, skonfigurowaliśmy zabezpieczenia przed niepowołanym dostępem, jesteśmy w stanie instalować dalsze oprogramowanie.