Debian jako serwer Javy – podstawy systemu

Poprzedni wpis (będący jednocześnie pierwszym) na temat wykorzystania Debiana jako serwera dla aplikacji Java skupiał się wyłącznie na uruchomieniu usług, które miały po prostu działać. Dziś skupimy się bardziej na samym systemie.

Użytkownicy systemów Windows są przyzwyczajeni do konieczności poinstalacyjnych operacji związanych ze ściąganiem olbrzymiej liczby poprawek połączonych z restartami systemu. W przypadku linuxa jest lepiej – cała operacja aktualizacji systemu przebiega bardzo sprawnie i nie wymaga spędzenia przy komputerze kilku godzin.

Zanim jednakże weźmiemy się do pracy kilka słów wyjaśnienia. Zakładam, iż czytelnik ma rozeznanie w podstawowych komendach w systemach linuxowych. Jeśli takowego brak (w co wątpię) wówczas można zajrzeć pod ten adres, gdzie można znaleźć szybką ściągawkę z podstawowych komend oraz ich parametrów. Zakładam również, że posiadamy na danym serwerze prawa ROOTa – mowa o konfiguracji serwera zatem oczywistym powino być, że mamy pełną kontrolę nad systemem.

Aktualizacje

Podstawową rzeczą w systemie jest jego ciągła aktualizacja. Na pewno zaś przynajmniej aktualizacje bezpieczeństwa, które niemożliwiają skorzystanie w naszym systemie z odkrytych w oprogramowaniu luk. Rzecz jest zatem bardzo istotna, ale tym samym diablo nudna i rutynowa. Potencjalna ilość aktualizacji codziennie dołączanych do dystrybucji jest bardzo duża. Dlatego też rzecz jasna cały proces trzeba zautomatyzować. Od wydania wersji Debian Woody sugerowanym rozwiązaniem jeśli chodzi o zarządzanie oprogramowaniem w systemie jest program apt. Po części to właśnie on stał się powodem olbrzymiej popularności Ubuntu. Klepiemy linijkę kodu i oto mamy zainstalowane oprogramowanie. To właśnie wzięło się z Debiana i jest jego olbrzymią siłą. Pełną dokumentację narzędzia apt warto przeczytać, zaś znaleźć można ją pod tym adresem.

Zaraz po instalacji najlepiej w konsoli wydać takie oto polecenia:

apt-get update <-- Co zaktualizuje liste pakietow
apt-get upgrade <-- Wprowadzi zmiany w systemie

Co sprawi, że wszystkie pakiety zainstalowane wraz z systemem zostaną zastąpione ich nowszym wersjami (jeśli takowe w ogóle istnieją). W przypadku zwykłego systemu serwerowego, który bynajmniej nie posiada serwera Xów, ani dużej ilości oprogramowania wchodzącego w skład KDE czy Gnome procesy akutalizacji są szybkie i nie wymagają ściągania olbrzymich ilości danych. Zasadniczo nie ma opcji by system automatycznie ściągał poprawki i je instalował – mogłoby to spowodować prawdziwą katastrofę w przypadku zwłaszcza serwera produkcyjnego. Dlatego praktyką jest automatyczne pobieranie aktualizacji, ale decyzja czy je zainstalować jest pozostawiana administratorowi. Można to osiągnąć instalując narzędzie cron-apt, które zgodnie z nazwą cyklicznie dokonuje aktualizacji pakietów. Mamy też możliwość dość solidnej konfiguracji tego narzędzia – w sumie dość profesjonalnym jest otrzymywanie mejli za każdym razem kiedy coś pójdzie nie tak. Wstęp do instalacji tego narzędzia i jego używania można znaleźć pod tym adresem. W związku z tym, iż posiadam tylko jeden serwer pozwoliłem sobie zostawić na razie ręczne akutalizowanie systemu. Na razie 🙂

Ekran logowania

Kolejna rzecz jest kosmetyką, ale dość istotną jeśli mamy raptem 1 serwer. Otóż istnieje możliwość własnego zdefiniowania bannera, który pojawi się przy zalogowaniu się do systemu przez SSH. By osiągnąć taki efekt musimy poddać edycji plik /etc/ssh/sshd_config i w nim odkomentować stosowną linijkę:

