- předchozí článek - následující článek - obsah -

Linuxové noviny Březen 1998

TCP wrapper

Leo Hadacz, 11. března 1998

Instalací tohoto balíku lze značně zvýšit odolnost instalace systému proti různým útokům ze sítě, neboť pomocí tohoto balíku je možné monitorovat a filtrovat přicházející požadavky pro síťové služby SYSTAT, FINGER, FTP, TELNET, RLOGIN, RSH, EXEC, TFTP, TALK a jiné. Jádrem balíku je síťový démon tcpd. Anglické slovo "wrapper" znamená něco jako "přepínač". Takto se skutečně dá charakterizovat činnost tohoto démona. Vysvětlíme si ji později na příkladu komunikace mezi klientem a serverem pro službu FINGER. Vzhledem k tomu, že neexistuje (pokud je mi známo) ustálený český ekvivalent k termínu wrapper, budu v dalším textu používat tento anglický výraz.

Mezi funkce wrapperu patří:

  1. ověřovat platnost jména klientského počítače
  2. ověřovat platnost IP adresy klientského počítače
  3. zjišťovat identitu uživatele (pokud je to možné) na straně klienta podle protokolů popsaných v dokumentu RFC 931 (a dalších) (client username lookups)
  4. pomocí tzv. tabulek kontroly přístupu (access control tables) zakázat použití některých služeb od některých počítačů.

Je požadováno, aby démoni odpovídající na síťové požadavky, byli spouštěni pomocí nějakého speciálního serveru, jako je (ve většině případů) démon inetd. Wrapper využívá nastavení tzv. programového rozhraní TLI (transport level interface), pokud je k dispozici.

Jak to pracuje

Téměř všechny aplikace provozované na protokolu TCP/IP jsou založeny na modelu klient-server. Např. pokud nějaký uživatel zadá na lokálním počítači příkaz telnet (klient), aby se připojil na vzdálený počítač, je na tomto počítači spuštěn proces (server), který umožní navázání spojení. Příklady programů klient-server jsou v tabulce Příklady architektury klient-server.

klientserveraplikace
telnettelnetdvzdálené přihlášení
ftpftpdpřenos souborů
fingerfingerdvýpis uživatelů

Tabulka 1: Příklady architektury klient-server

Většinou je na straně serveru spuštěn jediný démon, který čeká na všechny příchozí žádosti o spojení. Tento démon se většinou jmenuje inetd. Jakmile je spojení navázáno, inetd spustí příslušný server a začne opět čekat na další požadavky.

Programy typu wrapper fungují na jednoduchém principu. Místo aby inetd spustil hned příslušný server, inetd spustí wrapper a jako parametr mu předá jméno serveru, který se měl původně spustit. Wrapper pak zaznamená do nějakého souboru (logu) jméno a adresu klientského počítače a může též provést další kontrolní činnosti. Když tyto činnosti proběhnou dobře, wrapper spustí příslušný server a sám skončí.

Programy typu wrapper mají svoje výhody i nevýhody. Mezi výhody patří to, že wrapper je nezávislý jak na klientovi, tak na serveru, takže tyto programy nejsou závislé na aplikaci, lze je použít (s jistým omezením) na jakékoliv internetové služby. Kromě toho jsou wrappery pro klienty neviditelné (přinejmenším pro autorizované klienty). Výhodné je rovněž to, že wrapper je aktivní pouze při iniciálním kontaktu mezi klientem a serverem, takže jakmile wrapper splní svoji úlohu, nevzniká další overhead (tj. "nadbytečná data") v komunikaci mezi klientem a serverem.

Jednoduchý mechanismus funkce wrapperu má však jednu velkou nevýhodu. Wrapper víceméně nelze použít pro servery, které obhospodařují více než jednoho klienta. Wrapper by totiž měl efekt pouze na klienta, který první kontaktuje server. Typickým případem je NFS mount démon. V některých případech má však použití např. přístupových tabulek implementován přímo server, nebo lze někdy použít pomocný software, který tuto nevýhodu eliminuje.

