Úvod
Tento miniseriál se bude zabývat terminálovým serverem postaveným na FreeBSD. První část je zaměřena na základní konfiguraci serveru a nabootování klientů do textového režimu. V druhé části přidáme X window, konfiguraci window manageru, zabezpečení a další. Výsledkem má být terminálový server poskytující potřebné služby klentům, kteří slouží k surfování po internetu. Uživatelé mohou jen pustit Firefox (i více oken), nemohou PC nijak přenastavit a ani vypnout.
Co to vlastně je terminálový server? Představte si dostatečně výkonný server, ke kterému se připojují uživatelé přes terminál. Terminál je výkonově slabší stroj, v podstatě jen základní hw vybavení, které nabootuje základ operačního systému, má vstupní zařízení (klávesnice, myš) a výstupní (monitor). Spuštěné aplikace se spouští na serveru a přes síť se uživateli na jeho monitor jen posílá výstup a naopak se od něho bere vstup z klávesnice a myši.
X terminálový server má několik výhod, ale i nevýhod. Začnu výhodami:
- nízké náklady na klientské terminály – Klientská PC nemusí být nikterak výkonná a nemusí ani mít pevné disky (záleží na typu aplikace a jejím spouštění, někdy je např. výhodné mít swap apod. lokálně).
- snadné přidání dalších klientů – nemusíte na klienty instalovat žádný OS. Stačí jen dát dohromady železo a nastavit bootování ze sítě. Na straně serveru se provede jen přidání několika málo záznamů a změn do konfigurace. Pokud máte stejný hw klientů, dá se většina konfigurace zkopírovat.
- snadná správa – to je velmi výhodné, v podstatě se staráte jen o jeden server. Všechna konfigurace je na jednom stroji, to nám velmi zjednodušuje například zálohování.
Nevýhody:
- složitější konfigurace serveru – musí zde běžet více služeb, které se starají o připojování klientů.
- výpadky – při výpadku serveru nebo sítě nejsou klienti schopni žádné práce
Situace před akcí
Teď pár slov k tomu proč tento článek vzniká. Potřeboval jsem vytvořit několik pracovních míst, která slouží jen pro surfování po internetu. Mají se podobat blackboxům, se kterými se setkáte třeba na úřadech, nádražích, … Kdokoli přijde a může si na internetu vyhledat potřebné informace. K dispozici jsem měl na dnešní dobu poměrně slabý hardware.
Železo je každé jiné z rozsahu 266 – 500 MHz, 32 – 64 MB RAM. HDD malé kapacity, vše už starší a postupně odcházející do křemíkového nebe. Proto jsem pevné disky vyhodil a do všech PC dal 100 MBit síťovou kartu. Server je montované PC s procesorem Celeron 2.66 GHz, 1 GB RAM, síťovou kartou D-Link DGE-528 a pevným diskem 150 GB. Pro obsloužení 5 – 10 klientů by to mělo bez problémů stačit. Záleží samozřejmě na spouštěných aplikacích. Já používám Firefox, který je poměrně velký žrout systémových prostředků, a problém jsem nezaznamenal.
Pro server i stanice jsem použil OS FreeBSD 6.2. Výhoda je snadná optimalizace pro daný hardware (což se pro staré železo docela hodí), systém portů, snadné updaty,… Samozřejmě je možné sáhnout i po jiných Unix/Linux systémech a verzích. Ještě bych chtěl upozornit na některé projekty, které se stejné tématice věnují. Jejich seznam najdete na konci článku.
Spousta věcí se dá řešit mnoha různými způsoby. Zde to opravdu platí. V některých částech se snažím uvádět i jiné možnosti řešení, které by někomu mohly vyhovovat více.
Jak to celé pracuje?
Pro bootování klientů jsem se rozhodl použít PXE (Pre-boot Execution Environment). Je to moderní mechanismus pro bootování po síti podporovaný většinou výrobců síťových karet (intel, 3com, …).
Ve FreeBSD je PXE boot připraven, bootloader je v v souboru /boot/pxeboot. Více se dozvíte v manuálové stránce: man pxeboot. Je možné použít i jiné způsoby bootování, například bootp, ale drtivá většina dnešních karet (včetně integrovaných i starších PCI) podporuje PXE. Většinou stačí jen nastavit v BIOSu správně pořadí bootovacích zařízení, v některých případech se ještě musí zapnout zvlášť boot ROM.
Po inicializaci HW si PXE zažádá o IP pomocí DHCP. Server na základě MAC adresy (statický záznam v konfiguraci dhcp serveru) klientovi přidělí IP adresu, masku a bránu. Dalšími požadavky si PXE řekne o informace potřebné k bootování (kde získat PXE zavaděč,…). Jaké options se při této komunikaci používají, se dozvíte takhle:
$ man 5 dhcp-options
DHCP server pošle zpět jméno souboru se zavaděčem a IP adresu serveru, kde je soubor ke stažení (může to být i jiný server než DHCP). Klient si pomocí TFTP stáhne zavaděč (jmenuje se pxeboot) do paměti a následně jej spustí. Tady jen malé upozornění, že malou změnou konfigurace můžeme dosáhnout bootování pomocí bootp. Další DHCP option je informace, kde se nachází root (/) souborového systému. Ten je sdílen pomocí NFS (NFS zde rozebírat nebudeme, v odkazech uvádím jeden týkající se této problematiky).
Sdílený disk už obsahuje adresář /boot
a v něm kernel. Tím už začíná normální spouštění systému. Po připojení rootu FS (v ro režimu) a nabootování se spustí soubor /etc/rc
. Ten vykonává několik důležitých věcí – nastaví síťovou kartu, nastaví proměnou PATH, připojí si další sdílené disky přes NFS,… Ty už ale v rw režimu. Jedná se o /etc
, /var
a /tmp
.
Na serveru jsou tato sdílení připravena pro každou bezdiskovou stanici. Každá může mít své /etc kvůli různým konfiguracím a samozřejmě musí mít i své /tmp
apod. Dále tento rc skript zapne swap. O využití swapu a tmp by se asi mohlo diskutovat. Pokud má PC dostatek paměti, mohl by se patrně swap vynechat. Co je ale nutné, je /var
.
Na konci rc souboru je spuštění /etc/rc2
souboru. Ten už se nachází na nově přimapovaném /etc
(přemountovaném přes původní ro /etc
), které je určené jen této stanici. Ten si nastaví zbytek dle požadavků a hw nároků počítače. A tím je spouštění systému hotovo, zatím jen teoreticky.
Prakticky
V našem případě máme jeden server pro všechno – dhcp, tftp, nfs, X window. Má IP adresu 192.168.12.254, klienti pak mají 192.168.12.1 – 10. Server je i výchozí branou do internetu. Nejprve si připravíme adresářovou strukturu na serveru:
/diskless_tftpboot
/diskless_root
/diskless_rw
-/192.168.12.1
-/etc
-/tmp
-/var
-/log
-/192.168.12.2
-/etc
-/tmp
-/vatr
-/log
-/.......
-/...
V diskless_tftpboot je umístěn pxe zavaděč pxeboot, případně zde mohou být soubory pro jiné způsoby bootování. V diskless_root je základ filesystému. Terminálům se mountuje v RO režimu. V diskless_rw už jsou části určené pro jednotlivá pc.
Zprovoznění tftp serveru
Standardně se tftpd spouští přes inetd. Protože je po většinu doby nečinný, není důvod to měnit a pouštět si jej jako démona. Takže si jen do /etc/rc.conf
přidáme spuštění inetd. Stačí přidat inetd_enable="YES"
.
Protože jsem se ale rozhodl dát tftp root jinam než standardně je, provedl jsem malou úpravu v /etc/inetd.conf
. Řádek
#tftp dgram udp wait root /usr/libexec/tftpd tftpd -l -s /tftpboot
změňte na
tftp dgram udp wait root /usr/libexec/tftpd tftpd -l -s /diskless_tftpboot
Potom už jen stačí zkopírovat pxeboot a spustit inetd.conf
$ cp /boot/pxeboot /diskless_tftpboot $ /etc/rc.d/inetd start
Zprovoznění dhcp serveru
Použijeme ISC dhcpd z portů, pokud někdo preferuje balík, může instalovat ten. V případě kompilace z portů k funkčnosti nejsou potřeba žádné speciální optiony, které nabízí make config v tomto portu.
$ cd /usr/ports/net/isc-dhcpd-server $ make install clean
Musíme zajistit jeho spuštění po startu serveru, do /etc/rc.conf
přidáme dhcpd_enable="YES"
(případně další, např. paranoiu apod.). Spouští se příkazem /usr/local/etc/rc.d/isc-dhcpd start
.
Konfigurační soubor se nachází v adresáři /usr/local/etc
. Zde už bude více konfigurace. Nejprve si nastavíme obecné parametry a parametry společné pro všechna PC. Potom jsou vyjmenována jednotlivá PC.
# Server is authoritative for the subnets. authoritative; # option definitions common to all supported networks... option domain-name "domena.cz"; option domain-name-servers 192.168.12.254; option routers 192.168.12.254; default-lease-time 86400; max-lease-time 172800; # Disable dynamic DNS updates. ddns-update-style none; # Send the client the "hostname", specified in the option # "host" in the host declaration. use-host-decl-names on; # ukazuje na nas tftp server s pxeboot next-server 192.168.12.254; # jmeno souboru zavadece, ktery pres tftp budeme stahovat filename "pxeboot"; # ukazuje na root diskless stanice (sdileny pres NFS) option root-path "192.168.12.254:/diskless_root"; #deklarace subnetu subnet 192.168.12.0 netmask 255.255.255.0 { } # zde uz staticke zaznamy pro jednotliva pc host diskless-01 { hardware ethernet 00:11:22:22:22:11; fixed-address 192.168.12.1; } host diskless-02 { hardware ethernet 33:44:22:22:22:44; fixed-address 192.168.12.2; } ...
Pokud si chceme logovat dhcp požadavky někam jinam, například z důvodu ladění, stačí přidat řádek log-facility local7;
A do /etc/syslog.conf
toto
# local7.* /var/log/dhcpd.log
Pro další práci je vhodné si pro bezdiskové stanice udělat i doménové jméno. Buď můžete využít nějaký vlastní dns server nebo jen udělat jednoduché záznamy do /etc/hosts
:
diskless-01 192.168.12.1 diskless-02 192.168.12.2 ...
Zprovoznění NFS
Od NFS potřebujeme vyexportovat root filesystému a potom sdílení, kam mohou stanice zapisovat. Root je v adresáři diskless_root, je pouze pro čtení a je společný pro všechny bezdiskové stanice. Opět poznámka – vhodnou konfigurací dhcp serveru by bylo možné i každé stanici nebo skupinám stanic dělat jiný root. Výhodu bych viděl v rozložení zátěže (jednotlivé rooty na různých strojích).
V konfiguraci je nastaveno, aby se na diskless_root dostali všichni ze subnetu 192.168.12.0/24. Dále jsou tu adresáře, do kterých můžou terminály zapisovat. Každý terminál má své, jsou omezené na IP jednotlivých terminálů.
Konfigurace NFS exportů je v souboru /etc/exports
:
/diskless_root -alldirs -ro -maproot=0 -network 192.168.12.0 -mask 255.255.255.0 /diskless_rw/192.168.12.1/tmp /diskless_rw/192.168.12.1/etc /diskless_rw/192.168.12.1/var -maproot=0 192.168.12.1 /diskless_rw/192.168.12.2/tmp /diskless_rw/192.168.12.2/etc /diskless_rw/192.168.12.2/var -maproot=0 192.168.12.2
Ještě musíme NFS server spustit, a to provedeme přidáním následujících řádků do /etc/rc.conf
:
nfs_server_enable="YES" rpcbind_enable="YES"
Podle počtu klientů a vaší sítě si můžete ještě chování NFS serveru zoptimalizovat pomocí dalších řádků v rc.conf
( nfs_server_flags=
a mountd_flags=
).
Potřebné soubory
Adresářová struktura už byla nastíněna. Do rw části ještě musíme každému terminálu připravit swap. Například takhle:
$ dd if=/dev/zero of=/diskless_rw/192.168.12.1/var/swap bs=1k count=32000
Musíme vytvořit obsah adresáře /diskless_root
. Můžeme postupovat stejně, jako když kompilujeme kernel a world pro běžný stroj. Jen si nastavíme proměnnou DESTDIR.
Zároveň můžeme v /etc/make.conf
provést některé optimalizace pro hw slabší stroje, také není potřeba kompilovat např. games apod. Dále si můžeme připravit malý kernel pro bezdiskové terminály. Nemá cenu bootovat např. GENERIC se spoustou nepotřebných věcí. Můj konfigurační soubor kernelu vypadá takto:
machine i386
cpu I586_CPU
cpu I686_CPU
ident DISKLESS
options SCHED_4BSD # 4BSD scheduler
options PREEMPTION # Enable kernel thread preemption
options INET # InterNETworking
options NFSCLIENT # Network Filesystem Client
options NFS_ROOT # NFS usable as /, requires NFSCLIENT
options GEOM_GPT # GUID Partition Tables.
options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!]
options COMPAT_FREEBSD4 # Compatible with FreeBSD4
options COMPAT_FREEBSD5 # Compatible with FreeBSD5
options KTRACE # ktrace(1) support
options SYSVSHM # SYSV-style shared memory
options SYSVMSG # SYSV-style message queues
options SYSVSEM # SYSV-style semaphores
options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extension s
options KBD_INSTALL_CDEV # install a CDEV entry in /dev
options ADAPTIVE_GIANT # Giant mutex is adaptive.
device apic # I/O APIC
# Bus support.
device eisa
device pci
# atkbdc0 controls both the keyboard and the PS/2 mouse
device atkbdc # AT keyboard controller
device atkbd # AT keyboard
device psm # PS/2 mouse
device kbdmux # keyboard multiplexer
device vga # VGA video card driver
# syscons is the default console driver, resembling an SCO console
device sc
device agp # support several AGP chipsets
# Add suspend/resume support for the i8254.
device pmtimer
# Serial (COM) ports
device sio # 8250, 16[45]50 based serial ports
# PCI Ethernet NICs that use the common MII bus controller code.
# NOTE: Be sure to keep the 'device miibus' line in order to use these NICs!
device miibus # MII bus support
device fxp # Intel EtherExpress PRO/100B (82557, 82558)
device re # RealTek 8139C+/8169/8169S/8110S
device rl # RealTek 8129/8139
device vr # VIA Rhine, Rhine II
device xl # 3Com 3c90x (``Boomerang'', ``Cyclone'')
# Pseudo devices.
device loop # Network loopback
device random # Entropy device
device ether # Ethernet support
device pty # Pseudo-ttys (telnet etc)
# The `bpf' device enables the Berkeley Packet Filter.
# Be aware of the administrative consequences of enabling this!
# Note that 'bpf' is required for DHCP.
device bpf # Berkeley packet filter
Jistě by šel ještě zmenšit. Záleží na vás, co chcete používat.
Kompilace je dobře zdokumentovaná, opět ji tady nebudeme moc rozebírat. Předpokladem jsou nainstalované zdrojové kódy systému:
$ cd /usr/src $ export DESTDIR=/diskless_root $ make world $ make buildkernel KERNCONF=DISKLESS $ make installkernel KERNCONF=DISKLESS $ make installworld
Pokud jste si hints nezkompilovali do kernelu, zkopírujte je:
$ cp /boot/device.hints /diskless_root
Ještě potřebujeme některé soubory pro správné fungování NFS apod. Ty také zkopírujeme:
$ cd /etc $ cp services netconfig login.conf /etc/diskless_root/etc $ cp services netconfig login.conf /etc/diskless_rw/192.168.12.1/etc $ cp services netconfig login.conf /etc/diskless_rw/192.168.12.2/etc ...Pak potřebujeme po startu terminálu spustit několik příkazů, o to se postará
/diskless_root/etc/rc
. Nezapomeňte nastavit možnost spouštění:
$ chmod 755 /diskless_root/etc/rc
rc
#!/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin
export PATH
boot_ip=`kenv boot.netif.ip`
echo "Tva IP: ${boot_ip}"
echo "Pripojuji disky /etc, /var a /tmp"
mount -t nfs 192.168.12.254:/diskless_rw/${boot_ip}/etc /etc
mount -t nfs 192.168.12.254:/diskless_rw/${boot_ip}/var /var
mount -t nfs 192.168.12.254:/diskless_rw/${boot_ip}/tmp /tmp
echo "zapinam swap"
swapon /var/swap
echo "mazu obsah /tmp"
rm -rf /tmp/.*
rm -rf /tmp/*
# spustím si zbytek přímo pro tento stroj (už se spouští přímo z jeho /etc)
/etc/rc2
exit 0
V /diskless_rw/192.168.12.1/etc/rc2
si tedy doděláme zbytek konfigurace. Toto nezapomeňte udělat i pro adresáře odpovídající ostatním IP. V tomto souboru si rovnou můžeme spustit další aplikace. V příštím díle zde budeme provádět změny. Můžeme zde například spustit myš.
rc2
#!/bin/sh
#Je libo myš?
/usr/sbin/moused -tauto -p /dev/psm0
/bin/csh
Ještě poznámka k té myši – systémovější by asi bylo spustit ji normálně přes rc.conf
. Toto řešení jsem ale nezkoušel. Stačilo by v adresářích /diskless_rw/IP/etc
založit soubor rc.conf
a přidat do něj moused_enable=“YES“
+ případně další parametry. Toto se netýká jen myši, ale spouštění téměř všeho z /etc/rc.d
.
A je hotovo
Tím je konfigurace hotová. Pokud chcete přidat další terminál, stačí si jen přidat záznam do dhcp, případně /etc/hosts
, vytvořit adresářovou strukturu, nakopírovat soubory a založit swap. Díky odděleným /etc/
můžete na každém terminálu provozovat jiné aplikace a mít je v jiných konfiguracích.
Klient už nám po síti nabootoval, můžeme začít pracovat. Otázkou je, co můžete – např. spustit ssh a někam se připojit. Textový režim nám moc možností práce neposkytuje a spoustě lidí nebude stačit. Proto si v příští části toto řešení rozšíříme o X window. Na klientovi poběží X server a na terminálovém serveru si budeme spouštět aplikace, např. Firefox.
Tady jestě poznámka – asi jste si všimli, že neřeším žádnou autorizaci, nespouští se žádný login, jen samotný shell. Účelem tohoto seriálu je udělat server s X window a autorizaci řešit až tam.
Pokud někdo chce ověřovat uživatele v tomto místě, musí si vygenerovat nebo zkopírovat /etc/passwd
, /etc/master.passwd
a spustit login
.