Banner /etc/issue.net

Dzięki temu w pliku wskazanym (tutaj /etc/issue.net) możemy wkleić swój komunikat. Restartujemy demona SSH i oto mamy efekt – mała rzecz, a jak cieszy.

Co w procesach piszczy

Przy starcie każdego sytemu operacyjnego po załadowaniu podstawowych rzeczy składających się na sam system, rozpoczyna się sekwencyjne uruchamianie procesów. Jeśli uruchamiamy linuxa choćby na komputerze lokalnym wówczas mamy możliwość zobaczenia komunikatów o startowaniu kolejnych programów/demonów. Tym samym uruchamiane są kolejne procesy. Proces to nic innego jak pewne działanie, które jest wykonywane na serwerze. Każdy z procesów jest identyfikowany jednoznaczenie przez swój PID, czyli ID procesu. By zobaczyć działające w systemie procesy wydajemy w konsoli polecenie top lub htop (to troche ladniejsze i bardziej rozbudowane narzędzie). U mnie wygląda to tak:

Zasadniczo nie ma tam nic podejrzanego. Mamy i procesy Javy, mamy serwer WWW, działa też PHP i kilka podstawowych dla systemu rzeczy. Najistotniejszą rzeczą jest proces o nazwie init:

1 root 20 0 1988 528 496 S 0 0.1 0:00.56 init

Jest to pierwszy proces odpalany w systemie. Powoduje on zainicjalizowanie systemu, a następnie tenże system przechodzi po kolei po wszystkich skryptach znajdujących się w katalogach rcX.d, gdzie X to kolejne cyfry oznaczające tzw. runlevel. Dla nas interesujące są te z przedziału 2-5, gdyż oznaczają one normalne działanie systemu (w sensie uruchamiania). Level 0 to zamykanie systemu, zaś 6 to jego restart. Warto pochodzić po tychże katalogach i zobaczyć co z czym. U mnie dla przykładu katalog rc2.d wygląda tak:

drwxr-xr-x 2 root root 4096 Jan 31 20:48 .
drwxr-xr-x 74 root root 4096 Jan 31 21:18 ..
-rw-r--r-- 1 root root 556 Aug 12 2008 README
lrwxrwxrwx 1 root root 17 Dec 13 10:08 S10rsyslog -> ../init.d/rsyslog
lrwxrwxrwx 1 root root 14 Dec 13 10:17 S12dbus -> ../init.d/dbus
lrwxrwxrwx 1 root root 22 Dec 13 10:18 S14avahi-daemon -> ../init.d/avahi-daemon
lrwxrwxrwx 1 root root 13 Dec 13 10:08 S16ssh -> ../init.d/ssh
lrwxrwxrwx 1 root root 23 Dec 13 11:46 S17mysql-ndb-mgm -> ../init.d/mysql-ndb-mgm
lrwxrwxrwx 1 root root 19 Dec 13 11:46 S18mysql-ndb -> ../init.d/mysql-ndb
lrwxrwxrwx 1 root root 15 Dec 13 11:46 S19mysql -> ../init.d/mysql
lrwxrwxrwx 1 root root 18 Dec 21 12:04 S20lighttpd -> ../init.d/lighttpd
lrwxrwxrwx 1 root root 15 Dec 13 10:45 S20nginx -> ../init.d/nginx
lrwxrwxrwx 1 root root 23 Dec 13 10:08 S20openbsd-inetd -> ../init.d/openbsd-inetd
lrwxrwxrwx 1 root root 17 Dec 13 10:08 S20postfix -> ../init.d/postfix
lrwxrwxrwx 1 root root 18 Jan 31 20:48 S20startphp -> ../init.d/startphp
lrwxrwxrwx 1 root root 13 Dec 19 09:57 S21fam -> ../init.d/fam
lrwxrwxrwx 1 root root 13 Dec 13 10:08 S89atd -> ../init.d/atd
lrwxrwxrwx 1 root root 14 Dec 13 10:08 S89cron -> ../init.d/cron
lrwxrwxrwx 1 root root 17 Dec 13 11:08 S91apache2 -> ../init.d/apache2
lrwxrwxrwx 1 root root 17 Dec 13 10:26 S92tomcat6 -> ../init.d/tomcat6
lrwxrwxrwx 1 root root 18 Dec 13 10:08 S99rc.local -> ../init.d/rc.local
lrwxrwxrwx 1 root root 19 Dec 13 10:08 S99rmnologin -> ../init.d/rmnologin
lrwxrwxrwx 1 root root 23 Dec 13 10:08 S99stop-bootlogd -> ../init.d/stop-bootlogd