Wrapper zaznamenává informace o žádostech a průběhu připojení do logovacích souborů s využitím logovacího démona, který se většinou jmenuje syslogd (viz manová stránka syslogd(8)). To, do kterého souboru je informace ukládána, záleží na konfiguraci logovacího démona. Tato konfigurace je zpravidla v souboru /etc/syslog.conf. V distribuci Red Hat Linux wrapper zapisuje hlášky většinou do souboru /var/log/messages.

Wrapper lze nastavit několika způsoby. Nejběžnější přístup je změna v souboru /etc/inetd.conf. Uvedeme si nyní slíbený příklad se službou FINGER.

Původní položka v souboru /etc/inetd.conf mohla vypadat např. takto:

finger  stream  tcp     nowait  nobody \
   /usr/sbin/in.fingerd     in.fingerd

Abychom uvedli v činnost program tcpd, změníme původní položku takto:

finger  stream  tcp     nowait  nobody \
   /usr/sbin/tcpd           in.fingerd

Nyní tedy při požadavku na připojení službou FINGER nebude hned spuštěn program in.fingerd, ale program tcpd.

Pokud je démon pro danou službu uveden bez cesty, tcpd jej hledá v adresáři, který byl nastaven v konstantě REAL_DAEMON_DIR (lze ji zadat před překladem programu), což je v Red Hat Linux 5.0 adresář /usr/sbin. Lze však použít i absolutní cestu:

ntalk   dgram   udp     wait    root \
   /usr/etc/tcpd /usr/local/lib/ntalkd

Po této změně musíme zaslat signál HUP procesu inetd, aby se změna projevila. Učiníme tak např. příkazem

killall -HUP inetd

Tabulky kontroly přístupu

Program tcpd je v distribuci Red Hat přeložen s podporou kontroly přístupů, která je realizována pomocí dvou souborů: /etc/hosts.allow a /etc/hosts.deny. Tyto soubory se většinou označují jako tabulky kontroly přístupu. Tyto soubory obsahují pravidla určující, která připojení od kterých počítačů mají být akceptována a která ne. Tyto tabulky jsou využívány i některými dalšími programy, jako je např. ssh (alespoň podle mých zkušeností), které pomocí démonu tcpd spouštěny nejsou. S tímto je třeba počítat. Když např. povolíme jen některé démony, které vyčteme ze souboru /etc/inetd.conf, musíme být připraveni na to, že možná nepojedou některé jiné věci. Potom však stačí příslušné služby doplnit. Např. budeme chtít zakázat všechny služby volané démonem inetd pro počítač se jménem anchor.env.cz. Naeditujeme tedy soubor /etc/hosts.deny a dáme do něj pravidlo

ALL: anchor.env.cz

Zjistíme však, že se na náš počítač nelze z jmenovaného počítače připojit pomocí programu ssh. Dále se nám nelíbí, že najednou nejdou na počítači anchor montovat disky z našeho počítače. Je to proto, že tabulky kontroly přístupu ovlivňují i program portmapper, který je pro montování disků potřebný. Službu programu portmapper musíme tedy rovněž povolit. Tato služba se označuje řetězcem "portmap". Naše pravidlo tedy upravíme takto:

ALL EXCEPT sshd,portmap: anchor.env.cz

Nyní by již měly výše zmíněné věci fungovat.

Oba soubory mohou obsahovat více pravidel. Pravidla mají obecně tvar

<seznam démonů> : <klientské počítače> \
[ : <příkaz shellu> ]

Část v hranatých závorkách je nepovinná. Prvky seznamu mohou být odděleny čárkou nebo mezerou. Je možno používat např. tyto wildcards:

  • ALL - univerzální wildcard, vyhovuje (match) všemu.
  • LOCAL - vyhovuje všem jménům počítačů, které neobsahují tečku

