Hlavní navigace

Terminálový server na FreeBSD

25. 6. 2007
Doba čtení: 12 minut

Sdílet

Řešení, které si představíme, umožňuje využít jeden výkonný server pro vytvoření plnohodnotného pracovního prostředí pro několik uživatelů sedících za jednoduchými terminály. Ukážeme si, jak terminálový server realizovat na FreeBSD. Dnes vytvoříme základní prostředí a necháme počítače nastartovat do textového režimu.

Ú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=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.

root_podpora

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.

Byl pro vás článek přínosný?

Autor článku

Petr Macek studoval aplikovanou informatiku na Jihočeské univerzitě, pracuje jako síťový specialista ve firmě Kostax, s. r. o. Baví ho především FreeBSD, sítě a monitoring Cacti.