Jak zatem widać wszystko co się znajduje w tym katalogu (i w pozostałych też) to zasadniczo dowiązania symboliczne do skryptów z katalogu /etc/init.d. W ten sposób startują wszystkie nasze usługi i demony – poprzez dowiązanie symboliczne do skryptu. Istnieje też plik/skrypt o nazwie rc.local, w którym powinny znaleźć się nasze skrypty, które mają być uruchamiane po każdorazowym starcie systemu. Jednakże u mnie to rozwiązanie nie zadziałało (użyłem tego pliku do wrzucenia startu PHP ). I potem dziwiłem się czemu za każdym restartem (w sumie raptem 2 do tej pory, no ale zawsze) nie działały mi aplikacje PHP. Odpowiedź na ten problem znajduje się nawet w oficjalnej dokumentacji Debiana (punkt 10.6). By zatem wystartować PHP podczas startu systemu trzeba zrobić następujące czynności:

  • Tworzymy plik w katalogu /etc/init.d. Ja nadałem mu nazwę startphp.
  • Jego zawartość jest krótka
    /usr/bin/spawn-fcgi -a 127.0.0.1 -p 9000 -u www-data -g www-data -f /usr/bin/php5-cgi -P /var/run/fastcgi-php.pid -C 12
  • Informujemy system o fakcie istnienia takiego skryptu. W tym celu użyjemy narzędzia update-rc.d, które to trzeba wywołać z odpowiednimi parametrami. Ja zrobiłem to dość skromnie:
    update-rc.d /etc/init.d/startphp defaults
    I teraz skrypt ten będzie uruchamiał się podczas startu systemu (w runlevelach 2-5). Więcej na temat tego narzędzia oraz jego parametrów można znależć na stronach dokumentacji systemowej.

Rzecz jasna w ten sam sposób moglibyśmy podpiąć do wykonywania plik rc.local, ale po namyśle doszedłem do wniosku, że rozdzielenie skryptów będzie bardziej czytelne. Choć tutaj już każdy musi podjąć decyzję, co mu bardziej pasuje. Podobną decyzję trzeba też podjąć jeśli chodzi o procesy już uruchamiane. Przykładem jest choćby demon avahi, który jest dostarczany wraz z instalacją systemu i automatycznie uruchamiany. Co ten konkretny demon robi można przeczytać tutaj, zaś dyskusję na temat jego pozostawienia i używania tutaj. Mi jakoś specjalnie do niczego potrzebne to nie będzie, zatem trzeba temat wyrzucić. Komenda:

update-rc.d -f /etc/init.d/avahi-daemon remove

I po restarcie mamy nadzieję, że demon już nie powstaje. Niestety jest to nadzieja płonna – albowiem taki trick w Debianie bynajmniej nie wystarcza. Należy jeszcze edycji poddać plik /etc/default/avahi-daemon i tam dopisać linijkę z dyrektywą:

AVAHI_DAEMON_START

I ustawić jej wartość na 0. Reboot i w procesach już Avahi nie ma.

Co słychać w portach

Poza procesami warto też przyjrzeć się otwartym portom i usługom na nich działającym. Pomoże nam w tym taka instrukcja:

netstat -nlp

Pokaże ona interesujące nas rzeczy.

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:869 0.0.0.0:* LISTEN 693/famd
tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN 663/php5-cgi
tcp 0 0 94.23.178.117:3306 0.0.0.0:* LISTEN 792/mysqld
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 308/portmap
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 557/nginx
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 414/sshd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 653/master
tcp6 0 0 :::8080 :::* LISTEN 740/jsvc
tcp6 0 0 :::22 :::* LISTEN 414/sshd
udp 0 0 0.0.0.0:111 0.0.0.0:* 308/portmap