Podrobnější informace naleznete v manové stránce hosts_access(5). V seznamu může být též uveden operátor EXCEPT, jehož funkce je patrná z výše uvedeného příkladu.

Vysvětlíme si krátce, jak wrapper určuje oprávněnost požadavků o připojení. Wrapper hledá v tabulkách a použije první pravidlo, které vyhovuje požadavku. Při výběru pravidel se postupuje takto:

  1. Přístup bude povolen, pokud pár (démon, klient) vyhovuje nějakému pravidlu uvedenému v souboru /etc/hosts.allow.
  2. Přístup bude odepřen, pokud pár (démon, klient) vyhovuje nějakému pravidlu uvedenému v souboru /etc/hosts.deny.
  3. V ostatních případech je přístup povolen.

Syntaxe pravidel kontroly přístupu je dokumentována v manové stránce hosts_access(5). Je potřeba, aby wrapper nezpomaloval odezvu serveru, a proto byl jazyk pro psaní pravidel navržen tak, aby byl co nejjednodušší. Se zvyšující se rychlostí počítačů je tento jazyk možné rozšířit. Toto rozšíření je popsáno v manové stránce hosts_options(5). Aby bylo možné toto rozšíření použít, musí být wrapper s tímto rozšířením zkompilován. V případě distribuce Red Hat Linux tomu tak je.

Kontrolní výpis pravidel provedeme příkazem tcpdchk -v.

Pravidla pro kontrolu přístupu mohou být též použita k tomu, aby klientům byl spuštěn "ten správný" server. Např. chceme, aby WWW databáze komunikovala v rodném jazyce, pokud se připojí klient z dané země, a v angličtině, pokud se připojí klient odjinud.

Vypisování zpráv klientům (banner messages)

Pokud je povoleno rozšíření jazyka, je možné před spuštěním příslušného serveru vypsat klientovi nějakou zprávu. Pravidlo bude mít pak tento tvar:

<seznam démonů> : <seznam klientů> : \
banners /some/directory

Pokud dojde k vyhovění, program tcpd se nejprve podívá do adresáře /some/directory a pokud v něm najde soubor, který má stejné jméno, jako příslušný démon, zkopíruje jeho obsah klientovi. Např. pro službu TELNET se démon jmenuje in.telnetd, takže stejně se bude jmenovat i příslušný soubor. Může v něm být např. zpráva

Ahoj %u@%h, co tě k nám přivádí?

%u a %h jsou tzv. %<písmeno> expanze. Konkrétně %u bude expandováno na jméno uživatele a %h na jméno klientského počítače. Těchto expanzí je víc a jsou popsány v manové stránce hosts_access(5). Návod, jak spravovat soubory se zprávami je v souboru /usr/doc/tcp_wrappers*/Banners.Makefile.

Konfigurace a instalace

Instalace tohoto balíku na Linuxu je velice jednoduchá pokud používáte např. distribuci Red Hat. Tento balík může být instalován již při instalaci celého systému. Pro úplnost uvedu ještě příslušný postup, pokud balík při instalaci celého systému instalován nebyl:

  1. Musíme získat příslušný distrubuční balík, např. tcp_wrappers-7.6-1.i386.rpm (RPM balík pro platformu i386). Buď z distribučního CDčka, nebo z nějakého FTP mirroru distribuce Red Hat.
  2. Nainstalujeme ho pomocí programu rpm:
    rpm -i tcp_wrappers-7.6-1.i386.rpm
    

Instalace pomocí rpm provede příslušné změny do souboru /etc/inetd.conf. Soubory /etc/hosts.allow a /etc/hosts.deny si upravíme podle svých představ. Dále můžeme zkusit program tcpdchk, který kontroluje různé nesrovnalosti, např. při jeho spuštění můžeme dostat hlášku

warning: /etc/inetd.conf, line 28: \
/usr/sbin/wu-ftpd: not found: \
No such file or directory
takovéto nesrovnalosti bychom měli odstranit.

