Extrém rendszeradminisztráció: djbware és társai
A Unix/Linux szerverek üzemeltetése wikiből
(Változatok közti eltérés)
a (typo fixing) |
(v0.5) |
||
1. sor: | 1. sor: | ||
− | Előadó: Korn András (BME TMIT) |
+ | : Előadó: Korn András (BME TMIT) |
+ | : E-mail: <tt>korn.andras ''@'' tmit . bme . hu</tt> |
||
+ | : Az előadásvázlat URL-je: |
||
+ | : [https://wifi.tmit.bme.hu/unixlinux/index.php/Extrém_rendszeradminisztráció:_djbware_és_társai https://wifi.tmit.bme.hu/unixlinux/index.php/Extrém_rendszeradminisztráció:_djbware_és_társai] |
||
* Mi a djbware? |
* Mi a djbware? |
||
16. sor: | 16. sor: | ||
** daemontools |
** daemontools |
||
− | * De: ez itt egy szabad szoftveres konferencia |
+ | * De: ez itt egy szabadszoftveres konferencia |
* Úgyhogy a témánk a <tt>runit</tt> |
* Úgyhogy a témánk a <tt>runit</tt> |
||
** A daemontools szabad reimplementációja |
** A daemontools szabad reimplementációja |
||
231. sor: | 231. sor: | ||
== Megmentőnk, a runit == |
== Megmentőnk, a runit == |
||
+ | |||
+ | * Ötlet: válasszuk szét az init feladatait! |
||
+ | # Rendszerindítás, futtatás, leállítás |
||
+ | # Szolgáltatások futtatása |
||
+ | # utmp-piszkálás |
||
+ | # Runlevel-váltás |
||
+ | # Naplózás (bár ilyet az init nem nagyon csinál) |
||
+ | |||
+ | Így fest majd a processzfánk: |
||
+ | |||
+ | <pre> |
||
+ | runit-+-events/0 |
||
+ | [...] |
||
+ | |-runsvdir-+-runsv-+-dnscache |
||
+ | | | `-svlogd |
||
+ | | |-runsv-+-run---sleep |
||
+ | | | `-svlogd |
||
+ | | |-runsv-+-qmail-send-+-qmail-clean |
||
+ | | | | |-qmail-lspawn |
||
+ | | | | `-qmail-rspawn |
||
+ | | | `-svlogd |
||
+ | | |-runsv-+-socklog |
||
+ | | | `-svlogd] |
||
+ | | |-runsv---dd |
||
+ | | |-runsv---klogd |
||
+ | | |-runsv---cron |
||
+ | | |-runsv-+-munin-node |
||
+ | | | `-svlogd |
||
+ | | |-8*[runsv---getty] |
||
+ | | |-runsv-+-ntpd |
||
+ | | | `-svlogd |
||
+ | | |-runsv---sshd---sshd---zsh---screen |
||
+ | | |-runsv-+-smartd |
||
+ | | | `-svlogd |
||
+ | | |-runsv---mdadm |
||
+ | | |-runsv---pound---pound---2*[{pound}] |
||
+ | | `-runsv-+-svlogd |
||
+ | | `-tcpserver |
||
+ | [...] |
||
+ | </pre> |
||
+ | |||
+ | Vagyis: |
||
+ | * A <tt>runsvdir</tt> nézi, milyen szolgáltatások vannak |
||
+ | * A <tt>runsv</tt> futtat egy-egy szolgáltatást |
||
+ | ** A szolgáltatás-leállítás pl. úgy megy, hogy az adott runsv-hez tartozó FIFO-ba írunk egy parancsot |
||
+ | * Az <tt>svlogd</tt> naplózza egy-egy szolgáltatás üzeneteit |
||
+ | |||
+ | Előnyök a "sima" inithez képest: |
||
+ | * A szolgáltatások |
||
+ | ** tiszta környezettel indulnak |
||
+ | ** újraindulnak, ha kilépnek |
||
+ | ** opcionálisan megbízható naplózást kapnak |
||
+ | *** naplóüzenet nem vész el ''naplózás közben'' |
||
+ | *** méret alapján rotált logok |
||
+ | *** megbízható utófeldolgozás lehetősége |
||
+ | *** akkor is működik, ha a szolgáltatás chrootban fut |
||
+ | *** a logolás és a szolgáltatás egymástól függetlenül újraindítható/leállítható |
||
+ | ** kiválasztott felhasználók sudo nélkül is menedzselhetik őket |
||
+ | ** könnyedén lekérdezhető a státuszuk |
||
+ | ** könnyedén küldhető nekik signal |
||
+ | ** könnyedén biztosíthatjuk ezeket a tulajdonságokat a felhasználók saját "szolgáltatásainak" - pl.: |
||
+ | *** screen, benne irssi |
||
+ | *** eggdrop bot (sajnos át kell írni, mert mindenképpen a háttérbe akarja rakni magát) |
||
+ | *** fetchmail |
||
+ | *** signify |
||
+ | *** akár apache vagy egyéb |
||
+ | * Tetszőleges számú és nevű runlevelünk lehet |
||
+ | |||
+ | == Architektúra == |
||
+ | |||
+ | * Minden szolgáltatáshoz tartozik egy könyvtár (directory), amiben: |
||
+ | ** Megvan az a program (általában script), ami az adott szolgáltatást elindítja és futtatja (és <tt>run</tt> névre hallgat); addig nem léphet ki, amíg a szolgáltatás nem lépett ki |
||
+ | ** Lehet egy <tt>down</tt> nevű file, ami azt jelzi, hogy a szolgáltatás normális állapota az, hogy nem fut |
||
+ | ** Lehet egy <tt>log</tt> nevű könyvtár, ha a szolgáltatáshoz naplózást is szeretnénk - l. később |
||
+ | ** Lehet egy <tt>check</tt> nevű program, ami 0-ás visszatérési értékkel lép ki, ha a szolgáltatás működik (ami nem azonos azzal, hogy fut), egyébként nullától különbözővel |
||
+ | ** Lehet egy <tt>finish</tt> nevű program, amit abban az esetben kell lefuttatni, ha a <tt>run</tt> kilép |
||
+ | ** A runit létrehoz egy <tt>supervise</tt> könyvtárat (ebben van többek között a parancs-FIFO) |
||
+ | |||
+ | * A <tt>runsvdir</tt>-nek a parancssorban bootkor megadtuk, melyik könyvtárat figyelje (pl. <tt>/var/service</tt>) |
||
+ | * Ebbe a könyvtárba besymlinkeljük a futtatandó szolgáltatások könyvtárát (pl. <tt>/var/service/apache2</tt> -> <tt>/etc/runit/sv/apache2</tt>) |
||
+ | * A <tt>runsvdir</tt> ezt észreveszi, és elindítja a runsv-t (újra is indítja, ha kilép) |
||
+ | * A <tt>runsv</tt> elindítja a szolgáltatáshoz tartozó <tt>run</tt> scriptet |
||
+ | * Ez a script futtatja a szolgáltatást (<tt>exec apache2 -DNO_DETACH</tt> jelleggel) |
||
+ | * Így a script pontosan akkor lép ki, amikor a szolgáltatást |
||
+ | * Ekkor a <tt>runsv</tt> újraindíthatja (ill. ott a <tt>finish</tt>, amit előtte lefuttathat) |
||
+ | * s.í.t. |
||
+ | |||
+ | Egyebek: |
||
+ | |||
+ | * A <tt>run</tt> a <tt>runsv</tt>-től, az a <tt>runsvdir</tt>-től, az pedig a <tt>runit</tt>-től (1-es PID) örökli az állapotteret, nem a shelltől |
||
+ | * Ha nem akarjuk, nem indítja újra a szolgáltatásokat |
||
+ | * Van initscript-emulátor (<tt>/usr/bin/sv</tt>); a <tt>/etc/init.d/apache2</tt> lehet erre mutató symlink |
||
+ | * Runlevel-váltás: kicseréljük a <tt>runsvdir</tt> könyvtárát (symlink-zsonglőrködés); eszköze a <tt>runsvchdir</tt> |
||
+ | |||
+ | == Telepítés == |
||
+ | |||
+ | # <tt>apt-get install runit-run</tt> |
||
+ | # <tt>vim /etc/runit/{1,2,3}</tt> (indító- és leállítóscriptek) |
||
+ | # szolgáltatások symlinkelése (legalább egy getty legyen, a <tt>/etc/runit/sv</tt>-ben van, csak a symlinket kell létrehoznunk) |
||
+ | # * <tt>ln -s /etc/runit/sv/* /var/service</tt> |
||
+ | # <tt>sv status getty-1</tt> (nézzük meg, próbálja-e futtatni - nem fog menni, mert az init még futtat egyet a tty1-en) |
||
+ | # <tt>vim /etc/inittab</tt> (kapcsoljuk ki az inites gettyket) |
||
+ | # <tt>init q</tt> (győződjünk meg róla, hogy a runitos gettyk elindultak) |
||
+ | # <tt>/sbin/init.sysv 6</tt> (reboot) |
||
+ | |||
+ | * A szolgáltatásokkal áttérhetünk fokozatosan is; a <tt>/etc/runit/1</tt> tartalmazhatja az <tt>/etc/init.d/rc 2</tt> parancsot. |
||
+ | * A naplózással is érdemes áttérni (legalábbis syslogd-ről; syslog-ng-ről nem minden esetben) |
||
+ | |||
+ | == Ami kimaradt == |
||
+ | |||
+ | * Naplózás (socklog, svlogd) |
||
+ | * A runit többi komponense (pl. chpst) |
||
+ | * <tt>run</tt>-script HOWTO |
||
+ | * Egyéb djbware |
||
+ | |||
+ | == Ajánlott irodalom == |
||
+ | |||
+ | * Az előadáshoz tartozó cikk a kiadványban (sokkal részletesebb, mint az előadás) |
||
+ | * A [http://www.bme.hu/ Budapesti Műszaki és Gazdaságtudományi Egyetem] [http://www.vik.bme.hu/ Villamosmérnöki és Informatikai Kar]án általam oktatott [https://www.vik.bme.hu/targykov/valaszthato/vitmav28.htm Unix/Linux kiszolgálók üzemeltetése] című választható tárgy segédanyagát képező [https://wifi.tmit.bme.hu/unixlinux/ wiki], amely egyelőre a [https://wifi.tmit.bme.hu/unixlinux/ https://wifi.tmit.bme.hu/unixlinux/] címen érhető el |
||
+ | ** Itt olvashatunk pl. a socklogos naplózásról is |
||
+ | * [http://smarden.org/runit/ http://smarden.org/runit/] - a runit honlapja |
||
+ | * [http://cr.yp.to/ http://cr.yp.to/] - DJB honlapja |
A lap 2006. november 23., 23:37-kori változata
- Előadó: Korn András (BME TMIT)
- E-mail: korn.andras @ tmit . bme . hu
- Az előadásvázlat URL-je:
- https://wifi.tmit.bme.hu/unixlinux/index.php/Extrém_rendszeradminisztráció:_djbware_és_társai
- Mi a djbware?
- Daniel J. Bernstein (http://cr.yp.to/)
- Nem szabad szoftver, hanem "licence-free software" (kivéve, amelyik public domain)
- Fő tervezési szempontjai:
- Egyszerűség és modularitás
- Ezekre szélsőséges mértékben törekszik ("Unix-filozófia")
- A konfiguráció könnyen feldolgozható legyen
- Akár azon az áron is, hogy így több ész kell a megírásához
- Egyszerűség és modularitás
- Tágabb értelemben djbware az is, amit nem DJB írt
- Ismertebb djbware-ek:
- qmail
- djbdns
- daemontools
- De: ez itt egy szabadszoftveres konferencia
- Úgyhogy a témánk a runit
- A daemontools szabad reimplementációja
Tartalomjegyzék |
1 A runit motivációja
- Cseréljük le a System V initet!
- Hogy mi a baj vele?
- Maga az init program túl bonyolult, túl sok dolgot csinál
- Pl. van benne "UPS-kezelés"
- utmp/wtmp-kezelés
- A respawnt is csinálhatná külső program
- Feleslegesen lassú az elindítás/leállás
- Sok feladat párhuzamosítható lenne
- Ráadásul néhány disztribúcióban a csicsázás teszi ki a kód 50+%-át
- Nem indítja újra a szolgáltatásokat, ha kilépnek
- kivéve, ha az inittabból futtatjuk őket
- de akkor nem tudjuk őket szelektíven leállítani
- Az initscript örökli az őt indító shell környezetét
- Vagyis parancssorból indítva a szolgáltatást nem biztos, hogy ugyanazt csinálja majd, mint bootkor
- Nem triviális leállítani egy szolgáltatást, vagy signalt küldeni neki
- Maga az init program túl bonyolult, túl sok dolgot csinál
1.1 Szolgáltatások leállítása á la init
- Szolgáltatás leállítása: általában signalküldés
- Csakhogy: melyik PID-nak?
- Hja kérem, nem kellett volna daemonizálódni...
- "Mi a gond? Ott a pidfile..."
- Több processzből álló, processz poollal dolgozó szolgáltatás esetén elavulttá válhat
- Főleg, ha eleve a start-stop-daemon hozta létre
- Ha a pidfile helye konfigolható, indítás óta megváltozhatott a konfig, és talán már nem aktuális a pidfile elérési útja
- Összetett configfile esetén az initscript esetleg nem találja meg az érvényes pidfile-beállítást (pl. apache2)
- Vagyis: ha a pidfile-ból ki is olvasunk egy természetes számot, meg kell(ene) győződni arról, hogy az valóban a leállítandó szolgáltatáshoz tartozó processz PID-ja-e
- Itt viszont versenyhelyzetbe kerülhetünk, mert a szám kiolvasása, hitelesítése és a signal elküldése között az eredeti processz kiléphet, és másik kaphatja meg a PID-ját
- Még akkor is fennáll a versenyhelyzet, ha nem hitelesítjük a PID-t sehogy (ez amúgy rossz ötlet), mert a kiolvasás-signalküldés nem atomi művelet
- a kiolvasás és a signalküldés között eltűnhet az eredeti processz és létrejöhet ugyanolyan PID-val másik
- vagy csak eltűnhet az, aminek a signalt küldeni akartuk, de az is elég baj
- Több processzből álló, processz poollal dolgozó szolgáltatás esetén elavulttá válhat
Nézzünk erre egy példát (apache2, Ubuntu)!
ENV="env -i LANG=C PATH=/usr/local/bin:/usr/bin:/bin" APACHE2="$ENV /usr/sbin/apache2" APACHE2CTL="$ENV /usr/sbin/apache2ctl"
- Környezettisztítás, de hasztalan:
- Pl. mi lesz az ulimitekkel?
- LD_*?
apache_stop() { PID="" PIDFILE="" AP_CONF=/etc/apache2/apache2.conf # apache2 allows more than PidFile entry in the config but only the # last found in the config is used; we attempt to follow includes # here, but only first-level includes are supported, not nested ones for i in $AP_CONF `awk '$1 ~ /^\s*[Ii]nclude$/ && $2 ~ /^\// {print $2}' $AP_CONF`; do PIDFILE=`grep -i ^PidFile $i | tail -n 1 | awk '{print $2}'` if [ -e "$PIDFILE" ]; then PID=`cat $PIDFILE` fi done
Vagyis, ha többszintű include-rendszer volt, már itt elvéreztünk.
errors=`$APACHE2 -t 2>&1`
Vajon hibátlan-e a config?
- Az apache hibás configgal nem indul
- Vagyis ha a config hibás, de az apache fut, akkor a configot indítás után módosítottuk
- Vagyis a megtalált PidFile direktíva kerülhetett oda az indítás után
- Ha indítás óta módosítottuk a configot, de nem hibás, a script sehonnan se tudja meg
if [ $? = 0 ]; then # if the config is ok then we just stop normally if [ -n "$PID" ]; then $APACHE2CTL stop
Ez vajon mit csinál? Tömören:
open("/var/run/apache2.pid", O_RDONLY) = 4 read(4, "9155\n", 13) = 5 read(4, "", 8) = 0 close(4) = 0 kill(9155, SIG_0) = 0 kill(9155, SIGTERM) = 0
Vagyis majdnem vakon bízik a pidfile-ban, és itt is van versenyhelyzet.
Vissza a scriptre:
CNT=0 while [ 1 ]; do CNT=$(expr $CNT + 1) [ ! -d /proc/$PID ] && break
- Ha kilépett a pidfájlban szereplő PID, mi is kilépünk
- De: lehet hogy kilépett, és közben már indult azzal a PID-val más
- Ekkor esetleg sosem lépünk ki, vagy mégis?
if [ $CNT -gt 60 ]; then if [ "$VERBOSE" != "no" ]; then echo " ... failed!" echo "Apache2 failed to honor the stop command, please investigate the situation by hand." fi return 1 fi sleep 1 done
- Ha elbukjuk a versenyhelyzetet, azért még kiírunk egy félrevezető hibaüzenetet
else if [ "$VERBOSE" != "no" ]; then echo -n " ... no pidfile found! not running?" fi fi
- Nem volt pidfile, jaj-jaj!
- Ki is lépünk, nem csinálunk semmit
Lássuk, mi a helyzet, ha hibás volt a config:
else [ "$VERBOSE" != "no" ] && echo "$errors" # if we are here something is broken and we need to try # to exit as nice and clean as possible # if pidof is null for some reasons the script exits automagically # classified as good/unknown feature PIDS=`pidof apache2` || true REALPID=0 # if there is a pid we need to verify that belongs to apache2 # for real for i in $PIDS; do if [ "$i" = "$PID" ]; then # in this case the pid stored in the # pidfile matches one of the pidof apache # so a simple kill will make it REALPID=1 fi done if [ $REALPID = 1 ]; then # in this case everything is nice and dandy # and we kill apache2 kill $PID
Mi történt?
- Kerestünk apache2 nevű processzeket
- Amúgy a pidof(8) is írja, hogy teljes path kéne
- Lehet, hogy több apache2 példányunk is van, ekkor itt az összeset megtaláljuk
- Ha a megtalált PID-k közül valamelyik szerepelt a pidfile-ban, kilőjük
- De: hibás volt a config!
- Hibás configgal az apache el se indul, ugye
- Tehát a futó apache nem azzal a configgal indult
- Tehát ki tudja, mit olvastunk ki a pidfile-ból
- Arról nem is beszélve, hogy mikor; azóta már egy csomó idő eltelt
- Processzek léphettek ki és születhettek
- A pidfile tartalma is megváltozhatott
- Ráadásul a pidof és a kill között is eltelik valamennyi idő
- A múltban élünk...
Na és mi van, ha a pidof nem talál áldozatjelöltet?
else # this is the worst situation... just kill all of them #for i in $PIDS; do # kill $i #done # Except, we can't do that, because it's very, very bad if [ "$PIDS" ] && [ "$VERBOSE" != "no" ]; then echo " ... failed!" echo "You may still have some apache2 processes running. There are" echo "processes named 'apache2' which do not match your pid file," echo "and in the name of safety, we've left them alone. Please review" echo "the situation by hand." fi return 1 fi fi }
- Itt azért győzött a józanság szava... egyelőre :)
- A gond a daemonizálódás
- Ha az apache2 szépen az előtérben maradna, a szülője
- tudná a PID-ját és
- tudna neki signalt küldeni.
2 Megmentőnk, a runit
- Ötlet: válasszuk szét az init feladatait!
- Rendszerindítás, futtatás, leállítás
- Szolgáltatások futtatása
- utmp-piszkálás
- Runlevel-váltás
- Naplózás (bár ilyet az init nem nagyon csinál)
Így fest majd a processzfánk:
runit-+-events/0 [...] |-runsvdir-+-runsv-+-dnscache | | `-svlogd | |-runsv-+-run---sleep | | `-svlogd | |-runsv-+-qmail-send-+-qmail-clean | | | |-qmail-lspawn | | | `-qmail-rspawn | | `-svlogd | |-runsv-+-socklog | | `-svlogd] | |-runsv---dd | |-runsv---klogd | |-runsv---cron | |-runsv-+-munin-node | | `-svlogd | |-8*[runsv---getty] | |-runsv-+-ntpd | | `-svlogd | |-runsv---sshd---sshd---zsh---screen | |-runsv-+-smartd | | `-svlogd | |-runsv---mdadm | |-runsv---pound---pound---2*[{pound}] | `-runsv-+-svlogd | `-tcpserver [...]
Vagyis:
- A runsvdir nézi, milyen szolgáltatások vannak
- A runsv futtat egy-egy szolgáltatást
- A szolgáltatás-leállítás pl. úgy megy, hogy az adott runsv-hez tartozó FIFO-ba írunk egy parancsot
- Az svlogd naplózza egy-egy szolgáltatás üzeneteit
Előnyök a "sima" inithez képest:
- A szolgáltatások
- tiszta környezettel indulnak
- újraindulnak, ha kilépnek
- opcionálisan megbízható naplózást kapnak
- naplóüzenet nem vész el naplózás közben
- méret alapján rotált logok
- megbízható utófeldolgozás lehetősége
- akkor is működik, ha a szolgáltatás chrootban fut
- a logolás és a szolgáltatás egymástól függetlenül újraindítható/leállítható
- kiválasztott felhasználók sudo nélkül is menedzselhetik őket
- könnyedén lekérdezhető a státuszuk
- könnyedén küldhető nekik signal
- könnyedén biztosíthatjuk ezeket a tulajdonságokat a felhasználók saját "szolgáltatásainak" - pl.:
- screen, benne irssi
- eggdrop bot (sajnos át kell írni, mert mindenképpen a háttérbe akarja rakni magát)
- fetchmail
- signify
- akár apache vagy egyéb
- Tetszőleges számú és nevű runlevelünk lehet
3 Architektúra
- Minden szolgáltatáshoz tartozik egy könyvtár (directory), amiben:
- Megvan az a program (általában script), ami az adott szolgáltatást elindítja és futtatja (és run névre hallgat); addig nem léphet ki, amíg a szolgáltatás nem lépett ki
- Lehet egy down nevű file, ami azt jelzi, hogy a szolgáltatás normális állapota az, hogy nem fut
- Lehet egy log nevű könyvtár, ha a szolgáltatáshoz naplózást is szeretnénk - l. később
- Lehet egy check nevű program, ami 0-ás visszatérési értékkel lép ki, ha a szolgáltatás működik (ami nem azonos azzal, hogy fut), egyébként nullától különbözővel
- Lehet egy finish nevű program, amit abban az esetben kell lefuttatni, ha a run kilép
- A runit létrehoz egy supervise könyvtárat (ebben van többek között a parancs-FIFO)
- A runsvdir-nek a parancssorban bootkor megadtuk, melyik könyvtárat figyelje (pl. /var/service)
- Ebbe a könyvtárba besymlinkeljük a futtatandó szolgáltatások könyvtárát (pl. /var/service/apache2 -> /etc/runit/sv/apache2)
- A runsvdir ezt észreveszi, és elindítja a runsv-t (újra is indítja, ha kilép)
- A runsv elindítja a szolgáltatáshoz tartozó run scriptet
- Ez a script futtatja a szolgáltatást (exec apache2 -DNO_DETACH jelleggel)
- Így a script pontosan akkor lép ki, amikor a szolgáltatást
- Ekkor a runsv újraindíthatja (ill. ott a finish, amit előtte lefuttathat)
- s.í.t.
Egyebek:
- A run a runsv-től, az a runsvdir-től, az pedig a runit-től (1-es PID) örökli az állapotteret, nem a shelltől
- Ha nem akarjuk, nem indítja újra a szolgáltatásokat
- Van initscript-emulátor (/usr/bin/sv); a /etc/init.d/apache2 lehet erre mutató symlink
- Runlevel-váltás: kicseréljük a runsvdir könyvtárát (symlink-zsonglőrködés); eszköze a runsvchdir
4 Telepítés
- apt-get install runit-run
- vim /etc/runit/{1,2,3} (indító- és leállítóscriptek)
- szolgáltatások symlinkelése (legalább egy getty legyen, a /etc/runit/sv-ben van, csak a symlinket kell létrehoznunk)
- * ln -s /etc/runit/sv/* /var/service
- sv status getty-1 (nézzük meg, próbálja-e futtatni - nem fog menni, mert az init még futtat egyet a tty1-en)
- vim /etc/inittab (kapcsoljuk ki az inites gettyket)
- init q (győződjünk meg róla, hogy a runitos gettyk elindultak)
- /sbin/init.sysv 6 (reboot)
- A szolgáltatásokkal áttérhetünk fokozatosan is; a /etc/runit/1 tartalmazhatja az /etc/init.d/rc 2 parancsot.
- A naplózással is érdemes áttérni (legalábbis syslogd-ről; syslog-ng-ről nem minden esetben)
5 Ami kimaradt
- Naplózás (socklog, svlogd)
- A runit többi komponense (pl. chpst)
- run-script HOWTO
- Egyéb djbware
6 Ajánlott irodalom
- Az előadáshoz tartozó cikk a kiadványban (sokkal részletesebb, mint az előadás)
- A Budapesti Műszaki és Gazdaságtudományi Egyetem Villamosmérnöki és Informatikai Karán általam oktatott Unix/Linux kiszolgálók üzemeltetése című választható tárgy segédanyagát képező wiki, amely egyelőre a https://wifi.tmit.bme.hu/unixlinux/ címen érhető el
- Itt olvashatunk pl. a socklogos naplózásról is
- http://smarden.org/runit/ - a runit honlapja
- http://cr.yp.to/ - DJB honlapja