Portmapper to demon, który jest potrzebny do działania RPC, zatem zostawiamy go póki co sobie. Ciekawym z kolei jest pierwszy wiesz, czyli port 693 i działający tam demon famd. Szybka wycieczka do wujka googla i dowiadujemy się, iż jest to demon, którego celem jest monitorowanie zmian w systemie plików. Więcej na ten temat pod tym adresem no i co istotne – zalecana jest jego zamiana na demona gamin. Lecimy zaptem:

apt-get install gamin

I dostajemy w odpowiedzi:

chlebik@chlebik:~$ sudo apt-get install gamin
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
libgamin0
The following packages will be REMOVED:
fam libfam0
The following NEW packages will be installed:
gamin libgamin0
0 upgraded, 2 newly installed, 2 to remove and 54 not upgraded.
Need to get 102kB of archives.
After this operation, 65.5kB disk space will be freed.
Do you want to continue [Y/n]? Y
Get:1 http://ftp.debian.org lenny/main libgamin0 0.1.9-2 [37.8kB]
Get:2 http://ftp.debian.org lenny/main gamin 0.1.9-2 [64.0kB]
Fetched 102kB in 0s (558kB/s)
(Reading database ... 24203 files and directories currently installed.)
Removing fam ...
Stopping file alteration monitor: FAM.

dpkg: libfam0: dependency problems, but removing anyway as you request:
lighttpd depends on libfam0.
Removing libfam0 ...
Processing triggers for man-db ...
Selecting previously deselected package libgamin0.
(Reading database ... 24181 files and directories currently installed.)
Unpacking libgamin0 (from .../libgamin0_0.1.9-2_i386.deb) ...
Selecting previously deselected package gamin.
Unpacking gamin (from .../gamin_0.1.9-2_i386.deb) ...
Setting up gamin (0.1.9-2) ...
Setting up libgamin0 (0.1.9-2) ...

I po reboocie jest już lepiej:

tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN 636/php5-cgi
tcp 0 0 94.23.178.117:3306 0.0.0.0:* LISTEN 784/mysqld
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 308/portmap
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 561/nginx
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 414/sshd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 628/master
tcp6 0 0 :::8080 :::* LISTEN 694/jsvc
tcp6 0 0 :::22 :::* LISTEN 414/sshd
udp 0 0 0.0.0.0:111 0.0.0.0:* 308/portmap

Ciekawe też rzeczy może nam pokazać znany pogram nmap, ale tutaj zainteresowanych odsyłam na stronę domową nmapa.

Chcę oglądać twoje logi

Zasadniczo wszystkie aplikacje pozostawiają po sobie jakieś logi. Jest to dość naturalne – jak inaczej sprawdzić czy z naszymi programami wszystko porządku jeśli nie podsłuchując co do nas mówią. Problemem jednakże stają się przestarzałe artefakty – kiedy nagle kilkaset MB dysku jest zajętych przez stare pliki z logami. Możnaby rzecz jasna napisać własny skrypt powłoki, który usuwałby wskazane pliki (i najlepiej podpiąć go do crontaba i byłby spokój). Jednakże jest to rozwiązanie dość toporne. Rzecz jasna problem nie pojawił się wczoraj i powstały stosowne narzędzia dla uporania się z tym problemem. Jednym z nich jest logrotate. U mnie ta aplikacyjka była już zainstalowana i działała całkiem sprawnie. W katalogu /etc/logrotate.d/ znalazły się informacje o logach ngixa, lightiego, mysqla i kilku innych. Nie grozi mi zatem wyczerpanie miejsca na dysku 🙂
Pomijając usuwanie starych logów, warto też czasem zajrzeć do /var/log/syslog by wiedzieć co pod obudową się dzieje.

Zakończenie

Przedstawiłem dość podstawowe rzeczy dotyczące administracji serwerem opartym na Debianie. Rzecz jasna codzienna praktyka z pewnością będzie bardziej skomplikowana, coś pewnie nie raz się zepsuje i nie będzie działać tak jak powinno. Jeśli znalazłeś jakiś błąd w tekście, albo też masz pomysł, co by tu jeszcze dopisać proszę pisz śmiało.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s