Můžeme taky vyzkoušet, jak bude probíhat žádost o připojení na nějakou službu z nějakého klienta. K tomu použijeme program tcpdmatch. Např.

tcpdmatch in.telnetd anchor.env.cz

Vypíše např.

client:   hostname anchor.env.cz
client:   address  10.0.8.117
server:   process  in.telnetd
access:   granted

Program tcpd, všechny soubory, který tento program používá, a všechny příslušné adresáře by měli být čitelné, ale ne zapisovatelné pro neprivilegované uživatele (mód 755 nebo 555). Program tcpd by neměl být set-uid.

Pokud neexistují tabulky pro kontrolu přístupu, tcpd se bude chovat tak, jako by byly prázdné.

Podle dokumentace program tcpd nepracuje s RPC službami nad protokolem TCP. Ovšem jediná netriviální služba, která je tímto postižena, je rexd, jejíž používání je však prý velice nebezpečné.

Další informace a poznámky

Wrapper se snaží odhalit tzv. host name spoofing a host address spoofing. Jde o to, že klientský počítač se pokouší zfalšovat svoji identitu. V prvním případě se jedná o pokus zfalšování jména počítače, v druhém o pokus zfalšování jeho IP adresy. Pokud wrapper zjistí v tomto směru nějaké nesrovnalosti, spojení odepře.

Wrapper je v distribuci Red Hat 5.0 přeložen s volbou -DKILL_IP_OPTIONS, což znamená, že programy budou odmítat navázat TCP spojení u paketů, které mají nastaveno směrování (IP source routing packets).

Protokol navržený v dokumentu RFC 931 poskytuje prostředky pro získání uživatelského jména z počítače klienta (client username lookup). Je požadováno, aby na klientském počítači běžel nějaký démon, který vyhovuje specifikaci RFC 931 (identd). Tato specifikace bohužel není dána jednoznačně, těch protokolů je víc. Démon tcpd podporuje jen nejběžnější z nich.

Program tcpd provádí zjišťování jména uživatele pouze pokud je to vyžadováno v pravidlech pro kontrolu přístupu, nebo pokud je jméno uživatele potřeba v nějaké %<písmeno> expanzi.

Rutiny pro kontrolu přístupu mohou být snadno integrovány do dalších programů. Manová stránka hosts_access(3) popisuje aplikační interface knihovny libwrap.a.

Oznámení o nových verzích tohoto software je postováno do usenetových skupin (alespoň) comp.security.unix, comp.unix.admin a posíláno do speciální diskusní skupiny, do které se můžete přihlásit zasláním zprávičky bez subjectu, která bude obsahovat právě a jen řetězec subscribe tcp-wrappers-announce na adresu majordomo@wzv.win.tue.nl.

Můžete se též přihlásit do diskusní skupiny o firewallech (pošlete na adresu majordomo@greatcircle.com dopis bez subjectu obsahující právě a jen řetězec subscribe firewalls). Její archiv je na serveru ftp://ftp.greatcircle.com.

Další informace naleznete též v manových stránkách hosts_access(3, 5), hosts.allow(5), hosts.deny(5), hosts_options(5), tcpd(8), tcpdchk(8), tcpdmatch(8).

Příkazem

rpm -qil tcp_wrappers
získáme krátkou informaci o (nainstalovaném) balíku tcp_wrappers a výpis všech relevantních souborů.

Další informace jsou též k dispozici v adresáři /usr/doc/tcp_wrappers*.

Použitá literatura:

  1. W.Z. Venema, "TCP WRAPPER, network monitoring, access control and booby traps"
    ftp://ftp.win.tue.nl/pub/security/tcp_wrapper.ps.Z,
  2. W.R. Cheswick, "An Evening with Berferd, In Which a Cracker is Lured, Endured, and Studied"
    ftp://research.att.com/dist/internet_security/berferd.ps
*


- předchozí článek - následující článek - obsah -