Linux - podręcznik administratora sieci Olaf Kirch, Terry Dawson Tytuł oryginału: Linux Network Administrator’s Guide, Second Edition Tłumaczenie: Krzysztof Łabanowski Wydawnictwo RM, Warszawa 2000 Authorized translation of the English edition 2000 O’Reilly and Associates, Inc. This translation is published and sold by permission of O’Reilly and Associates, Inc., the owner of all rights to publish and sell the same. Wydawnictwo RM, 00-987 Warszawa 4, skr. poczt. 144 rm@rm.com.pl www.rm.com.pl Zezwala się na kopiowanie, drukowanie, rozpowszechnianie i modyfikowanie dokumentu elektronicznego na warunkach licencji GNU Free Documenation License w wersji 1.1 lub jakiejkolwiek nowszej wersji opublikowanej przez Free Software Foundation. 33, 1034 Treść licencji znajduje się w dodatku C na końcu książki. Wszystkie nazwy handlowe i towarów występujące w niniejszej publikacji są znakami towarowymi zastrzeżonymi lub nazwami zastrzeżonymi odpowiednich firm odnośnych właścicieli. Nazwy i adresy firm, nazwiska i adresy osób, nazwy towarów i inne dane wykorzystane w przykładach są fikcyjne i jakakolwiek zbieżność z rzeczywistością jest wyłącznie przypadkowa. Wydawnictwo RM dołożyło wszelkich starań, aby zapewnić najwyższą jakość tej książce. Jednakże nikomu nie udziela żadnej rękojmi ani gwarancji. Wydawnictwo RM nie jest w żadnym przypadku odpowiedzialne za jakąkolwiek szkodę (łącznie ze szkodami z tytułu utraty zysków związanych z prowadzeniem przedsiębiorstwa, przerw w działalności przedsiębiorstwa lub utraty informacji gospodarczej) będącą następstwem korzystania z informacji zawartych w niniejszej publikacji nawet, jeśli Wydawnictwo RM zostało zawiadomione o możliwości wystąpienia szkód. ISBN 83-7243-116-7 Redaktor prowadzący: Danuta Cyrul Redakcja: Irmina Pęgierska Korekta: Mirosława Szymańska Opracowanie graficzne okładki według oryginału: Grażyna Jędrzejec Redaktor techniczny: Beata Donner-Soska Skład: Marcin Fabijański Druk i oprawa: Oficyna Wydawnicza READ ME - Drukarnia w Łodzi Wydanie I 10 9 8 7 6 5 4 3 2 1 Spis treści Spis treści Wstęp XI Po co i dla kogo jest ta książka XII Źródła informacji XIII Standardy systemów plików XVIII Standardowa podstawa Linuksa XVIII O tej książce XIX Oficjalna wersja drukowania XX Przegląd treści XXII Konwencje zastosowane w tej książce XXIII Zgłaszanie uwag XXIV Podziękowania XXV Rozdział 1:?Wprowadzenie do sieci 1 Historia 1 Sieci TCP/IP 2 Sieci UUCP 12 Sieć w Linuksie 13 Utrzymywanie systemu 15 Rozdział 2:?Wybrane problemy sieci TCP/IP 19 Interfejsy sieciowe 19 Adresy IP 20 Rozwiązywanie adresów 22 Ruting IP 23 Internetowy protokół komunikatów kontrolnych (ICMP) 28 Rozwiązywanie nazwy hosta 29 Rozdział 3:?Konfigurowanie sprzętu sieciowego 31 Konfigurowanie jądra 34 Wycieczka po urządzeniach sieciowych Linuksa 40 Instalowanie Ethernetu 41 Sterownik PLIP 44 Sterowniki PPP i SLIP 46 Inne typy sieci 46 Rozdział 4:?Konfigurowanie urządzeń szeregowych 47 Oprogramowanie komunikacyjne do połączeń modemowych 47 Wprowadzenie do urządzeń szeregowych 48 Dostęp do urządzeń szeregowych 49 Urządzenia szeregowe 52 Używanie narzędzi konfiguracyjnych 53 Urządzenia szeregowe i monit login: 57 Rozdział 5:?Konfigurowanie sieci TCP/IP 61 Montowanie systemu plików /proc 62 Instalowanie plików binarnych 62 Ustalanie nazwy hosta 63 Przypisywanie adresu IP 63 Tworzenie podsieci 64 Tworzenie plików hosts i networks 65 Konfigurowanie interfejsu dla IP 66 Wszystko o ifconfig 74 Polecenie netstat 77 Sprawdzanie tablic ARP 80 Rozdział 6:?Usługi nazewnicze i konfigurowanie resolvera 83 Biblioteka resolvera 84 Jak działa DNS 90 Eksploatacja named 98 Rozdział 7:?IP łącza szeregowego 113 Wymagania ogólne 113 Działanie SLIP-a 114 Korzystanie z sieci prywatnych 116 Korzystanie z polecenia dip 117 Działanie w trybie serwera 122 Rozdział 8:?Protokół punkt-punkt 125 PPP w Linuksie 126 Eksploatacja pppd 127 Używanie plików opcji 128 Stosowanie chat do automatycznego dzwonienia 129 Opcje konfiguracyjne IP 132 Opcje sterowania łączem 135 Uwagi na temat bezpieczeństwa 137 Uwierzytelnianie w PPP 137 Debugowanie twojej konfiguracji PPP 141 Bardziej zaawansowana konfiguracja PPP 142 Rozdział 9 :?Firewall TCP/IP 147 Metody ataku 148 Co to jest firewall 149 Co to jest filtrowanie IP 151 Skonfigurowanie Linuksa w roli firewalla 152 Trzy sposoby realizacji filtrowania 154 Oryginalny firewall IP (jądra 2.0) 155 Łańcuchy firewalla IP (jądra 2.2) 162 Netfilter i tabele IP (jądra 2.4) 173 Operowanie bitem TOS 182 Testowanie konfiguracji firewalla 184 Przykładowa konfiguracja firewalla 186 Rozdział 10:?Liczenie ruchu IP 195 Konfigurowanie jądra do liczenia ruchu IP 195 Konfigurowanie liczenia ruchu IP 196 Wykorzystywanie wyników zliczania ruchu IP 202 Zerowanie liczników 203 Usuwanie zestawów reguł 204 Bierne zbieranie danych o ruchu 204 Rozdział 11:?Maskowanie IP i translacja adresów sieciowych 205 Skutki uboczne i dodatkowe korzyści 207 Konfigurowanie jądra do maskowania IP 208 Konfigurowanie maskowania IP 209 Obsługiwanie przeszukiwania serwerów nazw 211 Więcej na temat translacji adresów sieciowych 211 Rozdział 12:?Ważne funkcje sieciowe 213 Superserwer inetd 213 Funkcja kontroli dostępu tcpd 216 Pliki services i protocols 218 Zdalne wywołanie procedur 219 Konfigurowanie zdalnego logowania i uruchamiania 220 Rozdział 13:?System informacji sieciowej 229 Poznawanie NIS-a 230 NIS kontra NIS+ 233 NIS - strona klienta 233 Eksploatowanie serwera NIS 234 Bezpieczeństwo serwera NIS 235 Konfigurowanie klienta NIS z GNU libc 236 Wybór odpowiednich map 238 Korzystanie z map passwd i group 240 Używanie NIS-a z obsługą haseł shadow 242 Rozdział 14:?Sieciowy system plików 243 Przygotowanie NFS-a 244 Montowanie wolumenu NFS 245 Demony NFS 247 Plik exports 248 Serwer NFSv2 oparty na jądrze 250 Server NFSv3 oparty na jądrze 251 Rozdział 15:?IPX i system plików NCP 253 Xerox, Novell i historia 253 IPX i Linux 254 Konfigurowanie jądra do obsługi IPX-a i NCPFS 256 Konfigurowanie interfejsów IPX 256 Konfigurowanie rutera IPX 259 Montowanie zdalnych wolumenów NetWare 263 Kilka innych narzędzi IPX 266 Drukowanie do kolejki NetWare 267 Emulacja serwera NetWare 270 Rozdział 16:?Zarządzanie UUCP Taylora 271 Przesyłanie i zdalne wykonywanie w UUCP 273 Pliki konfiguracyjne UUCP 275 Kontrola dostępu do funkcji UUCP 289 Konfigurowanie systemu do przyjmowania połączeń komutowanych 292 Protokoły niskiego poziomu w UUCP 295 Rozwiązywanie problemów 297 Rozdział 17:?Poczta elektroniczna 301 Co to jest wiadomość pocztowa 302 Jak jest dostarczana poczta 305 Adresy e-mail 306 Jak działa ruting poczty 308 Konfigurowanie elma 313 Rozdział 18:?Sendmail 317 Wprowadzenie do sendmaila 317 Instalacja sendmaila 317 Przegląd plików konfiguracyjnych 318 Pliki sendmail.cf i sendmail.mc 319 Generowanie pliku sendmail.cf 324 Interpretacja i pisanie reguł podstawiania 324 Konfigurowanie opcji sendmaila 330 Użyteczne konfiguracje sendmaila 331 Testowanie konfiguracji 339 Eksploatowanie sendmaila 342 Sztuczki i kruczki 343 Rozdział 19:?Exim 347 Eksploatowanie Exima 348 Jeżeli twoja poczta nie dochodzi 349 Kompilowanie Exima 350 Tryby dostarczania poczty 351 Różne opcje konfiguracyjne 352 Ruting i dostarczanie poczty 353 Ochrona przed spamem 357 Konfigurowanie UUCP 358 Rozdział 20:?Grupy dyskusyjne 361 Historia Usenetu 361 Czym jest Usenet 362 Jak Usenet obsługuje grupy dyskusyjne 364 Rozdział 21:?C News 367 Dostarczanie grup dyskusyjnych 367 Instalacja 369 Plik sys 371 Plik active 374 Przetwarzanie wsadowe artykułów 375 Wygasanie grup dyskusyjnych 378 Różne dodatkowe pliki 380 Wiadomości kontrolne 382 C News w środowisku NFS 384 Narzędzia i zadania administracyjne 385 Rozdział 22:?NNTP i demon nntpd 387 Protokół NNTP 389 Instalowanie serwera NNTP 395 Ograniczanie dostępu NNTP 395 Autoryzacja NNTP 396 Współpraca nntpd z C News 397 Rozdział 23:?Internet News 399 Pewne tajniki wewnętrzne INN-a 399 Przeglądarki grup dyskusyjnych i INN 402 Instalowanie INN-a 402 Podstawowe konfigurowanie INN-a 403 Pliki konfiguracyjne INN-a 403 Eksploatowanie INN-a 418 Zarządzanie INN-em: polecenie ctlinnd 419 Rozdział 24:?Konfigurowanie przeglądarki grup dyskusyjnych 425 Konfigurowanie tina 426 Konfigurowanie trn 426 Konfigurowanie nn 427 Dodatek A:?Przykładowa sieć: browar wirtualny 429 Podłączanie sieci wirtualnej filli 430 Dodatek B:?Przydatne konfiguracje kabli 431 Kabel równoległy PLIP 431 Kabel szeregowy NULL modem 431 Dodatek C:?Linux - podręcznik administratora sieci. Wydanie drugie. Informacje o prawach autorskich 433 Dodatek D:?SAGE: cech administratorów systemu 441 Indeks 443 Wstęp Wstęp Termin "Internet" zadomowił się już na dobre w wielu językach, a mnóstwo, skądinąd poważnych ludzi, z radością podróżuje po infostradzie. Dlatego można powiedzieć, że sieci komputerowe stają się już czymś tak zwykłym jak telewizory i kuchenki mikrofalowe. Internet cieszy się niezwykłym zainteresowaniem mediów, a studenci socjologii zaczynają się specjalizować w grupach dyskusyjnych Usenetu, środowiskach elektronicznej rzeczywistości wirtualnej i WWW, badając w ten sposób nową "kulturę internetową". Oczywiście sieć istnieje z dawien dawna. Łączenie komputerów tak, aby tworzyły sieci lokalne, było powszechne w przypadku małych instalacji, a gdy maszyny były od siebie oddalone wykorzystywano łącza telekomunikacyjne. Jednakże szybki rozwój sieci ogólnoświatowych dał szansę przyłączenia się do globalnej wioski wielu zwykłym użytkownikom komputerów oraz małym, niedochodowym organizacjom prywatnym. Wyraźnie spadają ceny hostów internetowych z obsługą poczty i grup dyskusyjnych przez dostęp komutowany oraz ISDN, a pojawienie się DSL (Digital Subscriber Line) oraz technologii modemów kablowych niewątpliwie podtrzyma tę tendencję. Jeżeli mówimy o sieciach komputerowych, nie sposób nie wspomnieć o Uniksie. Oczywiście Unix nie jest jedynym systemem operacyjnym, który może pracować w sieci, ani też nawet nie jest najpopularniejszym z nich, ale w biznesie sieciowym istnieje od dawna i z całą pewnością będzie istniał jeszcze przez jakiś czas. Unix jest szczególnie ciekawy dla zwykłych użytkowników dzięki temu, że włożono wiele wysiłku w stworzenie dla PC darmowych uniksowych systemów operacyjnych, takich jak 386BSD, FreeBSD czy Linux. Linux jest dystrybuowaną bezpłatnie odmianą Uniksa, przeznaczoną dla komputerów osobistych. Aktualnie działa na różnych maszynach, i na tych z procesami firmy Intel, z procesorami Motorola 680x0 (np. Commodore Amiga i Apple Macintosh); na maszynach Sun SPARC i Ultra-SPARC; na Alphach firmy Compaq; MIPS-ach; na PowerPC, czyli na nowej generacji komputerów Apple Macintosh, i na StrongARM-ach, takich jak Netwinder firmy rebel.com czy palmtopy firmy 3Com. Linux został zaadaptowany także na pewne stosunkowo mało znane platformy, takie jak Fujitsu AP-1000 i IBM System 3/90. Aktualnie realizowane są adaptacje na inne interesujące architektury, a zadanie przeniesienia Linuksa do postaci zamkniętego kontrolera także wygląda obiecująco. Linux rozwija się dzięki zaangażowaniu dużej grupy ochotników z Internetu. Projekt został zapoczątkowany w 1990 roku przez Linusa Torvaldsa - wówczas studenta fińskiego college'u - w ramach zajęć z systemów operacyjnych. Od tego czasu Linux urósł do rangi pełnego klonu Uniksa, na którym można uruchamiać aplikacje tak różnorodne, jak programy do symulacji i modelowania, procesory tekstu, systemy rozpoznawania mowy, przeglądarki WWW i mnóstwo innego oprogramowania, włączając w to różne doskonałe gry. Współpracuje z różnorodnym sprzętem, a zawiera pełną implementację sieci TCP/IP (łącznie z protokołami SLIP i PPP oraz firewallami), pełną implementację protokołu IPX, a także implementacje wielu funkcji oraz protokołów, których nie znajdziemy w żadnym innym systemie operacyjnym. Linux jest wydajny, szybki i darmowy, a jego popularność na świecie poza Internetem rośnie w szybkim tempie. Sam system operacyjny Linux został objęty licencją publiczną GNU, tą samą, która jest używana przez oprogramowanie tworzone przez Free Software Foundation (Fundację Wolnego Oprogramowania). Licencja pozwala każdemu na dystrybuowanie i modyfikowanie oprogramowania (bezpłatnie lub dla zysku) dopóty, dopóki wszystkie modyfikacje i dystrybucje są również bezpłatnie udostępniane. Określenie "wolne oprogramowanie" oznacza wolność aplikacji, a nie wolność kosztów. Po co i dla kogo jest ta książka Niniejsza książka została napisana po to, aby w jednym miejscu zebrać informacje potrzebne administratorom sieci środowiska Linux. Zarówno początkujący, jak i zaawansowani użytkownicy powinni tu znaleźć informacje potrzebne do wykonania większości najważniejszych zadań administracyjnych, wymaganych do konfiguracji sieci w Linuksie. Temat tej książki - sieci - jest prawie nieograniczony, a więc oczywiście niemożliwością jest opisanie wszystkiego i w każdym aspekcie. Podjęliśmy próbę prezentacji większości ważnych i powszechnie spotykanych zadań. Naszym zamierzeniem było, aby ta książka służyła pomocą nawet początkującym adeptom sieci linuksowych (także tym, którzy nie mieli jeszcze do czynienia z uniksopodobnym systemem operacyjnym), aby po jej lekturze mogli poprawnie skonfigurować swoją sieć w Linuksie. Istnieje wiele książek i innych źródeł informacji, które poruszają tematy opisane w tej książce (z małymi wyjątkami prawdziwie linuksowych funkcji, takich jak nowy interfejs firewalla, który nie jest nigdzie indziej dobrze udokumentowany). Gdybyś chciał się dowiedzieć więcej, w poniższym podrozdziale zamieszczamy bibliografię. Źródła informacji Jeżeli jesteś nowicjuszem w świecie Linuksa, masz wiele do przejrzenia i przeczytania. Pomocne, aczkolwiek niekonieczne, jest posiadanie dostępu do Internetu. Podręczniki zespołu Linux Documentation Project (Projekt Dokumentacji Linuksa - LDP) Projekt Dokumentacji Linuksa to grupa ochotników, który opracowują książki (przewodniki), dokumenty HOWTO, strony podręcznika elektronicznego na różne tematy: od instalacji po programowanie jądra. Publikacje LDP to między innymi: Linux Installation and Getting Started Ta książka, napisana pod kierunkiem Matta Welsha, opisuje jak zdobyć, zainstalować i używać Linuksa. Zawiera wprowadzenie do Uniksa i informacje o administracji systemu, systemie X Window oraz sieci. Linux System Administration Guide Ta książka, napisana przez Larsa Wirzeniusa i Joannę Oja, jest ogólnym przewodnikiem po administracji Linuksa i porusza takie tematy, jak tworzenie i konfigurowanie użytkowników, wykonywanie kopii zapasowych systemu, konfigurowanie podstawowych pakietów i instalowanie oraz uaktualnianie oprogramowania. Linux System Administration Made Easy Ta książka, napisana przez Steve'a Framptona, opisuje codzienne zadania administracyjne i zagadnienia związane z utrzymaniem Linuksa w odniesieniu do jego użytkowników. Linux Programmers Guide Ta książka, napisana przez B. Scotta Burketta, Svena Goldta, Johna D. Harpera, Svena van der Meera i Matta Welsha, będzie interesująca dla tych, którzy chcą tworzyć aplikacje dla Linuksa. The Linux Kernel Ta książka, napisana przez Davida A. Ruslinga, zawiera wprowadzenie do jądra Linuksa: opisuje jego budowę oraz działanie. The Linux Kernel Module Programming Guide Ta książka, napisana przez Ori Pomerantza, stanowi podręcznik wyjaśniający, jak pisać moduły jądra Linuksa. W fazie tworzenia są kolejne podręczniki. Więcej informacji na temat LDP znajdziesz na stronach WWW pod adresem http://www.linuxdoc.org/ lub jednym z jego serwerów lustrzanych. Dokumenty HOWTO Dokumenty HOWTO poświęcone Linuksowi to szereg szczegółowych opracowań omawiających bardzo różne aspekty systemu, takie jak instalacja i konfiguracja oprogramowania systemu X Window lub pisanie w asemblerze pod Linuksem. Generalnie znajdują się one w podkatalogu HOWTO ośrodków FTP lub są dostępne na stronach WWW zawierających dokumenty Projektu Dokumentacji Linuksa. W pliku HOWTO-INDEX znajdziesz listę tego, co jest dostępne. Mogą ci się przydać: Installation HOWTO, opisujący jak zainstalować Linuksa na twoim komputerze, Hardware Compatibility HOWTO, zawierający listę urządzeń, o których wiadomo, że działają w Linuksie, oraz Distribution HOWTO, zawierający listę sprzedawców oprogramowania oferujących Linuksa na dyskietkach lub na płytach CD-ROM. Często zadawane pytania na temat Linuksa (Linux Frequently Asked Questions), FAQ FAQ (The Linux Frequently Asked Questions with Answers) gromadzi różnorodne pytania i odpowiedzi na temat systemu. Jest to obowiązkowa lektura dla każdego nowicjusza. Dokumentacja dostępna przez FTP Jeżeli masz dostęp do anonimowych serwerów FTP, możesz z nich pobrać całą wspomnianą tutaj dokumentację Linuksa. Wypróbuj takie adresy jak metalab.unc.edu:/pub/Linux/docs i tsx-11.mit.edu/pub/linux/docs. Dokumentacja dostępna przez WWW Dostępnych jest wiele ośrodków WWW związanych z Linuksem. Macierzysta strona Projektu Dokumentacji Linuksa znajduje się pod adresem http://www.linuxdoc.org/. OSWG (Open Source Writers Guild) jest projektem wykraczającym poza Linuksa. OSWG, podobnie jak ta książka, opowiada się za tworzeniem dokumentacji OpenSource. Witryna macierzysta OSWG znajduje się pod adresem http://www.oswg. org:8080/oswg. Obie powyższe witryny zawierają wersje hipertekstowe (i inne) wielu dokumentów związanych z Linuksem. Dokumentacja dostępna odpłatnie Liczne wydawnictwa i sprzedawcy oprogramowania publikują prace stworzone w ramach Projektu Dokumentacji Linuksa. Dwaj przykładowi sprzedawcy to: Specialized Systems Consultants, Inc. (SSC) http://www.ssc.com/ P.O. Box 55549 Seattle, WA 98155-0549 1-206-782-7733 1-206-782-7191 (faks) sales@ssc.com oraz Linux Systems Labs http://www.lsl.com/ 18300 Tara Drive Clinton Township, MI 48036 1-810-987-8807 1-810-987-3562 (faks) sales@lsl.com Obie firmy sprzedają kompendia dokumentów HOWTO i innej dokumentacji dotyczącej Linuksa w formie drukowanej. O'Reilly & Associates wydaje serię książek o Linuksie. Niniejsza książka powstała w ramach Projektu Dokumentacji Linuksa, ale większość została napisana niezależnie. Należą do nich: Running Linux (wyd. pol.: Linux, Wydawnictwo RM, Warszawa 2000) Przewodnik po instalacji i użytkowaniu systemu, opisujący, jak najlepiej wykorzystać komputer osobisty, pracując w Linuksie. Learning Debian GNU/Linux Learning Red Hat Linux (wyd. pol.: Red Hat Linux, Wydawnictwo RM, Warszawa 2000) Książki bardziej podstawowe niż Running Linux. Zawierają one popularne dystrybucje na płycie CD-ROM i informują dokładnie, jak je skonfigurować i jak z nich korzystać. Linux in Nutshell (wyd. pol.: Linux - podręcznik użytkownika, Wydawnictwo RM, Warszawa 1999) Kolejna książka z doskonałej serii "podręcznik użytkownika". Daje wyczerpujący opis poszczególnych poleceń Linuksa. Linux Journal and Linux Magazine "Linux Journal" i "Linux Magazine" to miesięczniki dla społeczności linuksowej, pisane i wydawane przez licznych linuksowych aktywistów. Poziom artykułów jest bardzo różny: od pytań nowicjuszy, po odpowiedzi dotyczące programowania jądra. Nawet jeżeli masz dostęp do grup dyskusyjnych Usenetu, te czasopisma są doskonałym sposobem, aby być na bieżąco ze sprawami społeczności Linuksa. "Linux Journal" jest najstarszym czasopismem i jest wydawany przez wspomniane wcześniej SSC, Incorporated. Czasopismo to możesz także znaleźć w sieci WWW pod adresem http://www.linuxjournal.com/. "Linux Magazine" jest nowszą, niezależną publikacją. Macierzysty adres WWW tego czasopisma to http://www.linuxmagazine.com/. Linuksowe grupy dyskusyjne Usenetu Oto grupy dyskusyjne Usenetu poświęcone Linuksowi: comp.os.linux.announce Moderowana grupa dyskusyjna zawierająca zapowiedzi nowego oprogramowania, dystrybucji, raporty o błędach i nowinki z życia społeczności Linuksa. Wszyscy użytkownicy Linuksa powinni czytać tę grupę. Propozycje mogą być wysyłane na adres linux-announce@news.ornl.gov. comp.os.linux.help Ogólne pytania i odpowiedzi na temat instalacji i użytkowania Linuksa. comp.os.linux.admin Dyskusje związane z administrowaniem systemu Linux. comp.os.linux.networking Dyskusje związane z siecią w Linuksie. comp.os.linux.development Dyskusje na temat tworzenia jądra Linuksa i samego systemu. comp.os.linux.misc Inne dyskusje, które nie pasują do żadnej z poprzednich kategorii. Istnieje również kilka innych grup poświęconych Linuksowi i prowadzonych w językach innych niż angielski, a należą do nich na przykład fr.comp.os.linux po francusku czy de.comp.os.linux po niemiecku. Pocztowe listy dyskusyjne związane z Linuksem Istnieje szereg specjalistycznych pocztowych list dyskusyjnych na temat Linuksa. Spotkasz na nich wiele osób, które chętnie odpowiedzą na twoje pytania. Najbardziej znane z nich to listy obsługiwane przez uniwersytet Rutgers. Możesz się do nich zapisać, wysyłając wiadomość e-mail sformatowaną w następujący sposób: To: majordomo@vger.rutgers.edu Subject: anything at all Body: subscribe nazwa-listy Niektóre listy związane z siecią w Linuksie to: linux-net Dyskusje związane z siecią w Linuksie. linux-ppp Dyskusje związane z implementacją PPP w Linuksie. linux-kernel Dyskusje związane z tworzeniem jądra Linuksa. Elektroniczne wsparcie Linuksa W wielu miejscach w sieci można uzyskać pomoc elektroniczną. Ochotnicy z całego świata oferują tam swoją specjalistyczną wiedzę i usługi tym użytkownikom, którzy mają pytania i problemy. Sieć OpenProjects IRC to sieć IRC poświęcona w całości projektom otwartym - zarówno Open Source, jak i Open Hardware. Niektóre kanały są przeznaczone do udostępniania elektronicznego wsparcia dla Linuksa. IRC to skrót od Internet Relay Chat. Jest to usługa sieciowa pozwalająca interaktywnie "rozmawiać" przez Internet z innymi użytkownikami. Sieci IRC obsługują wiele kanałów, na których grupy prowadzą pisane "rozmowy". Cokolwiek napiszesz na kanale, będzie to widoczne dla wszystkich pozostałych uczestników "rozmowy". W sieci OpenProjects IRC istnieje szereg aktywnych kanałów, na których spotkasz użytkowników przez 24 godziny na dobę, 7 dni w tygodniu. Są to użytkownicy, którzy chcą i potrafią pomóc w rozwiązaniu twoich problemów z Linuksem albo mogą po prostu z tobą pogadać. Z usługi tej możesz korzystać po zainstalowaniu klienta IRC, na przykład irc-II, podłączeniu się do serwera o zadanej nazwie, np. irc.openprojects.org:6667, i przyłączeniu się do kanału #linpeople. Grupy użytkowników Linuksa Bezpośrednią pomoc oferuje też wiele grup użytkowników Linuksa z całego świata. Ich uczestnicy angażują się w taką działalność, jak organizowanie dni instalacji, seminaria i dyskusje panelowe, prezentacje i inne imprezy towarzyskie. Grupy użytkowników Linuksa są doskonałym sposobem na spotkanie się z innymi linuksowcami z twojego rejonu. Istnieje szereg list grup użytkowników Linuksa. Do lepiej znanych należą: Group of Linux Users Everywhere - http://www.ssc.com/glue/groups LUG list project - http://www.nllgg.nl/lugww/ LUG registry - http://www.linux.org/users/ Skąd wziąć Linuksa Nie ma jednej jedynej dystrybucji oprogramowania dla Linuksa. Takich dystrybucji jest wiele, m.in. Debian, RedHat, Caldera, Corel, SuSE i Slackware. Każda dystrybucja zawiera wszystko, czego potrzebujesz do uruchomienia pełnego systemu Linux: jądro, podstawowe programy użytkowe, biblioteki, pliki pomocnicze i aplikacje. Dystrybucje Linuksa można zdobyć z szeregu źródeł elektronicznych, jak Internet. Każda poważna dystrybucja posiada własny ośrodek FTP i WWW. Oto niektóre ośrodki: Caldera http://www.caldera.com/ftp://ftp.caldera.com/ Corel http://www.corel.com/ftp://ftp.corel.com/ Debian http://www.debian.org/ftp://ftp.debian.org/ RedHat http://www.redhat.com/ftp://ftp.redhat.com/ Slackware http://www.slackware.com/ftp://ftp.slackware.com/ SuSE http://www.suse.com/ftp://ftp.suse.com/ Popularne archiwa FTP również zawierają różne dystrybucje Linuksa. Najbardziej znane z nich to: metalab.unc.edu:/pub/Linux/distributions/ ftp.funet.fi:/pub/Linux/mirrors/ tsx-11.mit.edu:/pub/linux/distributions/ mirror.aarnet.edu.au:/pub/linux/distributions/ Wiele z nowoczesnych dystrybucji można zainstalować bezpośrednio z Internetu. Jednak w przypadku typowej instalacji należy ściągnąć sporą liczbę oprogramowania, a więc prawdopodobnie zdecydujesz się na to tylko, jeżeli masz szybkie stałe połączenie sieciowe lub, jeżeli musisz uaktualnić swoją instalację*. Linuksa można kupić na płycie CD-ROM u coraz większej liczby sprzedawców. Jeżeli w twoim sklepie komputerowym go nie ma, możesz poprosić o sprowadzenie. Większość popularnych dystrybucji można zdobyć na płycie CD-ROM. Niektórzy sprzedawcy tworzą produkty składające się z wielu płyt CD-ROM zawierających poszczególne dystrybucje Linuksa. Jest to idealny sposób na wypróbowanie różnych dystrybucji, aby móc stwierdzić, która jest naszą ulubioną. Standardy systemów plików Niegdyś jednym z problemów, który dotykał dystrybucji Linuksa oraz pakietów oprogramowania, był brak jednolitego systemu plików. Wynikały z tego niezgodności pomiędzy różnymi pakietami, co wymagało od użytkowników i administratorów lokalizowania różnych plików i programów. Aby zaradzić tej kłopotliwej sytuacji w sierpniu 1993 roku powołano zespół do spraw standaryzacji systemu plików Linuksa (Linux File System Standard Group - FSSTND). W ciągu sześciu miesięcy opracowano szkic spójnej struktury systemu plików i zdefiniowano rozkład większości istotnych programów i plików konfiguracyjnych. Oczekiwano, że standard ten zostanie zaimplementowany w większości głównych dystrybucji Linuksa i pakietach. Niezupełnie tak się stało. Choć w większości dystrybucji starano się spełnić wymogi FSSTND, udało się to tylko w niewielu. W książce tej zakładamy, że wszelkie omawiane pliki znajdują się w miejscach określonych przez standard. Alternatywne niestandardowe lokalizacje będą przywoływane tylko wtedy, gdy są utrwalane długą tradycją. Linux FSSTND obowiązywał do 1997 roku, kiedy został zastąpiony przez FHS (Linux File Hierarchy Standard). FHS rozwiązuje zagadnienia międzyarchitekturowe, nieuwzględnione przez FSSTND. FHS można zdobyć z katalogu z dokumentacją większości ośrodków FTP Linuksa i ich serwerów lustrzanych lub ze strony macierzystej pod adresem http://www.pathname.com/fhs/. Z Danielem Quinlanem - koordynatorem grupy FHS - można skontaktować się pod adresem quinlan@transmeta.com. Standardowa podstawa Linuksa Wielość dystrybucji Linuksa, choć umożliwia wybór jego użytkownikom, przysparza problemów twórcom oprogramowania - szczególnie tego, które nie jest darmowe. Każda dystrybucja zawiera pewne podstawowe biblioteki, narzędzia konfiguracyjne, aplikacje systemowe i pliki konfiguracyjne. Niestety, różnice pomiędzy wersjami, nazwami i lokalizacjami powodują, że bardzo trudno jest zgadnąć, co będzie w danej dystrybucji. A bez tej wiedzy nie da się stworzyć binarnych wersji aplikacji, które działałyby niezawodnie we wszystkich dystrybucjach Linuksa. Aby rozwiązać ten problem, powołano nowy projekt o nazwie "Linux Standard Base" (standardowa podstawa Linuksa). Jego celem jest opisanie standardowej podstawy dystrybucji, do której dostosują się poszczególne dystrybucje. Jeżeli programista stworzy aplikację w oparciu o standardową podstawę, to będzie ona działała we wszelkich dystrybucjach zgodnych ze standardem. Informacje na temat stanu projektu standardowej podstawy Linuksa możesz znaleźć na jego stronie macierzystej pod adresem http://www.linuxbase.org/. Jeżeli martwisz się o zgodność, szczególnie oprogramowania komercyjnego, powinieneś upewnić się, czy w przypadku twojej dystrybucji zostały podjęte kroki prowadzące do zgodności z projektem standaryzacyjnym. O tej książce Gdy Olaf dołączył do Projektu Dokumentacji Linuksa w 1992 roku, napisał dwa małe rozdziały na temat UUCP i smaila, które zamierzał umieścić w książce System Administrator's Guide. Sieci TCP/IP zaczęły dopiero powstawać. W miarę ich rozwoju te dwa "małe rozdziały" zaczęły się rozrastać. Wtedy Olaf pomyślał, że byłoby dobrze mieć przewodnik po sieci. Każdy mówił: "Świetny pomysł", "zrób to!". A więc wziął się do pracy i napisał pierwszą wersję przewodnika po sieci, która została wydana we wrześniu 1993 roku. Olaf kontynuował prace nad przewodnikiem po sieci i ostatecznie stworzył znacznie rozszerzoną jego wersję. Rozdział na temat sendmaila napisał Vince Skahan. W tym wydaniu rozdział ten został całkowicie zmieniony, ze względu na nowy interfejs konfiguracyjny sendmaila. Wersja książki, którą czytasz, została skorygowana i uaktualniona przez Terry'ego Dawsona* na życzenie wydawnictwa O'Reilly & Associates. Terry przez 20 lat był operatorem radia amatorskiego, z czego 15 lat przepracował w przemyśle telekomunikacyjnym. Był współautorem dokumentu NET-FAQ i napisał oraz utrzymywał różne dokumenty HOWTO związane z siecią. Terry zawsze z entuzjazmem wspierał projekt podręcznika administratora sieci i dodał w niniejszej edycji kilka rozdziałów na najnowsze tematy, które ze zrozumiałych względów nie trafiły do pierwszego wydania. Dokonał też mnóstwa zmian w celu uaktualnienia całej książki. Rozdział omawiający exim napisał Philip Hazel**, który jest głównym twórcą pakietu. Książka ta ma formę sekwencji kroków, jakie należy podjąć, by skonfigurować system do pracy w sieci. Rozpoczyna się omówieniem podstawowych pojęć sieciowych, a w szczególności sieci opartych na TCP/IP. Następnie kolejno wprowadza w konfigurowanie TCP/IP na poziomie urządzenia konfigurowanie firewalli, liczenie ruchu IP (accounting) i maskowanie IP, wreszcie w konfigurowanie popularnych aplikacji, takich jak rlogin i tym podobne, sieciowego systemu plików (NFS - Network File System) oraz systemu informacji sieciowej (NIS - Network Information System). Dalej znajduje się rozdział o tym, jak skonfigurować maszynę jako węzeł UUCP. Większość pozostałych podrozdziałów jest poświęcona dwóm podstawowym aplikacjom, które działają na TCP/IP i UUCP: poczcie elektronicznej i grupom dyskusyjnym. Specjalny rozdział został poświęcony protokołowi IPX i systemowi plików NCP, ponieważ są one używane w środowiskach korporacyjnych, w których spotyka się Linuksa. W części omawiającej pocztę znajduje się bardziej gruntowne wprowadzenie do transportu i rutingu poczty oraz miriady schematów adresowania, które możesz napotkać. Opisuje ona konfigurację exima i zarządzanie nim. Exim to agent transportowy poczty, idealny tam, gdzie nie są wymagane UUCP ani tym bardziej sendmail, który jest dla realizujących ruting bardziej skomplikowany, niż te obsługiwane przez UUCP. Część poświęcona grupom dyskusyjnym daje pojęcie o tym, jak działa Usenet. Omawia INN i C News - dwa powszechnie używane pakiety oprogramowania transportowego grup dyskusyjnych oraz zastosowanie NNTP do zapewnienia dostępu do czytania grup w sieci lokalnej. Książkę zamyka rozdział na temat stosowania najpopularniejszych programów do czytania grup dyskusyjnych w Linuksie. Oczywiście książka ta na pewno nie jest w stanie wyczerpująco odpowiedzieć na wszystkie potencjalne pytania. Tak, więc jeżeli będziesz postępował zgodnie z instrukcjami w niej zawartymi, a coś wciąż nie będzie działało, bądź cierpliwy. Niektóre z twoich problemów mogą wynikać z naszych błędów (zobacz podrozdział Zgłaszanie uwag w dalszej części Wstępu), ale mogą także być spowodowane zmianami w oprogramowaniu sieciowym. Dlatego powinieneś sprawdzić najpierw informacje zawarte w zasobach. Istnieje duże prawdopodobieństwo, że nie tylko ty masz takie problemy, a więc poprawka lub przynajmniej proponowane rozwiązanie jest już być może znane. Jeżeli masz okazję, powinieneś także spróbować zdobyć najnowszą wersję jądra i sieci z jednego z linuksowych ośrodków FTP lub z pobliskiego BBS-u. Wiele problemów wynika z nierównomiernego rozwoju różnego oprogramowania, które nie współpracuje poprawnie ze sobą. W końcu Linux to "praca w toku". Oficjalna wersja drukowana Na jesieni 1993 roku Andy Oram, który prawie od początku był związany z listą dyskusyjną LDP, zaproponował Olafowi opublikowanie tej książki w wydawnictwie O'Reilly & Associates. Był nią zachwycony, ale nigdy nie przypuszczał, że odniesie ona taki sukces. Postanowiono, że O'Reilly stworzy rozszerzoną oficjalną wersję drukowaną przewodnika po sieci, natomiast Olaf zatrzyma prawa autorskie i źródła książki będą mogły być rozpowszechniane za darmo. Oznacza to, że masz wolny wybór: możesz wziąć różne darmowe wersje dokumentu z najbliższego ośrodka lustrzanego Projektu Dokumentacji Linuksa i wydrukować je sobie albo zakupić oficjalną wersję drukowaną wydaną przez O'Reilly'ego. Nasuwa się pytanie: dlaczego masz płacić za coś, co możesz mieć za darmo? Czy Tim O'Reilly postradał zmysły i wydaje coś, co każdy może sobie sam wydrukować, a nawet sam sprzedawać?*. Czy istnieją jakieś różnice pomiędzy tymi wersjami? Odpowiedzi brzmią "to zależy", "nie, zdecydowanie nie" i "tak i nie". O'Reilly & Associates podejmuje ryzyko, wydając przewodnik po sieci w formie tradycyjnej, ale jakoś się im to opłaca (poprosili autorów, by przygotowali następne wydanie). Wierzymy, że to przedsięwzięcie jest doskonałym przykładem tego, jak świat darmowego oprogramowania i firmy komercyjne mogą ze sobą współpracować, by stworzyć coś, z czego obie strony czerpią korzyści. Z naszego punktu widzenia wydawnictwo O'Reilly przysłużyło się społeczności Linuksa (nie tylko tą książką, która jest dostępna w twojej księgarni). Dzięki niemu Linux zaczął być rozpoznawany jako coś poważnego: jako rentowna i użyteczna alternatywa dla innych, komercyjnych systemów operacyjnych. Jeżeli jakaś księgarnia techniczna w USA nie ma u siebie przynajmniej jednej półki z książkami wydawnictwa O'Reilly, to jest to kiepska księgarnia. Dlaczego to wydają? Uznają to za swoją specjalność. Oto, czego oczekują, podpisując z autorami kontrakt na napisanie książki o Linuksie: tempo, poziom szczegółowości i styl mają dokładnie odpowiadać innym wydanym przez nich książkom. Celem licencji LDP jest zapewnienie wszystkim dostępu do książki. Niektórzy mogą wydrukować sobie tę książkę sami i nikt nie będzie cię winił, jeżeli z niej skorzystasz. Jednak, jeżeli nie miałeś okazji zobaczyć wersji wydawnictwa O'Reilly, przejdź się do księgarni albo obejrzyj książkę u kolegi. Wydaje nam się, że spodoba ci się to, co zobaczysz, i będziesz chciał książkę kupić. Jakie są, więc różnice pomiędzy wersją drukowaną a wersją elektroniczną? Andy Oram włożył wiele pracy w to, aby przetworzyć nasze chaotyczne myśli w potoczysty wykład wart wydrukowania. (Dokonał także korekty kilku innych książek stworzonych w ramach Projektu Dokumentacji Linuksa, służąc społeczności Linuksa całą swoją fachową wiedzą). Na redakcji Andy'ego książka znacznie zyskała w stosunku do wersji oryginalnej. Nie można było marnować okazji skorzystania z usług i umiejętności profesjonalnego redaktora. Pod wieloma względami praca Andy'ego jest równie ważna jak autorów. To samo dotyczy również redaktorów technicznych, którzy nadali książce obecny kształt. Wszystkie te poprawki zostały również wprowadzone w wersji elektronicznej, a więc w zawartości nie ma różnic. Jednak wciąż wersja wydana przez O'Reilly'ego będzie inna. Jest porządnie oprawiona. Możesz mieć problemy z ładnym wydrukowaniem wersji domowej. Jest też mało prawdopodobne, abyś uzyskał zbliżoną jakość, a jeśli już - to zapewne za dużo większe pieniądze. Ponadto nasze amatorskie ilustracje zostały w wersji drukowanej zastąpione innymi grafikami, pięknie przygotowanymi przez profesjonalnych artystów z wydawnictwa O'Reilly. Dla wersji drukowanej przygotowano też nowy, dokładniejszy indeks, dzięki czemu dużo łatwiej wyszukuje się informacje. Jeżeli ta książka jest czymś, co zamierzasz przeczytać od początku do końca, powinieneś zastanowić się nad przeczytaniem oficjalnej wersji drukowanej. Przegląd treści Rozdział 1, Wprowadzenie do sieci, omawia historię Linuksa i podaje podstawowe informacje o UUCP, TCP/IP, różnych protokołach, sprzęcie i bezpieczeństwie. Kolejne kilka rozdziałów omawia konfigurowanie Linuksa w sieci TCP/IP i uruchamianie podstawowych aplikacji. Nieco dokładniej przyglądamy się IP w rozdziale 2, Wybrane problemy sieci TCP/IP, zanim przejdziemy do edycji plików i tym podobnych tematów. Jeżeli wiesz już, jak działa ruting IP i na czym polega rozwiązywanie adresów, możesz pominąć ten rozdział. Rozdział 3, Konfigurowanie sprzętu sieciowego, omawia podstawowe zagadnienia konfiguracyjne, takie jak tworzenie jądra i konfigurowanie karty Ethernet. Konfiguracja portów szeregowych jest przedstawiona oddzielnie w rozdziale 4, Konfigurowanie urządzeń szeregowych, ponieważ ten temat nie dotyczy jedynie sieci TCP/IP, ale ma także związek z UUCP. Rozdział 5, Konfigurowanie sieci TCP/IP, pomaga skonfigurować maszynę w sieci TCP/IP. Zawiera wskazówki instalacyjne dla samodzielnych hostów z włączonym jedynie interfejsem pętli zwrotnej i hostów podłączonych do sieci Ethernet. Pokazuje także kilka przydatnych narzędzi, których możesz używać do testowania i debugowania swojej konfiguracji. Rozdział 6, Usługi nazewnicze i konfigurowanie resolvera, wyjaśnia, jak skonfigurować rozwiązywanie nazw i uruchomić serwer nazw. Rozdział 7, IP łącza szeregowego, pokazuje, jak zestawić połączenie SLIP i szczegółowo omawia dip - narzędzie pozwalające na automatyzację większości niezbędnych kroków. Rozdział 8, Protokół punkt-punkt, jest poświęcony PPP i pppd - demonowi PPP. Rozdział 9, Firewall TCP/IP, rozwija zagadnienia bezpieczeństwa sieciowego i opisuje firewall TCP/IP dla Linuksa oraz narzędzia do jego konfiguracji: ipfwadm, ipchains i iptables. Firewall IP zapewnia dokładną kontrolę nadal tym, kto dostaje się do sieci i z jakiego hosta. Rozdział 10, Liczenie ruchu IP, wyjaśnia, jak skonfigurować funkcję liczenia ruchu IP w Linuksie, tak, aby śledzić, jak duży jest ruch wychodzący i kto go generuje. Rozdział 11, Maskowanie IP i translacja adresów sieciowych, omawia własności specjalnego typu oprogramowania sieciowego Linuksa zwanego maskowaniem IP, które pozwala łączyć ze sobą całe sieci IP i korzystać z Internetu tylko przy użyciu jednego adresu IP, tak że wewnętrzna struktura sieci staje się niewidoczna. Rozdział 12, Ważne funkcje sieciowe, stanowi krótkie wprowadzenie do konfigurowania pewnych ważniejszych aplikacji sieciowych, takich jak rlogin, ssh i tym podobne. Rozdział ten omawia również zarządzanie usługami przez inetd i podpowiada, w jaki sposób można zwiększyć bezpieczeństwo pewnych usług skierowanych do zaufanych hostów. Rozdział 13, System informacji sieciowej, i rozdział 14, Sieciowy system plików, omawiają NIS i NFS. NIS to narzędzie używane do dystrybuowania informacji administracyjnych, takich jak hasła użytkownika w sieci lokalnej. NFS pozwala na współdzielenie systemów plików pomiędzy hostami w sieci. W rozdziale 15, IPX i system plików NCP, omawiamy protokół IPX i system plików NCP. Pozwalają one zintegrować Linuksa ze środowiskiem Novell Netware przez współdzielenie plików oraz drukarek z maszynami nielinuksowymi. Rozdział 16, Zarządzanie UUCP Taylora, stanowi wyczerpujące wprowadzenie do administrowania UUCP Taylora - darmową implementacją UUCP. Pozostałe rozdziały książki szczegółowo przedstawiają pocztę elektroniczną i grupy dyskusyjne Usenetu. Rozdział 17, Poczta elektroniczna, wprowadza w główne zagadnienia poczty elektronicznej, takie jak wygląd adresów pocztowych i sposób, w jaki system obsługuje pocztę, by dotarła do adresata. Rozdział 18, Sendmail, i rozdział 19, Exim, omawiają konfigurację programów sendmail i exim - dwóch małych agentów transportowych, które możesz wykorzystać w Linuksie. Przedstawiamy oba, ponieważ exim jest łatwiejszy do zainstalowania dla początkującego, a sendmail obsługuje UUCP. Od rozdziału 20, Grupy dyskusyjne, do rozdziału 23, Internet News, wyjaśniamy obsługę wiadomości Usenetu i sposób instalacji i używania C News, nntpd i INN - trzech popularnych pakietów oprogramowania do zarządzania wiadomościami Usenetu. Po krótkim wprowadzeniu w rozdziale 20, możesz przeczytać rozdział 21, C News, jeżeli chcesz przesyłać wiadomości za pomocą C News - tradycyjnej usługi używanej wraz z UUCP. Kolejne rozdziały omawiają nowocześniejsze metody wykorzystujące protokół internetowy NNTP (Network News Transport Protocol). Rozdział 22, NNTP i demon nntpd, przedstawia sposób konfiguracji prostego demona NNTP o nazwie nntp, który zapewnia dostęp do czytania wiadomości w sieci lokalnej, zaś rozdział 23 opisuje silniejszy serwer do bardziej intensywnych transferów NetNews'ów: INN (InterNet News). I na koniec rozdział 24, Konfigurowanie przeglądarki grup dyskusyjnych, pokazuje, jak skonfigurować różne programy do czytania grup. Konwencje zastosowane w tej książce We wszystkich przykładach przedstawionych w tej książce zakładamy, że używasz powłoki, która jest kompatybilna z sh. Standardową powłoką wszystkich dystrybucji Linuksa jest bash kompatybilna z sh. Jeżeli korzystasz z csh, będziesz musiał odpowiednio zmodyfikować przykłady. Poniżej przedstawiamy listę konwencji typograficznych użytych w książce: Czcionka pochyła Używana do oznaczenia nazw plików i katalogów, programów i poleceń, opcji wiersza poleceń, adresów e-mail i ścieżki, URL i do podkreślenia nowych pojęć. Czcionka pogrubiona Używana do nazw maszyn, hostów, ośrodków, użytkowników i ID oraz, okazjonalnie, do podkreślania pojęć. Czcionka o stałej szerokości Używana w przykładach do pokazania zawartości kodu plików lub wyniku działania poleceń oraz wskazywania zmiennych środowiskowych i słów kluczowych, które pojawiają się w kodzie. Czcionka pochyła o stałej szerokości Używana do wskazania opcji zmiennych, słów kluczowych albo tekstu, który użytkownik ma zastąpić konkretną wartością. Czcionka pogrubiona o stałej szerokości Używana w przykładach do pokazania poleceń lub innego tekstu, który powinien być wpisywany przez użytkownika dosłownie. Ramka z tą ikoną zawiera ostrzeżenie. Łatwo tu o błąd, który może źle się skończyć dla twojego systemu lub jest trudny od naprawienia. Ramka z tą ikoną zawiera komentarz do pobliskiego tekstu. Zgłaszanie uwag Informacje zawarte w tej książce sprawdzaliśmy i weryfikowaliśmy na tyle, na ile byliśmy w stanie, ale pewne rzeczy mogły się zmienić (lub my mogliśmy popełnić błąd!). Będziemy wdzięczni za powiadomienie nas o wszelkich dostrzeżonych błędach oraz podzielenie się swoimi sugestiami, co do przyszłych wydań. Prosimy pisać na adres: O'Reilly & Associates, Inc. 101 Morris Street Sebastopol, CA 95472 1-800-998-9938 (w USA lub Kanadzie) 1-707-829-0515 (międzynarodowy lub lokalny) 1-707-829-0104 (faks) Możesz nam także wysyłać wiadomości elektronicznie. Aby zapisać się na listę dyskusyjną lub poprosić o katalog, wyślij e-mail na adres: info@oreilly.com Aby poprosić o pomoc techniczną lub komentarz na temat książki, wyślij e-mail na adres: bookquestions@oreilly.com Prowadzimy witrynę WWW dla niniejszej książki. Znajdują się na niej przykłady, errata i plany przyszłych wydań. Strona ta znajduje się pod adresem: http://www.oreilly.com/catalog/linag2 Więcej informacji na temat tej i innych książek znajdziesz w witrynie WWW wydawnictwa O'Reilly: http://www.oreilly.com/ Podziękowania To wydanie Podręcznika administratora sieci jest niemal wyłączną zasługą Olafa i Vince'a. Trudno docenić wysiłek włożony w badania i napisanie tego typu książki, jeżeli nie zrobi się tego samemu. Uaktualnianie książki było wyzwaniem - poważnym, ale dzięki dobrej podstawie także przyjemnym. Książka wiele zawdzięcza tym, którzy poświęcili czas na jej korektę i pomogli usunąć wiele błędów, zarówno technicznych, jak i językowych. W tym działaniu znakomicie się uzupełniali Phil Hughes, John MacDonald i Erik Ratcliffe. Serdeczne podziękowania kierujemy do członków zespołu redakcyjnego wydawnictwa O'Reilly, z którymi mieliśmy przyjemność pracować. Dziękujemy Sarah Jane Shangraw, która nadała książce obecny kształt; Maureen Dempsey, która redagowała tekst; Robowi Romano, Rhonowi Porterowi i Chrisowi Reilleyowi, którzy wykonali rysunki; Hannie Dyer, która zaprojektowała okładkę, Alicii Cech, Davidowi Futato i Jennifer Niedherst za układ wewnętrzny, Larsowi Kaufmanowi, który wpadł na pomysł zamieszczenia drzeworytów; Judy Hoer za indeks i na koniec Timowi O'Reilly'emu za odwagę podjęcia takiego projektu. Na naszą wdzięczność zasłużyli też Andres Sepúlveda, Wolfgang Michaelis Michael K. Johnson i wszyscy programiści, którzy poświęcili wolny czas na sprawdzenie informacji zawartych w Podręczniku administratora sieci. Phil Hughes, John MacDonald i Eric Ratcliffe zgłosili nieocenione komentarze do drugiego wydania. Chcemy również podziękować wszystkim, którzy przeczytali pierwsze wydanie książki i przysłali poprawki i sugestie. Pełną, miejmy nadzieję, listę tych osób możesz znaleźć w pliku Thanks w wersji elektronicznej. Ostatecznie ta książka nie powstałaby bez wsparcia Holgera Grothego, który udostępnił Olafowi podłączenie do Internetu, niezbędne do powstania oryginalnej wersji. Olaf chciałby również podziękować następującym grupom i firmom, które wydrukowały pierwsze wydanie Podręcznika administratora sieci i wsparły finansowo zarówno jego osobę, jak i cały Projekt Dokumentacji Linuksa: Linux Support Team, Erlangen, Niemcy; S.u.S.E. GmbH, Fuerth, Niemcy; Linux System Labs, Inc., Clinton Twp., USA; RedHat Software, Północna Karolina, USA. Terry dziękuje swojej żonie Maggie, która niestrudzenie wspierała go w pracy na rzecz Projektu mimo wyzwania, jakie stawiało przed nią urodzenie ich pierwszego dziecka, Jacka. Ponadto dziękuje wielu osobom ze społeczności Linuksa, dzięki którym osiągnął poziom pozwalający mu na wzięcie udziału w tym przedsięwzięciu. "Pomogę ci, jeżeli obiecasz pomóc za to komuś innemu". Jest jeszcze wiele osób, poza już wspomnianymi, które przyczyniły się do powstania Podręcznika administratora sieci. Zapoznali się z nim i przesyłali nam poprawki i sugestie. Jesteśmy im bardzo wdzięczni. Oto lista tych, których działalność pozostawiła ślad w naszych folderach pocztowych. Al Longyear, Alan Cox, Andres Sepúlveda, Ben Cooper, Cameron Spitzer, Colin McCormack, D.J. Roberts, Emilio Lopes, Fred N. van Kempen, Gert Doering, Greg Hankins, Heiko Eissfeldt, J.P. Szikora, Johannes Stille, Karl Eichwalder, Les Johnson, Ludger Kunz, Marc van Diest, Michael K. Johnson, Michael Nebel, Michael Wing, Mitch D'Souza, Paul Gortmaker, Peter Brouwer, Peter Eriksson, Phil Hughes, Raul Deluth Miller, Rich Braun, Rick Sladkey, Ronald Aarts, Swen Thüemmler, Terry Dawson, Thomas Quinot i Yury Shevchuk. 1 Wprowadzenie do sieci Rozdział 1: Wprowadzenie do sieci Historia Idea sieci jest prawdopodobnie tak stara jak sama komunikacja. Sięgnijmy do epoki kamiennej, kiedy to ludzie używali bębnów do przesyłania wiadomości. Załóżmy, że jaskiniowiec A chce zaprosić jaskiniowca B do gry w rzucanie kamieniami, ale mieszkają oni zbyt daleko od siebie, by B usłyszał uderzenia A w bęben. Co może zrobić jaskiniowiec A? Może on 1) iść do miejsca zamieszkania B, 2) użyć większego bębna lub 3) poprosić C, który mieszka w połowie drogi pomiędzy nimi, aby przekazał komunikat. Ostatnią możliwość można nazwać siecią. Oczywiście od czasów naszych przodków zmieniły się metody i urządzenia służące komunikacji. Obecnie mamy komputery połączone ze sobą zwojami drutów, światłowodami, mikrofalami i tym podobnymi; za ich pomocą umawiamy się na sobotni mecz piłki nożnej*. Poniżej opiszemy, jakimi środkami i metodami można nakłonić komputery do porozumiewania się, choć pominiemy i druty, i piłkę nożną. W tym przewodniku opiszemy trzy typy sieci. Głównie skupimy się na sieciach opartych na TCP/IP, który jest najpopularniejszym zestawem protokołów stosowanym zarówno w sieciach lokalnych (Local Area Networks - LAN), jak i w sieciach rozległych (Wide Area Networks - WAN), takich jak Internet. Przyjrzymy się również protokołom UUCP i IPX. Swego czasu UUCP był powszechnie używany do przesyłania wiadomości Usenet i poczty przez komutowane połączenia telefoniczne. Obecnie jest mniej popularny, ale wciąż bywa przydatny w pewnych sytuacjach. Protokół IPX jest używany przeważnie w środowisku Novell NetWare. Opiszemy, jak wykorzystać go do podłączenia maszyny linuksowej do sieci Novell. Każdy z wymienionych protokołów jest protokołem sieciowym służącym do przesyłania danych pomiędzy komputerami. Omówimy, jak są one używane, i pokażemy rządzące nimi zasady. Sieć definiujemy jako zbiór hostów, które są w stanie komunikować się ze sobą, często za pośrednictwem pewnych wybranych spośród nich hostów, które rozsyłają dane pomiędzy uczestników. Hosty to często komputery, ale nie zawsze - za hosty można uznać także X terminale czy inteligentne drukarki. Niewielkie zbiorowiska hostów są nazywane również ośrodkami (ang. sites). Komunikacja nie jest możliwa bez pewnego rodzaju języka czy kodu. W sieciach komputerowych te języki są nazywane protokołami. Jednak protokołu sieciowego nie powinieneś kojarzyć z pisemnym sprawozdaniem z zebrania. Trafniejsza jest analogia do sformalizowanych reguł zachowania obowiązujących, gdy na przykład spotykają się głowy państw, czyli do protokołu dyplomatycznego. Podobne protokoły używane w sieciach komputerowych to po prostu sztywne zasady wymiany komunikatów pomiędzy dwoma lub więcej hostami. Sieci TCP/IP Nowoczesne aplikacje sieciowe wymagają wyrafinowanego podejścia do przesyłania danych z jednej maszyny do drugiej. Jeżeli zarządzasz maszyną z Linuksem, z której korzysta wielu użytkowników, to może się zdarzyć, że wszyscy jednocześnie będą chcieli połączyć się ze zdalnymi hostami w sieci. Potrzebujesz więc sposobu, który pozwoli im współdzielić połączenie sieciowe bez przeszkadzania sobie wzajemnie. Rozwiązanie, które wykorzystuje wiele współczesnych protokołów sieciowych, nazywane jest przełączaniem pakietów. Pakiet to mała porcja danych, przesyłana przez sieć z jednej maszyny do drugiej. Przełączanie występuje w momencie, gdy datagram jest przenoszony przez dowolne łącze w sieci. W sieci z przełączaniem pakietów jedno łącze jest współdzielone przez wielu użytkowników w ten sposób, że przez to łącze pakiety są wysyłane kolejno od jednego użytkownika do drugiego. Rozwiązanie, które przyjęło się w wielu systemach Unix, a następnie także w systemach nieuniksowych, nosi nazwę TCP/IP. Przy omawianiu sieci TCP/IP spotkasz się z określeniem datagram, które jest często używane wymiennie z określeniem pakiet, choć ma też inne, techniczne znaczenie. W tym podrozdziale przyjrzymy się podstawowym pojęciom związanym z TCP/IP. Wprowadzenie do sieci TCP/IP Początki TCP/IP sięgają programu badawczego finansowanego przez amerykańską agencję rządową DARPA (Defense Advanced Research Projects Agency) w 1969 roku. ARPANET była siecią eksperymentalną, która w 1975 roku, po latach zakończonych sukcesem badań, stała się siecią operacyjną. W 1983 roku jako standard przyjęto nowy zestaw protokołów o nazwie TCP/IP, którego miały używać wszystkie hosty w sieci. Ostatecznie ARPANET przekształcił się w Internet (sam ARPANET przestał istnieć w 1990 roku), a zestaw TCP/IP jest stosowany także poza nim. Wiele firm stworzyło korporacyjne sieci TCP/IP, a Internet osiągnął poziom, w którym można go uznać za wszechobecną technologię. Trudno jest, czytając gazetę lub czasopismo, nie zauważyć odnośników do Internetu - prawie każdy ma dziś do niego dostęp. Aby nasze rozważania o TCP/IP oprzeć na czymś konkretnym, weźmy jako przykład sieć uniwersytetu Groucho Marx (GMU), znajdującego się gdzieś w Fredland. Większość wydziałów tej uczelni posiada własne sieci lokalne, jednak niektóre współdzielą jedną sieć, a inne mają ich po kilka. Wszystkie one są połączone ze sobą i podłączone do Internetu poprzez jedno szybkie łącze. Załóżmy, że twój linuksowy komputer jest podłączony do sieci LAN zbudowanej z hostów uniksowych na wydziale matematyki i nazywa się erdos. Aby dostać się do hosta, powiedzmy quark, na wydziale fizyki, wprowadzasz następujące polecenie: $ rlogin quark.physics Welcome to the Physics Department at GMU (ttyq2) login: Po monicie wpisujesz nazwę użytkownika, powiedzmy andres, i swoje hasło. Następnie uzyskujesz dostęp do powłoki* komputera quark, w której możesz pisać tak, jakbyś siedział przy jego konsoli. Gdy wyjdziesz z powłoki, powracasz do monitu własnej maszyny. Właśnie użyłeś jednej z natychmiastowych, interaktywnych aplikacji, udostępnianych przez TCP/IP: zdalnego logowania. Gdy jesteś zalogowany do maszyny quark, możesz również uruchomić aplikację graficzną, np. program procesora tekstów, program do rysowania czy przeglądarkę WWW. System X Window jest w pełni sieciowym środowiskiem graficznym, dostępnym dla wielu różnych systemów komputerowych. Aby powiedzieć aplikacji, że chcesz, aby na ekranie twojego hosta ukazywały się jej okna, musisz ustawić zmienną środowiskową DISPLAY: $ DISPLAY=erdos.maths:0.0 $ export DISPLAY Jeżeli teraz uruchomisz swoją aplikację, skontaktuje się ona z twoim X serwerem, a nie z tym działającym na quarku, i wyświetli wszystkie okna na twoim ekranie. Oczywiście na erdosie musi działać X11. Istota sprawy polega na tym, że TCP/IP pozwala quarkowi i erdosowi na wysyłanie pakietów X11 w tę i z powrotem, stąd masz wrażenie, że znajdujesz się w jednym systemie. Sieć jest tu niemal przezroczysta. Kolejną bardzo ważną aplikacją TCP/IP jest NFS. Jej nazwa to skrót od słów Network File System (sieciowy system plików). Jest to inny sposób na spowodowanie, by sieć była przezroczysta. NFS pozwala na traktowanie hierarchii katalogów z innych hostów tak, jakby były one lokalnymi systemami plików, i sprawia, że wyglądają one jak inne katalogi na twoim hoście. Na przykład katalogi domowe wszystkich użytkowników mogą być przechowywane na serwerze centralnym, z którego mogą je montować wszystkie hosty w sieci LAN. W efekcie użytkownicy mogą logować się do dowolnej maszyny i znaleźć się w tym samym katalogu. Podobnie możliwe jest współdzielenie dużej liczby danych (takich jak bazy danych, dokumentacje czy aplikacje) przez wiele hostów w ten sposób, że na serwerze jest utrzymywana jedna baza danych, do której mają dostęp inne hosty. Do NFS-u powrócimy w rozdziale 14, Sieciowy system plików. Oczywiście są to tylko przykłady tego, co możesz zrobić w sieciach TCP/IP. Możliwości są prawie nieograniczone i podczas lektury tej książki poznasz ich więcej. Teraz przyjrzymy się bliżej sposobowi działania TCP/IP. Wiedza ta pomoże ci zrozumieć, jak musisz skonfigurować swój komputer i dlaczego. Rozpoczniemy od analizy sprzętu. Ethernet Najpopularniejszym rodzajem sprzętu w sieci lokalnej jest Ethernet. W najprostszej postaci składa się z jednego kabla i hostów podłączonych do niego przez wtyczki lub transceivery. Prosta instalacja ethernetowa jest stosunkowo niedroga, co wraz z przepustowością sieci rzędu 10, 100 czy nawet 1000 megabitów na sekundę przyczyniło się do dużej popularności tego standardu sprzętowego. Ethernet występuje w trzech odmianach: cienki, gruby i skrętkowy. Cienki Ethernet i gruby Ethernet wykorzystują kable współosiowe, które różnią się średnicą i sposobem podłączania kabla do hosta. Cienki Ethernet wykorzystuje złącza "BNC" w kształcie litery T, które wkładasz w kabel i wkręcasz do gniazda z tyłu komputera. Gruby Ethernet wymaga wywiercenia niewielkiej dziurki w kablu i podłączenia transceivera za pomocą "zaczepu wampirowego" (ang. vampire tap). Następnie do transceivera można podłączyć hosty (jeden lub więcej). Cienki kabel ethernetowy może mieć maksymalnie 200 metrów długości, zaś kabel gruby - 500; ich nazwy to, odpowiednio, 10base-2 i 10base-5. "Base" odnosi się do modulacji pasma podstawowego (ang. baseband modulation) i po prostu oznacza, że dane są wysyłane do kabla bezpośrednio, bez żadnego modemu. Liczba na początku oznacza prędkość w megabitach na sekundę, a liczba na końcu maksymalną długość kabla w setkach metrów. Sieć skrętkowa wykorzystuje kabel zbudowany z dwóch par drutów miedzianych i zwykle wymaga dodatkowego urządzenia zwanego hubem aktywnym. Sieć skrętkowa jest także znana pod nazwą 10base-T, gdzie "T" oznacza skrętkę. Wersja sieci działająca z prędkością 100 megabitów nosi nazwę 100base-T. Aby dodać host do sieci zbudowanej w oparciu o cienki Ethernet, musisz przerwać jej działanie na co najmniej kilka minut, ponieważ trzeba rozłączyć kabel i dołożyć wtyczki. Chociaż dodanie hosta do instalacji zbudowanej w oparciu o gruby Ethernet jest nieco bardziej skomplikowane, zwykle nie wymaga wyłączenia sieci. Ethernet oparty na skrętce jest jeszcze mniej kłopotliwy. Wykorzystuje urządzenie zwane hubem. Pełni ono rolę punktu podłączeniowego. Możesz dołączać hosty do huba lub odłączać je bez przerywania pracy całej sieci. Wiele osób woli cienki Ethernet w małych sieciach, ponieważ jest on niedrogi. Karty PC kosztują około 30 USD (obecnie wiele firm dosłownie je wyrzuca), a kabel - kilka centów za metr. Jednak w dużych instalacjach lepszy jest gruby Ethernet lub skrętka. Na przykład na wydziale matematyki GMU pierwotnie wybrano gruby Ethernet, ponieważ kabel musiał być długi, a więc ruch nie może być zakłócany za każdym razem, gdy do sieci jest dodawany nowy host. Instalacje skrętkowe są obecnie bardzo popularne. Huby tanieją, a mniejsze jednostki można dostać za cenę, która jest atrakcyjna nawet dla małych sieci domowych. Okablowanie skrętkowe może być znacznie tańsze w przypadku dużych instalacji, a sam kabel jest dużo bardziej elastyczny niż kable współosiowe używane w innych rodzajach sieci Ethernet. Administratorzy sieci na wydziale matematyki GMU planują w przyszłym roku finansowym wymienić istniejące okablowanie i urządzenia na skrętkowe, by unowocześnić sieć i zaoszczędzić czas przy instalowaniu nowych hostów i przenoszeniu istniejących z miejsca na miejsce. Jedną z wad technologii Ethernet jest ograniczenie długości kabla, co uniemożliwia jej zastosowanie w sieciach innych niż LAN. Jednak za pomocą wzmacniaków (ang. repeater), brydży i ruterów możliwe jest łączenie ze sobą segmentów sieci Ethernet. Wzmacniaki po prostu kopiują sygnały pomiędzy dwoma lub więcej segmentami tak, że wszystkie segmenty działają jakby to była jedna sieć Ethernet. Ze względu na wymagania czasowe, można umieścić co najwyżej cztery wzmacniaki pomiędzy dwoma hostami w sieci. Brydże i rutery są bardziej inteligentne. Analizują nadchodzące dane i przekazują je tylko wtedy, jeżeli docelowy host nie znajduje się w sieci lokalnej. Ethernet działa na zasadzie systemu magistralowego, gdzie host może wysyłać pakiety (lub ramki) o wielkości do 1500 bajtów do innego hosta w tej samej sieci Ethernet. Host jest identyfikowany za pomocą sześciobajtowego adresu trwale zapisanego w oprogramowaniu firmowym interfejsu karty sieciowej Ethernet (Network Interface Card, NIC). Adresy te są zwykle sekwencją dwucyfrowych liczb szesnastkowych oddzielonych dwukropkami, czyli na przykład aa:bb:cc:dd:ee:ff. Ramkę wysyłaną przez jedną stację widzą wszystkie podłączone stacje, ale tylko host, dla którego jest przeznaczona, odczytuje ją i przetwarza. Jeżeli dwie stacje próbują wysłać ramkę w tym samym czasie, dochodzi do kolizji. Kolizje w sieci Ethernet są wykrywane bardzo szybko przez elektronikę kart interfejsu i są rozwiązywane przez przerwanie wysyłania z obu stacji, odczekanie przez każdą z nich losowego przedziału czasu i ponowną próbę transmisji. Nieraz spotkasz się z opinią, że kolizje w Ethernecie są problemem i że przez nie wykorzystanie Ethernetu wynosi zaledwie około 30 procent dostępnego pasma. Kolizje są zjawiskiem typowym dla sieci Ethernet i nie powinieneś być zaskoczony, zwłaszcza jeśli sieć jest przeciążona. Może ich być maksymalnie 30 procent. Wykorzystanie sieci Ethernet jest w rzeczywistości ograniczone do około 60 procent - dopiero jeżeli nie osiągniesz tej wartości, to możesz zacząć się martwić*. Inne typy urządzeń W większych instalacjach, takich jak na uniwersytecie Groucho Marx, Ethernet zwykle nie jest jedynym typem używanego sprzętu. Istnieje wiele innych protokołów przesyłania danych, które można wykorzystywać. Wszystkie wymienione poniżej protokoły są obsługiwane przez Linuksa, ale ze względu na ograniczoną ilość miejsca przedstawimy je skrótowo. Szczegółowy opis wielu innych protokołów znajduje się w odpowiednich dokumentach HOWTO, możesz tam zajrzeć, jeżeli jesteś zainteresowany poznaniem tych, których nie opisujemy w naszej książce. Na uniwersytecie Groucho Marx sieć LAN każdego wydziału jest podłączona do szybkiej sieci szkieletowej, w której wykorzystano światłowód i technologię sieciową FDDI (Fiber Distributed Data Interface). FDDI prezentuje całkiem inne podejście do przesyłania danych, zasadniczo polegające na wysyłaniu żetonów (ang. tokens). Stacja ma prawo wysłać ramkę tylko wtedy, jeżeli wcześniej odbierze żeton. Główną zaletą protokołu przekazywania żetonów jest zmniejszenie liczby kolizji. Protokół może dużo prościej osiągnąć pełną prędkość przesyłania, w przypadku FDDI do 100 Mb/s. FDDI oparte na światłowodzie ma wiele zalet, ponieważ dopuszczalna długość kabla jest dużo większa niż w technologiach wykorzystujących zwykły kabel miedziany. Limit wynosi tutaj około 200 km, co sprawia, że FDDI znakomicie nadaje się do łączenia wielu budynków w mieście lub, tak jak w naszym przykładzie, wielu budynków campusu. Podobnie jeżeli w okolicy znajdują się urządzenia sieciowe firmy IBM, prawdopodobnie zainstalowano sieć IBM Token Ring. Token Ring jest stosowana jako alternatywa dla Ethernetu w niektórych sieciach LAN i ma te same zalety co FDDI, jeśli chodzi o prędkość, ale mniejszą przepustowość (4 lub 16 Mb/s). Jest też tańsza, ponieważ wykorzystuje kabel miedziany, a nie światłowodowy. W Linuksie sieć Token Ring jest konfigurowana prawie tak samo jak Ethernet, a więc nie musimy jej tutaj poświęcać więcej uwagi. W sieciach lokalnych LAN mogą być też stosowane inne technologie, takie jak ArcNet czy DECNet, choć obecnie już raczej sporadycznie. Linux również je obsługuje, ale nie będziemy ich tu opisywać. Wiele sieci państwowych obsługiwanych przez firmy telekomunikacyjne wykorzystuje protokoły przełączania pakietów. Chyba największą popularnością cieszy się standard o nazwie X.25. Wiele sieci publicznych, takich jak Tymnet w USA, Austpac w Australii i Datex-P w Niemczech, oferuje tę usługę. X.25 definiuje zestaw protokołów sieciowych, które opisują, jak urządzenie będące terminalem danych, takie jak host, łączy się ze urządzeniem do przesyłania danych (przełącznikiem X.25). X.25 wymaga synchronicznego łącza danych, a zatem specjalnego synchronicznego portu szeregowego. Można stosować X.25 z normalnymi portami szeregowymi pod warunkiem, że ma się specjalne urządzenie o nazwie PAD (Packet Assembler Disassembler). PAD jest samodzielnym urządzeniem udostępniającym synchroniczne i asynchroniczne porty szeregowe. Obsługuje protokół X.25, tak więc proste urządzenia terminalowe mogą nawiązywać i przyjmować połączenia realizowane za pomocą tego protokołu. X.25 jest często używany do przesyłania innych protokołów sieciowych, takich jak TCP/IP. Ponieważ datagramy IP nie mogą być w prosty sposób przetłumaczone na X.25 (lub odwrotnie), są one enkapsulowane w pakietach X.25 i wysyłane przez sieć. W Linuksie dostępna jest eksperymentalna implementacja protokołu X.25. Nowszym protokołem, powszechnie oferowanym przez firmy telekomunikacyjne, jest Frame Relay. Pod względem technicznym ma on wiele wspólnego z protokołem X.25, ale w działaniu bardziej przypomina protokół IP. Podobnie jak X.25, tak Frame Relay wymaga specjalnego synchronicznego portu szeregowego. Stąd wiele kart obsługuje oba te protokoły. Alternatywą jest urządzenie nazywane Frame Relay Access Device (FRAD) obsługujące enkapsulację pakietów Ethernet w pakietach Frame Relay na czas transmisji w sieci. Frame Relay znakomicie nadaje się do przesyłania pakietów TCP/IP pomiędzy ośrodkami. Linux jest wyposażony w sterowniki, które obsługują pewne typy wewnętrznych urządzeń Frame Relay. Jeżeli potrzebujesz szybszej sieci, która będzie przesyłać wiele różnych i nietypowych rodzajów danych, takich jak cyfrowo zapisany głos i wideo, to zapewne zainteresuje cię ATM (Asynchronous Transfer Mode). ATM jest nową technologią sieciową, która została zaprojektowana tak, by zapewnić łatwe zarządzanie, dużą prędkość, małe opóźnienia przy przesyłaniu danych i kontrolę nad jakością usług (Quality of Service - QS). Wiele firm telekomunikacyjnych, które liczą na usprawnienie zarządzania siecią i jej obsługi, sięga po infrastrukturę sieci ATM, ponieważ pozwala ona łączyć wiele różnych usług sieciowych na jednej platformie. ATM jest często używana do przesyłania protokołu TCP/IP. W Networking-HOWTO znajdziesz informacje na temat obsługi ATM-u przez Linuksa. Często radioamatorzy wykorzystują swój sprzęt do łączenia komputerów w sieć - powszechnie nosi to nazwę radia pakietowego (ang. packet radio). Jednym z protokołów wykorzystywanych przez nich jest AX.25, w pewnym stopniu oparty na X.25. Radioamatorzy używają protokołu AX.25 do przesyłania TCP/IP, a także innych protokołów. AX.25, podobnie jak X.25, wymaga urządzenia szeregowego, które może działać w trybie synchronicznym lub urządzenia zewnętrznego o nazwie Terminal Node Controller, które konwertuje pakiety przesyłane przez łącze asynchroniczne na pakiety przesyłane synchronicznie. Istnieje szereg różnych kart interfejsów obsługujących radio pakietowe - mówi się, że są to karty oparte na Z8530 SCC. Nazwa ta odnosi się do najpopularniejszego kontrolera komunikacyjnego używanego do ich budowy. Dwa inne protokoły, często przesyłane przez AX.25, to NetRom i Rose - są to protokoły warstwy sieciowej. Ponieważ protokoły te działają w oparciu o AX.25, mają te same wymagania sprzętowe. Linux w pełni implementuje protokoły AX.25, NetRom i Rose. AX25-HOWTO jest dobrym źródłem informacji na temat implementacji tych protokołów w Linuksie. Dostęp do Internetu można również uzyskać poprzez połączenia komutowane do systemu centralnego korzystające z wolnych, ale tanich łączy szeregowych (telefon, ISDN i tym podobne). Wymagają one jeszcze innych protokołów przesyłania pakietów, takich jak SLIP czy PPP. Opiszemy je później. Protokół internetowy (IP) Zapewne szczytem twoich marzeń nie jest sieć oparta na jednym połączeniu ethernetowym lub typu punkt-punkt. Idealnie byłoby, gdybyś mógł łączyć się z hostem bez względu na to, jakiego typu łączem fizycznym jest podłączony do sieci. Na przykład w dużych instalacjach, takich jak na przykładowym uniwersytecie Groucho Marx, zwykle masz kilka oddzielnych sieci, które są w pewien sposób ze sobą połączone. Wydział matematyki ma dwie sieci Ethernet, jedną z szybkimi maszynami dla profesorów i absolwentów, a drugą z wolnymi komputerami dla studentów. Obie są podłączone do szkieletowej sieci FDDI w campusie. Połączenie to jest obsługiwane przez dedykowany host zwany gatewayem, który obsługuje nadchodzące i wychodzące pakiety, kopiując je między dwoma Ethernetami i kablem optycznym w sieci FDDI. Na przykład gdybyś był na wydziale matematyki i chciałbyś dostać się ze swojego Linuksa do komputera quark na wydziale fizyki, oprogramowanie sieciowe nie wysłałoby pakietów bezpośrednio do komputera quark, ponieważ nie znajduje się on w tym samym segmencie Ethernet. W tym wypadku jako przekaźnik zostanie wykorzystany gateway. Gateway (o nazwie sophus) przekazuje te pakiety poprzez sieć szkieletową do gatewaya niels na wydziale fizyki. Dopiero niels dostarcza je do docelowej maszyny. Przepływ danych pomiędzy komputerami erdos i quark pokazano na rysunku 1-1. Rysunek 1-1. Trzy etapy wysyłania datagramu z erdosa do quarka http://www.rm.com.pl/upgr/lpas/01-01.tif Taki sposób przekazywania danych do zdalnego hosta nazywa się rutowaniem, a w tym kontekście pakiety często są nazywane datagramami. Aby uprościć opisaną procedurę, wymianę datagramów niezależnie od stosowanych urządzeń, powierza się zawsze temu samemu protokołowi, który nosi nazwę protokołu internetowego (Internet Protocol - IP). W rozdziale 2, Wybrane problemy sieci TCP/IP, opiszemy bardziej szczegółowo zarówno IP, jak i ruting. Główną zaletą IP jest to, że przekształca on fizycznie różne od siebie sieci w jedną, stuprocentowo homogeniczną sieć. Nazywa się to współdziałaniem międzysieciowym (ang. internetworking), a uzyskana "metasieć" to internet. Zwróć tutaj uwagę na subtelną różnicę pomiędzy nazwami "internet" a "Internet". Ta ostatnia to nazwa własna konkretnego internetu o globalnym zasięgu. Oczywiście IP wymaga także niezależnego od sprzętu schematu adresowania. Taki schemat to unikalny 32-bitowy numer przypisywany każdemu hostowi, zwany adresem IP. Adres IP ma zwykle postać czterech liczb dziesiętnych, oddzielonych kropkami, po jednej liczbie na każdy 8-bitowy segment. Na przykład quark mógłby mieć adres IP o postaci 0x954C0C04, który byłby zapisany jako 149.76.12.4. Format ten jest również nazywany kropkową notacją dziesiętną (ang. dotted decimal notation), a czasem kropkową notacją czwórkową (ang. dotted quad notation). Dla adresów IP coraz częściej spotyka się nazwę IPv4 (od Internet Protocol Version 4), ponieważ nowy standard o nazwie IPv6 oferuje dużo bardziej elastyczny sposób adresowania oraz inne, nowoczesne własności. Ale minie co najmniej rok od wydania tej książki, zanim wejdzie on w życie. Zapewne już zauważyłeś, że mamy teraz trzy różne typy adresów: pierwszy to nazwa hosta, jak quark, następnie adres IP i jeszcze adresy sprzętowe, takie jak 6-bajtowy adres ethernetowy. Wszystkie te adresy w pewien sposób muszą do siebie pasować, tak żeby po napisaniu rlogin quark, oprogramowanie sieciowe mogło podać adres IP komputera quark, a następnie znaleźć adres ethernetowy odpowiadający adresowi IP, wtedy gdy IP dostarczy już dane do sieci Ethernet na wydziale fizyki. Sytuację tę omówimy w rozdziale 2. Teraz wystarczy zapamiętać, że wyszukiwanie adresów jest nazywane albo rozwiązywaniem nazwy hosta, jeśli dotyczy zamiany nazw hostów na adresy IP, albo rozwiązywaniem adresów, jeśli ma nastąpić zamiana tych drugich na adresy sprzętowe. IP w łączach szeregowych W łączach szeregowych obowiązuje standard znany jako SLIP (Serial Line IP - protokół internetowy łącza szeregowego). Zmodyfikowana wersja SLIP, znana pod nazwą CSLIP (Compressed SLIP - SLIP z kompresją), kompresuje nagłówki IP, co pozwala lepiej wykorzystać relatywnie małą przepustowość cechującą większość łączy szeregowych. Innym protokołem szeregowym jest PPP (Point-to-Point Protocol - protokół punkt-punkt). PPP jest bardziej nowoczesny, niż SLIP i posiada różne właściwości, które stanowią o jego większej atrakcyjności. Jego główną zaletą w stosunku do SLIP jest to, że nie ogranicza się do przesyłania datagramów IP, ale jest zaprojektowany tak, by można było przez niego przesyłać dowolny protokół. Protokół kontroli transmisji (TCP) Wysyłanie datagramów z jednego hosta do innego to nie wszystko. Jeżeli zalogujesz się do quarka, będziesz chciał mieć niezawodne połączenie pomiędzy twoim procesem rlogin na erdosie a procesem powłoki na quarku. Tak, więc informacja wysłana tam i z powrotem musi być podzielona na pakiety przez nadawcę i ponownie połączona w ciąg znaków przez odbiorcę. Choć wydaje się to trywialne, jest jednak czynnością dość złożoną. Należy pamiętać, że IP jest z założenia protokołem zawodnym. Załóżmy, że dziesięć osób w twojej sieci Ethernet rozpoczęło pobieranie najnowszej wersji kodu źródłowego przeglądarki Netscape z serwera FTP należącego do przykładowego uniwersytetu. Wygenerowany w ten sposób ruch może być za duży dla gatewaya, który jest za wolny, i ma za mało pamięci. Jeżeli teraz zdarzy się, że wyślesz pakiet do quarka, sophusowi może zabraknąć przez chwilę miejsca na buforowanie i nie będzie w stanie przekazać twojego pakietu. W tej sytuacji IP po prostu gubi pakiet, który znika bezpowrotnie. Dlatego to komunikujące się hosty są odpowiedzialne za sprawdzenie integralności i kompletności danych oraz ich ponowną transmisję w przypadku błędu. To zadanie jest realizowane przez inny protokół - TCP (Transmission Control Protocol), który jest niezawodną usługą ponad IP. Istotną własnością TCP jest to, że używa on IP, by dać ci wrażenie prostego połączenia pomiędzy dwoma procesami, odpowiednio na twoim hoście i zdalnej maszynie, a więc nie musisz martwić się o to, jak i którędy są w rzeczywistości przesyłane twoje dane. Połączenie TCP działa w rzeczywistości jak dwukierunkowy potok, do którego oba procesy mogą zapisywać i odczytywać. Dobra jest tu analogia do rozmowy telefonicznej. TCP identyfikuje punkty końcowe każdego połączenia po adresach IP dwóch komunikujących się hostów i numerach portów na każdym z nich. Porty mogą być postrzegane jako punkty zaczepienia połączeń sieciowych. Gdybyśmy wrócili do przykładu z rozmową telefoniczną, to można sobie wyobrazić, że hosty to miasta, zaś adresy IP to numery kierunkowe (gdzie numery odwzorowują miasta), a numery portów to konkretne numery lokalne (gdzie numery odwzorowują indywidualne numery telefonów). Pojedynczy host może realizować wiele różnych usług, rozpoznawanych po numerze portu. W przykładzie rlogin, aplikacja klienta (rlogin) otwiera port na hoście erdos i łączy się z portem 513 hosta quark, na którym nasłuchuje serwer rlogind. W ten sposób zostaje nawiązane połączenie TCP. Za pomocą tego połączenia rlogind przeprowadza procedurę autoryzacji, a następnie uruchamia powłokę. Standardowe wejście i wyjście powłoki są przekierowywane na połączenie TCP, a więc wszystko, co napiszesz w aplikacji rlogin na swojej maszynie, zostanie przekazane przez strumień TCP i podane powłoce jako standardowe wejście. Protokół datagramów użytkownika (UDP) Oczywiście TCP nie jest jedynym protokołem użytkownika w sieci TCP/IP. Choć jest odpowiedni dla aplikacji takich jak rlogin, jego złożoność uniemożliwia wykorzystanie go w aplikacjach, takich jak NFS, które z kolei używają bratniego protokołu - UDP (User Datagram Protocol - protokół datagramów użytkownika). Podobnie jak TCP, UDP pozwala aplikacji na łączenie się z usługą na pewnym porcie zdalnej maszyny, ale bez zestawiania połączenia. Można go wykorzystać do wysyłania pojedynczych pakietów do docelowej usługi - stąd nazwa. Załóżmy, że chcesz poprosić o niewielką porcję danych z serwera baz danych. Zestawienie połączenia TCP wymaga co najmniej trzech datagramów, kolejne trzy są potrzebne do wysłania i potwierdzenia niewielkiej porcji danych w każdą stronę, a następne trzy do zamknięcia połączenia. UDP obsłuży takie połączenie za pomocą tylko dwóch datagramów, a efekt końcowy będzie taki sam. UDP jest protokołem bezpołączeniowym i nie wymaga zestawiania i zamykania sesji. Po prostu umieszczamy dane w datagramie i wysyłamy go do serwera - serwer przygotowuje odpowiedź, umieszcza dane w datagramie zaadresowanym zwrotnie (do nas) i przesyła go z powrotem. Choć w przypadku prostych transakcji UDP działa szybciej i bardziej efektywnie niż TCP, nie reaguje na gubienie datagramów. Dbałość o kompletność danych pozostawia się aplikacji, na przykład aplikacji serwera nazw. Więcej na temat portów Porty można traktować jako punkty zaczepienia połączeń sieciowych. Jeżeli aplikacja chce udostępnić jakąś usługę, podłącza się sama do portu i czeka na klientów (często nazywa się to nasłuchiwaniem na porcie). Klient, który chce skorzystać z tej usługi, alokuje port na swoim hoście lokalnym i podłącza się do portu serwera na hoście zdalnym. Ten sam port może być otwarty na wielu różnych maszynach, ale na każdej maszynie tylko jeden proces może otworzyć port w danej chwili. Istotną własnością portów jest to, że gdy zostanie ustanowione połączenie pomiędzy klientem a serwerem, inna kopia serwera może podłączyć się do portu serwera i oczekiwać kolejnych klientów. Ta właściwość pozwala na przykład na kilka jednoczesnych zdalnych logowań do tego samego hosta wykorzystujących port 513. TCP jest w stanie rozróżnić te połączenia, ponieważ przychodzą one z różnych portów lub hostów. Jeżeli zalogujesz się dwukrotnie z erdosa do quarka, pierwszy klient rlogin wykorzysta port lokalny 1023, a drugi port 1022. Jednak oba podłączą się do tego samego portu 513 hosta quark. Te dwa połączenia będą rozróżniane poprzez numery portów na erdosie. W powyższym przykładzie użyto portów jako miejsca spotkania - klient kontaktuje się z określonym portem, by uzyskać daną usługę. Aby klient wiedział, z jakim numerem portu ma się kontaktować, administratorzy obu systemów muszą uzgodnić przypisanie numerów portów. W przypadku popularnych usług, takich jak rlogin, numerami tymi administruje centralnie organizacja IETF (Internet Engineering Task Force), która regularnie publikuje RFC o nazwie Assigned Numbers (RFC-1700). Dokument ten zawiera między innymi numery portów przypisane dobrze znanym usługom. Linux wykorzystuje plik o nazwie /etc/services, który kojarzy nazwy usług z numerami portów. Warto zauważyć, że choć zarówno połączenia TCP, jak i UDP opierają się na portach, to ich numery nie kłócą się ze sobą. Oznacza to, że na przykład port 513 TCP różni się od portu 513 UDP. W rzeczywistości porty te działają jako punkty dostępu dla dwóch różnych usług: rlogin (TCP) i rwho (UDP). Biblioteka socket W uniksowych systemach operacyjnych oprogramowanie realizujące wszystkie zadania i obsługujące opisane powyżej protokoły jest zwykle częścią jądra. Podobnie jest w Linuksie. Najpopularniejszym interfejsem programowania w świecie Uniksa jest biblioteka Berkeley Socket. Jej nazwa wywodzi się z popularnej analogii, w której port jest postrzegany jako gniazdo, a podłączanie się do portu - jako włączanie do gniazda. Biblioteka udostępnia wywołanie bind, w którym podaje się zdalny host, protokół transportowy i usługę, do której program może się podłączyć lub, której ma nasłuchiwać (za pomocą connect, listen i accept). Biblioteka socket jest nieco bardziej ogólna, ponieważ udostępnia nie tylko klasę gniazd opartych na TCP/IP (gniazda AF_INET), ale także klasę, która obsługuje połączenia lokalne do maszyny (klasa AF_UNIX). Niektóre implementacje mogą także obsługiwać inne klasy, takie jak protokół XNS (Xerox Networking System) lub X.25. W Linuksie biblioteka socket jest częścią standardowej biblioteki lib C. Obsługuje gniazda AF_INET i AF_INET6 dla TCP/IP oraz AF_UNIX dla gniazd domeny Uniksa. Obsługuje również gniazda AF_IPX dla protokołów sieci Novell, AF_X25 dla protokołu sieci X.25, AF_ATMPVC i AF_ATMSVC dla protokołów sieci ATM i AF_AX25, AF_NETROM i AF_ROSE dla protokołów radia amatorskiego. Inne rodziny protokołów są w trakcie tworzenia i będą stopniowo dodawane. Sieci UUCP UUCP (Unix-to-Unix Copy Program - program kopiujący między systemami uniksowymi) był pakietem programów, które przesyłały pliki po łączach szeregowych, rozplanowywały te przesłania w czasie i inicjowały wykonywanie programów w zdalnych ośrodkach. Od czasu pierwszej implementacji, pod koniec lat siedemdziesiątych, UUCP znacznie się zmieniło, chociaż zakres oferowanych usług pozostał niewielki. UUCP stosuje się głównie w sieciach rozległych (WAN), opartych o okresowo uruchamiane łącza komutowane. UUCP stworzono w Bell Laboratories w 1977 roku w celu zapewnienia komunikacji pomiędzy ośrodkami programistycznymi pracującymi pod Uniksem. W połowie 1978 roku sieć łączyła już ponad 80 ośrodków. Działała w niej poczta elektroniczna oraz zdalne drukowanie. Jednak podstawowym zastosowaniem systemu była dystrybucja nowego oprogramowania i poprawianie błędów. Obecnie UUCP nie jest ograniczone wyłącznie do środowiska Unix. Istnieją darmowe i komercyjne wersje dla wielu innych platform, takich jak AmigaOS, DOS i Atari TOS. Jedną z głównych wad sieci UUCP jest to, że działają one wsadowo. Zamiast stałego połączenia pomiędzy hostami, wykorzystują połączenia tymczasowe. Host UUCP może połączyć się z innym hostem UUCP tylko raz dziennie i to na krótko. W czasie trwania połączenia przesyła wszystkie grupy dyskusyjne, pocztę i pliki, które znajdują się w kolejce, a następnie się rozłącza. To właśnie konieczność kolejkowania ogranicza różnorodność zastosowań UUCP. W przypadku poczty elektronicznej, użytkownik może przygotować wiadomość e-mail i wysłać ją. Będzie ona oczekiwać w kolejce na hoście UUCP, aż zadzwoni on do innego hosta, by przesłać wiadomość. Jest to do przyjęcia w przypadku usług sieciowych takich jak poczta elektroniczna, ale nie nadaje się dla innych usług, na przykład rlogin. Pomimo tych ograniczeń, wciąż na świecie istnieje wiele sieci UUCP utrzymywanych głównie przez hobbystów, którzy oferują prywatnym użytkownikom dostęp do Internetu za rozsądną cenę. Głównym powodem długotrwałej popularności UUCP była jej atrakcyjność cenowa w porównaniu z bezpośrednim podłączeniem do Internetu. Aby zrobić z twojego komputera węzeł UUCP, potrzebujesz jedynie modemu, działającej implementacji UUCP i innego węzła UUCP, który będzie chciał przyjmować twoją pocztę i grupy dyskusyjne. Wiele osób chętnie obsługiwało ruch UUCP dla indywidualnych użytkowników, ponieważ takie połączenia nie zakłócały zbytnio pracy ich sieci. Konfigurację UUCP omawiamy w jednym z dalszych rozdziałów książki, choć czynimy to skrótowo, gdyż protokół ten jest obecnie wypierany przez TCP/IP. Dostęp do Internetu jest powszechny i nie stanowi problemu w większości zakątków świata. Sieć w Linuksie Linux, który powstaje wspólnym wysiłkiem programistów z całego świata, nie byłby możliwy bez sieci globalnej. Nie ma więc nic dziwnego w tym, że od samego początku pracowano nad zapewnieniem mu zdolności sieciowych. Implementacja UUCP działała już w pierwszych wersjach Linuksa, a prace nad siecią opartą na TCP/IP rozpoczęły się jesienią 1992 roku, kiedy Ross Biro wraz z grupą programistów stworzyli to, co teraz jest znane pod nazwą Net-1. Po Rossie, który odszedł w maju 1993 roku, pracę nad nową implementacją kontynuował Fred van Kempen, przepisując główne części kodu. Projekt ten był znany jako Net-2. Pierwsza publiczna wersja, Net-2d, została udostępniona w lecie 1993 roku (jako część jądra 0.99.10) i od tego czasu była utrzymywana i rozwijana przez kilka osób, a przede wszystkim przez Alana Coxa*. Oryginalne prace Alana były znane pod nazwą Net-2Debugged, gdyż uwolnił on kod od wielu błędów i wprowadził liczne udoskonalenia. Od wersji 1.0 Linuksa kod sieciowy Alana nosił nazwę Net-3. Kod ten był dalej rozwijany w Linuksie 1.2 i 2.0. Jądra 2.2 i nowsze wykorzystują wersję Net-4, która pozostaje standardem do chwili obecnej. Kod sieciowy Linuksa Net-4 oferuje różnorodne sterowniki urządzeń i zaawansowane własności. Do standardowych protokołów Net-4 zaliczają się: SLIP i PPP (do przesyłania danych przez łącza szeregowe), PLIP (dla łączy równoległych), IPX (dla sieci kompatybilnych z Novellem, które omówimy w rozdziale 15, IPX i system plików NCP), Appletalk (dla sieci Apple) i AX.25, NetRom i Rose (dla sieci radioamatorskich). Inne standardy obsługiwane przez Net-4 to: firewalle IP, liczenie ruchu IP (omawiane w rozdziałach 9 i 10) i maskowanie IP (omawiane w rozdziale 11, Maskowanie IP i translacja adresów sieciowych). Zaawansowane algorytmy rutingu i tunelowanie IP są obsługiwane na kilka możliwych sposobów. W Net-4 zawarto sterowniki dla szeregu urządzeń Ethernet, a także dla FDDI, Token Ring, Frame Relay i ISDN oraz ATM. Ponadto istnieje tu wiele innych właściwości, które znacznie rozszerzają elastyczność Linuksa. Należą do nich implementacja systemu plików SMB, która współdziała z takimi aplikacjami, jak lanmanager i Microsoft Windows, oraz implementacja Novell NCP (NetWare Core Protocol)*. Różne ścieżki rozwoju W różnych okresach w różnych kierunkach rozwijano oprogramowanie sieciowe dla Linuksa. Po uznaniu Net-2Debugged za implementację sieci, Fred nadal pracował nad kodem sieciowym. W rezultacie powstała wersja kodu o nazwie Net-2e, która charakteryzowała się dużo lepiej przemyślaną konstrukcją warstwy sieciowej. Fred chciał też ustandaryzować interfejs sterowników urządzeń (Device Driver Interface - DDI), ale prace nad Net-2e zakończono. Inna implementacja sieci TCP/IP pochodzi od Matthiasa Urlichsa, który napisał sterownik ISDN dla Linuksa i FreeBSD. W tym celu zintegrował on część kodu sieciowego BSD z jądrem Linuksa. Projekt ten również nie jest rozwijany. Wiele się zmieniło w implementacji sieci w jądrze Linuksa, i wciąż się zmienia. Czasem oznacza to, że zmiany muszą wystąpić także w innym oprogramowaniu, takim jak narzędzia do konfiguracji sieci. Choć nie jest to obecnie tak dużym problemem jak niegdyś, jednak wciąż może się zdarzyć, że jeśli zainstalujesz nowszą wersję jądra, to narzędzia do konfiguracji sieci również będą wymagały uaktualnienia. Na szczęście w większości obecnych dystrybucji Linuksa jest to proste zadanie. Implementacja sieci Net-4 jest produktem w pełni dopracowanym, stosowanym w bardzo wielu ośrodkach na całym świecie. Wiele wysiłku włożono w poprawę wydajności implementacji Net-4 i teraz może ona konkurować z najlepszymi implementacjami dostępnymi dla danych platform sprzętowych. Linux cieszy się coraz większym wzięciem w środowisku dostawców Internetu, gdzie często jest używany do tworzenia tanich i niezawodnych serwerów WWW, serwerów pocztowych i serwerów grup dyskusyjnych dla tego typu organizacji. Obecnie zainteresowanie rozwojem Linuksa jest na tyle duże, że wszystkie zmiany w technologii sieciowej znajdują swoje odzwierciedlenie w kolejnych wersjach jądra, a jego najnowsze wersje oferują jako standard kolejną generację protokołu IP IPv6. Skąd wziąć kod Dzisiaj wydaje się dziwne, że w początkach rozwoju kodu sieciowego Linuksa standardowe jądro wymagało ogromnego pakietu poprawek dodającego obsługę sieci. Obecnie obsługa sieci jest uwzględniona w głównym jądrze Linuksa. Ostatnie stabilne jądra Linuksa można znaleźć w ośrodku ftp.kernel.org w katalogu /pub/linux/kernel/v2.x/, gdzie x jest liczbą parzystą. Najnowsze eksperymentalne wersje jądra Linuksa można znaleźć w ośrodku ftp.kernel.org w katalogu /pub/linux/kernel/v2.y/, gdzie y jest liczbą nieparzystą. Na całym świecie znajdują się serwery lustrzane z kodem źródłowym jądra Linuksa. Trudno sobie obecnie wyobrazić Linuksa bez standardowej obsługi sieci. Utrzymywanie systemu W niniejszej książce będziemy mówić głównie o instalacji i konfiguracji. Jednakże administracja jest czymś więcej - po skonfigurowaniu usługi musisz także pilnować, by działała. Większość usług nie wymaga zbyt wielkiej uwagi, ale przy niektórych, takich jak poczta i grupy dyskusyjne, musisz wykonywać rutynowe czynności, by twój system był sprawny. Zadania te omówimy w kolejnych rozdziałach. Absolutnym minimum niezbędnym do poprawnego funkcjonowania systemu jest regularne sprawdzanie plików log systemu oraz plików log każdej aplikacji w celu wykrycia błędów czy nietypowych zdarzeń. Zwykle pisze się w tym celu skrypty administracyjne i co jakiś czas uruchamia się je z usługi cron. ?ródłowe dystrybucje niektórych większych aplikacji, takich jak inn czy C News, zawierają takie skrypty. Musisz tylko dopasować je do swoich potrzeb. Wynik wszelkich zadań wykonywanych przez usługę cron powinien być wysyłany pocztą elektroniczną na konto administracyjne. Domyślnie wiele aplikacji wysyła raporty o błędach, statystyki wykorzystania czy streszczenia plików log na konto root. Ma to sens tylko wtedy, jeżeli często logujesz się jako root. Dużo lepiej jest przekazywać pocztę użytkownika root na własne konto, ustawiając alias pocztowy według opisu w rozdziale 19, Exim, lub rozdziale 18, Sendmail. Choćbyś skonfigurował swój ośrodek z największą dbałością, zgodnie z prawami Murphy'ego i tak wystąpi jakiś problem. Dlatego utrzymywanie systemu oznacza także przyjmowanie skarg. Zwykle ludzie spodziewają się, że z administratorem systemu można skontaktować się pocztą elektroniczną pod adresem root, ale istnieją także inne adresy, które są powszechnie używane do kontaktu z osobami odpowiedzialnymi za konkretny aspekt utrzymania ośrodka. Na przykład skargi na temat błędnej konfiguracji poczty zwykle będą wysyłane na adres postmaster, a problemy z grupami dyskusyjnymi mogą być raportowane na adres newsmaster lub usenet. Poczta na adres hostmaster powinna być przekierowana do osoby odpowiedzialnej za podstawowe usługi sieciowe hosta i usługi DNS, jeżeli na twojej maszynie działa serwer nazw. Bezpieczeństwo systemu Kolejnym, bardzo istotnym aspektem administracji systemu w środowisku sieciowym jest zabezpieczenie go i jego użytkowników przed intruzami. Niedbale zarządzane systemy stanowią łatwy cel dla złośliwych osób. Ataki zaczynają się od zgadywania haseł, a kończą na wysyłaniu fałszywych pakietów Ethernet, natomiast zniszczenia zaczynają się od fałszywych poczt elektronicznych, a mogą skończyć się utratą danych lub pogwałceniem prywatności twoich użytkowników. O pewnych konkretnych problemach powiemy przy omawianiu kontekstu, w którym mogą one wystąpić, i pokażemy sposoby obrony. Ten podrozdział omawia kilka przykładów i podstawowych technik związanych z bezpieczeństwem systemu. Oczywiście nie przedstawia wszystkich zagadnień bezpieczeństwa, jakie możesz napotkać. Chcemy jedynie zasygnalizować problemy, które mogą wystąpić. Dlatego przeczytanie dobrej książki na temat bezpieczeństwa jest absolutnie niezbędne, szczególnie w przypadku systemu sieciowego. Podstawą bezpieczeństwa systemu jest dobra administracja. Oznacza to sprawdzanie własności wszystkich istotnych plików i katalogów oraz prawa dostępu do nich, a także monitorowanie wykorzystania uprzywilejowanych kont. Na przykład program COPS przeszukuje twój system plików i podstawowe pliki konfiguracyjne pod kątem nietypowych praw dostępu lub innych anomalii. Mądrze jest także używać takiego systemu haseł, który wymaga od użytkowników stosowania się do pewnych reguł, przez co hasła jest trudno odgadnąć. Na przykład pakiet haseł shadow wymaga, by hasło miało co najmniej 5 znaków i zawierało liczby oraz znaki niealfanumeryczne. Gdy udostępniasz jakąś usługę w sieci, pamiętaj, żeby dać jej "jak najmniej przywilejów". Pozwalaj na robienie tylko tych rzeczy, które są wymagane, by działała tak, jak została zaprojektowana. Na przykład powinieneś nadać programom prawo setuid roota lub innego uprzywilejowanego konta, tylko wtedy gdy jest to niezbędne. Także, jeżeli chcesz używać usługi tylko w bardzo ograniczonym zakresie, nie wahaj się jej skonfigurować odpowiednio do twoich szczególnych zastosowań. Na przykład gdybyś chciał pozwolić, aby stacje bezdyskowe uruchamiały się z twojej maszyny, musisz udostępnić uproszczony protokół przesyłania plików (Trivial File Transfer Protocol - TFTP), tak by mogły skopiować podstawowe pliki konfiguracyjne z katalogu /boot twojej maszyny. Jednak w przypadku nieograniczonego użycia TFTP pozwala użytkownikom z całego świata kopiować te pliki z twojego systemu, do których wszyscy mają prawo odczytu. Jeżeli sobie tego nie życzysz, ogranicz usługę TFTP jedynie do katalogu /boot*. Możesz również ograniczyć usługi przyznawane użytkownikom określonych hostów, powiedzmy z twojej sieci lokalnej. W rozdziale 12 przedstawiamy demon tcpd, który wykonuje to zadanie dla wielu aplikacji sieciowych. Bardziej wyrafinowane metody ograniczania dostępu do poszczególnych hostów lub usług omówimy w rozdziale 9. Kolejną ważną rzeczą jest unikanie "niebezpiecznego" oprogramowania. W pewnym sensie każde oprogramowanie może być niebezpieczne, ponieważ może zawierać błędy, które sprytni ludzie mogą wykorzystać, by uzyskać dostęp do twojego systemu. Takie rzeczy się zdarzają i nie da się przed tym zabezpieczyć. Problem ten dotyczy zarówno oprogramowania darmowego, jak i produktów komercyjnych**. Jednak programy wymagające specjalnych przywilejów są z natury bardziej narażone na niebezpieczeństwo niż pozostałe, ponieważ wszelkie luki mogą prowadzić do poważnych konsekwencji*. Jeżeli instalujesz program z prawem setuid, który ma pracować z siecią, bądź dwa razy bardziej ostrożny i przeczytaj dokumentację, abyś przez przypadek nie stworzył dziury w bezpieczeństwie. Uwagę powinieneś zwrócić także na programy, które pozwalają na logowanie lub wykonywanie poleceń z niepełnym uwierzytelnianiem. Polecenia, takie jak rlogin, rsh i rexec, są bardzo przydatne, ale od osoby uruchamiającej wymagają jedynie ograniczonego uwierzytelnienia, które opiera się na zaufaniu do nazwy wywołującego hosta, ustalonej na podstawie serwera nazw (będziemy mówili o tym później), którą łatwo można sfałszować. Obecnie standardową praktyką powinno być zupełne wyłączanie poleceń r i zastępowanie ich narzędziami z pakietu ssh. Narzędzia ssh wykorzystują bardziej niezawodne metody uwierzytelniania i oferują także inne usługi, takie jak szyfrowanie i kompresja. Nigdy nie możesz wykluczyć możliwości, że twoje zabezpieczenia kiedyś zawiodą, bez względu na to, jak byłeś ostrożny. Dlatego powinieneś upewnić się, że dostatecznie wcześnie wykrywasz intruzów. Sprawdzanie logów systemu jest dobrym punktem początkowym, ale intruz jest prawdopodobnie wystarczająco mądry, by przewidzieć, że tak postąpisz, i usunie wszelkie oczywiste ślady pozostawione przez siebie. Jednak istnieją narzędzia takie jak tripwire, napisane przez Gene Kima i Gene Spafforda, które pozwalają sprawdzać istotne pliki systemu, by zobaczyć, czy ich zawartość lub prawa dostępu nie zostały zmienione; tripwire liczy różne sumy kontrolne tych plików i umieszcza je w bazie danych. W czasie kolejnych przebiegów sumy są liczone ponownie i porównywane z wcześniej zapisanymi, by w ten sposób wykryć modyfikacje. 2 Wybrane problemy sieci TCP/IP Rozdział 2: Wybrane problemy sieci TCP/IP W tym rozdziale powiemy, jakie decyzje konfiguracyjne musisz podjąć, jeśli chcesz podłączyć swojego Linuksa do sieci TCP/IP. Zajmiemy się adresami IP, nazwami hostów i rutingiem. Rozdział ten daje ci podstawową wiedzę, niezbędną do zrozumienia, czego wymaga twoja konfiguracja, natomiast w następnych rozdziałach poznasz narzędzia, których będziesz używał. Aby dowiedzieć się więcej o TCP/IP i jego budowie, zajrzyj do trzytomowej książki Internetworking with TCP/IP Douglasa R. Comera (Prentice Hall). Bardziej szczegółowym przewodnikiem po zarządzaniu siecią TCP/IP jest książka TCP/IP Network Administration Craiga Hunta (O'Reilly). Interfejsy sieciowe Aby ukryć różnorodność sprzętu obecnego w środowisku sieciowym, TCP/IP odwołuje się do interfejsu, przez który następuje dostęp do sprzętu. Interfejs oferuje zestaw operacji identyczny dla wszystkich rodzajów urządzeń; za jego pomocą obsługuje się wysyłanie i odbieranie pakietów. Każde sieciowe urządzenie peryferyjne musi mieć w jądrze odpowiedni interfejs. Na przykład interfejsy Ethernet w Linuksie noszą nazwy eth0 i eth1, interfejsy PPP (omówione w rozdziale 8, Protokół punkt-punkt) są nazywane ppp0 i ppp1, a interfejsy FDDI - fddi0 i fddi1. Nazwy interfejsów są używane tylko w poleceniu konfiguracyjnym, kiedy chcesz się odwołać do konkretnego urządzenia fizycznego. Poza tym nie są stosowane. Zanim interfejsu będzie można użyć w sieci TCP/IP, należy mu przypisać adres IP, który identyfikuje go w procesie komunikacji z resztą świata. Adres ten jest różny od wspomnianej poprzednio nazwy interfejsu. Jeżeli porównasz interfejs do drzwi, to adres jest przyczepioną na nich tabliczką z nazwiskiem. Można ustawiać także inne parametry urządzenia, takie jak maksymalny rozmiar datagramów (Maximum Transfer Unit - MTU), które mogą być przetworzone przez konkretne urządzenie. Inne atrybuty omówimy później. Na szczęście większość atrybutów ma sensowne wartości domyślne. Adresy IP Jak wspomnieliśmy w rozdziale 1, Wprowadzenie do sieci, protokół sieciowy IP rozumie adresy w postaci liczb 32-bitowych. Każda maszyna musi mieć przypisany numer, który jest niepowtarzalny w środowisku sieciowym*. Jeżeli jesteś podłączony do sieci lokalnej, która nie wymienia ruchu TCP/IP z innymi sieciami, możesz przypisać adresy zgodnie z własnym widzimisię. Istnieją pewne zakresy adresów IP, które zostały zarezerwowane dla takich sieci prywatnych. Pokazano je w tabeli 2-1. Jednak ośrodkom podłączonym do Internetu adresy są nadawane przez administrację centralną: NIC (Network Information Center)**. Adresy IP, aby były łatwo czytelne, są podzielone na cztery 8-bitowe liczby, zwane oktetami. Na przykład quark.physics.groucho.edu ma adres IP 0x954C0C04, zapisywany jako 149.76.12.4. Format ten często nazywany jest kropkową notacją czwórkową. Innym powodem zastosowania takiego zapisu jest to, że adresy IP są dzielone na numer sieci zawarty w pierwszej części adresu i na numer hosta zawarty w pozostałej jego części. Gdy prosisz NIC o adresy IP, nie dostajesz adresu dla każdego hosta, który planujesz podłączyć. Otrzymujesz numer sieci i pozwolenie na utworzenie w przyznanym zakresie prawidłowych adresów IP dla hostów w twojej sieci, zgodnie z potrzebami. Rozmiar części sieciowej adresu zależy od wielkości sieci. Aby uwzględnić różne potrzeby, zdefiniowano kilka klas sieci dzielących adresy IP w różnych miejscach. Klasy sieci są następujące: Klasa A Klasa A obejmuje sieci od 1.0.0.0 do 127.0.0.0. Numer sieci jest zapisany w pierwszym oktecie. Klasa ta udostępnia 24-bitowy adres hosta, co pozwala na podłączenie do jednej sieci, z grubsza rzecz biorąc, 1,6 miliona hostów w każdej sieci. Klasa B Klasa B obejmuje sieci od 128.0.0.0 do 191.255.0.0. Numer sieci jest zapisany w dwóch pierwszych oktetach. Klasa ta pozwala na stworzenie 16 320 sieci o 65 024 hostach w każdej z nich. Klasa C Klasa C obejmuje sieci od 192.0.0.0 do 223.255.255.0, gdzie numer sieci jest zapisany w trzech pierwszych oktetach. Klasa ta pozwala na zarejstrowanie prawie 2 milionów sieci po 254 hosty w każdej. Klasy D, E i F Adresy należące do zakresu 224.0.0.0 do 254.0.0.0 są albo eksperymentalne, albo zarezerwowane do zastosowań specjalnych i nie określają żadnej sieci. Transmisja grupowa IP (ang. IP multicasting) - usługa pozwalająca na przesyłanie danych do wielu miejsc w Internecie jednocześnie - wymaga przypisania adresów właśnie z tego zakresu. Jeśli wrócimy do przykładu z rozdziału 1, stwierdzimy, że 149.76.12.4 (adres quarka) oznacza host o numerze 12.4 w sieci klasy B o numerze 149.76.0.0. Być może zauważyłeś przy opisie klas adresów, że nie wszystkie możliwe wartości były dozwolone dla każdego oktetu w części opisującej hosta. Dzieje się tak dlatego, że oktety 0 i 255 są zarezerwowane do specjalnych celów. Adres, w którym wszystkie bity w części hosta mają wartość 0, jest adresem sieci, a adres, w którym wszystkie bity w części hosta mają wartość 1, nazywa się adresem rozgłoszeniowym (ang. broadcast address). Odnosi się on do wszystkich hostów w zadanej sieci jednocześnie. Tak więc 149.76.255.255 nie jest poprawnym adresem hosta, ale odnosi się do wszystkich hostów w sieci 149.76.0.0. Kilka adresów sieci jest zarezerwowane do szczególnych celów. Dwa takie adresy to: 0.0.0.0 i 127.0.0.0. Pierwszy nazywamy domyślnym rutingiem (ang. default route), a drugi adresem pętli zwrotnej (ang. loopback address). Domyślny ruting jest związany ze sposobem kierowania datagramów IP. Sieć 127.0.0.0 jest zarezerwowana dla ruchu IP lokalnego względem twojego hosta. Zwykle adres 127.0.0.1 zostaje przypisany specjalnemu interfejsowi twojego hosta - interfejsowi pętli zwrotnej, który działa jak obwód zamknięty. Dowolny pakiet IP skierowany na ten interfejs z TCP lub UDP zostanie mu zwrócony tak, jakby właśnie nadszedł z jakiejś sieci. Dzięki temu można testować oprogramowanie sieciowe bez wykorzystywania "rzeczywistej" sieci. Sieć pętli zwrotnej pozwala także na używanie oprogramowania sieciowego na pojedynczym hoście. Choć nie wygląda to na zbyt przydatne, to jednak jest. Na przykład wiele ośrodków UUCP nie posiada w ogóle podłączenia IP, ale wciąż może w nich działać system grup dyskusyjnych INN. Aby prawidłowo pracować w Linuksie, INN wymaga interfejsu pętli zwrotnej. W każdej klasie sieci pewne zakresy adresów zostały odłożone na bok i określone jako "zarezerwowane" lub "prywatne" zakresy adresów. Adresy te są przeznaczone do użytku w sieciach prywatnych i nie są rutowane do Internetu. Zwykle korzystają z nich organizacje tworzące własny intranet, ale także małe sieci. Jak już mówiliśmy, zarezerwowane adresy sieci podaje tabela 2-1. Tabela 2-1. Zakresy adresów IP zarezerwowane do użytku prywatnego Klasa Sieci A 10.0.0.0 do 10.255.255.255 B 172.16.0.0 do 172.31.0.0 C 192.168.0.0 do 192.168.255.0 Rozwiązywanie adresów Teraz, gdy wiesz już, jak tworzy się adresy IP, możesz zastanawiać się, w jaki sposób są one używane do adresowania hostów w sieci Ethernet lub Token Ring. Przecież protokoły te mają własne adresy identyfikujące hosty, które nie mają nic wspólnego z adresem IP. Prawda? Tak, masz rację. Potrzebny jest mechanizm, który odwzorowuje adresy IP na adresy sieci niższej warstwy. Tym mechanizmem jest protokół rozwiązywania adresów (Address Resolution Protocol - ARP). W praktyce ARP można stosować nie tylko w Ethernecie czy Token Ringu, ale również w innych typach sieci, między innymi takich, w których pracuje protokół AX.25. Metoda działania ARP jest taka sama jak ta, którą posługuje się większość ludzi, kiedy musi znaleźć Pana X wśród 150 gości: osoba szukająca krzyczy na tyle głośno, by każdy mógł ją usłyszeć, i oczekuje, że jeżeli Pan X jest wśród zgromadzonych, to się odezwie. Gdy X odpowie, wiemy,  która to osoba. Gdy ARP chce znaleźć adres ethernetowy odpowiadający określonemu adresowi IP, wykorzystuje funkcję Ethernetu zwaną rozgłaszaniem (ang. broadcasting). Rozgłaszanie polega na tym, że datagram jest adresowany do wszystkich stacji w sieci jednocześnie. Datagram rozgłoszeniowy wysłany przez ARP zawiera zapytanie o adres IP. Każdy host, który go odbierze, porównuje to zapytanie ze swoim własnym adresem IP. Jeżeli znajdzie się host, którego adres IP odpowiada poszukiwanemu, to zwraca on odpowiedź ARP do pytającego hosta. Pytający host może teraz - na podstawie odpowiedzi - odczytać adres ethernetowy nadawcy. Możesz się zastanawiać, jak host może uzyskać adres innego hosta, który znajduje się na przykład w zupełnie innej sieci na drugim końcu świata. Odpowiedź na to pytanie wymaga wyjaśnienia mechanizmu rutingu, czyli znalezienia fizycznej lokalizacji hosta w sieci. To zagadnienie omówimy dokładniej w następnym podrozdziale. Powiedzmy nieco więcej o protokole ARP. Gdy host znajdzie adres ethernetowy, zapisuje go w pamięci podręcznej ARP, aby nie pytać o niego, gdy będzie chciał ponownie wysłać datagram do tego samego hosta. Jednak niemądre byłoby trzymanie tej informacji bez końca. Karta Ethernet zdalnego hosta może zostać wymieniona z powodów technicznych, a więc wpis ARP byłby błędny. Dlatego wpisy w pamięci podręcznej ARP są po pewnym czasie usuwane, by wymusić kolejne zapytanie o adres IP. Czasem trzeba również znaleźć adres IP odpowiadający danemu adresowi ethernetowemu. Dzieje się tak, gdy maszyna bezdyskowa chce uruchomić się z serwera w sieci. Sytuacja ta jest powszechnie spotykana w sieciach LAN. Jednak klient bezdyskowy nie ma o sobie informacji - za wyjątkiem swojego adresu Ethernet. Tak więc rozgłasza komunikat, w którym prosi serwer uruchomieniowy (ang. boot server) o adres IP. Tę sytuację obsługuje protokół o nazwie odwrotny protokół rozwiązywania adresów (Reverse Address Resolution Protocol - RARP). Wraz z protokołem BOOTP pozwala na uruchamianie bezdyskowych klientów z sieci. Ruting IP Teraz wyjaśnijmy, jak na podstawie adresu IP odszukać host, do którego są adresowane datagramy. Różne części adresu są obsługiwane w różny sposób. Twoim zadaniem jest skonfigurowanie plików tak, aby mówiły, jak ma być traktowana każda z poszczególnych części adresu IP. Sieci IP Gdy piszesz do kogoś list, zwykle umieszczasz na kopercie pełny adres, czyli także państwo, region administracyjny (np. stan, województwo), nazwę poczty wraz z kodem. Po włożeniu listu do skrzynki pocztowej, poczta dostarczy go do miejsca przeznaczenia: zostanie wysłany do podanego na kopercie kraju, gdzie służby krajowe skierują go do odpowiedniego regionu. Zaleta takiego hierarchicznego schematu jest oczywista: gdy wysyłasz list do innego miasta lub kraju, miejscowa poczta wie z grubsza, w jakim kierunku ma go przekazać, ale nie martwi się, którędy list będzie szedł, gdy już dotrze do kraju przeznaczenia. Sieci IP mają podobną strukturę. Cały Internet składa się z szeregu sieci, zwanych systemami niezależnymi. Każdy system realizuje wewnętrznie ruting pomiędzy swoimi hostami, tak więc zadanie dostarczenia datagramu redukuje się do znalezienia ścieżki do sieci zawierającej host adresata. Wystarczy przekazać datagram do jakiegokolwiek hosta w sieci adresata, a dalsza wędrówka odbywa się już wyłącznie w obrębie tej sieci. Podsieci Zasada podziału jest widoczna w wyodrębnieniu w adresach IP części hosta i części sieciowej, jak już wyjaśnialiśmy wcześniej. Domyślnie sieć przeznaczenia jest uzyskiwana z części sieciowej adresu IP. Tak więc hosty o identycznych numerach sieci IP powinny znajdować się w tej samej sieci*. Zastosowanie podobnego schematu ma także sens wewnątrz sieci, ponieważ może się ona składać z setek mniejszych sieci, w których najmniejszymi jednostkami są fizyczne sieci np. Ethernet. Dlatego IP pozwala na dalszy podział sieci IP na kilka podsieci. Podsieć odpowiada za dostarczanie datagramów do pewnego zakresu adresów IP. Jest to rozszerzenie pojęcia podziału pól bitowych, tak jak w klasach A, B i C. Jednak część sieciowa jest teraz rozszerzana tak, by zawierała niektóre bity z części hosta. Liczba bitów, interpretowana jako numer podsieci, jest określona przez tak zwaną maskę podsieci lub maskę sieci. Jest to również liczba 32-bitowa, określająca maskę bitową dla części sieciowej adresu IP. Sieć campusowa przykładowego uniwersytetu Groucho Marx to właśnie taka sieć. Ma sieć klasy B o numerze 149.76.0.0 i dlatego jej maska to 255.255.0.0. Wewnętrznie sieć campusowa składa się z kilku mniejszych sieci, takich jak sieci lokalne różnych wydziałów. Tak więc zakres adresów IP jest podzielony na 254 podsieci od 149.76.1.0 do 149.76.254.0. Na przykład wydział fizyki teoretycznej ma przypisany adres 149.76.12.0. Szkielet campusu jest siecią samą w sobie i ma numer 149.76.1.0. Podsieci te korzystają ze wspólnej części sieciowej adresu IP, a rozróżniane są na podstawie 3. oktetu. Dlatego maska podsieci w tym przypadku ma postać 255.255.255.0. 2-1 pokazuje, jak adres quarka: 149.76.12.4 jest interpretowany, gdy ma być zwykłym adresem w sieci klasy B i wtedy, gdy ma uwzględniać podsieci. Rysunek 2-1. Podział sieci klasy B na podsieci http://www.rm.com.pl/upgr/lpas/02-01.tif Warto zauważyć, że dzielenie na podsieci (technika tworzenia podsieci) jest jedynie wewnętrznym podziałem sieci. Podsieci są generowane przez właściciela sieci (lub administratorów). Często podsieci są tworzone, aby odzwierciedlać istniejące granice fizyczne (pomiędzy dwoma sieciami Ethernet), administracyjne (pomiędzy dwoma wydziałami) lub geograficzne (pomiędzy dwoma lokalizacjami), natomiast władza nad każdą z podsieci jest oddawana innej osobie. Jednak struktura ta dotyczy tylko wewnętrznego zachowania sieci i jest zupełnie niewidoczna dla świata zewnętrznego. Gatewaye Podział na podsieci jest korzystny nie tylko ze względów organizacyjnych. Często jest naturalną konsekwencją ograniczeń sprzętowych. Punkt widzenia hosta na daną sieć fizyczną, np. Ethernet, jest bardzo ograniczony: może on komunikować się tylko z hostem w sieci, do której jest podłączony. Dostęp do wszystkich innych hostów jest możliwy tylko przez przeznaczone do tego urządzenia nazywane gatewayami. Gateway to host, który jest podłączony do dwóch lub więcej sieci fizycznych jednocześnie i skonfigurowany tak, by przekazywać pakiety między tymi sieciami. Rysunek 2-2 pokazuje fragment topologii sieci uniwersytetu Groucho Marx (GMU). Hosty należące jednocześnie do dwóch podsieci są opatrzone oboma adresami. Rysunek 2-2. Fragment schematu sieci uniwersytetu Groucho Marx http://www.rm.com.pl/upgr/lpas/02-02.tif Różne sieci fizyczne muszą być różnymi sieciami IP, aby protokół IP był w stanie rozpoznać, że host jest w sieci lokalnej. Na przykład numer sieci 149.76.4.0 jest zarezerwowany dla hostów w sieci LAN wydziału matematyki. Przy przesyłaniu datagramów do quarka, oprogramowanie sieciowe na erdosie natychmiast rozpoznaje na podstawie adresu IP 149.76.12.4, że host docelowy jest w innej sieci fizycznej, a co za tym idzie można się do niego dostać jedynie przez gateway (domyślnie sophus). Sam sophus jest podłączony do dwóch różnych podsieci: wydziału matematyki i sieci szkieletowej campusu. Dostęp do każdej z nich ma przez różne interfejsy, odpowiednio eth0 i fddi0. Jaki w takim razie powinniśmy przypisać mu adres IP? Powinien mieć adres z podsieci 149.76.1.0 czy może raczej z 149.76.4.0? Odpowiedź brzmi: oba. Gateway sophus ma przypisany adres 149.76.1.1 do użytku w sieci 149.76.1.0 i adres 149.76.4.1 do użytku w sieci 149.76.4.0. Gateway musi mieć odrębny adres IP w każdej sieci, do której należy. Adresy te, wraz z odpowiadającymi im maskami sieci, są związane z interfejsem, przez który następuje dostęp do sieci. Tak więc odwzorowanie interfejsu na adres w przypadku sophusa wygląda następująco: Interfejs Adres Maska sieci eth0 149.76.4.1 255.255.255.0 fddi0 149.76.1.1 255.255.255.0 lo 127.0.0.1 255.0.0.0 Ostatnia pozycja to interfejs pętli zwrotnej lo, o którym pisaliśmy wcześniej. Zwykle możesz zignorować subtelne różnice pomiędzy wiązaniem adresu z hostem lub jego interfejsem. Jeśli host jest tylko w jednej sieci, tak jak erdos, będziesz się odwoływał do hosta o takim a takim adresie IP, choć dokładnie rzecz biorąc, to interfejs Ethernet ma przypisany adres IP. Różnica jest naprawdę istotna tylko w przypadku gatewaya. Tablica rutingu Teraz skupimy się na tym, jak IP wybiera gateway, który ma zostać wykorzystany do dostarczenia datagramu do odległej sieci. Widzieliśmy, że kiedy erdos otrzyma datagram przeznaczony dla quarka, sprawdza adres docelowy i stwierdza, że nie leży on w sieci lokalnej. Dlatego erdos wysyła datagram do domyślnego gatewaya sophus, przed którym stoi teraz to samo zadanie. sophus stwierdza, że nie ma takiego hosta w sieciach, do których jest bezpośrednio podłączony. Musi więc znaleźć inny gateway, do którego będzie mógł przekazać datagram. Poprawnym wyborem będzie niels, gateway wydziału fizyki. sophus potrzebuje zatem informacji wiążących docelową sieć z odpowiednim gatewayem. IP wykorzystuje do tego celu tablicę, która łączy sieci z gatewayami, przez które można do nich dotrzeć. Musi w niej istnieć także wpis uniwersalny (ruting domyślny) - jest to gateway związany z siecią 0.0.0.0. Wszystkie adresy docelowe pasują do tej trasy, ponieważ żaden z 32 bitów nie musi odpowiadać temu wpisowi i dlatego pakiety do nie znanej sieci są wysyłane przez trasę domyślną. Dla gatewaya sophusa, tablica mogłaby wyglądać tak: Sieć Maska sieci Gateway Interfejs 149.76.1.0 255.255.255.0 - fddi0 149.76.2.0 255.255.255.0 149.76.1.2 fddi0 149.76.3.0 255.255.255.0 149.76.1.3 fddi0 149.76.4.0 255.255.255.0 - eth0 149.76.5.0 255.255.255.0 149.76.1.5 fddi0 ... ... ... ... 0.0.0.0 0.0.0.0 149.76.1.2 fddi0 Jeżeli masz skorzystać z trasy do tej sieci, do której sophus jest bezpośrednio podłączony, nie potrzebujesz gatewaya. Kolumna z wpisem gatewaya w takim przypadku zawiera kreskę. Proces identyfikacji, czy dany adres docelowy pasuje do trasy, jest operacją matematyczną. Jest dość prosty, ale wymaga znajomości logiki i arytmetyki binarnej: żądana trasa pasuje do trasy docelowej, jeżeli adres sieci po wykonaniu logicznej operacji AND z maską sieci jest dokładnie taki sam, jak adres docelowy po wykonaniu operacji logicznej AND z maską sieci. Wyjaśnienie: trasa jest prawidłowa, jeżeli liczba bitów adresu sieci określona przez maskę sieci (począwszy od pierwszego bitu leżącego od lewej strony, czyli najstarszego bitu pierwszego bajtu adresu) jest taka sama jak liczba bitów w adresie docelowym. Gdy implementacja IP poszukuje najlepszej trasy do miejsca docelowego, może znaleźć wiele pasujących wpisów z trasami. Na przykład wiemy, że domyślny ruting pasuje do każdego adresu docelowego, ale datagramy kierowane do sieci podłączonych lokalnie będą pasowały także do własnych tras. Skąd IP wie, której trasy użyć? To właśnie tutaj maska sieci ma decydujące znaczenie. Choć obie trasy pasują do adresu docelowego, jedna z nich ma większą maskę sieci niż druga. Wspomnieliśmy wcześniej, że maska sieci była używana do podziału naszej przestrzeni adresowej na mniejsze sieci. Im większa jest maska, tym lepiej jest dopasowywany adres docelowy. Wyznaczając trasę dla datagramu powinniśmy zawsze wybierać trasę o największej masce sieci. Domyślna trasa ma maskę sieci o wielkości 0 bitów, a w powyżej pokazanej konfiguracji, lokalnie podłączone sieci mają maski sieci o długości 24 bitów. Jeżeli datagram odpowiada lokalnie podłączonej sieci, będzie rutowany w pierwszej kolejności do odpowiedniego urządzenia, a nie na adres domyślny, gdyż lokalne trasy są dopasowane większą liczbą bitów. Tylko te datagramy, które nie pasują do żadnej trasy, będą przesyłane przez trasę domyślną. Tablice rutingu możesz tworzyć na różne sposoby. Dla małych sieci lokalnych zwykle najlepiej przygotować ją ręcznie i udostępnić protokołowi IP za pomocą polecenia route w czasie uruchamiania maszyny (zobacz rozdział 5, Konfigurowanie sieci TCP/IP). Dla większych sieci tablice są budowane i uzupełniane w czasie pracy sieci przez demony rutingu; te programy pracują na centralnych hostach sieci i wymieniają informacje o rutingu, by obliczyć "optymalne" trasy pomiędzy podłączonymi sieciami. Rozmiar sieci decyduje też o wyborze protokołów rutingu. W przypadku rutingu w systemach niezależnych (tak jak w campusie Groucho Marx), używane są wewnętrzne protokoły rutingu. Najbardziej znanym z nich jest RIP (Routing Information Protocol), zaimplementowany w demonie routed BSD. W przypadku rutingu pomiędzy systemami autonomicznymi stosowane są zewnętrzne protokoły rutingu, takie jak EGP (External Gateway Protocol) lub BGP (Border Gateway Protocol). Protokoły te, wraz z RIP-em, zostały zaimplementowane w demonie gated napisanym na Uniwersytecie Cornella. Wartości metryki Można skorzystać z rutingu dynamicznego, jeżeli trzeba znaleźć najlepszą trasę do hosta docelowego lub sieci na podstawie liczby hopów. Hopy oznaczają liczbę gatewayów, przez które datagram musi przejść, zanim dotrze do hosta lub sieci. Im krótsza jest trasa, tym lepiej radzi sobie z nią RIP. Bardzo długie trasy (ponad 16 hopów) są traktowane jako bezużyteczne i są usuwane. RIP obsługuje informacje o rutingu wewnątrz twojej sieci lokalnej, ale na wszystkich hostach musisz uruchomić demona gated. W czasie startu komputera gated sprawdza wszystkie aktywne interfejsy sieciowe. Jeżeli jest aktywny więcej niż jeden interfejs (nie licząc interfejsu pętli zwrotnej), demon zakłada, że host przekazuje pakiety pomiędzy kilkoma sieciami i czynnie wymienia oraz rozgłasza informacje o rutingu. W przeciwnym razie jedynie pasywnie odbiera uaktualnienia RIP i odświeża lokalną tablicę rutingu. Przy rozgłaszaniu informacji z lokalnej tablicy rutingu, gated liczy długość trasy na podstawie tak zwanej wartości metryki (ang. metric value) związanej z wpisem w tablicy. Ta wartość jest ustawiana przez administratora podczas konfigurowania rutingu i powinna odpowiadać rzeczywistemu kosztowi trasy*. Dlatego metryka trasy do podsieci, do której host jest podłączony bezpośrednio, zawsze powinna wynosić zero, natomiast trasa prowadząca przez dwa gatewaye powinna mieć metrykę o wartości dwa. Nie musisz przejmować się metryką, jeżeli nie używasz protokołu RIP-a ani gated. Internetowy protokół komunikatów kontrolnych (ICMP) IP ma protokół towarzyszący, o którym jeszcze nie mówiliśmy. Jest nim ICMP (Internet Control Message Protocol) używany przez kod sieciowy jądra do przesyłania komunikatów o błędach do innych hostów. Na przykład załóżmy, że jesteś znów na erdosie i chcesz zrealizować połączenie telnet z portem 12345 na quarku, ale na tym porcie nie ma procesu nasłuchującego. Gdy pierwszy pakiet TCP zaadresowany na ten port nadejdzie do quarka, warstwa sieciowa rozpozna, że coś przyszło i natychmiast zwróci do erdosa komunikat ICMP o treści "Port Unreachable" (port nieosiągalny). Protokół ICMP udostępnia różne komunikaty, głównie z informacjami o błędach. Jednak istnieje jeden ciekawy komunikat, tak zwany komunikat przekierowania (ang. redirect message). Jest on generowany przez moduł rutingu, gdy wykryje on, że inny host używa naszego hosta jako gatewaya, mimo że istnieje krótsza trasa. Na przykład po uruchomieniu systemu tablica rutingu na sophusie może być niepełna. Może zawierać trasy do sieci wydziału matematyki, do szkieletu FDDI i domyślną trasę do gatewaya centrum obliczeniowego Groucho (gcc1). Tak więc pakiety adresowane do quarka będą wysyłane do gcc1, a nie do nielsa - gatewaya wydziału fizyki. Po odebraniu takiego datagramu gcc1 zauważy, że jest to nieoptymalna trasa i przekaże pakiet do nielsa, zwracając równocześnie do sophusa komunikat przekierowania ICMP z informacją o lepszej trasie. Wydaje się, że w ten sposób można łatwo uniknąć ręcznej konfiguracji wszelkich tras poza podstawowymi. Trzeba jednak zdawać sobie sprawę, że poleganie na schematach rutingu dynamicznego, czy to będzie RIP, czy komunikat przekierowania ICMP, nie zawsze jest dobre. Przekierowanie ICMP i RIP dają ci niewielką możliwość (lub wręcz nie dają ci żadnej szansy) weryfikowania pokrywających się informacji o rutingu. Ta sytuacja może prowadzić do zakłócenia pracy całej twojej sieci lub jeszcze gorszych rzeczy. W rezultacie kod sieciowy Linuksa traktuje komunikaty przekierowania sieci tak, jakby to były przekierowania hosta. Minimalizuje to zniszczenia w przypadku ataku, które dotkną wówczas jeden host, a nie całą sieć. Z drugiej strony oznacza to, że w przypadku legalnej sytuacji generowany jest nieco większy ruch, gdyż każdy host wysyła komunikat przekierowania ICMP. Obecnie opieranie się na przekierowaniach ICMP nie jest dobrze widziane i uznaje się je raczej za złą praktykę. Rozwiązywanie nazwy hosta Jak wcześniej napisaliśmy, adresowanie w sieci TCP/IP, przynajmniej tam, gdzie korzysta się z IP w wersji 4, opiera się na liczbach 32-bitowych. Nie ukrywamy, że zapamiętywanie takich liczb nie jest łatwe. Dlatego hosty występują również pod "zwykłymi" nazwami, takimi jak gauss czy strange. Znalezienie adresu IP odpowiadającego nazwie to obowiązek aplikacji. Proces ten jest nazywany rozwiązywaniem nazwy hosta. Gdy aplikacja chce znaleźć adres IP danego hosta, korzysta z funkcji bibliotecznej gethostbyname(3) i gethostbyaddr(3). Tradycyjnie te i inne związane z nimi procedury były zgrupowane w oddzielnej bibliotece o nazwie resolverlibrary. W Linuksie funkcje te są częścią standardowej biblioteki libc. Potocznie zestaw tych funkcji jest nazywany "resolverem". Konfigurację mechanizmu rozwiązywania nazw opisano szczegółowo w rozdziale 6, Usługi nazewnicze i konfigurowanie resolvera. W przypadku małej sieci Ethernet czy nawet grupy takich sieci, nie jest trudno utrzymywać tablice odwzorowujące nazwy hostów na adresy. Informacja ta jest zwykle przechowywana w pliku o nazwie /etc/hosts. Podczas dodawania lub usuwania hostów albo zmiany przypisania adresów, wystarczy uaktualnić plik hosts na wszystkich hostach. Oczywiście staje się to uciążliwe przy sieciach, które składają się z więcej niż kilku maszyn. Jednym z rozwiązań jest NIS (Network Information System - system informacji sieciowej)  stworzony przez firmę Sun Microsystems, potocznie nazywany YP lub Yellow Pages. NIS przechowuje plik hosts (i inne informacje) w bazie danych na hoście głównym, z którego klienty mogą go w razie potrzeby odczytywać. Rozwiązanie takie jest odpowiednie jedynie dla średniej wielkości sieci typu LAN, ponieważ wymaga utrzymania centralnej bazy danych hosts i dystrybuowania jej do wszystkich serwerów. Instalacja i konfiguracja NIS-a została omówiona w rozdziale 13, System informacji sieciowej. W Internecie informacje adresowe były pierwotnie przechowywane także w pliku bazy danych HOSTS.TXT. Plik ten był utrzymywany przez NIC (Network Information Center - centrum informacji sieciowej) i musiał być stamtąd pobierany i instalowany przez wszystkie ośrodki podłączone do Internetu. Gdy sieć się rozrosła, takie rozwiązanie stało się niewygodne. Poza uciążliwym w administracji regularnym instalowaniem pliku HOSTS.TXT, niebezpiecznie wzrosło obciążenie dystrybuujących go serwerów. Co więcej, wszystkie nazwy musiały być rejestrowane w NIC, aby mieć pewność, że żadna się nie powtarza. Dlatego w 1994 roku przyjęto nowy schemat rozwiązywania nazw: system nazw domen (Domain Name System - DNS) autorstwa Paula Mockapetrisa. System nazw domen omawiamy szczegółowo w rozdziale 6. 3 Konfigurowanie sprzętu sieciowego Rozdział 3: Konfigurowanie sprzętu sieciowego Powiedzieliśmy nieco o interfejsach sieciowych i ogólnie o TCP/IP, ale nie opisaliśmy, co tak naprawdę się dzieje, gdy "kod sieciowy" jądra uzyskuje dostęp do sprzętu. Aby to wyjaśnić, musimy podać trochę informacji o interfejsach i sterownikach. Na początku jest oczywiście sprzęt, na przykład karta Ethernet, FDDI czy Token Ring: jest to płytka drukowana, wypełniona wieloma małymi układami scalonymi z wypisanymi na nich dziwnymi numerkami, umieszczona w złączu w płycie twojego PC. Nazywamy to ogólnie urządzeniem fizycznym. Abyś mógł używać karty sieciowej, jądro Linuksa musi zawierać specjalne funkcje, które rozumieją określony dla danego urządzenia sposób dostępu. Oprogramowanie, które implementuje te funkcje, nazywane jest sterownikiem urządzenia. Linux ma sterowniki dla wielu różnych typów kart sieciowych: ISA, PCI, MCA, EISA, port równoległy, PCMCIA i najnowszy USB. Co jednak mamy na myśli, mówiąc, że sterownik "obsługuje" urządzenie? Rozważmy to na przykładzie karty Ethernet. Sterownik powinien komunikować się w jakiś sposób z peryferiami karty: musi wysyłać polecenia i dane do karty, natomiast karta powinna dostarczać wszelkie odebrane dane do sterownika. W komputerach osobistych IBM komunikacja ta odbywa się przez zestaw adresów wejścia/wyjścia, które są odwzorowywane na rejestry na karcie, a także (lub wyłącznie) przez współdzielony lub bezpośredni dostęp do pamięci. Wszystkie polecenia i dane, jakie jądro wysyła do karty, muszą zostać przesłane na te adresy. Adresy wejścia/wyjścia oraz pamięci są zwykle podawane w postaci adresu początkowego lub adresu podstawowego (ang. base address). Typowe adresy podstawowe w przypadku kart Ethernet dla magistrali ISA to 0x280 lub 0x300. Karty przeznaczone dla magistrali PCI mają automatycznie przypisywane własne adresy wejścia/wyjścia. Zwykle nie musisz się martwić o zagadnienia sprzętowe, takie jak adres podstawowy, ponieważ jądro w czasie startu podejmuje próbę wykrycia lokalizacji karty. Nazywa się to autowykrywaniem, co oznacza, że jądro odczytuje kilka lokalizacji pamięci i wejścia/wyjścia oraz porównuje odczytane dane z tym, czego oczekuje, jeżeli dana karta sieciowa jest zainstalowana pod tym adresem. Jednak zdarzają się karty sieciowe, których nie da się wykryć automatycznie. Czasem dzieje się tak w przypadku tanich kart sieciowych, które nie są w pełni klonami standardowych kart innych producentów. W czasie startu jądro próbuje wykryć tylko jedną kartę sieciową. Jeżeli używasz więcej niż jednej karty, musisz jawnie powiedzieć o tym jądru. Innym parametrem, który być może będzie trzeba podać jądru, jest numer przerwania. Urządzenia zwykle generują przerwanie do jądra, aby na przykład zwrócić na siebie uwagę, gdy nadeszły dane lub wystąpiła jakaś szczególna sytuacja. W komputerach PC z magistralą ISA przerwania mogą pojawiać się na jednym z 15 kanałów przerwań,  ponumerowanych następująco: 0, 1, 3 i tak dalej do 15. Numer przerwania przypisany do urządzenia nazywa się numerem zgłoszenia przerwania (ang. Interrupt request number - IRQ)*. Z rozdziału 2, Wybrane problemy sieci TCP/IP, wiemy, że jądro uzyskuje dostęp do urządzenia sieciowego przez oprogramowanie nazywane interfejsem. Interfejsy są zestawami funkcji (np. wysyłania lub odbierania datagramu), identycznymi dla różnych typów urządzeń. Interfejsy są identyfikowane na podstawie nazw. W wielu uniksowych systemach operacyjnych interfejs sieciowy jest implementowany jako specjalny plik w katalogu /dev. Jeżeli napiszesz polecenie ls -las /dev/, zobaczysz, jak wyglądają takie pliki. Zauważysz, że w kolumnie praw dostępu (drugiej) pliki urządzeń zaczynają się raczej literą, a nie myślnikiem (jak zwykłe pliki). Znak ten określa typ urządzenia. Najpopularniejsze są urządzenia typu b, czyli urządzenia blokowe obsługujące całe bloki danych przy każdym odczycie i zapisie oraz urządzenia typu c, czyli urządzenia znakowe, obsługujące dane po jednym znaku. Tam, gdzie zwykle w wyniku pokazywanym przez polecenie ls widzisz rozmiar pliku, tutaj są dwie liczby nazywane numerem nadrzędnym i podrzędnym urządzenia. Liczby te wskazują rzeczywiste urządzenie, z którym jest związany plik. Każdy sterownik rejestruje unikalny numer nadrzędny w jądrze. Każda instancja urządzenia rejestruje unikalny numer podrzędny danego urządzenia nadrzędnego. Interfejsy tty, /dev/tty*, są urządzeniami znakowymi wskazywanymi przez literę c i każde ma numer nadrzędny 4, ale /dev/tty1 ma numer podrzędny 1, a /dev/tty2 ma numer podrzędny 2. Pliki urządzeń są bardzo użyteczne dla wielu typów urządzeń, ale mogą sprawiać kłopoty, gdy chcesz otworzyć nie używane urządzenie. Nazwy interfejsów w Linuksie są zdefiniowane wewnętrznie w jądrze i nie są plikami urządzeń w katalogu /dev. Niektóre typowe nazwy podano w dalszym podrozdziale Wycieczka po urządzeniach sieciowych Linuksa. Przypisanie interfejsów do urządzeń zwykle zależy od kolejności, w której są one konfigurowane. Na przykład pierwsza zainstalowana karta Ethernet będzie nosiła nazwę eth0, a następna eth1. Interfejsy SLIP są obsługiwane inaczej niż pozostałe urządzenia, ponieważ są przypisywane dynamicznie. Kiedy zostanie zestawione połączenie SLIP, interfejs jest przypisywany do portu szeregowego. Rysunek 3-1 pokazuje zależności pomiędzy sprzętem, sterownikami urządzenia i interfejsami. Rysunek 3-1. Związek pomiędzy sterownikami, interfejsami i sprzętem http://www.rm.com.pl/upgr/lpas/03-01.tif Przy uruchamianiu systemu jądro wyświetla wykryte urządzenia i instalowane interfejsy. Oto fragment typowych komunikatów wyświetlanych w czasie uruchamiania systemu: . .   This processor honors the WP bit even when in supervisor mode./    Good. Swansea University Computer Society NET3.035 for Linux 2.0 NET3: Unix domain sockets 0.13 for Linux NET3.035. Swansea University Computer Society TCP/IP for NET3.034 IP Protocols: IGMP, ICMP, UDP, TCP Swansea University Computer Society IPX 0.34 for NET3.035 IPX Portions Copyright (c) 1995 Caldera, Inc. Serial driver version 4.13 with no serial options enabled tty00 at 0x03f8 (irq = 4) is a 16550A tty01 at 0x02f8 (irq = 3) is a 16550A CSLIP: code copyright 1989 Regents of the University of California PPP: Version 2.2.0 (dynamic channel allocation) PPP Dynamic channel allocation code copyright 1995 Caldera, Inc. PPP line disciplne registered. eth0: 3C509 at 0x300 tag 1, 10baseT port, address 00 a0 24 0e e4 e0, /    IRQ 10. 3c509.c:1.12 6/4/97 becker@cesdis.gsfc.nasa.gov Linux Version 2.0.32 (root@perf) (gcc Version 2.7.2.1) #1 Tue Oct 21 15:30:44 EST 1997 . . Ten przykład pokazuje, że jądro zostało skompilowane z włączonym protokołem TCP/IP i zawiera sterowniki dla SLIP, CSLIP i PPP. Trzeci wiersz od końca mówi, że została wykryta karta Ethernet 3C509, która jest zainstalowana jako interfejs eth0. Gdybyś miał kartę innego typu, na przykład D-Link pocket adaptor, jądro wypisałoby wiersz rozpoczynający się od nazwy takiego urządzenia - dl0 w przypadku D-Link, a następnie pokazałoby typ wykrytej karty. Gdybyś miał zainstalowaną kartę sieciową, ale nie widziałbyś żadnego podobnego komunikatu, oznacza to, że jądro nie jest w stanie jej poprawnie wykryć. Sytuacja ta zostanie omówiona w dalszym podrozdziale Automatyczne wykrywanie kart Ethernet. Konfigurowanie jądra Do wielu dystrybucji Linuksa są dołączane dyskietki startowe, które działają z większością sprzętu PC. Dostarczone jądro jest znacznie zmodularyzowane i zawiera prawie wszelkie możliwe sterowniki. Takie rozwiązanie wygląda świetnie na dyskietce startowej, ale raczej nie przyda się zwykłemu użytkownikowi. Nie ma sensu zajmować miejsca na dysku sterownikami, których nie będziesz używał. Dlatego najlepiej przygotować własne jądro i umieścić w nim tylko te sterowniki, których rzeczywiście potrzebujesz - w ten sposób zaoszczędzisz nieco miejsca na dysku i zmniejszysz czas potrzebny na skompilowanie nowego jądra. W każdym razie jeżeli pracujesz z Linuksem, powinieneś umieć tworzyć jądro. Uznaj to za potwierdzenie tego, że darmowe oprogramowanie jest świetne - masz kod źródłowy. Nie myśl: "Muszę skompilować jądro", ale raczej: "Mogę skompilować jądro". Podstawy kompilacji jądra Linuksa zostały wyjaśnione w książce Matta Welsha Running Linux (wyd. pol.: Linux, Wydawnictwo RM, Warszawa 2000). Dlatego w tym podrozdziale omówimy jedynie opcje konfiguracyjne dotyczące sieci. Naprawdę ważną rzeczą, którą warto tutaj przypomieć, jest schemat numeracji jądra. Jądra Linuksa są numerowane w formacie: 2.2.14. Pierwsza cyfra oznacza główny numer wersji. Zmienia się ona wtedy, gdy następują poważne, znaczące przekształcenia w architekturze jądra. Na przykład wersję jądra przenumerowano z 1. na 2., gdy zostało dodane wsparcie dla maszyn opartych na nieintelowskich procesorach. Druga liczba to drugorzędny numer wersji. Pod wieloma względami ważniejsza jest właśnie ona. Społeczność twórców Linuksa przyjęła zasadę, że parzyste drugorzędne numery wersji oznaczają jądra produkcyjne lub stabilne, a nieparzyste numery wersji oznaczają jądra rozwojowe lub niestabline. Na maszynie, która jest dla ciebie ważna, powinieneś używać jąder stabilnych, gdyż są one lepiej przetestowane. Po jądra rozwojowe warto sięgnąć wtedy, gdy lubisz eksperymentować z najnowszymi funkcjami Linuksa, ale musisz liczyć się z tym, że mogą pojawić się jeszcze nie znane i nie poprawione błędy. Trzecia liczba to po prostu kolejne wersje wersji oznaczonej numerem drugorzędnym*. Gdy wydasz polecenie make menuconfig, pojawi się tekstowe menu z listą pytań dotyczących konfiguracji. Będą to pytania typu: czy chcesz emulacji koprocesora w jądrze. Jedno z tych pytań dotyczy obsługi sieci TCP/IP. Musisz na nie odpowiedzieć y, aby jądro było w stanie obsłużyć sieć. Opcje jądra w Linuksie 2.0 i nowszych Po ustaleniu ogólnych opcji konfiguracyjnych następują pytania o to, czy chcesz zapewnić obsługę różnych funkcji, takich jak sterowniki SCSI czy karty dźwiękowe. Monit będzie pokazywał dostępne opcje. Możesz nacisnąć ?, aby zapoznać się z opisem danej opcji. Zawsze masz do wyboru "tak" (y), aby statycznie dołączyć element do jądra, lub "nie" (n), aby usunąć go całkowicie z jądra. Spotkasz także opcję modułu (m) w przypadku elementów, które mogą zostać skompilowane jako moduły ładowane w czasie pracy jądra. Moduły ładuje się, zanim zostaną wykorzystane i są one szczególnie przydatne dla sterowników lub rzadziej używanych elementów. Dalej następuje lista pytań o obsługę sieci. Dokładny zestaw opcji konfiguracyjnych nieustannie się zmienia ze względu na ciągły rozwój. Typowa lista opcji oferowanych przez większość jąder rodziny 2.0 i 2.1 wygląda tak: * * Network device support * Network device support (CONFIG_NETDEVICES) [Y/n/?] Musisz odpowiedzieć na to pytanie y, jeżeli chcesz korzystać z jakichkolwiek urządzeń sieciowych, czy to będzie Ethernet, SLIP, PPP, czy cokolwiek innego. Gdy odpowiesz na pytanie twierdząco, automatycznie zostanie włączona obsługa urządzeń typu Ethernet. Jeżeli chcesz włączyć obsługę innych typów sterowników sieciowych, musisz odpowiedzieć na dodatkowe pytania. PLIP (parallel port) support (CONFIG_PLIP) [N/y/m/?] y PPP (point-to-point) support (CONFIG_PPP) [N/y/m/?] y * * CCP compressors for PPP are only built as modules. * SLIP (serial line) support (CONFIG_SLIP) [N/y/m/?] m CSLIP compressed headers (CONFIG_SLIP_COMPRESSED) [N/y/?] (NEW) y Keepalive and linefill (CONFIG_SLIP_SMART) [N/y/?] (NEW) y Six bit SLIP encapsulation (CONFIG_SLIP_MODE_SLIP6) [N/y/?] (NEW) y Pytania te dotyczą różnych protokołów warstwy łącza obsługiwanych przez Linuksa. Zarówno PPP, jak i SLIP pozwalają na przesyłanie datagramów IP po łączach szeregowych. PPP w rzeczywistości jest zestawem protokołów używanych do wysyłania danych po łączach szeregowych. Niektóre protokoły wchodzące w skład zestawu PPP obsługują uwierzytelnianie się użytkownika na serwerze dostępowym, natomiast inne zajmują się przenoszeniem pewnych protokołów przez łącze - PPP transportuje nie tylko datagramy  TCP/IP - może także przenosić inne protokoły, takie jak IPX. Jeżeli na pytanie o obsługę protokołu SLIP odpowiesz y lub m, zostaniesz poproszony o odpowiedź na trzy kolejne pytania. Opcja kompresji nagłówka pozwala na korzystanie z  CSLIP - techniki, która kompresuje nagłówki TCP/IP do zaledwie trzech bajtów. Zauważ, że ta opcja jądra nie włącza automatycznie CSLIP, a jedynie udostępnia niezbędne do tego celu funkcje jądra. Opcja Keepalive and linefill powoduje, że co jakiś czas jest generowany sztuczny ruch na łączu SLIP, aby uniknąć zerwania połączenia przez czujnik nieaktywności. Opcja Six bit SLIP encapsulation pozwala na uruchomienie SLIP na liniach i obwodach, które nie są w stanie przesyłać pełnych 8-bitowych zestawów danych. Jest to technika podobna do uukodowania (ang. uuencoding) lub algorytmu binhex, stosowanych do przesyłania plików binarnych pocztą elektroniczną. Protokół PLIP jest sposobem przesłania datagramów IP przez łącze oparte o porty równoległe. Używa się go do komunikowania się komputerów PC pracujących w systemie DOS. Na typowym komputerze PC, protokół PLIP może być szybszy niż PPP czy SLIP, ale bardziej obciąża procesor, a więc choć przepustowość pozostanie odpowiednia, to inne zadania mogą być realizowane wolniej. Poniższe pytania dotyczą kart sieciowych różnych sprzedawców. Im więcej sterowników jest dostępnych na rynku, tym bardziej prawdopodobne, że w tej sekcji pojawi się nowe pytanie. Gdybyś chciał stworzyć jądro, mógłbyś robić to na wielu różnych maszynach, a gdyby twoja maszyna miała zainstalowane różne rodzaje kart sieciowych, mógłbyś włączyć więcej niż jeden sterownik: . . Ethernet (10 or 100Mbit) (CONFIG_NET_ETHERNET) [Y/n/?] 3COM cards (CONFIG_NET_VENDOR_3COM) [Y/n/?] 3c501 support (CONFIG_EL1) [N/y/m/?] 3c503 support (CONFIG_EL2) [N/y/m/?] 3c509/3c579 support (CONFIG_EL3) [N/y/m/?] 3c590/3c900 series (592/595/597/900/905) "Vortex/Boomerang" support     (CONFIG_VORTEX) [N/y/m/?] AMD LANCE and PCnet (AT1500 and NE2100) support (CONFIG_LANCE) [N/y/?] AMD PCInet32 (VLB and PCI) support (CONFIG_LANCE32) [N/y/?] (NEW) Western Digital/SMC cards (CONFIG_NET_VENDOR_SMC) [N/y/?] WD80*3 support (CONFIG_WD80x3) [N/y/m/?] (NEW) SMC Ultra support (CONFIG_ULTRA) [N/y/m/?] (NEW) SMC Ultra32 support (CONFIG_ULTRA32) [N/y/m/?] (NEW) SMC 9194 support (CONFIG_SMC9194) [N/y/m/?] (NEW) Other ISA cards (CONFIG_NET_ISA) [N/y/?] Cabletron E21xx support (CONFIG_E2100) [N/y/m/?] (NEW) DEPCA, DE10x, DE200, DE201, DE202, DE422 support (CONFIG_DEPCA) [N/y/m/?] (NEW) EtherWORKS 3 (DE203, DE204, DE205) support (CONFIG_EWRK3) [N/y/m/?] (NEW) EtherExpress 16 support (CONFIG_EEXPRESS) [N/y/m/?] (NEW) HP PCLAN+ (27247B and 27252A) support (CONFIG_HPLAN_PLUS) [N/y/m/?] (NEW) HP PCLAN (27245 and other 27xxx series) support (CONFIG_HPLAN) [N/y/m/?] (NEW) HP 10/100VG PCLAN (ISA, EISA, PCI) support (CONFIG_HP100) [N/y/m/?] (NEW) NE2000/NE1000 support (CONFIG_NE2000) [N/y/m/?] (NEW) SK_G16 support (CONFIG_SK_G16) [N/y/?] (NEW) EISA, VLB, PCI and on card controllers (CONFIG_NET_EISA) [N/y/?] Apricot Xen-II on card ethernet (CONFIG_APRICOT) [N/y/m/?] (NEW) Intel EtherExpress/Pro 100B support (CONFIG_EEXPRESS_PRO100B) [N/y/m/?] (NEW) DE425, DE434, DE435, DE450, DE500 support (CONFIG_DE4X5) [N/y/m/?] (NEW) DECchip Tulip (dc21x4x) PCI support (CONFIG_DEC_ELCP) [N/y/m/?] (NEW) Digi Intl. RightSwitch SE-X support (CONFIG_DGRS) [N/y/m/?] (NEW) Pocket and portable adaptors (CONFIG_NET_POCKET) [N/y/?] AT-LAN-TEC/RealTek pocket adaptor support (CONFIG_ATP) [N/y/?] (NEW) D-Link DE600 pocket adaptor support (CONFIG_DE600) [N/y/m/?] (NEW) D-Link DE620 pocket adaptor support (CONFIG_DE620) [N/y/m/?] (NEW) Token Ring driver support (CONFIG_TR) [N/y/?] IBM Tropic chipset based adaptor support (CONFIG_IBMTR) [N/y/m/?] (NEW) FDDI driver support (CONFIG_FDDI) [N/y/?] Digital DEFEA and DEFPA adapter support (CONFIG_DEFXX) [N/y/?] (NEW) ARCnet support (CONFIG_ARCNET) [N/y/m/?]  Enable arc0e (ARCnet "Ether-Encap" packet format) (CONFIG_ARCNET_ETH)/       [N/y/?] (NEW)  Enable arc0s (ARCnet RFC1051 packet format) (CONFIG_ARCNET_1051)/       [N/y/?] (NEW) . . Pod koniec sekcji dotyczącej systemu plików skrypt konfiguracyjny zapyta cię, czy chcesz włączyć obsługę NFS - sieciowego systemu plików. NFS pozwala na udostępnienie systemu plików kilku hostom, na których pliki z twojego hosta będą widoczne tak, jakby były na zwykłym dysku podłączonym lokalnie: NFS file system support (CONFIG_NFS_FS) [y] NFS opiszemy szczegółowo w rozdziale 14, Sieciowy system plików. Opcje sieciowe jądra w Linuksie 2.0.0 i nowszych W jądrze Linuksa 2.0.0 nastąpiły znaczne zmiany w obsłudze sieci. Wiele funkcji stało się standardową częścią jądra, na przykład obsługa protokołu IPX. Dodano także szereg opcji, co otworzyło nowe możliwości konfiguracyjne. Wielu opcji używa się tylko w bardzo szczególnych sytuacjach i nie będziemy ich opisywać. Dokument Networking-HOWTO opisuje to, co my tutaj pomijamy. W tym podrozdziale podajemy najbardziej przydatne opcje i wyjaśniamy, kiedy należy ich używać: Podstawy Aby używać sieci TCP/IP, musisz odpowiedzieć na to pytanie, wpisując y. Jeżeli odpowiesz n, wciąż będziesz mógł skompilować jądro z obsługą IPX: Networking options --->    [*] TCP/IP networking Gatewaye Musisz włączyć tę opcję, jeżeli twój system pracuje jako gateway pomiędzy dwoma sieciami lub pomiędzy siecią lokalną a łączem SLIP. To, że opcja jest domyślnie włączona, w niczym nie przeszkadza, ale trzeba ją wyłączyć, jeżeli chcesz skonfigurować host jako firewall. Firewalle to hosty, które są podłączone do dwóch lub więcej sieci, ale nie rutują ruchu pomiędzy nimi. Są one powszechnie stosowane, aby udostępnić użytkownikom Internet przy minimalnym ryzyku dla sieci wewnętrznej. Użytkownicy mogą logować się do firewalla i korzystać z usług internetowych, a komputery firmowe są zabezpieczone przed atakami z zewnątrz, ponieważ firewalle nie przepuszczają żadnych połączeń przychodzących z zewnątrz (firewalle opisujemy szczegółowo w rozdziale 9, Firewall TCP/IP): [*] IP: forwarding/gatewaying Wirtualne hosty Opcje te pozwalają na skonfigurowanie więcej niż jednego adresu IP dla jednego interfejsu. Przydają się, jeżeli chcesz tworzyć "hosty wirtualne", czyli skonfigurować maszynę tak, że wygląda i działa jak kilka oddzielnych maszyn, każda o własnych parametrach sieciowych. Więcej na temat tworzenia aliasów IP powiemy za chwilę: [*] Network aliasing   <*> IP: aliasing support Liczenie ruchu IP Opcja ta pozwala na zbieranie danych na temat wielkości ruchu IP (wychodzącego i wchodzącego) w danej maszynie. (Omówienie tego zagadnienia zawiera rozdział 10, Liczenie ruchu IP). [*] IP: accounting Błąd PC Opcja ta rozwiązuje problem niekompatybilności z niektórymi wersjami zestawu PC/TCP, bedącego komercyjną implementacją TCP/IP dla komputerów PC opartych na DOS-ie. Jeżeli włączysz tę opcję, wciąż będziesz mógł komunikować się ze zwykłymi maszynami uniksowymi, ale wydajność na gorszych łączach może być słabsza: --- (it is safe to leave these untouched) [*] IP: PC/TCP compatibility mode Uruchamianie bezdyskowe Funkcja ta włącza RARP (odwrotny protokół rozwiązywania adresów). RARP jest używany przez klienty bezdyskowe i X terminale do uzyskiwania swojego adresu IP przy uruchamianiu. Powinieneś włączyć RARP, jeżeli planujesz obsługę klientów tego typu. Mały program o nazwie rarp, dołączony do standardowych narzędzi sieciowych, jest używany to dodawania wpisów do tablicy RARP jądra: <*> IP: Reverse ARP MTU Aby dane wysyłane przez TCP/IP mogły zostać przekazane do protokołu IP, jądro musi podzielić ich strumień na bloki. Rozmiar bloku jest określany za pomocą maksymalnej jednostki transmisji (Maximum Transmission Unit - MTU). W przypadku hostów, które są osiągalne przez sieć lokalną, np. Ethernet, typowe jest używanie MTU odpowiadającego maksymalnej wielkości pakietu Ethernet - 1500 bajtom. W przypadku rutingu IP przez sieci rozległe takie jak Internet, preferowane jest stosowanie mniejszych datagramów, aby nie musiały być dalej dzielone w procesie zwanym fragmentacją IP (ang. IP fragmentation)*. Jądro jest w stanie automatycznie określić najmniejszą wartość MTU dla danej trasy IP i automatycznie skonfigurować połączenie TCP dla tej trasy. Zachowanie to jest domyślne. Jeżeli odpowiesz y przy wyborze tej opcji, właściwość ta zostanie wyłączona. Jeżeli rzeczywiście chcesz wysyłać dane w mniejszych pakietach do określonych hostów (ponieważ na przykład dane są przesyłane przez łącze SLIP), skorzystaj z opcji mss polecenia route, które zostanie krótko omówione pod koniec tego rozdziału: [ ] IP: Disable Path MTU Discovery (normally enabled) Bezpieczeństwo Protokół IP obsługuje funkcję źródłowego wyboru trasy (ang. source routing). ?ródłowy wybór trasy pozwala na zakodowanie trasy datagramu w nim samym. Z całą pewnością było to dobre rozwiązanie, zanim upowszechniły się protokoły RIP i OSPF. Obecnie uznawane jest za niebezpieczne, ponieważ daje osobom niepowołanym narzędzie do pokonania zabezpieczeń firewalli, mianowicie pozwala na ominięcie tablicy rutingu rutera. W normalnej sytuacji powinieneś filtrować datagramy ze źródłowym wyborem trasy, a więc ta opcja powinna być włączona: [*] IP: Drop source routed frames Obsługa sieci Novell Opcja ta włącza obsługę IPX - protokołu transportowego wykorzystywanego w sieci Novell. Linux będzie działał doskonale jako ruter IPX, a ponadto funkcja ta jest przydatna w środowiskach, gdzie znajdują się serwery plików Novell. System plików NCP również wymaga włączonej obsługi IPX w jądrze. Gdybyś chciał podłączyć się i zamontować systemy plików Novell, musiałbyś mieć tę opcję włączoną (IPX i system plików NCP omawiamy w rozdziale 15, IPX i system plików NCP): <*> The IPX protocol Radio amatorskie Trzy poniższe opcje włączają obsługę protokołów radia amatorskiego obsługiwanych przez Linuksa: AX.25, NetRom i Rose (nie opisujemy ich w tej książce, ale są one szczegółowo przedstawione w dokumencie AX25-HOWTO): <*> Amateur Radio AX.25 Level 2 <*> Amateur Radio NET/ROM <*> Amateur Radio X.25 PLP (Rose) Linux obsługuje jeszcze jeden typ sterownika: sterownik fikcyjny (ang. dummy driver). Poniższe pytanie pojawia się na początku sekcji dotyczącej sterowników urządzeń: <*> Dummy net driver support Sterownik fikcyjny jest w zasadzie przydatny tylko w przypadku samodzielnych hostów PPP/SLIP. Jest to w istocie interfejs pętli zwrotnej z maskowaniem IP. Na hostach, które posiadają jedynie interfejsy PPP/SLIP, będziesz chciał mieć interfejs, który przez cały czas utrzymuje twój adres IP. Omawiamy to nieco bardziej szczegółowo w podrozdziale Interfejs fikcyjny w rozdziale 5, Konfigurowanie sieci TCP/IP. Zauważ, że dzisiaj to samo możesz uzyskać, używając aliasu IP i konfigurując swój adres IP jako alias na interfejsie pętli zwrotnej. Wycieczka po urządzeniach sieciowych Linuksa Jądro Linuksa obsługuje szereg sterowników dla różnego rodzaju sprzętu. Ten podrozdział to krótki przegląd dostępnych rodzin sterowników i używanych przez nie nazw interfejsów. Interfejsy w Linuksie mają standardowe nazwy, wymienione poniżej. Większość sterowników obsługuje więcej niż jeden interfejs, dlatego interfejsy są numerowane, na przykład eth0 i eth1. lo To lokalny interfejs pętli zwrotnej. Jest używany zarówno do celów testowych, jak i przez kilka aplikacji sieciowych. Działa na zasadzie obwodu zamkniętego, w którym wszelkie dane wysłane do interfejsu są zwracane do warstwy sieciowej hosta. W jądrze istnieje zawsze tylko jeden interfejs pętli zwrotnej i nie ma sensu, aby było ich więcej. eth0, eth1... To interfejsy kart Ethernet. Są używane przez większość kart Ethernet, włącznie z tymi podłączanymi przez port równoległy. tr0, tr1... To interfejsy kart Token Ring. Są używane przez większość kart Token Ring, włącznie z produkowanymi przez firmy inne niż IBM. sl0, sl1... To interfejsy SLIP. Są związane z łączami szeregowymi w kolejności alokowania dla SLIP. ppp0, ppp1... To interfejsy PPP. Podobnie jak interfejsy SLIP, interfejs PPP jest związany z łączem szeregowym pracującym w trybie PPP. plip0, plip1... To interfejsy PLIP. PLIP przesyła datagramy IP przez łącza równoległe. Interfejsy są alokowane przez sterownik PLIP w czasie uruchamiania systemu i są odwzorowane na porty równoległe. W jądrach 2.0.x istnieje bezpośredni związek między nazwą urządzenia a portem wejścia/wyjścia portu równoległego, ale w nowszych jądrach nazwy urządzeń są przypisywane kolejno, tak jak w urządzeniach SLIP i PPP. ax0, ax1... To interfejsy AX.25. AX.25 jest podstawowym protokołem używanym przez operatorów radia amatorskiego. Interfejsy AX.25 są alokowane i przypisywane w podobny sposób jak urządzenia SLIP. Istnieje wiele innych typów interfejsów dla innych urządzeń sieciowych. Wymieniliśmy tylko najpopularniejsze z nich. W kilku następnych podrozdziałach omówimy dokładniej korzystanie z opisanych powyżej sterowników. Dokument Networkig-HOWTO opisuje konfigurację większości pozostałych interfejsów, natomiast AX25-HOWTO wyjaśnia, jak skonfigurować urządzenia sieciowe radia amatorskiego. Instalowanie Ethernetu Kod sieciowy Liunksa w obecnej postaci obsługuje wiele kart Ehternet. Większość sterowników została napisana przez Donalda Beckera, który stworzył rodzinę sterowników dla kart opartych o układ National Semiconductor 8390. Są one znane pod nazwą Becker Series Drivers. Sterowniki dla różnego sprzętu pisali też inni programiści. Dzięki temu większość popularnych kart jest obsługiwana przez Linuksa, z naprawdę nielicznymi wyjątkami. Lista obsługiwanych kart Ethernet stale się wydłuża, a więc jeżeli twoja karta jeszcze się na niej nie znajduje, to istnieje realna szansa, że wkrótce tam dołączy. Niegdyś próbowano sporządzić listę wszystkich obsługiwanych kart Ethernet, ale obecnie zajęłoby to zbyt dużo czasu i miejsca. Na szczęście Paul Gortmaker, który redaguje dokument Ethernet-HOWTO, zamieszcza listę wszystkich obsługiwanych kart i podaje przydatne informacje na temat ich uruchamiania w Linuksie*. Co miesiąc jest ona wysyłana do grupy dyskusyjnej comp.os.linux.answers, a także jest dostępna w ośrodkach lustrzanych Projektu Dokumentacji Linuksa. Nawet, jeżeli jesteś przekonany, że potrafisz zainstalować dany typ karty Ethernet w swoim komputerze, warto zajrzeć do Ethernet-HOWTO i dowiedzieć się, co ma do powiedzenia na ten temat. Znajdziesz tam informacje wykraczające poza proste zagadnienia konfiguracji. Na przykład zapewne unikniesz niepotrzebnych kłopotów, jeśli będziesz wiedział, jak się zachowują niektóre karty Ethernet oparte na DMA i wykorzystujące ten sam kanał DMA, który jest domyślnie przeznaczony dla kontrolera SCSI Adaptec AHA 1542. Dopóki nie przełączysz ich na inny kanał DMA, uruchomienie komputera będzie się kończyło zapisywaniem pakietów przez kartę Ethernet na losowe miejsca twojego dysku twardego. Aby skorzystać z dowolnej obsługiwanej przez Linuksa karty Ethernet, możesz użyć prekompilowanego jądra z jakiejś znanej dystrybucji Linuksa. Zwykle mają one moduły dla wszystkich obsługiwanych sterowników, a w procesie instalacji zwykle możesz wybrać te sterowniki, które chcesz załadować. Jednak na dłuższą metę lepiej jest skompilować własne jądro i umieścić w nim tylko te sterowniki, które są rzeczywiście potrzebne. Zaoszczędzisz miejsce na dysku i pamięć. Automatyczne wykrywanie kart Ethernet Sterowniki Ethernet w Linuksie są zwykle na tyle inteligentne, by znaleźć lokalizację karty Ethernet. Dzięki temu nie musisz sam wskazywać jej jądra. Ethernet-HOWTO informuje, czy dany sterownik używa automatycznego wykrywania i w jakiej kolejności sprawdza adresy wejścia/wyjścia karty. Kod automatycznego wykrywania ma trzy ograniczenia. Po pierwsze, nie jest on w stanie poprawnie rozpoznać wszystkich kart. Jest to szczególnie widoczne w przypadku tańszych klonów popularnych kart. Po drugie, jądro nie wykryje automatycznie więcej niż jednej karty, dopóki mu tego jawnie nie zaznaczysz. Jest to świadome założenie konstrukcyjne, gdyż uznano, że będziesz chciał mieć kontrolę nad tym, która karta jest przypisywana do którego interfejsu. Najlepszym sposobem na zrobienie tego porządnie jest ręczne skonfigurowanie kart Ethernet we własnym komputerze. Po trzecie, sterownik może przeoczyć adres, pod którym jest skonfigurowana twoja karta. Podsumowując, sterowniki będą automatycznie szukały karty tylko pod tymi adresami, pod którymi dane urządzenie może być skonfigurowane, ale czasem pewne adresy są ignorowane w celu uniknięcia konfliktów sprzętowych z innymi typami kart, które często wykorzystują ten sam adres. Karty sieciowe PCI powinny być wykrywane bez kłopotów. Jeżeli jednak używasz więcej niż jednej karty albo jeżeli automatyczne wykrywanie się nie powiedzie, istnieje sposób na jawne powiadomienie jądra o adresie podstawowym i nazwie karty. W czasie uruchamiania systemu możesz podać do jądra argumenty i informacje, które mogą się przydać niektórym jego składnikom. Mechanizm ten pozwala ci na przykład na przekazanie do jądra informacji, które umożliwią sterownikom Ethernet zlokalizowanie sprzętu Ethernet bez wykrywania go przez sterownik. Jeżeli korzystasz z systemu uruchamiania lilo, możesz przekazać parametry do jądra, wpisując je za pomocą opcji append w pliku lilo.conf. Aby powiadomić jądro o urządzeniu Ethernet, możesz przekazać mu następujące parametry: ether=irq,base_addr,[param1,][param2,]name Pierwsze cztery parametry są liczbami, natomiast ostatni to nazwa urządzenia. Obowiązkowe są irq, base_addr i name, opcjonalne - dwa parametry param. Dowolne wartości liczbowe mogą być ustawione na zero, co powoduje, że jądro określi je przez wykrywanie. Pierwszy parametr określa IRQ przypisane do urządzenia. Domyślnie jądro będzie próbowało automatycznie wykryć kanał IRQ urządzenia. Sterownik 3c503, na przykład, ma specjalną funkcję, która wybiera wolne IRQ z listy 5, 9, 3, 4 i konfiguruje kartę tak, by z niego korzystała. Parametr base_addr określa podstawowy adres wejścia/wyjścia karty - wartość zero mówi jądru, by sprawdziło podane adresy. Kolejne dwa parametry są różnie wykorzystywane przez różne sterowniki. W przypadku kart wykorzystujących współdzielenie pamięci, takich jak WD80x3, parametry te określają adresy początkowy i końcowy obszaru pamięci. Inne karty powszechnie używają param1 do ustawienia poziomu wyświetlanych informacji debugujących. Wartości od 1 do 7 wyznaczają kolejne poziomy ilości informacji, natomiast 8 wyłącza je wszystkie. 0 jest wartością domyślną. Sterownik 3c503 używa param2 do wyboru pomiędzy wewnętrznym (domyślnie) a zewnętrznym (wartość 1) transceiverem. Ten pierwszy wykorzystuje złącze karty BNC, natomiast drugi jej port AUI. Argumenty param nie muszą być w ogóle podawane, jeżeli nie masz nic szczególnego do skonfigurowania. Pierwszy, nieliczbowy argument jest interpretowany przez jądro jako nazwa urządzenia. Musisz podać nazwę urządzenia dla każdej konfigurowanej karty Ethernet. Gdybyś miał dwie karty Ethernet, Linux mógłby wykryć jedną kartę automatycznie i przez lilo przekazać parametry do drugiej karty, ale prawdopodobnie wolałbyś ręcznie skonfigurować obie karty. Jeśli decydujesz się na wykrywanie jednej karty przez jądro i ręczne konfigurowanie drugiej, musisz mieć pewność, że jądro nie znajdzie przypadkowo najpierw drugiej karty i że pierwsza zostanie w ogóle znaleziona. Dlatego przekaż do lilo opcję reserve, która jawnie mówi jądru, by nie sprawdzało obszaru wejścia/wyjścia zajętego przez drugą kartę. Na przykład, aby Linux zainstalował drugą kartę Ethernet znajdującą się pod adresem 0x300 jako eth1, musiałbyś przekazać jądru następujące parametry: reserve=0x300,32 ether=0,0x300,eth1 Opcja reserve gwarantuje, że żaden sterownik nie będzie miał dostępu do obszaru wejścia/wyjścia drugiej karty w czasie wykrywania innych urządzeń. Możesz także użyć parametru jądra, który unieważnia automatyczne wykrywanie eth0: reserve=0x340,32 ether=0,0x340,eth0 Możesz także w ogóle wyłączyć automatyczne wykrywanie, na przykład, aby jądro nie próbowało szukać karty Ethernet, którą tymczasowo usunąłeś. W tym celu ustaw argument base_addr na wartość -1: ether=0,-1,eth0 Aby przekazać te parametry do jądra w czasie uruchamiania, wpisujesz je w monicie "boot:" lilo. Aby lilo pokazało monit "boot:", musisz nacisnąć jeden z klawiszy [Control], [Alt] lub [Shift] w czasie uruchamiania lilo. Jeżeli mając monit, naciśniesz klawisz [Tab], pojawi się lista jąder. Aby uruchomić jądro z podanymi parametrami, wprowadź nazwę wybranego jądra, a następnie spację i parametry, które chcesz przekazać. Po naciśnięciu [Enter] lilo załaduje jądro z uwzględnieniem podanych parametrów. Aby te nowe parametry pojawiły się automatycznie przy ponownym uruchamianiu systemu, wprowadź je do pliku /etc/lilo.conf, używając słowa kluczowego append=. Oto przykład: boot=/dev/hda root=/dev/hda2 install=/boot/boot.b map=/boot/map vga=normal delay=20 append="ether=10,300,eth0" image=/boot/vmlinuz-2.2.14 label=2.2.14 read-only Po edycji pliku lilo.conf musisz ponownie uruchomić polecenie lilo, aby uaktywnić zmiany. Sterownik PLIP Protokół IP łącza równoległego (Parallel Line IP - PLIP) to łatwy i tani sposób na połączenie dwóch maszyn w sieć. Wykorzystuje port równoległy i specjalny kabel. Osiąga prędkość od 10 do 20 kilobajtów na sekundę. PLIP powstał w firmie Cyrnwr, Inc. Na swoje czasy odznaczał się pomysłową (lub, jeśli wolisz, typowo hakerską architekturą), ponieważ oryginalne porty równoległe IBM PC były projektowane jako jednokierunkowe porty drukarki. Osiem linii danych służyło do wysyłania danych jedynie z PC do urządzenia peryferyjnego, ale nie w drugą stronę.* Protokół PLIP firmy Cyrnwr znosił to ograniczenie. W PLIP do przyjmowania danych przeznaczono tylko pięć linii stanu portu, co ograniczyło wielkoć dostarczanych danych do półbajtu, ale dopuszczono przesyłanie w obie strony. Ten tryb działania został nazwany PLIP tryb 0. Obecnie porty równoległe PC obsługują pełne dwukierunkowe przesyłanie danych 8-bitowych, a PLIP został rozszerzony i nosi nazwę PLIP tryb 1. Jądra Linuksa do wersji 2.0 (włącznie) obsługiwały jedynie PLIP tryb 0, ale istniały rozszerzone sterowniki portu równoległego (w postaci poprawek dla jądra 2.0 i jako standardowy kod w jądrze 2.2), które obsługiwały także PLIP tryb 1**. W odróżnieniu od wcześniejszych wersji kodu PLIP, obecny sterownik próbuje być kompatybilny z implementacjami PLIP firmy Cyrnwr oraz sterownikiem PLIP umieszczonym w NCSA telnet***. Aby połączyć dwa komputery za pomocą PLIP, musisz mieć specjalny kabel sprzedawany w niektórych sklepach pod nazwą Null Printer lub Turbo Laplink. Możesz jednak wykonać go samodzielnie i nie jest to trudne. Dodatek B, Przydatne konfiguracje kabli, wyjaśnia, jak to zrobić. Sterownik PLIP dla Linuksa jest dziełem prawie niezliczonej rzeszy użytkowników. Obecnie znajduje się pod opieką Niibe Yutaka (adres kontaktowy: gniibe@mri.co.jp). Sterownik po wkompilowaniu w jądro konfiguruje interfejs sieciowy dla każdego możliwego portu drukarki, gdzie plip0 odpowiada portowi lp0, plip1 portowi lp1 i tak dalej. Odwzorowanie interfejsów na porty inaczej wygląda w jądrach 2.0 niż w jądrach 2.2. W jądrach 2.0 odwzorowanie było zdefiniowane w pliku drives/ net/Space.c w kodzie jądra i nie mogło się zmienić. Domyślne odwzorowanie w tym pliku jest następujące: Interfejs Port wejścia/wyjścia IRQ plip0 0x3BC 7 plip1 0x378 7 plip2 0x278 5 Gdybyś skonfigurował swój port drukarki w inny sposób, musiałbyś zmienić odpowiednie wartości w pliku drivers/net/Space.c w kodzie źródłowym jądra Linuksa, które trzeba byłoby przekompilować. W jądrach 2.2 sterownik PLIP wykorzystuje sterownik portu równoległego "parport" napisany przez Philipa Blundella*. Nowy sterownik przypisuje nazwy urządzeń sieciowych PLIP kolejno, tak jak sterowniki Ethernet czy PPP, a więc pierwsze utworzone urządzenie PLIP ma nazwę plip0, drugie plip1 i tak dalej. Fizyczne porty równoległe są również przypisywane kolejno. Domyślnie sterownik portu równoległego zastosuje procedurę automatycznego wykrywania, aby zidentyfikować sprzęt, który go obsługuje, i kolejno zapisze uzyskiwane informacje o urządzeniu fizycznym. Lepiej jest jawnie przekazać jądru fizyczne parametry wejścia/wyjścia. W tym celu trzeba podać argumenty do modułu parport_pc.o w czasie jego ładowania, a jeżeli sterownik jest wkompilowany w jądro, argumenty podaje się w czasie uruchamiania lilo. Ustawienia IRQ dowolnego urządzenia mogą zostać zmienione później przez zapisanie nowej wartości IRQ do pliku /proc/parport/*/irq. Konfigurowanie parametrów fizycznych wejścia/wyjścia w jądrze 2.2 w czasie ładowania modułu jest proste. Na przykład, aby przekazać sterownikowi, że masz dwa porty równoległe typu PC pod adresami wejścia/wyjścia 0x278 i 0x378 oraz IRQ odpowiednio 5 i 7, możesz załadować moduł z następującymi argumentami: modprobe parport_pc io=0x278,0x378 irq=5,7 Odpowiednie argumenty przekazywane do jądra w przypadku wkompilowanego sterownika są następujące: parport=0x278,5 parport=0x378,7 Aby argumenty te przekazać do jądra automatycznie w czasie uruchamiania systemu, musisz użyć słowa kluczowego append w lilo. Gdy sterownik PLIP zostanie zainicjowany, czy to w czasie uruchamiania systemu, jeżeli jest wbudowany, czy też w czasie ładowania modułu plip.o, każdy z portów równoległych będzie miał związane z nim urządzenie sieciowe plip. Urządzenie plip0 zostanie przypisane do pierwszego portu równoległego, plip1 do drugiego i tak dalej. To przypisanie można pominąć, ręcznie zadając inny zestaw argumentów jądra. Na przykład, aby przypisać parport0 do urządzenia plip0 i parport1 do urządzenia plip1, użyłbyś następujących argumentów jądra: plip=parport1 plip=parport0 Jednak takie przypisanie nie znaczy, że nie możesz wykorzystywać tych portów równoległych do drukowania czy innych celów. Fizyczne porty równoległe są używane przez sterownik PLIP jedynie wtedy, gdy odpowiadający im interfejs jest w trybie up. Sterowniki PPP i SLIP Protokoły PPP (Point-to-point Protocol - protokół punkt-punkt) i SLIP (Serial Line IP - IP łącza szeregowego) są powszechnie stosowane do przesyłania pakietów IP przez łącze szeregowe. Wiele firm oferuje dostęp komutowany PPP i SLIP do maszyn, które są podłączone do Internetu, zapewniając w ten sposób połączenia IP dla prywatnych osób (często inaczej trudno dostępne). Aby uruchomić PPP czy SLIP, nie trzeba modyfikować sprzętu - możesz użyć dowolnego portu szeregowego. Ponieważ konfiguracja portu szeregowego nie jest istotą sieci TCP/IP, zagadnienie to znalazło się w rozdziale 4, Konfigurowanie urządzeń szeregowych. Natomiast PPP omawiamy szczegółowo w rozdziale 8, Protokół punkt-punkt, a SLIP - w rozdziale 7, IP łącza szeregowego. Inne typy sieci Większość pozostałych typów sieci jest konfigurowana podobnie jak Ethernet. Argumenty przekazywane do modułów ładowalnych będą oczywiście inne, a niektóre sterowniki mogą obsługiwać tylko jedną kartę, ale cała reszta jest taka sama. Dokumentację tych kart możesz znaleźć w katalogu /usr/src/linux/Documentation/networking w kodzie źródłowym Linuksa. 4 Konfigurowanie urządzeń szeregowych Rozdział 4: Konfigurowanie urządzeń szeregowych Internet rozwija się bardzo szybko. A przecież wiekszość jego użytkowników stanowią ci, którzy nie mogą sobie pozwolić na stałe i szybkie łącza i używają protokołów takich jak SLIP, PPP czy UUCP, dzwoniąc do dostawcy usług internetowych i odbierając dzienną porcję swojej poczty i wiadomości grup dyskusyjnych. Rozdział niniejszy ma pomóc tym wszystkim, którzy swoje połączenie ze światem zewnętrznym opierają na modemach. Nie będziemy mówili, jak skonfigurować modem (instrukcja konkretnego urządzenia powie ci więcej na ten temat), ale opiszemy aspekty specyficzne dla Linuksa i dotyczące zarządzania urządzeniami wykorzystującymi porty szeregowe. Interesujące nas tematy to: oprogramowanie do komunikacji szeregowej, tworzenie plików urządzeń szeregowych, urządzenia szeregowe i konfigurowanie urządzeń szeregowych za pomocą poleceń setserial i stty. Wiele innych tematów można znaleźć w Serial-HOWTO autorstwa Davida Lawyera*. Oprogramowanie komunikacyjne do połączeń modemowych Istnieje wiele pakietów komunikacyjnych dla Linuksa. Głównie są to programy terminala, które pozwalają użytkownikowi dzwonić do innego komputera i poczuć się tak, jakby siedział przed prostym terminalem. Tradycyjny program terminala dla środowisk uniksowych to kermit. Obecnie jest on już nieco przestarzały i może wydawać się trudny. Istnieją wygodniejsze programy, które obsługują funkcje, takie jak książki telefoniczne, języki skryptowe do automatycznego dzwonienia i logowania się do zdalnych systemów komputerowych oraz różne protokoły wymiany plików. Jednym z tych programów jest minicom, wzorowany na najpopularniejszym DOS-owym programie terminala. Użytkownicy X11 także mają narzędzie dla siebie - seyon jest w pełni funkcjonalnym programem komunikacyjnym opartym na X11. Programy terminala nie są jedynym rodzajem programów do połączeń szeregowych. Inne pozwalają połączyć się z hostem i pobrać wiadomości grup dyskusyjnych oraz pocztę w jednej paczce, aby później, w wolnej chwili, zapoznać się z nimi i dać odpowiedź. Może zaoszczędzisz w ten sposób dużo czasu i pieniędzy, jeżeli złożyło się tak nieszczęśliwie, że mieszkasz w rejonie, gdzie połączenia lokalne są płatne*. Podczas czytania i przygotowania odpowiedzi nie musisz mieć połączenia z siecią, a gdy będziesz gotowy, zadzwonisz ponownie i umieścisz swoje odpowiedzi na serwerze za jednym zamachem. Potrzebujesz też nieco więcej miejsca na dysku twardym, ponieważ wszystkie wiadomości muszą być na nim umieszczone, zanim je przeczytasz, ale może być to sensowny kompromis przy obecnych cenach dysków twardych. UUCP zawiera w sobie właśnie tego typu oprogramowanie komunikacyjne. Jest to zestaw programów, które kopiują pliki z jednego hosta na drugi i uruchamiają programy na hoście zdalnym. Często jest używany do przenoszenia poczty czy grup dyskusyjnych w sieciach prywatnych. Pakiet UUCP Iana Taylora, działający także pod Linuksem, opisujemy szczegółowo w rozdziale 16, Zarządzanie UUCP Taylora. Pozostałe nieinteraktywne oprogramowanie komunikacyjne jest używane w sieciach takich, jak Fidonet. Wersje aplikacji pochodzące z Fidonet, takie jak ifmail, są również dostępne, chociaż wydaje się nam, że już niewiele osób z nich korzysta. PPP i SLIP są pośrodku, gdyż pozwalają zarówno na interaktywne, jak i nieinteraktywne użycie. Wiele osób używa PPP i SLIP w celu dzwonienia do swoich sieci campusowych lub innych dostawców Internetu, a potem korzysta z FTP lub czyta strony WWW. PPP i SLIP są także powszechnie stosowane do połączeń stałych i półstałych pomiędzy sieciami LAN, choć jest to ciekawe jedynie przy połączeniach ISDN lub innych o podobnej szybkości. Wprowadzenie do urządzeń szeregowych Jądro Linuksa daje możliwość komunikacji z urządzeniami szeregowymi, zwykle nazywanymi urządzeniami tty. Jest to skrót od angielskiej nazwy Teletype device**, która wskazuje na głównego producenta urządzeń terminalowych z początków Uniksa. Termin "urządzenie tty" odnosi się obecnie do wszelkich terminali znakowych. W tym rozdziale zawężamy jego zakres wyłącznie do plików urządzeń w Linuksie, czyli oznacza on tutaj fizyczny terminal. Linux udostępnia trzy klasy urządzeń tty: urządzenia szeregowe, terminale wirtualne (do których masz dostęp przez naciśnięcie klawiszy od [Alt+F1] do [Alt+Fnn] na konsoli lokalnej) i pseudoterminale (podobne do potoków dwukierunkowych i używane przez aplikacje takie jak X11). Te pierwsze zostały nazwane urządzeniami tty, ponieważ oryginalne terminale znakowe były podłączone do maszyny uniksowej przez kabel szeregowy lub linię telefoniczną i modem. Dwa kolejne zostały też zaliczone do grupy urządzeń tty, ponieważ z punktu widzenia programisty działały podobnie do tych pierwszych. SLIP i PPP są przeważnie implementowane w jądrze. Jądro w rzeczywistości nie traktuje urządzenia tty jako urządzenia sieciowego, którym możesz posługiwać się tak jak urządzeniem Ethernet, używając poleceń ifconfig. Natomiast widzi je jako coś, do czego może podłączyć urządzenia sieciowe. Aby to zrobić, jądro zmienia tzw. protokół obsługi (ang. line discipline) urządzenia tty. Zarówno SLIP, jak i PPP są protokołami obsługi, które mogą zostać włączone na urządzeniach tty. Ogólna zasada jest taka, że sterownik szeregowy obsługuje otrzymane dane w różny sposób, w zależności od tego, z jakiego protokołu obsługi korzysta. W przypadku domyślnego protokołu obsługi sterownik po prostu przesyła kolejno każdy otrzymany znak. Gdy zostanie wybrany protokół obsługi PPP lub SLIP, sterownik nie czyta bloków danych, ale opatruje je specjalnym nagłówkiem, który pozwala na identyfikację bloku danych w strumieniu po drugiej stronie i przesłanie nowego bloku danych. Na razie zrozumienie tego nie jest zbyt istotne. W dalszych rozdziałach omówimy dokładniej PPP oraz SLIP i wszystko stanie się jasne. Dostęp do urządzeń szeregowych Tak jak wszystkie urządzenia w systemie Unix, tak i porty szeregowe są dostępne poprzez specjalne pliki urządzeń znajdujące się w katalogu /dev. Istnieją dwa rodzaje plików urządzeń związanych ze sterownikami szeregowymi i dla każdego portu istnieje jeden taki plik. Zachowanie urządzenia będzie zależało od tego, który z jego plików otworzymy. Tutaj wskażemy różnice, co pomoże nam zrozumieć pewne konfiguracje. Jednak w praktyce wystarczy używać tylko jednego z tych plików. Niedługo jeden z nich może w ogóle przestać istnieć. Ważniejsze urządzenia z dwóch klas urządzeń szeregowych mają numer nadrzędny 4, a pliki specjalne urządzeń noszą nazwy ttyS0, ttyS1 itd. Drugi rodzaj ma numer nadrzędny 5 i został stworzony do wykorzystania przy dzwonieniu na zewnątrz przez port. Pliki specjalne w tym przypadku noszą nazwy cua0, cua1 itd. W świecie Uniksa liczenie generalnie rozpoczyna się od zera, choć inteligentni ludzie zwykle liczą od jednego. Wprowadza to lekkie zamieszanie, ponieważ COM1: jest reprezentowany przez /dev/ttyS0, COM2: przez /dev/ttyS1 itd. Każdy, kto zna architekturę sprzętową IBM PC wie, że port COM3: i porty o większych numerach nigdy nie stały się w rzeczywistości standardem. Urządzenia cua, czyli "służące do dzwonienia" (z ang. calling out), miały rozwiązać problem konfliktów urządzeń szeregowych przeznaczonych dla modemów i obsługujących zarówno połączenia przychodzące, jak i wychodzące. Niestety, stały się one źródłem innych kłopotów i zapewne trzeba będzie z nich zrezygnować. Przyjrzyjmy się pokrótce problemowi. Linux, podobnie jak Unix, pozwala, by urządzenie lub inny plik były otwierane przez więcej niż jeden proces jednocześnie. Niestety nie jest to zaletą w przypadku urządzeń tty, gdyż dwa procesy prawie na pewno będą sobie przeszkadzały. Na szczęście wymyślono mechanizm pozwalający sprawdzać procesowi, czy urządzenie tty zostało już otwarte przez inny proces. Mechanizm ten wykorzystuje tak zwane pliki blokujące (ang. lock files). Działa na następującej zasadzie: gdy proces chce otworzyć urządzenie tty, sprawdza, czy w określonym miejscu istnieje plik o nazwie podobnej do urządzenia, które chce otworzyć. Jeżeli plik nie istnieje, proces go tworzy i otwiera urządzenie tty. Jeżeli plik istnieje, proces zakłada, że urządzenie otworzył już inny proces i podejmuje stosowne działanie. Jeszcze jeden pomysł na sprawne działanie systemu zarządzania plikami blokującymi to zapisywanie w samym pliku ID procesu (pid), który stworzył plik blokujący. Więcej na ten temat powiemy za chwilę. Mechanizm pliku blokującego działa doskonale w warunkach, gdy jest zdefiniowane miejsce dla takich plików i wszystkie programy wiedzą, gdzie ich szukać. Niestety nie zawsze tak było w Linuksie. Korzystanie z tego mechanizmu stało się możliwe dopiero, gdy został zdefiniowany FSSTND (standard systemu plików Linuksa) z ustaloną  lokalizacją plików blokujących, które zaczęły wtedy działać poprawnie dla urządzeń tty. Wcześniej zdarzyło się, że współistniało kilka możliwych lokalizacji plików blokujących wybranych przez programistów: /usr/spool/locks/, /var/spool/locks/, /var/lock/ i /usr/lock/. Zamieszanie rodziło chaos. Programy otwierały pliki blokujące z różnych miejsc, a mające kontrolować jedno urządzenie tty. Efekt był taki, jakby pliki blokujące w ogóle nie były używane. Aby rozwiązać ten problem, stworzono urządzenia cua. Zamiast polegać na plikach blokujących, które miały zabezpieczać przed kolidowaniem ze sobą programów korzystających z urządzeń szeregowych, zdecydowano, że to jądro będzie decydować, kto ma mieć dostęp do urządzenia. Jeżeli urządzenie ttyS było już otwarte, próba otwarcia cua kończyła się błędem. Program mógł to zinterpretować jako informację, że urządzenie jest używane. Jeżeli urządzenie cua było już otwarte i została podjęta próba otwarcia urządzenia ttyS, żądanie było blokowane, to znaczy wstrzymywane do czasu zamknięcia urządzenia cua przez inny proces. Działało do całkiem dobrze, jeżeli miałeś jeden modem skonfigurowany do odbierania połączeń i co jakiś czas chciałeś zadzwonić za pomocą tego samego urządzenia. Kłopoty pojawiły się w środowiskach, gdzie wiele programów chciało dzwonić z tego samego urządzenia. Jedynym sposobem na rozwiązanie tego problemu było zastosowanie plików blokujących. Powrót do punktu wyjścia. Wystarczy wspomnieć, że przyszedł tu z pomocą standard systemu plików Linuksa. Teraz pliki blokujące muszą znajdować się w katalogu /var/lock i nazywać zgodnie z przyjętą konwencją, czyli plik blokujący dla urządzenia ttyS1 nazywa się na przykład LCK..ttyS1. Pliki blokujące cua powinny także znajdować się w tym katalogu, ale używanie urządzeń cua nie jest zalecane. Przez jakiś czas urządzenia cua będą jeszcze funkcjonowały, by zapewnić kompatybilność w okresie przejściowym, ale stopniowo będą wycofywane. Jeżeli zastanawiasz się, czego używać, trzymaj się urządzeń ttyS i upewnij się, że twój system jest zgodny z FSSTND lub że przynajmniej wszystkie programy korzystające z urządzeń szeregowych umieszczają pliki blokujące w tym samym miejscu. Większość oprogramowania pracującego z urządzeniami szeregowymi tty posiada opcję kompilacyjną pozwalającą na wskazanie miejsca umieszczania plików blokujących. Często występuje ona w postaci zmiennej o nazwie typu LOCKDIR w pliku Makefile lub w nagłówkowym pliku konfiguracyjnym. Jeżeli sam kompilujesz oprogramowanie, najlepiej jest ustawić tę zmienną tak, by zapewnić zgodność z lokalizacją określoną przez FSSTND. Jeżeli korzystasz ze skompilowanych plików binarnych i nie jesteś pewien, gdzie program zapisuje swoje pliki blokujące, możesz użyć poniższego polecenia, by uzyskać wskazówkę: strings plikbinarny | grep lock Jeżeli wskazana lokalizacja nie zgadza się z pozostałą częścią twojego systemu, staraj się utworzyć dowiązanie symboliczne z katalogu plików blokujących, którego chce używać dany program, do katalogu /var/lock. Nie jest to zbyt eleganckie rozwiązanie, ale działa. Pliki specjalne urządzenia szeregowego Numery podrzędne są identyczne dla obu typów urządzeń szeregowych. Gdybyś miał swój modem na jednym z czterech standardowych portów COM, jego numer podrzędny byłby numerem portu COM plus 63. Gdybyś używał specjalnego urządzenia szeregowego, takiego jak szybki wieloportowy kontroler szeregowy, prawdopodobnie musiałbyś tworzyć dla niego specjalne pliki urządzeń. Zapewne karta taka nie posługiwałaby się standardowym sterownikiem urządzenia. Odpowiednie szczegóły zapewne znajdziesz w dokumencie Serial-HOWTO. Załóżmy, że twój modem jest podłączony do COM2:. Jego numer podrzędny to 65, a nadrzędny to 4 w przypadku normalnego zastosowania. Powinno istnieć urządzenie ttyS1, które ma takie numery. Wylistuj urządzenia szeregowe tty w katalogu /dev/. Piąta i szósta kolumna pokazują odpowiednio numery podrzędne i nadrzędne: $ ls -l /dev/ttyS* 0 crw-rw---- 1 uucp dialout 4, 64 Oct 13   1997 /dev/ttyS0 0 crw-rw---- 1 uucp dialout 4, 65 Jan 26  21:55 /dev/ttyS1 0 crw-rw---- 1 uucp dialout 4, 66 Oct 13   1997 /dev/ttyS2 0 crw-rw---- 1 uucp dialout 4, 67 Oct 13   1997 /dev/ttyS3 Gdyby nie było urządzenia o numerze nadrzędnym 4 i podrzędnym 65, musiałbyś je stworzyć. W takiej sytuacji zaloguj się jako użytkownik uprzywilejowany i napisz: # mknod -m 666 /dev/ttyS1 c 4 65 # chown uucp.dialout /dev/ttyS1 Dystrybucje Linuksa używają różnych strategii do określania, kto powinien być właścicielem urządzeń szeregowych. Czasem będą one własnością użytkownika root, a innym razem będą należały na przykład do uucp, tak jak w naszym przykładzie. Współczesne dystrybucje mają specjalną grupę dla urządzeń służących do dzwonienia. Każdy użytkownik, który ma prawo ich używać, jest dodawany do tej grupy. Niektórzy sugerują stworzenie dowiązania symbolicznego /dev/modem do urządzenia modemu, tak by zwykli użytkownicy nie musieli zapamiętywać czegoś tak skomplikowanego jak ttyS1. Jednak nie możesz używać w jednym programie nazwy modem, a w drugim rzeczywistej nazwy pliku urządzenia. Ich pliki blokujące będą miały różne nazwy i mechanizm blokowania nie zadziała. Urządzenia szeregowe RS-232 jest obecnie najbardziej znanym standardem komunikacji szeregowej w świecie PC. Wykorzystuje wiele układów do transmisji pojedynczych bitów oraz do synchronizacji. Można wprowadzić dodatkowe linie do sygnalizacji obecności nośnej (używanej przez modemy) i do uzgadniania (ang. handshaking). Linux obsługuje wiele kart szeregowych zgodnych ze standardem RS-232. Uzgadnianie sprzętowe jest opcjonalne, ale bardzo przydatne. Pozwala obu stronom na sygnalizowanie gotowości odbioru kolejnych danych lub na powiadomienie, że druga strona powinna poczekać, aż odbiorca zakończy przetwarzanie odebranych danych. Linie używane do tego celu są nazywane odpowiednio "Clear to Send" (CTS) i "Ready to Send" (RTS), co wyjaśnia potoczną nazwę uzgadniania sprzętowego: RTS/CTS. Innym rodzajem uzgadniania, z którym mogłeś się już spotkać, jest XON/XOFF. Wykorzystuje ono dwa wyznaczone znaki, zwykle [CTRL+S] i [CTRL+Q] do sygnalizowania drugiej stronie, że powinna odpowiednio zatrzymać lub rozpocząć przesyłanie danych. Choć sposób ten jest łatwy do zaimplementowania i działa poprawnie na terminalach uproszczonych (ang. dumb terminals), powoduje zamieszanie w przypadku danych binarnych. Może się bowiem zdarzyć, że wolisz przesłać te znaki jako część strumienia danych i chcesz, aby były interpretowane jako znaki sterujące. Poza tym metoda ta jest wolniejsza niż uzgadnianie sprzętowe, które jako proste i szybkie jest zalecane zamiast XON/XOFF, o ile oczywiście masz wybór. W pierwszych modelach IBM PC interfejs RS-232 był sterowany przez układ scalony UART 8250. PC z czasów procesora 486 używały nowszej wersji układu UART 16450. Był on nieco szybszy niż 8250. Prawie wszystkie komputery oparte na Pentium są wyposażone w jeszcze nowszą wersję układu UART 16550. Niektóre marki (przeważnie modemy wewnętrzne wyposażone w zestaw układów Rockwell) wykorzystują zupełnie inne układy emulujące zachowanie 16550 i mogą być traktowane podobnie. Standardowy sterownik portu szeregowego Linuksa obsługuje je wszystkie*. Układ 16550 jest znacznym krokiem naprzód w stosunku do 8250 i 16450, ponieważ oferuje 16-bajtowy bufor FIFO. 16550 jest w rzeczywistości rodziną urządzeń UART, do której należą układy 16550, 16550A i 16550AFN (nazwa została później zmieniona na PCI16550DN). Różnice między nimi polegają na zapewnieniu działania FIFO; w układzie 16550AFN działa ono na pewno. Istniał także układ NS16550, ale w nim bufor FIFO nigdy tak naprawdę nie działał. Układy UART 8250 i 16450 miały prosty bufor jednobajtowy. Oznaczało to, że 16450 generował przerwanie dla każdego nadanego lub odebranego znaku. Każde wymagało krótkiego czasu na jego obsługę i to niewielkie opóźnienie ograniczało prędkość układu 16450 do 9600 bitów na sekundę w typowym komputerze z magistralą ISA. W domyślnej konfiguracji jądro sprawdza cztery standardowe porty szeregowe, od COM1: do COM4:. Jądro jest także w stanie wykryć, jaki układ UART jest używany dla każdego ze standardowych portów szeregowych i wykorzystuje bufor FIFO układu 16550, jeżeli jest dostępny. Używanie narzędzi konfiguracyjnych Teraz przyjrzyjmy się krótko dwóm najbardziej przydatnym narzędziom do konfiguracji urządzenia szeregowego: setserial i stty. Polecenie setserial Jądro zrobi wszystko co w jego mocy, by poprawnie rozpoznać konfigurację twojego urządzenia szeregowego, ale wielość możliwości powoduje, że trudno jest uzyskać w praktyce stuprocentową niezawodność. Dobrym przykładem tego, co sprawia problemy, są modemy wewnętrzne, o których mówiliśmy wcześniej. Używany przez nie układ UART ma 16-bajtowy bufor FIFO, ale z punktu widzenia sterownika urządzenia w jądrze wygląda jak układ UART 16450: dopóki nie wskażemy sterownikowi, że jest to urządzenie 16550, jądro nie będzie wykorzystywać rozszerzonego bufora. Innym przykładem są uproszczone karty 4-portowe pozwalające na współdzielenie jednego IRQ przez wiele urządzeń szeregowych. W takiej sytuacji musimy wskazać jądru właściwe IRQ i uprzedzić je, że IRQ może być współdzielone. Do konfiguracji sterownika szeregowego w czasie pracy stworzono program setserial. Polecenie to jest powszechnie uruchamiane w czasie startu systemu ze skryptu 0setserial lub rc.serial, w zależności od dystrybucji. Skrypt ma tak ustawić inicjację sterownika szeregowego, aby ten dostosował się do niestandardowych lub niezwykłych urządzeń szeregowych zainstalowanych w komputerze. Ogólna składnia polecenia setserial jest następująca: setserial urządzenie [parametry] gdzie urządzenie to jedno z urządzeń szeregowych, na przykład ttyS0. Polecenie setserial ma wiele parametrów. Najpopularniejsze z nich opisano w tabeli 4-1. Informacje o pozostałych znajdziesz w podręczniku elektronicznym setserial. Tabela 4-1. Parametry polecenia setserial Parametr Opis port numer_portu Określa adres portu wejścia/wyjścia urządzenia szeregowego. Numery portu powinny być podawane w notacji szesnastkowej, tzn. 0x2f8. irq numer Określa numer przerwania używany przez urządzenie szeregowe. uart typ_uart Określa typ UART urządzenia szeregowego. Powszechnie stosowane wartości to 16450, 16550 itd. Ustawienie tej wartości na none wyłącza dane urządzenie szeregowe. fourport Określenie tego parametru mówi sterownikowi szeregowemu jądra, że port jest jednym z portów czteroportowej karty AST. spd_hi Programuje UART na prędkość 57,6 kb/s, gdy proces żąda 38,4 kb/s. spd_vhi Programuje UART na prędkość 115 kb/s, gdy proces żąda 38,4 kb/s. spd_normal Programuje UART na domyślną prędkość 38,4 kb/s, gdy zostanie zażądana. Parametr ten jest używany do wyłączenia działania spd_hi i spd_vhi wykonanych na danym urządzeniu szeregowym. auto_irq Parametr ten powoduje, że jądro próbuje automatycznie określić IRQ danego urządzenia. Próba może się nie powieść, a więc lepiej traktować to jako żądanie odgadnięcia IRQ przez jądro. Jeżeli znasz IRQ urządzenia, powinieneś od razu użyć opcji irq. autoconfig Parametr ten musi być określony w połączeniu z parametrem port. Podanie tego parametru powoduje, że setserial zleca jądru próbę automatycznego określenia typu układu UART znajdującego się pod zadanym adresem portu. Jeżeli zostanie podany również parametr auto_irq, jądro podejmie także próbę automatycznego wykrycia IRQ. skip_test Parametr ten mówi jądru, aby nie wykonywało sprawdzania typu układu UART podczas automatycznej konfiguracji. Jest on niezbędny, jeżeli układ UART nie jest poprawnie wykrywany przez jądro. Plik rc konfigurujący porty szeregowe w czasie uruchamiania komputera może wyglądać tak, jak w przykładzie 4-1. W większości dystrybucji Linuksa będzie on bardziej wyrafinowany niż tutaj. Przykład 4-1. Przykładowy plik rc.serial zawierający polecenia setserial # /etc/rc.serial - skrypt konfigurujący łącze szeregowe # # Konfiguracja urządzeń szeregowych /sbin/setserial /dev/ttyS0 auto_irq skip_test autoconfig /sbin/setserial /dev/ttyS1 auto_irq skip_test autoconfig /sbin/setserial /dev/ttyS2 auto_irq skip_test autoconfig /sbin/setserial /dev/ttyS3 auto_irq skip_test autoconfig # # Wyświetlenie konfiguracji urządzeń szeregowych /sbin/setserial -bg /dev/ttyS* Argument -bg /dev/ttyS* w ostatnim poleceniu wypisze ładnie sformatowane podsumowanie konfiguracji wszystkich urządzeń szeregowych. Wynik będzie wyglądał tak, jak w przykładzie 4-2. Przykład 4-2. Wynik polecenia setserial -bg /dev/ttyS /dev/ttyS0 at 0x03f8 (irq = 4) is a 16550A /dev/ttyS1 at 0x02f8 (irq = 3) is a 16550A Polecenie stty Nazwa stty może oznaczać "set tty", ale polecenie stty bywa też używane do wyświetlania konfiguracji terminala. Polecenie stty, prawdopodobnie jeszcze bardziej niż setserial, wprawia w konsternację posiadaną liczbą charakterystyk, które można konfigurować. W tej chwili pokażemy najważniejsze z nich. Pozostałe znajdziesz na stronie podręcznika elektronicznego stty. Polecenie stty jest najczęściej używane do konfigurowania parametrów terminala, które decyduje na przykład, czy wprowadzane znaki będą wyświetlane na ekranie albo czy klawisz powinien generować sygnał przerwania. Wcześniej wyjaśniliśmy, że urządzenia szeregowe są urządzeniami tty i dlatego polecenie stty odnosi się także do nich. Jednym z najważniejszych zastosowań stty w urządzeniach szeregowych jest włączenie uzgadniania sprzętowego w urządzeniu. Wcześniej krótko wspomnieliśmy o uzgadnianiu sprzętowym. Domyślna konfiguracja urządzeń szeregowych zakłada wyłączenie uzgadniania sprzętowego. Wówczas mogą działać kable szeregowe "trzyżyłowe". Nie obsługują one sygnałów wymaganych do uzgadniania sprzętowego i gdyby było ono domyślnie włączone, nie można byłoby przez nie przesłać żadnych znaków, by to zmienić. Co dziwniejsze, niektóre szeregowe programy komunikacyjne nie włączają uzgadniaia sprzętowego, a więc jeżeli twój modem je obsługuje, powinieneś go skonfigurować tak, żeby go używał (odszukaj w instrukcji modemu właściwe polecenie), a także skonfiguruj odpowiednio urządzenie szeregowe. Polecenie stty ma znacznik crtscts, który włącza uzgadnianie sprzętowe w urządzeniu - będziesz musiał go użyć. Polecenie prawdopodobnie najlepiej uruchomić z pliku rc.serial (lub równoważnego) w czasie startu systemu za pomocą poleceń pokazanych w przykładzie 4-3. Przykład 4-3. Przykładowe polecenia stty w pliku rc.serial # stty crtscts < /dev/ttyS0 stty crtscts < /dev/ttyS1 stty crtscts < /dev/ttyS2 stty crtscts < /dev/ttyS3 # Polecenie stty działa domyślnie na bieżącym terminalu, ale używając funkcji przekierowującej wejście ("<") powłoki, możemy za pomocą stty operować na dowolnym urządzeniu tty. Znak przekierowania "<" często bywał mylony z ">" - na szczęście nowsze wersje stty mają dużo prostszą składnię takiego przekierowania. Aby użyć nowej składni, musimy napisać naszą przykładową konfigurację tak, jak w przykładzie 4-4. Przykład 4-4. Przykład polecenia stty w pliku rc.serial z wykorzystaniem nowej składni # stty crtscts -F /dev/ttys0 stty crtscts -F /dev/ttys1 stty crtscts -F /dev/ttys2 stty crtscts -F /dev/ttys3 # Wspomnieliśmy, że polecenie stty może być używane do wyświetlenia parametrów konfiguracyjnych terminala. Aby wyświetlić wszystkie aktywne ustawienia urządzenia tty, użyj: $ stty -a -F /dev/ttyS1 Wynik działania tego polecenia, przedstawiony jako przykład 4-5, pokazuje stan wszystkich znaczników urządzenia. Znacznik poprzedzony znakiem minus, na przykład -crtscts, oznacza, że dana opcja jest wyłączona. Przykład 4-5. Wynik działania polecenia stty -a speed 19200 baud; rows 0; columns 0; line = 0; intr = ^C; quit = "\; erase = ^?; kill = ^U; eof = ^D; eol = ; eol2 = ; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0; -parenb -parodd cs8 hupcl -cstopb cread clocl -crtscts -ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon -ixoff -iuclc -ixany -imaxbel -opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0 -isig -icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke Opis najważniejszych znaczników znajduje się w tabeli 4-2. Każdy z nich jest włączany przez podanie w poleceniu stty i wyłączany przez podanie w poleceniu stty z poprzedzającym znakiem -. Zatem, aby wyłączyć uzgadnianie sprzętowe na urządzeniu ttyS0, napisałbyś: $ stty -crtscts -F /dev/ttyS0 Kolejny przykład łączy niektóre z tych znaczników i konfiguruje urządzenie ttyS0 na 19200 bitów na sekundę, 8 bitów danych, brak parzystości i uzgadnianie sprzętowe bez wypisywania odebranych znaków u nadawcy: $ stty 19200 cs8 -parenb -crtscts -echo -F /dev/ttyS0 Tabela 4-2. Najważniejsze znaczniki w konfiguracji urządzeń szeregowych Znaczniki Opis N Ustawienie prędkości łącza na N b/s. crtscts Włączenie/wyłączenie uzgadniania sprzętowego. ixon Włączenie/wyłączenie kontroli przepływu XON/XOFF. Znaczniki Opis clocal Włączenie/wyłączenie sygnałów sterowania modemem, takich jak DTR/DTS i DVD. Jest to potrzebne, jeżeli używasz "trzyżyłowego" kabla szeregowego. cs5 cs6 cs7 cs8 Ustawienie liczby bitów danych odpowiednio na 5, 6, 7 lub 8. parodd Włączenie dopełniania bajtu do nieparzystej liczby jedynek. Wyłączenie tego znacznika powoduje włączenie dopełniania bajtu do parzystej liczby jedynek. parenb Włączenie sprawdzania parzystości. Zanegowanie tego znacznika powoduje nieużywanie parzystości. cstopb Włączenie używania dwóch bitów stopu na znak. Zanegowanie tego znacznika powoduje używanie jednego bitu stopu na znak. echo Włączenie/wyłączenie wysyłania odebranych znaków do nadawcy. Urządzenia szeregowe i monit login: Swego czasu instalacja Uniksa wymagała najczęściej jednego serwera i wielu "uproszczonych" terminali znakowych lub modemów do połączeń komutowanych. Obecnie ten typ instalacji jest mniej powszechny. To dobra wiadomość dla wielu osób zainteresowanych taką metodą pracy, ponieważ "uproszczone" terminale można teraz kupić za grosze. Konfiguracje z modemami nie straciły na popularności, ale dzisiaj są one raczej używane do obsługi logowania przez SLIP lub PPP (co omawiamy w rozdziale 7, IP łącza szeregowego, i w rozdziale 8, Protokół punkt-punkt), a nie do zwykłego logowania. Niemniej jednak każda z tych konfiguracji może wykorzystywać prosty program o nazwie getty. Określenie getty można traktować jako skrót od "get tty". Program getty otwiera urządzenie szeregowe, konfiguruje je w odpowiedni sposób, opcjonalnie konfiguruje modem i czeka na zestawienie połączenia. Aktywne połączenie na urządzeniu szeregowym jest zwykle wskazywane przez wyprowadzenie DCD (Data Carrier Detect) wzbudzanego urządzenia szeregowego. Gdy zostanie wykryte połączenie, program getty wyświetla monit login: i wywołuje program login, aby obsłużył rzeczywiste logowanie do systemu. Każdy terminal wirtualny (na przykład dev/tty1) w Linuksie posiada działający na jego rzecz program getty. Istnieje szereg różnych implementacji getty, a każda z nich jest zaprojektowana tak, aby pewne konfiguracje obsługiwać lepiej niż inne. Opisywany tutaj getty nosi nazwę mgetty. Jest dosyć popularny, ponieważ posiada wszelkie funkcje, które czynią go szczególnie przydatnym do obsługi modemów. Między innymi jest wyposażony w programy do automatycznej obsługi faksu i modemów głosowych. Skoncentrujemy się na konfigurowaniu mgetty do odpowiadania na typowe połączenia mające na celu transmisję danych, a całą resztę pozostawiamy ci do zbadania w wolnej chwili. Konfigurowanie demona mgetty Demon mgetty jest dostępny w postaci źródłowej pod adresem ftp://alpha.greenie.net/ pub/mgetty/source/, a w każdej dystrybucji Linuksa występuje w postaci pakietu. Demon mgetty różni się od większości pozostałych implementacji getty tym, że został stworzony specjalnie dla modemów kompatybilnych ze standardem Hayesa. Wciąż obsługuje bezpośrednie połączenia terminalowe, ale najlepiej nadaje się do aplikacji pracujących po łączu komutowanym. Zamiast używać linii DCD do wykrywania przychodzącego połączenia, oczekuje na komunikat RING generowany w momencie wykrycia nadchodzącego połączenia przez nowoczesne modemy, o ile nie są skonfigurowane na automatyczne odpowiadanie. Główny program wykonywalny nazywa się /usr/sbin/mgetty, a jego plik konfiguracyjny to /etc/mgetty/mgetty.config. Poza tym jest szereg innych programów binarnych i plików konfiguracyjnych, które obsługują inne funkcje mgetty. W większości instalacji konfiguracja polega na edycji pliku /etc/mgetty/mgetty.config i dodaniu odpowiednich wpisów w pliku /etc/inittab, automatycznie uruchamiających mgetty. Przykład 4-6 pokazuje bardzo prosty plik konfiguracyjny mgetty dla dwóch urządzeń szeregowych. Pierwsze urządzenie /dev/ttyS0, obsługuje modem kompatybilny ze standardem Hayesa przy prędkości 38 400 bps. Drugie, /dev/ttyS1, obsługuje bezpośrednio podłączony terminal VT100 z prędkością 19200 bps. Przykład 4-6. Przykładowy plik /etc/mgetty/mgetty.config # # plik konfiguracyjny mgetty # # jest to przykładowy plik konfiguracyjny, więcej szczegółów # znajdziesz w mgetty.info # # wiersze komentarza zaczynają się od "#", puste wiersze są # ignorowane # # ----- sekcja ogólna ----- # # w tej sekcji umieszczasz ogólne wartości domyślne, dane # dotyczące portu znajdują się dalej # # modem pracuje z prędkością 38400 bps speed 38400 # # ustawienie ogólnego poziomu debugowania na "4" (domyślnie z # policy.h) debug 4 # # ----- sekcja określająca porty ----- # # Tutaj możesz umieścić ustawienia dotyczące tylko danej linii # i nie dotyczące innych # # # Modem Hayesa podłączony do ttyS0: bez obsługi faksu, bez # logowania # port ttyS0  debug 3  data-only y # # bezpośrednie podłączenie terminala VT100, który potrzebuje # DTR # port ttyS1  direct y  speed 19200  toggle-dtr n # Plik konfiguracyjny zawiera opcje ogólne i specyficzne dla portów. W naszym przykładzie użyliśmy opcji ogólnych do ustawienia prędkości na 38 400 bitów na sekundę. Wartość ta jest dziedziczona przez port ttyS0. To ustawienie prędkości dotyczy portów mgetty, dopóki nie zostanie ono nadpisane przez ustawienie prędkości specyficznej dla portu, co robimy w konfiguracji ttyS1. Słowo kluczowe debug kontroluje liczbę informacji logowanych przez mgetty. Słowo kluczowe data-only w konfiguracji ttyS0 powoduje, że mgetty ignoruje wszelkie funkcje faksowe modemu, i w związku z tym modem przesyła tylko dane. Słowo kluczowe direct w konfiguracji ttyS1 mówi programowi mgetty, aby nie próbował inicjować modemu na danym porcie. Wreszcie słowo kluczowe toggle-dtr mówi mgetty, aby nie próbował zawieszać linii przy braku sygnału DTR (Data Terminal Ready) na interfejsie szeregowym. Niektóre terminale tego nie lubią. Możesz także zdecydować się na pozostawienie pustego pliku mgetty.config, a większość z tych parametrów określić za pomocą argumentów wiersza poleceń. Dokumentacja dotycząca aplikacji zawiera pełny opis parametrów pliku konfiguracyjnego mgetty i argumentów wiersza poleceń. (Patrz fragment pliku poniżej). Aby uaktywnić tę konfigurację, musimy dodać dwa wpisy do pliku /etc/inittab. Plik inittab jest plikiem konfiguracyjnym polecenia init Uniksa w wersji System V. Polecenie init jest odpowiedzialne za inicjację systemu. Zapewnia automatyczne uruchamianie programów w czasie startu systemu i ponowne ich uruchamianie po zakończeniu pracy. Rozwiązanie to idealnie nadaje się do obsługi programu getty. T0:23:respawn:/sbin/mgetty ttyS0 T1:23:respawn:/sbin/mgetty ttyS1 Każdy wiersz pliku /etc/inittab zawiera cztery pola oddzielone dwukropkami. Pierwsze pole to identyfikator jednoznacznie określający wpis w pliku. Tradycyjnie jest on dwuznakowy, ale nowsze wersje pozwalają na zastosowanie czterech znaków. Drugie pole to lista poziomów uruchomienia (ang. run levels), przy których wpis powinien być aktywny. Poziom uruchomienia pozwala na różne konfiguracje systemu i jest zaimplementowany za pomocą drzewiastej struktury skryptów startowych, znajdujących się w katalogach /etc/rc1.d, /etc/rc2.d itd. Funkcja ta jest zwykle implementowana w bardzo prosty sposób i powinieneś wzorować swoje wpisy na innych wpisach w pliku lub zajrzeć do dokumentacji, jeżeli potrzebujesz dodatkowych informacji. Trzecie pole opisuje, kiedy zadziałać. W przypadku uruchamiania programu getty, pole to powinno mieć wartość respawn, co oznacza, że polecenie powinno być automatycznie uruchomione ponownie po zakończeniu działania. Istnieje kilka innych możliwości, ale nie są dla nas teraz przydatne. Czwarte pole to rzeczywiste polecenie do wykonania. Tutaj wpisujemy polecenie mgetty i jego argumenty. W naszym prostym przykładzie inicjujemy i ponownie uruchamiamy mgetty, gdy system działa na poziomie drugim lub trzecim, a jako argumenty podajemy nazwę urządzenia, z którego chcemy korzystać. Polecenie mgetty automatycznie zakłada ścieżkę /dev/, a więc nie musimy jej tutaj podawać. Podrozdział ten był krótkim omówieniem mgetty i sposobu udostępnienia monitu logowania dla urządzeń szeregowych. Więcej na ten temat możesz znaleźć w dokumencie Serial-HOWTO. Gdy dokonasz edycji plików konfiguracyjnych, musisz przeładować proces init, aby zmiany były aktywne. Po prostu wyślij sygnał hangup do procesu init. Proces ten zawsze ma ID równe 1, a więc możesz bezpiecznie wydać następujące polecenie: # kill -HUP 1 5 Konfigurowanie sieci TCP/IP Rozdział 5: Konfigurowanie sieci TCP/IP W tym rozdziale pokażemy wszystkie kroki niezbędne do skonfigurowania sieci TCP/IP na twoim komputerze. Zaczniemy od przypisania adresów IP, potem zajmiemy się konfigurowaniem interfejsów sieciowych TCP/IP i na koniec przedstawimy kilka narzędzi, które przydają się przy rozwiązywaniu problemów z siecią. Większość zadań omówionych w tym rozdziale wykonuje się zwykle tylko raz. Po pliki konfiguracyjne sięga się powtórnie tylko wtedy, gdy dodaje się nowy system do sieci lub zupełnie przekonfigurowuje istniejący system. Niektóre polecenia używane do konfigurowania TCP/IP muszą być jednak uruchamiane przy każdym starcie systemu, zwykle przez ich wywołanie ze skryptów /etc/rc*. Część sieciowa procedury konfiguracyjnej zwykle jest zawarta w skrypcie. Jego nazwa zależy od dystrybucji Linuksa. W wielu starszych dystrybucjach był to skrypt rc.net lub rc.inet. Czasem spotkasz się także z dwoma skryptami o nazwach rc.inet1 i rc.inet2 - pierwszy z nich inicjuje część sieciową związaną z jądrem, a drugi uruchamia podstawowe usługi sieciowe i aplikacje. We współczesnych dystrybucjach pliki rc są uporządkowane w bardziej wyrafinowany sposób. W katalogu /etc/init.d/ (lub /etc/rc.d/rc.init.d/) możesz znaleźć skrypty tworzące urządzenia sieciowe, a inne pliki rc mogą uruchamiać aplikacje sieciowe. Przykłady w tej książce zostały oparte właśnie na tym ostatnim porządku plików. Niniejszy rozdział przedstawia części skryptu konfigurujące interfejsy sieciowe, natomiast aplikacje zostaną omówione w dalszych rozdziałach. Po lekturze tego rozdziału będziesz znać zestaw poleceń, za pomocą których poprawnie skonfigurujesz sieć TCP/IP na swoim komputerze. Zatem powinieneś zastąpić wszelkie przykładowe polecenia w swoich skryptach konfiguracyjnych własnymi, upewnić się, że skrypt jest uruchamiany z podstawowego skryptu rc w czasie uruchamiania systemu i ponownie uruchomić komputer. Skrypty sieciowe rc zawarte w twojej ulubionej dystrybucji Linuksa powinny zawierać idealny przykład, z którego możesz skorzystać. Montowanie systemu plików /proc Niektóre narzędzia konfiguracyjne NET-2 i NET-3 w Linuksie komunikują się z jądrem za pomocą systemu plików /proc. Interfejs ten pozwala na dostęp do roboczych informacji jądra przez mechanizm przypominający system plików. Po jego zamontowaniu możesz oglądać pliki tak jak w każdym innym systemie plików lub wyświetlać ich zawartość. Do typowych elementów należą: plik loadavg informujący o średnim obciążeniu systemu i plik meminfo pokazujący aktualne wykorzystanie pamięci głównej i pamięci wymiany. Do tego wszystkiego kod sieciowy dodaje katalog net. Zawiera on szereg plików pokazujących takie rzeczy, jak tablica ARP jądra, stan połączeń TCP oraz tablice rutingu. Większość narzędzi do administrowania sieci odczytuje potrzebne im informacje właśnie z tych plików. System plików proc (znany też pod nazwą procfs) zwykle jest montowany w katalogu /proc w czasie uruchamiania systemu. Najlepszym sposobem na zrobienie tego jest dodanie następującego wiersza w pliku /etc/fstab: # punkt montowania procfs none      /proc      proc      defaults a następnie wykonanie mount /proc ze skryptu /etc/rc. Obecnie procfs jest skonfigurowany domyślnie w większości jąder. Jeżeli w twoim jądrze nie ma procfs, otrzymasz komunikat typu: mount: fs type procfs not supported by kernel. Będziesz zatem musiał przekompilować jądro i odpowiedzieć "yes" na pytanie o obsługę procfs. Instalowanie plików binarnych Jeżeli korzystasz z dowolnej gotowej dystrybucji Linuksa, znajdziesz w niej główne aplikacje i narzędzia sieciowe wraz z odpowiednim zestawem przykładowych plików. Jedynym przypadkiem, w którym może zajść potrzeba znalezienia i zainstalowania nowych narzędzi, jest instalacja nowej wersji jądra. Nowe jądro miewa zmiany w warstwie sieciowej i dlatego należy uaktualnić podstawowe narzędzia konfiguracyjne. Uaktualnienie takie oznacza przynajmniej ponowną kompilację, ale czasem także wymaga nowego zestawu plików binarnych. Są one dostępne na oficjalnej witrynie macierzystej ftp.inka.de/pub/comp/Linux/networking/NetTools/ w postaci pakietu net-tools-XXX.tar.gz, gdzie XXX to numer wersji. Wersja dla Linuksa 2.0 nosi nazwę net-tools-1.45. Gdybyś chciał skompilować i zainstalować samodzielnie standardowe aplikacje sieciowe TCP/IP, mógłbyś zdobyć ich źródła z większości serwerów FTP Linuksa. Wszystkie współczesne dystrybucje Linuksa zawierają pełny zestaw aplikacji sieciowych TCP/IP, takich jak przeglądarka WWW, programy telnet i ftp oraz inne aplikacje sieciowe, na przykład talk. Jeżeli jednak dojdziesz do wniosku, że coś musisz skompilować samodzielnie, prawdopodobnie nie będziesz miał z tym problemów w Linuksie, jeżeli tylko będziesz postępował zgodnie z instrukcjami zawartymi w pakiecie źródłowym. Ustalanie nazwy hosta Większość aplikacji sieciowych, jeżeli nie wszystkie, oczekuje od ciebie ustawienia lokalnej nazwy hosta na jakąś sensowną wartość. Najlepiej zrobić to w czasie procedury uruchamiania systemu przez wykonanie polecenia hostname. Aby ustalić nazwę hosta nazwa, wprowadź: # hostname nazwa Powszechnie stosuje się skróconą nazwę hosta bez podawania nazwy domeny. Na przykład hosty w wirtualnym browarze (opisanym w dodatku A, Przykładowa sieć: browar wirtualny) mogłyby nosić nazwy vale.vbrew.com czy vlager.vbrew.com. Są to ich pełne nazwy domenowe (ang. fully qualified domain names - FQDN). Nazwa hosta to jedynie pierwszy człon pełnej nazwy, czyli na przykład vale. Jednak choć lokalna nazwa hosta jest często używana do szukania jego adresu IP, musisz mieć pewność, że biblioteka resolvera będzie w stanie znaleźć adres IP hosta. Zwykle oznacza to, że musisz wprowadzić nazwę do pliku /etc/hosts. Niektórzy zalecają użycie polecenia domainname, by powiadomić jądro o nazwie domeny, czyli o pozostałej części FQDN. Wydaje się, że  można by połączyć wynik hostname i domainname, aby uzyskać pełną nazwę domenową. Jednak w najlepszym razie rezultat byłby tylko w połowie poprawny. Polecenie domainname jest bowiem używane do definiowania domeny NIS, która może być zupełnie inna niż domena DNS, do której należy host. Dlatego warto zadbać o to, aby nazwa hosta była rozwiązywalna przez wszystkie nowe wersje polecenia hostname. W tym celu należy dodać wpis do lokalnego serwera nazw domen lub umieścić pełną nazwę domenową w pliku /etc/hosts. Teraz możesz użyć argumentu -fqdn polecenia hostname, aby wyświetlić pełną nazwę domenową. Przypisywanie adresu IP Jeżeli nie planujesz pracy w sieci, ale konfigurujesz oprogramowanie sieciowe na swoim hoście, aby na przykład móc uruchomić oprogramowanie INN Netnews, możesz bezpiecznie pominąć ten podrozdział, ponieważ jedynym potrzebnym ci adresem IP będzie interfejs pętli zwrotnej, który zawsze ma numer 127.0.0.1. Rzeczy nieco bardziej się komplikują w rzeczywistych sieciach takich jak Ethernet. Gdybyś chciał podłączyć swój host do istniejącej sieci, musiałbyś poprosić administratorów o nadanie ci w niej adresu IP. Jeżeli konfigurujesz sam całą sieć, musisz sam przypisać adresy IP. Hosty w sieci lokalnej zwykle powinny mieć adresy z tej samej logicznej sieci IP. W związku z tym musisz przypisać adres IP dla sieci. Jeżeli masz kilka sieci fizycznych, musisz przypisać im różne numery sieci albo użyć podsieci i podzielić posiadany zakres adresów IP na kilka podsieci. Podsieci zostaną omówione w najbliższym podrozdziale. Wybór numeru IP sieci w dużym stopniu zależy od tego, czy w niedalekiej przyszłości zamierzasz podłączyć się do Internetu. Jeżeli tak, powinieneś uzyskać oficjalny adres IP już teraz. Poproś o pomoc swojego dostawcę usług internetowych. Jeżeli chcesz uzyskać numer sieci po prostu na wypadek, gdybyś kiedyś podłączył się do Internetu, poproś o formularz prośby o adres sieci, pisząc na adres hostmaster@internic.net lub zgłoś się do centrum informacji sieciowej w twoim kraju, o ile takie istnieje. Jeżeli twoja sieć nie jest podłączona do Internetu i nie nosisz się z takim zamiarem, możesz wybrać dowolny dopuszczalny adres sieci. Wystarczy upewnić się, że żadne pakiety z twojej sieci wewnętrznej nie przedostaną się do prawdziwego Internetu. Aby zagwarantować, że nic się nie stanie, nawet jeżeli pakiety się przedostaną, powinieneś użyć jednego z numerów sieci zarezerwowanych dla sieci prywatnych. Organizacja zajmująca się przydzielaniem numerów w Internecie (Internet Assigned Numbers Authority - IANA) wyznaczyła kilka adresów sieci z klasy A, B i C, których możesz używać bez rejestrowania. Adresy te są ważne tylko w twojej sieci prywatnej i nie są rutowane pomiędzy prawdziwymi ośrodkami w Internecie. Są one zdefiniowane w RFC 1597. My zamieściliśmy je w tabeli 2-1 w rozdziale 2, Wybrane problemy sieci TCP/IP. Zauważ, że druga i trzecia klasa zawierają odpowiednio 16 i 256 sieci. Wybranie swojego adresu w jednej z tych sieci sprawdza się nie tylko w przypadku sieci zupełnie nie podłączonych do Internetu. Będąc w takiej sieci, możesz zaimplementować nieco bardziej ograniczony dostęp za pomocą jednego hosta jako gatewaya. Dla twojej sieci lokalnej gateway jest dostępny pod swoim wewnętrznym adresem IP, natomiast dla świata zewnętrznego - pod oficjalnie zarejestrowanym adresem (nadanym ci przez dostawcę). Powrócimy do tego rozwiązania przy omawianiu funkcji maskowania (ang. masquarading) w rozdziale 11, Maskowanie IP i translacja adresów sieciowych. Na potrzeby naszych rozważań zakładamy, że administrator przykładowej sieci browarów używa numeru sieci z klasy B, powiedzmy 172.16.0.0. Oczywiście numer z klasy C w zupełności by wystarczył zarówno dla sieci browarów, jak i winiarni. Klasy B używamy tu dla uproszczenia. Dzięki temu przykłady podziału na podsieci pokazane w następnym podrozdziale będą bardziej przekonujące. Tworzenie podsieci Aby obsłużyć kilka sieci Ethernet (lub innych, dla których dostępny jest sterownik), musisz podzielić swoją sieć na podsieci. Zauważ, że podział taki jest potrzebny tylko wtedy, gdy masz więcej niż jedną sieć rozgłoszeniową - łącza punkt-punkt się nie liczą. Na przykład gdybyś miał jedną sieć Ethernet i przynajmniej jedno łącze SLIP do świata zewnętrznego, nie musiałbyś dzielić swojej sieci na podsieci. Wyjaśniamy to bardziej szczegółowo w rozdziale 7, IP łącza szeregowego. Aby obsłużyć dwie sieci Ethernet, administrator sieci browaru zdecydował się przeznaczyć w adresie 8 bitów części hosta na dodatkowe bity podsieci. Dla hosta zostaje 8 bitów, co pozwala na umieszczenie w każdej podsieci po 254 hosty. Następnie sieć numer 1 została przypisana do browaru, a sieć numer 2 do winiarni. Odpowiednie adresy sieci to 172.16.1.0 i 172.16.2.0. Maska podsieci to 255.255.255.0. Gateway pomiędzy tymi dwoma sieciami, vlager, ma w obu sieciach numer hosta 1, co daje adresy IP odpowiednio 172.16.1.1 i 172.16.2.1. W tym przykładzie używamy dla uproszczenia sieci klasy B, choć sieć klasy C byłaby bardziej realistyczna. W nowym kodzie sieciowym jądra podział na podsieci nie zależy od granic bajtowych, a więc nawet klasa C może być dzielona na kilka podsieci. Na przykład mógłbyś użyć dwóch bitów części hosta na adres sieci, co dałoby 4 możliwe podsieci, po 64 hosty w każdej*. Tworzenie plików hosts i networks Jeśli już podzieliłeś swoją sieć na podsieci, powinieneś postarać się o proste rozwiązywanie nazw hostów za pomocą pliku /etc/hosts. Jeżeli nie zamierzasz korzystać z DNS-u lub NIS-a do rozwiązywania adresów, musisz umieścić wszystkie hosty w pliku hosts. Nawet jeżeli będziesz używał DNS-u lub NIS-a w czasie normalnej pracy, w pliku /etc/hosts powinieneś mieć pewien podzbiór wszystkich nazw hostów. Musisz zapewnić rozwiązywanie nazw, nawet jeżeli nie działają żadne interfejsy sieciowe - na przykład w czasie uruchamiania systemu. Chodzi nie tylko o wygodę, ale też o możliwość zastosowania symbolicznych nazw hostów w skryptach sieciowych rc. Dzięki temu gdy zmienisz adresy IP, wystarczy jedynie skopiować uaktualniony plik hosts na wszystkie komputery i uruchomić je ponownie, zamiast edytować mnóstwo plików rc. Zwykle w pliku hosts umieszczasz wszystkie lokalne nazwy hostów i adresy oraz dodajesz adresy używanych gatewayów i serwerów NIS**. Powinieneś się upewnić, że twój resolver w czasie testowania przy inicjacji wykorzystuje jedynie informacje z pliku hosts. Przykładowe pliki dostarczane wraz z oprogramowaniem DNS czy NIS mogą dawać dziwne rezultaty. Aby wszystkie aplikacje korzystały wyłącznie z /etc/hosts przy poszukiwaniu adresu IP hosta, musisz dokonać edycji pliku /etc/host.conf. Poprzedź znakiem komentarza (#) wszystkie linie zaczynające się od słowa kluczowego order, i wstaw wiersz: order hosts Konfiguracja resolvera jest dokładnie opisana w rozdziale 6, Usługi nazewnicze i konfigurowanie resolvera. Plik hosts zawiera po jednym wpisie w wierszu, a każdy wpis składa się z adresu IP i nazwy hosta oraz opcjonalnej listy aliasów tej nazwy. Pola są oddzielone spacjami albo tabulatorami, a pole adresu musi zaczynać się w pierwszej kolumnie. Wszystko, co jest poprzedzone hashem, jest uznawane za komentarz i ignorowane. Nazwy hostów mogą być pełne lub względne dla domeny lokalnej. W przypadku vale wprowadziłbyś w pliku hosts pełną nazwę vale.vbrew.com oraz vale, aby host był znany zarówno pod nazwą oficjalną, jak i skróconą - lokalną. Oto przykład, jak może wyglądać plik hosts dla wirtualnego browaru. Dodano dwie nazwy specjalne vlager-if1 i vlager-if2, które zawierają adresy obu interfejsów używanych na hoście vlager: # # Plik hosts dla wirtualnego browaru/wirtualnej winiarni # # IP         FQDN                aliasy # 127.0.0.1 localhost # 172.16.1.1   vlager.vbrew.com       vlager vlager-if1 172.16.1.2   vstout.vbrew.com       vstout 172.16.1.3   vale.vbrew.com         vale # 172.16.2.1 vlager-if2 172.16.2.2 vbeaujolais.vbrew.com  vbeaujolais 172.16.2.3 vbardolino.vbrew.com   vbardolino 172.16.2.4 vchianti.vbrew.com     vchianti Podobnie jak w przypadku adresów IP hosta, tak i dla numerów sieci powinieneś czasem używać również nazw symbolicznych. Dlatego plik hosts posiada bliźniaczy plik /etc/networks, który odwzorowuje nazwy sieci na ich numery i odwrotnie. W wirtualnym browarze zainstalowalibyśmy następujący plik networks:* # /etc/networks dla wirtualnego browaru brew-net      172.16.1.0 wine-net      172.16.2.0 Konfigurowanie interfejsu dla IP Zgodnie z tym, co napisaliśmy w rozdziale 4, Konfigurowanie urządzeń szeregowych, po skonfigurowaniu sprzętu musisz zadbać o to, aby oprogramowanie sieciowe jądra rozpoznawało urządzenia. Do skonfigurowania interfejsów sieciowych i zainicjowania tablicy rutingu stosuje się kilka poleceń. Zadania te zwykle są wykonywane ze skryptu inicjującego sieć każdorazowo podczas uruchomienia systemu. Podstawowe narzędzia do tego celu to ifconfig (gdzie if jest skrótem od interfejs) i route. Polecenie ifconfig jest używane do udostępnienia interfejsu warstwie sieciowej jądra. Wymaga to przypisania adresu IP i zdefiniowania innych parametrów oraz aktywacji interfejsu, często nazywanej także "podniesieniem" interfejsu. Interfejs aktywny oznacza tutaj, że jądro będzie przez niego wysyłało i odbierało datagramy IP. Oto najprostsza procedura tego zadania: ifconfig interfejs adres-IP Polecenie to przypisuje adres-IP do interfejsu i go aktywuje. Wszystkie pozostałe parametry są ustawiane na wartości domyślne. Na przykład domyślna maska sieci jest ustalana na podstawie klasy sieci, do której należy podany adres IP, czyli 255.255.0.0 dla klasy B. ifconfig jest opisane szczegółowo w podrozdziale Wszystko o ifconfig. Polecenie route pozwala na dodanie lub usunięcie trasy z tablicy rutingu jądra. Można wywołać je następująco: route [add|del] [-net|-host] przeznaczenie [if] Argumenty add i del określają, czy należy dodać, czy też usunąć trasę do przeznaczenia. Argumenty -net i -host mówią poleceniu route, czy przeznaczenie to sieć, czy host (domyślnie, jeżeli nic nie podasz, przyjmowany jest host). Argument if jest opcjonalny i pozwala na podanie interfejsu sieciowego, do którego powinna zostać przekierowana dana trasa - jądro Linuksa rozsądnie zgaduje, jeżeli nie podasz tej informacji. Temat ten zostanie szczegółowo wyjaśniony w kolejnych podrozdziałach. Interfejs pętli zwrotnej W pierwszej kolejności aktywowany jest interfejs pętli zwrotnej: # ifconfig lo 127.0.0.1 Może się zdarzyć, że zamiast adresu IP zobaczysz fikcyjną nazwę hosta localhost. ifconfig będzie szukać nazwy w pliku hosts, gdzie powinien znajdować się wpis wiążący tę nazwę z adresem 127.0.0.1. # Przykładowy wpis localhost w /etc/hosts localhost      127.0.0.1 Aby obejrzeć konfigurację interfejsu, wywołujesz polecenie ifconfig, podając jako argument jedynie nazwę interfejsu. $ ifconfig lo lo      Link encap:Local Loopback       inet addr:127.0.0.1  Mask:255.0.0.0       UP LOOPBACK RUNNING  MTU:3924  Metric:1       RX packets:0 errors:0 dropped:0 overruns:0 frame:0       TX packets:0 errors:0 dropped:0 overruns:0 carrier:0       Collisions:0 Jak widzisz, interfejsowi pętli zwrotnej została przypisana maska sieci 255.0.0.0, ponieważ adres 127.0.0.1 należy do klasy A. Teraz w zasadzie możesz zacząć zabawę ze swoją minisiecią. Wciąż jednak brakuje wpisu w tablicy rutingu, mówiącego IP, że może używać tego interfejsu jako trasy do adresu 127.0.0.1. Można go dodać następująco: # route add 127.0.0.1 Znów możesz użyć localhost zamiast adresu IP, pod warunkiem, że wpisałeś go do pliku /etc/hosts. Następnie powinieneś sprawdzić, czy wszystko poprawnie działa, na przykład używając polecenia ping. Polecenie to sprawdza, czy podany adres jest rzeczywiście osiągalny, i mierzy opóźnienia występujące przy wysyłaniu datagramu na ten adres i z powrotem. Czas potrzebny do wykonania tego zadania jest często nazywany "czasem przewidzianym na transmisję i potwierdzenie przyjęcia" (ang. round-trip time): # ping localhost PING localhost (127.0.0.1): 56 data bytes 64 bytes from 127.0.0.1: icmp_seq=0 ttl=255 time=0.4 ms 64 bytes from 127.0.0.1: icmp_seq=1 ttl=255 time=0.4 ms 64 bytes from 127.0.0.1: icmp_seq=2 ttl=255 time=0.4 ms ^C --- localhost ping statistics --- 3 packets transmitted, 3 packets received, 0% packet loss round-trip min/avg/max = 0.4/0.4/0.4 ms # Kiedy ping zostanie wywołane w pokazany tu sposób, będzie wysyłało pakiety dopóty, dopóki użytkownik nie przerwie wykonywania polecenia. Znak ^C pokazuje, gdzie nacisnęliśmy [CTRL+C]. W tym przykładzie widać, że pakiety są poprawnie dostarczane na adres 127.0.0.1, a odpowiedź jest zwracana natychmiast. To znak, że prawidłowo skonfigurowałeś swój pierwszy interfejs sieciowy. Jeśli wynik polecenia ping nie przypomina pokazanego w powyższym przykładzie, znaczy to, że masz kłopot. Sprawdź wszelkie odstępstwa - czy nie wskazują one, że jakieś pliki nie zostały poprawnie zainstalowane? Sprawdź, czy binaria ifconfig i route, których używasz, są kompatybilne z twoją wersją jądra, a przede wszystkim, czy jądro zostało skompilowane z obsługą sieci (powinieneś mieć katalog /proc/net). Jeżeli otrzymasz komunikat o treści "Network unreachable", prawdopodobnie zrobiłeś coś nie tak w poleceniu route. Sprawdź, czy użyłeś tego samego adresu, który podałeś w ifconfig. Przedstawiona procedura powinna umożliwić ci korzystanie z aplikacji sieciowych na pojedynczym hoście. Po dodaniu wcześniej wspomnianych linii do skryptu inicjującego sieć i upewnieniu się, że zostanie on uruchomiony w czasie startu, możesz ponownie uruchomić swój komputer i wypróbować różne aplikacje. Na przykład telnet localhost powinno zrealizować połączenie telnet z twoim hostem, pokazując monit login:. Jednak interfejs pętli zwrotnej jest przydatny nie tylko jako przykład w książkach o sieci czy do testowania oprogramowania, ale jest rzeczywiście używany przez niektóre aplikacje w czasie normalnej pracy*. Dlatego zawsze musisz go konfigurować bez względu na to, czy twoja maszyna jest podłączona do sieci, czy nie. Interfejsy Ethernet Konfigurowanie interfejsu Ethernet jest prawie identyczne z konfigurowaniem interfejsu pętli zwrotnej. Wymaga jedynie wprowadzenia kilku dodatkowych parametrów, jeżeli używasz podziału na podsieci. W wirtualnym browarze podzieliliśmy oryginalną sieć IP klasy B na podsieci o postaci sieci klasy C. Aby interfejs rozpoznał podział na podsieci, wywołanie ifconfig powinno być następujące: # ifconfig eth0 vstout netmask 255.255.255.0 Polecenie to przypisuje interfejsowi eth0 adres IP vstout (172.16.1.2). Gdybyśmy pominęli maskę sieci, ifconfig zredukowałoby maskę sieci na podstawie adresu IP i uzyskalibyśmy niepoprawną maskę postaci 255.255.0.0. Teraz szybko sprawdzamy wynik: # ifconfig eth0 eth0      Link encap 10Mps Ethernet HWaddr 00:00:C0:90:B3:42       inet addr 172.16.1.2 Bcast 172.16.1.255 Mask 255.255.255.0       UP BROADCAST RUNNING MTU 1500 Metric 1       RX packets 0 errors 0 dropped 0 overrun 0       TX packets 0 errors 0 dropped 0 overrun 0 Możesz zauważyć, że ifconfig automatycznie ustawia adres rozgłoszeniowy (pole Bcast) na typową wartość, która składa się z numeru sieci hosta i ustawionych wszystkich bitów w części numeru hosta. Także maksymalna jednostka transmisji (maksymalny rozmiar datagramów IP tworzonych dla interfejsu przez jądro) została ustawiona na maksymalny rozmiar pakietów Ethernet: 1500 bajtów. Zwykle będziesz używał wartości domyślnych, ale w razie potrzeby możesz je zmienić za pomocą specjalnych opcji, które zostaną opisane w podrozdziale Wszystko o ifconfig. Tak jak przy konfiguracji interfejsu pętli zwrotnej, musisz teraz utworzyć wpis w tablicy rutingu mówiący jądru o sieci, która jest osiągalna przez eth0. W przypadku wirtualnego browaru możesz wywołać polecenie route następująco: # route add -net 172.16.1.0 Z początku wygląda to nieco tajemniczo, ponieważ nie jest zupełnie jasne, jak route wykrywa interfejs, przez który ma przesyłać pakiety. Jednak cały zabieg jest raczej prosty: jądro sprawdza wszystkie interfejsy, które zostały do tej pory skonfigurowane, i porównuje adres docelowy (w tym przypadku 172.16.1.0) z częścią sieciową adresu interfejsu (to znaczy wykonuje bitową logiczną operację AND na adresie interfejsu i masce sieci). Jedynym pasującym interfejsem jest eth0. A do czego służy opcja -net? Jest ona potrzebna, ponieważ route może obsłużyć obie trasy: do sieci i do pojedynczego hosta (co widziałeś wcześniej przy localhost). Kiedy podamy adres w notacji kropkowej, route próbuje zgadnąć, czy jest to adres sieci czy hosta, patrząc na bity części hosta. Jeżeli w adresie część hosta jest zerowa, route zakłada, że chodzi o adres sieci - w przeciwnym razie route uznaje go za adres hosta. Dlatego route uznałoby, że 172.16.1.0 to adres hosta, a nie adres sieci, ponieważ nie wie, że zastosowaliśmy podział na podsieci. Musimy powiedzieć jawnie, że chodzi o sieć, a więc podajemy opcję -net. Oczywiście wpisywanie polecenia route jest nużące i łatwo przy tym o pomyłkę. Wygodniejsze jest użycie nazw sieci, które zdefiniowaliśmy w /etc/networks. Polecenie staje się bardziej czytelne i można nawet pominąć opcję -net, ponieważ route wie, że 172.16.1.0 oznacza sieć. # route add brew-net Teraz, gdy już masz za sobą podstawowe kroki konfiguracyjne, upewnj się, że interfejs Ethernet naprawdę działa poprawnie. Wybierz jakiś host ze swojej sieci, na przykład vlager, i napisz: # ping vlager PING vlager: 64 byte packets 64 bytes from 172.16.1.1: icmp_seq=0. time=11. ms 64 bytes from 172.16.1.1: icmp_seq=1. time=7. ms 64 bytes from 172.16.1.1: icmp_seq=2. time=12. ms 64 bytes from 172.16.1.1: icmp_seq=3. time=3. ms ^C --- vstout.vbrew.com PING Statistics --- 4 packets transmitted, 4 packets received, 0 round-trip (ms) min/avg/max = 3/8/12 Jeżeli twój wynik się różni, coś jest nie tak. Jeżeli zauważysz, że współczynnik utraty pakietów ma jakąś nieprawdopodobną wartość, wskazuje to na problem sprzętowy, na przykład złe terminatory w przypadku kabla współosiowego lub ich brak. Jeżeli nie uzyskasz w ogóle żadnych odpowiedzi, powinieneś sprawdzić konfigurację interfejsu za pomocą polecenia netstat (patrz podrozdział Polecenie netstat w tym rozdziale). Statystyka pakietów pokazana przez ifconfig powinna powiedzieć ci, czy jakieś pakiety zostały w ogóle wysłane przez interfejs. Jeżeli masz również dostęp do zdalnego hosta, powinieneś podejść do niego i sprawdzić statystyki interfejsu. W ten sposób możesz dokładnie stwierdzić, gdzie pakiety zostały zgubione. Ponadto za pomocą polecenia route powinieneś wyświetlić informacje o rutingu i zobaczyć, czy oba hosty mają poprawne wpisy dotyczące rutingu. route wyświetli pełną tablicę rutingu jądra, jeżeli zostanie wywołane bez argumentów (-n powoduje jedynie, że są drukowane adresy w postaci numerycznej, a nie nazwy hostów): # route -n Kernel routing table Destination    Gateway   Genmask          Flags Metric Ref Use Iface 127.0.0.1      *       255.255.255.255   UH     1      0 112 lo 172.16.1.0    *       255.255.255.0     U     1      0 10 eth0 Znaczenie poszczególnych pól zostanie wyjaśnione dalej w podrozdziale Polecenie netstat. Kolumna Flags zawiera listę znaczników ustawionych dla każdego interfejsu. U zawsze jest ustawione w przypadku aktywnych interfejsów, a H mówi, że adresem docelowym jest adres hosta. Jeżeli znacznik H jest ustawiony dla trasy, która miała być trasą do sieci, musisz ponownie wydać polecenie route z opcją -net. Aby dowiedzieć się, czy wprowadzona trasa jest w ogóle używana, sprawdź, czy wartość pola Use w drugiej kolumnie od końca zwiększa się pomiędzy wywołaniami polecenia ping. Ruting przez gateway W poprzednim podrozdziale omówiliśmy konfigurację hosta podłączonego do jednej sieci Ethernet. Często się jednak zdarza, że sieci są ze sobą połączone. Służą do tego gatewaye, które łączą po prostu dwie lub więcej sieci Ethernet, ale mogą także stanowić pomost do świata zewnętrznego, na przykład do Internetu. Aby wykorzystać gateway, musisz podać warstwie sieciowej dodatkowe informacje o rutingu. Sieci Ethernet należące do wirtualnego browaru i wirtualnej winiarni są połączone takim właśnie gatewayem. Nosi on nazwę vlager. Zakładając, że vlager został już skonfigurowany, musimy po prostu dodać do tablicy rutingu vstout wpis, który poinformuje jądro, jak może dostać się przez vlager do wszystkich hostów w sieci winiarni. Odpowiednie wywołanie polecenia route zostało pokazane poniżej. Słowo kluczowe gw mówi, że następny argument oznacza gateway: # route add wine-net gw vlager Oczywiście dowolny host w sieci winiarni, z którym się chcesz połączyć, musi mieć wpis dotyczący trasy do sieci browaru. W przeciwnym razie będziesz w stanie jedynie wysłać dane z sieci browaru do sieci winiarni, ale hosty w sieci winiarni nie będą w stanie odpowiedzieć. Przykład ten opisuje tylko gateway, który przekazuje pakiety pomiędzy dwoma wyizolowanymi sieciami Ethernet. Załóżmy teraz, że vlager ma także połączenie z Internetem (przyjmij, że przez dodatkowe łącze SLIP). W takim razie chcemy, aby datagramy adresowane do dowolnego miejsca poza siecią browaru były obsługiwane przez vlager. Można to zrobić, definiując ten gateway jako domyślny dla vstout: # route add default gw vlager Nazwa sieci default stanowi skrót dla adresu 0.0.0.0, który oznacza trasę domyślną. Domyślna trasa pasuje do każdego adresu docelowego i będzie używana, jeżeli w tablicy rutingu nie ma dokładniejszej trasy. Nie musisz dodawać tej nazwy do pliku /etc/networks, ponieważ jest ona wbudowana w polecenie route. Jeżeli polecenie ping skierowane do hosta znajdującego się za jednym lub kilkoma gatewayami pokazuje, że dużo pakietów jest gubionych, może to oznaczać, że sieć jest zapchana. Gubienie pakietów nie wynika z wad technicznych, ale z tymczasowego przeciążenia hostów przekazujących, które powoduje opóźnienia, a nawet gubienie przychodzących pakietów. Konfigurowanie gatewaya Skonfigurowanie maszyny, która przekazuje pakiety pomiędzy dwoma sieciami Ethernet, jest dosyć proste. Wróćmy do hosta vlager, który jest wyposażony w dwie karty Ethernet, a każda z nich jest podłączona do jednej z dwóch sieci. Musisz jedynie skonfigurować oddzielnie obie karty i nadać im odpowiednie adresy IP oraz wyznaczyć trasy. Dosyć przydatne jest dodanie informacji o obu interfejsach do pliku hosts, by mieć pod ręką łatwe do zapamiętania nazwy, co pokazano w poniższym przykładzie. 172.16.1.1   vlager.vbrew.com   vlager vlager-if1 172.16.2.1 vlager-if2 Aby skonfigurować te dwa interfejsy, należy wydać następujące polecenia: # ifconfig eth0 vlager-if1 # route add brew-net # ifconfig eth1 vlager-if2 # route add wine-net Jeżeli te polecenia nie działają, sprawdź, czy jądro zostało skompilowane z włączoną opcją przekazywania IP (ang. IP forwarding). W tym celu upewnij się, czy pierwsza liczba w drugim wierszu pliku /proc/net/snmp jest ustawiona na 1. Interfejs PLIP Łącze PLIP używane do połączenia dwóch komputerów różni się nieco od Ethernetu. Łącza PLIP należą do łączy typu punkt-punkt, co oznacza, że na każdym końcu takiego łącza jest jeden host. Sieci typu Ethernet są nazywane sieciami rozgłoszeniowymi. Konfiguracja łączy punkt-punkt jest inna, ponieważ w odróżnieniu od sieci rozgłoszeniowych nie tworzą one własnej sieci. PLIP to bardzo tanie i przenośne łącze pomiędzy komputerami. Jako przykład rozważmy komputer typu laptop należący do pracownika wirtualnego browaru. Komputer ten jest podłączony do hosta vlager przez łącze PLIP. Sam laptop nazywa się vlite i ma tylko jeden port równoległy. W czasie uruchamiania systemu port ten rejestruje się jako plip1. Aby uaktywnić łącze, musisz skonfigurować interfejs plip1, używając poniższych poleceń*: # ifconfig plip1 vlite pointopoint vlager # route add default gw vlager Pierwsze polecenie konfiguruje interfejs mówiąc jądru, że jest to łącze punkt-punkt i że druga strona ma adres vlager. Drugie polecenie dodaje domyślną trasę, używając hosta vlager jako gatewaya. Do uaktywnienia łącza na hoście vlager niezbędne jest podobne polecenie ifconfig (wywołanie route nie jest potrzebne): # ifconfig plip1 vlager pointopoint vlite Zauważ, że interfejs plip1 na hoście vlager nie potrzebuje oddzielnego adresu IP, ale można mu nadać również adres 172.16.1.1. Łącza punkt-punkt nie obsługują bezpośrednio sieci, a więc interfejsy nie wymagają adresu. Jądro wykorzystuje informacje o interfejsie zawarte w tablicy rutingu, aby uniknąć jakichś pomyłek**. Skonfigurowaliśmy już ruting z laptopa do sieci browaru. Wciąż jednak nie mamy trasy z dowolnego hosta browaru do vlite. Dodawanie takiej trasy w tablicy rutingu każdego hosta jest wyjątkowo kłopotliwe. Trzeba byłoby tam wskazać, że vlager jest gatewayem dla vlite: # route add vlite gw vlager Dla tras tymczasowych lepszy jest ruting dynamiczny. Na każdym hoście w sieci można zainstalować demona rutingu gated, który będzie dynamicznie rozpowszechniał informacje o rutingu. Prostszym wyjściem jednak jest użycie proxy ARP (Address Resolution Protocol). Dzięki proxy ARP, vlager będzie odpowiadał na każde zapytanie ARP o vlite, wysyłając własny adres Ethernet. Wszystkie pakiety dla vlite będą docierały do vlagera, który następnie będzie je przekazywał do laptopa. Do proxy ARP powrócimy w podrozdziale Sprawdzanie tablic ARP. Obecna wersja net-tools zawiera narzędzie o nazwie plipconfig pozwalające na ustawienie odpowiednich parametrów czasowych PLIP. IRQ dla portu równoległego można ustawić za pomocą polecenia ifconfig. Interfejsy SLIP i PPP Choć łącza SLIP i PPP są, tak jak PLIP, jedynie prostymi łączami typu punkt-punkt, można o nich powiedzieć dużo więcej. Zwykle ustanowienie połączenia SLIP wymaga zadzwonienia do drugiej strony przez modem i ustawienia trybu SLIP dla łącza szeregowego. Z PPP korzysta się podobnie. SLIP i PPP omawiamy dokładniej w rozdziałach 7, IP łącza szeregowego, i 8, Protokół punkt-punkt. Interfejs fikcyjny (ang. dummy interface) Interfejs fikcyjny (ang. dummy interface) jest nieco egzotyczny, ale jednak przydatny. Jego główną zaletą w przypadku pojedynczych hostów i komputerów posiadających jedynie podłączenie do sieci IP jest łącze komutowane. W rzeczywistości przeważnie obsługuje pojedyncze hosty. Problem z pojedynczymi hostami polega na tym, że mają one aktywne tylko jedno urządzenie sieciowe - interfejs pętli zwrotnej, któremu zwykle jest przypisywany adres 127.0.0.1. Czasami jednak musisz wysłać dane na "oficjalny" adres IP hosta lokalnego. Na przykład załóżmy, że laptop vlite został chwilowo odłączony od sieci. Aplikacja na vlite może teraz chcieć wysłać dane do innej aplikacji na tym samym hoście. Sprawdzenie vlite w pliku /etc/hosts daje adres IP 172.16.1.65, a więc aplikacja próbuje wysyłać dane na taki adres. Ponieważ interfejs pętli zwrotnej jest obecnie jedynym aktywnym interfejsem w tym komputerze, jądro nie ma pojęcia, że adres 172.16.1.65 tak naprawdę odnosi się do tej samej maszyny! W konsekwencji jądro odrzuca datagram i zwraca do aplikacji komunikat o błędzie. Tu właśnie przydaje się interfejs fikcyjny. Rozwiązuje on problem wykorzystując interfejs pętli zwrotnej. W przypadku vlite, po prostu nadajesz interfejsowi adres 172.16.1.65 i dodajesz trasę, tak by na niego wskazywała. Każdy datagram przeznaczony dla adresu 172.16.1.65 będzie od tej chwili dostarczony lokalnie. Oto poprawne wywołanie*: # ifconfig dummy vlite # route add vlite Alias IP Nowe jądra obsługują funkcję, która może zastąpić interfejs fikcyjny i pełnić inne użyteczne role. Alias IP pozwala na skonfigurowanie wielu adresów IP na jednym urządzeniu fizycznym. W najprostszym przypadku można inaczej zrealizować interfejs fikcyjny. Wystarczy skonfigurować adres hosta jako alias dla interfejsu pętli zwrotnej i możesz zupełnie zrezygnować z interfejsu fikcyjnego. W bardziej złożonych zastosowaniach mógłbyś skonfigurować swój host tak, by wyglądał jak inne hosty, każdy o swoim własnym adresie IP. Konfiguracja taka jest czasem nazywana tworzeniem hostów wirtualnych, choć technicznie jest również używana w wielu innych celach**. Aby skonfigurować alias dla interfejsu, musisz najpierw sprawdzić, czy jądro zostało skonfigurowane z obsługą aliasów IP (sprawdź, czy masz plik /proc/net/ip_alias; jeżeli nie - trzeba ponownie skompilować jądro). Konfiguracja aliasu IP przebiega tak samo jak konfiguracja normalnego urządzenia sieciowego. Jedyna różnica polega na użyciu specjalnej nazwy wskazującej, że jest to alias. Na przykład: # ifconfig lo:0 172.16.1.1 To polecenie utworzy alias o adresie 172.16.1.1 dla interfejsu pętli zwrotnej. Aliasy IP są oznaczane przez dodanie :n do rzeczywistej nazwy urządzenia sieciowego, gdzie "n" jest liczbą całkowitą. W naszym przykładzie tworzymy alias o numerze 0 dla urządzenia sieciowego lo. Dzięki numeracji pojedyncze urządzenie fizyczne może obsłużyć wiele aliasów. Każdy alias może być traktowany jako oddzielne urządzenie i z punktu widzenia oprogramowania IP jądra tak właśnie jest. Będzie jednak współdzielił sprzęt z innym interfejsem. Wszystko o ifconfig Polecenie ifconfig ma dużo więcej parametrów, niż opisaliśmy do tej pory. Typowe wywołanie wygląda tak: ifconfig interfejs [adres [parametry]] Oczywiste jest, że interfejs to nazwa interfejsu, a adres to nazwa adresu IP przypisanego interfejsowi. Może być to adres w postaci liczbowej lub nazwa, którą ifconfig odnajdzie w pliku /etc/hosts. Gdybyśmy wywołali ifconfig tylko z nazwą interfejsu, zobaczylibyśmy konfigurację interfejsu. Przy wywołaniu bez parametrów ifconfig wyświetla wszystkie interfejsy, jakie masz do tej pory skonfigurowane. Opcja -a wymusza również pokazanie interfejsów nieaktywnych. Przykładowe wywołanie dla interfejsu Ethernet eth0 może wyglądać następująco: # ifconfig eth0 eth0      Link encap 10Mbps Ethernet HWaddr 00:00:C0:90:B3:42       inet addr 172.16.1.2 Bcast 172.16.1.255 Mask 255.255.255.0       UP BROADCAST RUNNING MTU 1500 Metric 0       RX packets 3136 errors 217 dropped 7 overrun 26       TX packets 1752 errors 25 dropped 0 overrun 0 Pola MTU i Metric pokazują aktualne wartości MTU i metryki interfejsu. Metryka jest tradycyjnie używana przez niektóre systemy operacyjne do obliczenia kosztu trasy. Linux nie korzysta z tej wartości, ale definiuje ją dla zachowania kompatybilności. Wiersze RX i TX pokazują, ile pakietów zostało pomyślnie odebranych i wysłanych, ile wystąpiło błędów, ile pakietów zostało pominiętych (prawdopodobnie ze względu na brak pamięci), a ile zostało zgubionych ze względu na przeciążenie. Przeciążenia odbiorcy występują zwykle wtedy, gdy pakiety nadchodzą szybciej niż jądro jest w stanie obsłużyć ostatnie przerwanie. Znaczniki pokazywane przez ifconfig z grubsza odpowiadają nazwom opcji wiersza poleceń, które omówimy dalej. Poniżej przedstawiamy listę parametrów rozpoznawanych przez ifconfig z odpowiednimi nazwami znaczników. Opcje, które włączają funkcję, pozwalają również ją wyłączyć, jeśli przed opcją umieścimy znak minus (-). up Ta opcja udostępnia interfejs warstwie IP. Opcja jest domyślna w momencie podania w wierszu poleceń adresu. Może być także użyta do ponownego włączenia interfejsu, który został tymczasowo zamknięty za pomocą opcji down. Z tą opcją związane są znaczniki UP i RUNNING. down Ta opcja oznacza, że interfejs jest niedostępny dla warstwy IP. W rzeczywistości odcina cały ruch IP do interfejsu. Zauważ, że ta opcja usunie automatycznie także wszystkie wpisy w tablicy rutingu, które wykorzystują dany interfejs. netmask maska Ta opcja określa maskę sieci używaną przez interfejs. Może być ona podana w postaci 32-bitowej liczby szesnastkowej poprzedzonej 0x albo w postaci liczb dziesiętnych oddzielonych kropkami. Choć postać liczb dziesiętnych jest popularniejsza, często dużo łatwiej jest pracować z notacją szesnastkową. Maski sieci są w gruncie rzeczy binarne i łatwiej dokonać konwersji z zapisu binarnego na szesnastkowy, niż z binarnego na dziesiętny. pointopoint adres Ta opcja jest używana przy łączach IP punkt-punkt łączących tylko dwa hosty. Jest potrzebna na przykład do skonfigurowania interfejsów SLIP i PPP. Jeżeli zostanie ustawiony adres punkt-punkt, ifconfig wyświetli znacznik POINTOPOINT. broadcast adres Adres rozgłoszeniowy jest zwykle złożony z adresu sieci i wszystkich bitów ustawionych w adresie hosta. Niektóre implementacje IP (systemy pochodzące na przykład z BSD 4.2) wykorzystują inny schemat, w którym wszystkie bity w części hosta są zerowane. Opcja broadcast przystosowuje się do tych dziwnych środowisk. Jeżeli adres rozgłoszeniowy został określony, ifconfig  wyświetla znacznik BROADCAST. irq Ta opcja pozwala ustalić IRQ używane przez zadane urządzenia. Jest to przydatne zwłaszcza w łączach PLIP, ale także przy niektórych kartach Ethernet. metric liczba Ta opcja może być użyta do przypisania metryki we wpisie utworzonym dla interfejsu w tablicy rutingu. Metryka jest używana przez protokół rutowania RIP (Routing Information Protocol) do tworzenia tablic rutingu dla sieci*. Domyślna metryka używana przez ifconfig ma wartość zero. Jeżeli nie korzystasz z demona RIP, nie potrzebujesz w ogóle tej opcji. A nawet jeżeli go używasz, rzadko będziesz musiał zmieniać wartość metryki. mtu bajty W ten sposób ustawia się maksymalną jednostkę transmisji, która określa maksymalną liczbę oktetów, jaką interfejs jest w stanie obsłużyć w jednym ruchu. W przypadku Ethernetu domyślna wartość MTU wynosi 1500 (największy dopuszczalny rozmiar dla pakietu Ethernet). W przypadku interfejsów SLIP jest to 296 (nie ma ograniczeń MTU w łączach SLIP - ta wartość jest po prostu pewnym kompromisem). arp Ta opcja jest właściwa dla sieci rozgłoszeniowych, takich jak Ethernet, lub dla radia pakietowego. Włącza ona protokół rozwiązywania adresów (ARP), używany do znajdowania fizycznych adresów hostów podłączonych do sieci. W sieciach rozgłoszeniowych użycie tego protokołu jest domyślne. Jeżeli ARP jest wyłączony, ifconfig wyświetla znacznik NOARP. -arp Ta opcja wyłącza użycie ARP na interfejsie. promisc Ta opcja przełącza interfejs w tryb przechwytywania pakietów (ang. promiscuous mode). W sieciach rozgłoszeniowych oznacza to, że interfejs odbiera wszystkie pakiety, bez względu na to, czy są one dla niego przeznaczone, czy też nie. Pozwala to na analizę ruchu za pomocą filtrów pakietów i tym podobnych narzędzi, co jest nazywane także snoopingiem Ethernetu. Zwykle jest to dobra technika wykrywania problemów z siecią, które inną metodą byłyby trudne do znalezienia. Narzędzia takie jak tcpdump opierają się na tym trybie interfejsu. Z drugiej strony opcja ta pozwala włamywaczom na robienie brzydkich rzeczy, na przykład na przeglądanie pakietów twojej sieci w poszukiwaniu haseł. Możesz się zabezpieczyć przed tego typu atakiem, zabraniając komukolwiek włączać komputery do twojej sieci Ethernet. Możesz także używać bezpiecznych protokołów uwierzytelniania, takich jak Kerberos czy pakiet secure shell*. Opcji tej odpowiada znacznik PROMISC. -promisc Ta opcja wyłącza tryb przechwytywania pakietów. allmulti Adresy grupowe (ang. multicast addresses) mają wiele wspólnego z adresami rozgłoszeniowymi Ethernet, z tym wyjątkiem, że nie implikują automatycznego kierowania do pakietów wszystkich członków sieci. Pakiety wysłane na adres grupowy dostają tylko te osoby, które ustawiły ich odbieranie. Jest to przydatne w takich zastosowaniach, jak wideokonferencje oparte na sieci Ethernet czy audio w sieci, gdzie tylko zainteresowani odbierają dane pakiety. Adresowanie grupowe jest obsługiwane przez większość sterowników Ethernet, aczkolwiek nie przez wszystkie. Gdy opcja ta jest włączona, interfejs odbiera i przekazuje pakiety grupowe do przetwarzania. Opcji tej odpowiada znacznik ALLMULTI. -allmulti Ta opcja wyłącza adresy grupowe. Polecenie netstat netstat jest przydatnym narzędziem do sprawdzania konfiguracji sieci i jej działania. W gruncie rzeczy jest to zestaw kilku połączonych ze sobą narzędzi. W kolejnych podrozdziałach omawiamy każdą z funkcji polecenia. Wyświetlanie tablicy rutingu Kiedy wywołasz netstat z opcją -r, wyświetli ono tablicę rutingu jądra w postaci podobnej jak polecenie route. Na hoście vstout wynik wygląda następująco: # netstat -nr Kernel IP routing table Destination   Gateway     Genmask         Flags  MSS   Window   irtt   Iface 127.0.0.1    *       255.255.255.255 UH    0    0   0    lo 172.16.1.0    *       255.255.255.0   U    0    0    0    eth0 172.16.2.0    172.16.1.1  255.255.255.0   UG    0   0    0    eth0 Opcja -n powoduje, że netstat wyświetla adresy w postaci numerów IP, a nie symbolicznych nazw hostów i sieci. Opcja ta jest szczególnie przydatna, jeżeli chcesz uniknąć szukania adresów w sieci (tzn. na serwerach DNS albo NIS). Druga kolumna wyniku polecenia netstat pokazuje gateway, na który wskazuje dany wpis. Jeżeli gateway nie jest używany, wyświetlana jest gwiazdka. Trzecia kolumna pokazuje maskę sieci dla danej trasy. Gdy podamy adres IP, dla którego chcemy znaleźć odpowiednią trasę, jądro przegląda kolejne wpisy w tablicy rutingu i wykonuje bitowo logiczną operację AND na adresie i masce sieci, porównując adres docelowy z trasą. Czwarta kolumna zawiera następujące znaczniki opisujące trasę: G Trasa przez gateway. U Interfejs, który ma być użyty, jest aktywny. H Przez tę trasę można dostać się tylko do jednego hosta. Na przykład znacznik ten występuje w przypadku wpisu dla pętli zwrotnej 127.0.0.1. D Ta trasa jest tworzona dynamicznie. Znacznik jest ustawiany, jeżeli wpis w tablicy został stworzony przez demona rutingu, na przykład gated, lub przez komunikat przekierowania ICMP (zobacz podrozdział Internetowy protokół komunikatów kontrolnych (ICMP) w rozdziale 2). M Ten znacznik jest ustawiony, jeżeli wpis w tablicy został zmodyfikowany przez komunikat przekierowania ICMP. ! Ta trasa została odrzucona i datagramy do niej skierowane będą gubione. Kolejne trzy kolumny pokazują MSS, Window i irtt, czyli zmienne dotyczące połączeń TCP zrealizowanych w oparciu o daną trasę. MSS to maksymalny rozmiar segmentu (ang. maximum segment size); jest to rozmiar największego datagramu, jaki jądro może zbudować i wysłać tą trasą. Window to maksymalna liczba danych, jaką system przyjmie jednorazowo ze zdalnego hosta. Skrót irtt pochodzi od słów initial round trip time (wstępny czas przewidywany na transmisję i potwierdzenie przyjęcia). Protokół TCP zapewnia niezawodność dostarczania danych pomiędzy hostami, ponieważ ponownie wysyła datagram, jeżeli zostanie on zgubiony. Pilnuje też licznika mierzącego czas potrzebny na dostarczenie datagramu na drugi koniec i odebranie potwierdzenia. Na podstawie tego licznika wie, po jakim czasie należy dokonać ewentualnej ponownej transmisji datagramu. Proces ten jest nazywany czasem przewidywanym na transmisję i potwierdzenie przyjęcia (ang. round-trip time). Wstępny czas przewidywany na transmisję i potwierdzenie przyjęcia to wartość, jakiej protokół TCP używa, kiedy po raz pierwszy realizuje połączenie. W większości typów sieci domyślna wartość jest poprawna, ale w przypadku niektórych wolnych sieci, jak na przykład w pewnych typach sieci amatorskiego radia pakietowego, czas ten jest zbyt krótki i powoduje niepotrzebne retransmisje. Wartość irtt może być ustawiona za pomocą polecenia route. Wartości zero w tych polach oznaczają, że będzie używana wartość domyślna. No i ostatnie pole pokazuje interfejs sieciowy używany dla danej trasy. Wyświetlanie statystyk interfejsu Wywołanie netstat z opcją -i wyświetla statystyki obecnie skonfigurowanych interfejsów sieciowych. Jeżeli zostanie podana również opcja -a, wyświetlane są wszystkie interfejsy obecne w jądrze, a nie tylko te obecnie skonfigurowane. Na hoście vstout wynik polecenia netstat będzie wyglądał następująco: # netstat -i Kernel Interface table Iface MTU Met RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flags lo    0   0 3185       0      0      0  3185      0     0      0 BLRU eth0 1500   0 972633    17     20    120 628711   217     0      0 BRU Pola MTU i Met pokazują aktualnie ustalone wartości MTU i metryki dla danego interfejsu. Kolumny RX i TX pokazują, ile pakietów zostało odebranych albo wysłanych bezbłędnie (RX-OK/TX-OK), albo uszkodzonych (RX-ERR/TX-ERR), ile pakietów zostało zgubionych (RX-DRP/TX-DRP) oraz ile zostało zgubionych z powodu przeciążenia (RX-OVR/TX-OVR). Ostatnia kolumna pokazuje znaczniki, które zostały ustawione dla danego interfejsu. Litery te są skróconą wersją długich nazw znaczników wyświetlanych dla konfiguracji interfejsu przez ifconfig: B Został ustawiony adres rozgłoszeniowy. L Ten interfejs to urządzenie pętli zwrotnej. M Odbierane są wszystkie pakiety (tryb przechwytywania). O ARP dla interfejsu jest wyłączony. P Jest to połączenie punkt-punkt. R Interfejs działa. U Interfejs jest aktywny. Wyświetlanie połączeń netstat obsługuje zestaw opcji do wyświetlania aktywnych lub pasywnych gniazd. Opcje -t, -u, -w i -x pokazują aktywne połączenia TCP, UDP, RAW i gniazda Uniksa. Jeżeli ponadto podasz opcję -a, gniazda oczekujące na połączenie (tzn. nasłuchujące) także zostaną wyświetlone. W wyniku zobaczysz listę wszystkich serwerów, które aktualnie działają w twoim systemie. Wywołanie netstat -ta na hoście vlager da następujący wynik: $ netstat -ta Active Internet Connections Proto Recv-Q Send-Q Local Address   Foreign Address    (State) tcp        0    0 *:domain       *:*            LISTEN tcp        0    0 *:time       *:*            LISTEN tcp        0    0 *:smtp       *:*            LISTEN tcp        0    0 vlager:smtp   vstout:1040         ESTABLISHED tcp        0    0 *:telnet       *:*            LISTEN tcp        0    0 localhost:1046  vbardolino:telnet   ESTABLISHED tcp        0    0 *:chargen       *:*            LISTEN tcp        0    0 *:daytime       *:*            LISTEN tcp        0    0 *:discard       *:*            LISTEN tcp 0 0 *:echo *:* LISTEN tcp        0    0 *:shell       *:*            LISTEN tcp        0    0 *:login       *:*            LISTEN Widać, że większość serwerów po prostu oczekuje na nadchodzące połączenia. Jednak czwarta linia pokazuje przychodzące połączenie SMTP z hosta vstout, a szósta linia mówi, że istnieje wychodzące połączenie telnet do hosta vbardolino*. Użycie samej opcji -a wyświetli wszystkie gniazda ze wszystkich rodzin. Sprawdzanie tablic ARP W pewnych sytuacjach warto obejrzeć lub zmienić zawartość tablic ARP jądra. Przydaje się to, kiedy na przykład podejrzewasz, że zduplikowany adres internetowy jest powodem sporadycznych problemów z siecią. Narzędzie arp zostało stworzone do użycia w tego typu sytuacjach. Opcje wiersza poleceń arp są następujące: arp [-v] [-t typhw] -a [nazwahosta] arp [-v] [-t typhw] -s nazwahosta hwadres arp [-v] -d nazwahosta [nazwahosta...] Wszystkie argumenty nazwahosta mogą mieć postać symbolicznych nazw hostów lub adresów IP w notacji kropkowej. Pierwsze wywołanie wyświetla wpis ARP dla podanego adresu IP lub nazwy hosta albo wszystkich hostów, jeżeli nie zostanie podana nazwahosta. Na przykład wywołanie arp na hoście vlager może pokazać coś takiego: # arp -a IP address   HW type          HW address 172.16.1.3   10Mbps Ethernet   00:00:C0:5A:42:C1 172.16.1.2   10Mbps Ethernet   00:00:C0:90:B3:42 172.16.2.4   10Mbps Ethernet   00:00:C0:04:69:AA Są to adresy Ethernet hostów vlager, vstout i vale. Używając opcji -t, możesz ograniczyć wyświetlanie do zadanego typu karty. Może to być ether, ax25 albo pronet, czyli odpowiednio Ethernet 10 Mb/s, AMPR AX.25 i token ring IEEE 802.5. Opcja -s jest używana do dodawania na stałe w tablicy ARP adresu ethernetowego nazwyhosta. Argument hwadres określa adres sprzętowy, który domyślnie powinien być adresem Ethernet podanym w postaci sześciu liczb szesnastkowych oddzielonych dwukropkami. Za pomocą opcji -t możesz również ustawić adresy sprzętowe dla innych typów urządzeń. Zapytania ARP o zdalny host nie udają się czasem z różnych powodów. Na przykład gdy sterownik ARP jest błędny lub inny host w sieci błędnie identyfikuje się z adresem IP innego hosta. Problem ten wymaga ręcznego dodania adresu IP do tablicy ARP. Adresy IP na sztywno (ręcznie) wpisane w tablicy ARP są również (bardzo drastycznym) zabezpieczeniem przed tymi hostami w twojej sieci, które udają, że są kim innym. Wywołanie arp z opcją -d powoduje usunięcie wszystkich wpisów ARP dotyczących danego hosta. W ten sposób można wymusić na interfejsie ponowną próbę uzyskania adresu Ethernet związanego z danym adresem IP. Jest to przydatne, gdy błędnie skonfigurowany system rozgłosi złą informację ARP (oczywiście musisz najpierw przekonfigurować błędny host). Wspomniana powyżej opcja -s może być używana do implementacji serwera proxy ARP. Jest to specjalna technika, dzięki której host, powiedzmy gate, działa jako gateway dla innego hosta fnord udając, że oba adresy odnoszą się do tego samego hosta gate. W tym celu rozgłasza wpis ARP dla fnord wskazujący na jego własny interfejs Ethernet. Teraz gdy host wyśle zapytanie ARP o fnord, gate zwróci odpowiedź zawierającą jego własny adres Ethernet. Pytający host wyśle wszystkie datagramy do gate, który z kolei posłusznie przekaże je do fnord. Taki mechanizm może być potrzebny, gdy chcesz się dostać do fnord z komputera DOS-owego z niepoprawną implementacją TCP, niezbyt dobrze rozumiejącą ruting. Gdy użyjesz proxy ARP, maszyna DOS-owa będzie widziała fnord tak, jakby był on w lokalnej podsieci, a więc nie będzie musiała rutować pakietów przez gateway. Proxy ARP przydaje się też, gdy jeden z twoich hostów działa tymczasowo jako gateway dla innego hosta, na przykład połączonego przez łącze komutowane. W jednym z poprzednich przykładów spotkaliśmy się z laptopem vlite, który był czasem podłączony do vlagera przez łącze PLIP. Oczywiście protokół zadziała tylko wtedy, jeżeli adres hosta, dla którego chcesz realizować proxy ARP, znajduje się w tej samej podsieci IP co gateway. vstout może pełnić rolę proxy ARP dla dowolnego hosta w podsieci browaru (172.16.1.0), ale nie może dla hostów w podsieci winiarni (172.16.2.0). Poniżej pokazujemy poprawne wywołanie tworzące proxy ARP dla fnord. Oczywiście podany adres Ethernet musi być adresem gate'a: # arp -s fnord 00:00:c0:a1:42:e0 pub Wpis proxy ARP może zostać usunięty przez ponowne wywołanie: # arp -d fnord 6 Usługi nazewnicze i konfigurowanie resolvera Rozdział 6: Usługi nazewnicze i konfigurowanie resolvera Jak powiedzieliśmy w rozdziale 2, Wybrane problemy sieci TCP/IP, w sieci TCP/IP mogą funkcjonować różne schematy konwersji nazw na adresy. Najprostszym rozwiązaniem jest tablica hostów zapisana w pliku /etc/hosts. Sprawdza się ona jedynie w małych sieciach LAN, które są pod opieką jednego administratora albo nie obsługują ruchu IP do świata zewnętrznego. Format pliku hosts został już opisany w rozdziale 5, Konfigurowanie sieci TCP/IP. Idąc dalej, do zamiany nazw hostów na adresy IP możesz użyć usługi z BIND (Berkeley Internet Name Domain Service - internetowe usługi nazewnicze domen z Berkeley). Konfigurowanie BIND-a bywa przykre, ale jak już to zrobisz, łatwo wprowadzisz każdą zmianę w topologii sieci. W Linuksie, jak i w wielu innych systemach uniksowych, usługi nazewnicze są obsługiwane przez program o nazwie named. Przy uruchamianiu ładuje on zestaw głównych plików do swojej pamięci wewnętrznej i czeka na zapytania od lokalnych lub zdalnych procesów użytkownika. Istnieją różne sposoby skonfigurowania BIND-a i nie wszystkie wymagają uruchamiania serwera nazw na każdym hoście. Chcielibyśmy, aby ten rozdział był czymś więcej niż pobieżnym szkicem na temat DNS-u i obsługi serwera nazw. Informacje tu podane powinny wystarczyć, jeżeli masz małą sieć lokalną i połączenie z Internetem. Najświeższe informacje znajdziesz w dokumentacji zamieszczonej w pakiecie źródłowym BIND, który zawiera strony podręcznika elektronicznego, uwagi do danej wersji oraz Podręcznik operatora BIND (BIND Operator's Guide - BOG). Nie pozwól, by ta nazwa cię odstraszyła. W praktyce jest to bardzo użyteczny dokument. Pełniejszy opis DNS-u i związanych z nim zagadnień możesz znaleźć w książce DNS and BIND autorstwa Paula Albitza i Cricketa Liu (wyd. pol.: DNS i BIND, Wydawnictwo RM, Warszawa 1999), która stanowi doskonałe źródło informacji na ten temat. Odpowiedzi na pytania na temat DNS-u możesz znaleźć w wiadomościach grupy dyskusyjnej comp.protocols.tcp-ip.domains. Szczegóły techniczne DNS-u są zdefiniowane w następujących dokumentach RFC: 1033, 1034 i 1035. Biblioteka resolvera Określenie resolver nie odnosi się do jakiejś szczególnej aplikacji, ale do biblioteki resolvera. Jest to zbiór funkcji, które można znaleźć w standardowej bibliotece C. Podstawowe procedury to gethostyname(2) i gethostbyaddr(2), poszukujące adresów IP związanych z daną nazwą hosta i odwrotnie. Mogą być skonfigurowane tak, aby po prostu szukać informacji w pliku hosts, albo zadawać zapytania do serwerów nazw DNS, albo też korzystać z bazy danych hosts NIS-a. Funkcje resolvera odczytują pliki konfiguracyjne w momencie, gdy są wywoływane. Na ich podstawie ustalają, którą bazę danych zapytać i w jakiej kolejności, oraz dowiadują się innych szczegółów na temat konfiguracji środowiska. Starsza standardowa biblioteka, libc, w Linuksie wykorzystywała plik /etc/host.conf jako główny plik konfiguracyjny, ale wersja 2. standardowej biblioteki GNU, glibc, wykorzystuje plik /etc/nsswitch.conf. Opiszemy kolejno każdy z nich, ponieważ oba są powszechnie używane. Plik host.conf Plik /etc/host.conf mówi funkcjom resolvera ze starszej biblioteki standardowej w Linuksie, jakich usług używać i w jakiej kolejności. Opcje w pliku host.conf trzeba umieszczać w oddzielnych wierszach. Pola mogą być oddzielone białymi znakami (spacjami lub tabulatorami). Znak hasha (#) oznacza linię z komentarzem. Dostępne są następujące opcje: order Ta opcja określa kolejność, w jakiej wypróbowane są usługi. Dopuszczalne opcje to: bind dla zapytań serwera nazw, hosts dla sprawdzania pliku /etc/hosts i nis dla zapytań NIS. Można podać jedną opcję lub wszystkie. Kolejność przepytywania (sprawdzania) usług zależy od uporządkowania opcji w wierszu. multi multi może posiadać opcje on lub off. Określa, czy host wpisany do pliku /etc/hosts może mieć kilka adresów IP. Domyślna wartość to off. Znacznik nie ma wpływu na zapytania do DNS-u czy NIS-a. nospoof Jak wyjaśnimy dalej w podrozdziale Wyszukiwanie odwrotne, DNS pozwala na znalezienie nazwy hosta związanej z danym adresem IP za pomocą domeny in-addr.arpa. Próbę dostarczenia przez serwery nazw fałszywej nazwy hosta nazywa się spoofingiem. Aby się przed tym obronić, resolver można skonfigurować tak, żeby sprawdzał, czy oryginalny adres IP faktycznie jest związany z uzyskaną nazwą hosta. Jeżeli nie, nazwa jest odrzucana i zwracany jest błąd. Zachowanie to jest włączane przez ustawienie nospoof. alert Ta opcja przyjmuje parametry on lub off. Jeżeli jest włączona, próby spoofingu skończą się tym, że resolver zapisze komunikat za pomocą funkcji syslog. trim Jako argument tej opcji występuje nazwa domeny, usuniętej z nazw hostów przed rozpoczęciem wyszukiwania. Jest to przydatne dla wpisów w pliku hosts, w których chcesz podawać same nazwy hosta, bez lokalnej domeny. Jeżeli podasz swoją domenę lokalną, zostanie ona usunięta przy poszukiwaniu hosta z dodaną nazwą domeny lokalnej, co pozwala na poprawne wyszukiwanie w pliku /etc/hosts. Nazwa domeny, którą podajesz, musi kończyć się kropką (na przykład linux.org.au.), jeżeli trim ma działać poprawnie. Opcje trim łączą się ze sobą. Możesz sprawić, że twój host będzie uznawany za lokalny w kilku domenach. W przykładzie 6-1 pokazano plik host.conf dla hosta vlager. Przykład 6-1. Przykładowy plik host.conf # /etc/host.conf # named działa, ale nie mamy NIS-a (jeszcze) order bind,hosts # Pozwalamy na wielokrotne adresy multi on # Zabezpieczamy się przed próbami spoofingu nospoof on # obcinamy domenę lokalną (nie jest to naprawdę niezbędne). trim vrew.com. Zmienne środowiskowe resolvera Ustawienia w pliku host.conf mogą być zmienione za pomocą szeregu zmiennych środowiskowych: RESOLV_HOST_CONF Ta zmienna określa, jaki plik ma być czytany zamiast /etc/host.conf. RESOLV_SERV_ORDER Ta zmienna unieważnia opcję order zawartą w pliku host.conf. Usługi są podawane jako hosts, bind i nis, oddzielone spacjami, przecinkami, dwukropkami lub średnikami. RESOLV_SPOOF_CHECK Ta zmienna określa stopień ochrony przed spoofingiem. Podanie off wyłącza tę opcję. Wartości warn i warn off włączają sprawdzanie spoofingu, odpowiednio, przez włączenie i wyłącznie logowania. Wartość* włącza sprawdzanie spoofingu, ale pozostawia funkcję logowania zgodnie z tym, co jest zdefiniowane w pliku host.conf. RESOLV_MULTI Ta zmienna pozwala na podanie wartości on lub off i unieważnia opcję multi z pliku host.conf. RESOLV_OVERRIDE_TRIM_DOMAINS Ta zmienna określa listę domen, które mają być obcinane, i unieważnia te podane w pliku host.conf. Obcinanie domen omówiliśmy wcześniej, przy opisie słowa kluczowego trim. RESOLV_ADD_TRIM_DOMAINS Ta zmienna określa listę obcinanych domen, dodawaną do listy podanej w pliku host.conf. Plik nsswitch.conf Wersja 2. standardowej biblioteki GNU oferuje wydajniejszy i bardziej elastyczny mechanizm, który zastępuje starszy plik host.conf. Pojęcie usługi nazewniczej zostało rozszerzone tak, że obecnie jej plik zawiera wiele różnych informacji. Opcje konfiguracyjne dla różnych funkcji zadających zapytania do jej baz danych zostały z powrotem umieszczone w jednym pliku konfiguracyjnym o nazwie nsswitch.conf. Plik nsswitch.conf pozwala administratorowi systemu skonfigurować szereg różnych baz danych. Ograniczymy omówienie do opcji związanych z rozwiązywaniem adresów IP hostów i sieci. Więcej informacji na temat innych funkcji możesz znaleźć w dokumentacji standardowej biblioteki GNU. Opcje w pliku nsswitch.conf muszą występować w oddzielnych wierszach. Pola mogą być oddzielone białymi znakami (spacjami lub tabulatorami). Znak hasha (#) oznacza komentarz, który ciągnie się do następnego wiersza. Każdy wiersz opisuje określoną usługę - jedną z nich jest rozwiązywanie nazwy hosta. Pierwsze pole w każdym wierszu to nazwa bazy danych kończąca się dwukropkiem. Nazwa bazy związanej z rozwiązywaniem adresów hostów to hosts. Inna, związana z usługą nazewniczą baza to networks; służy do zamiany nazw sieci na ich adresy. Pozostała część każdego wiersza zawiera opcje określające sposób wyszukiwania w bazie danych. Dostępne są następujące opcje: dns Użycie systemu nazw domen (DNS) do rozwiązywania adresów. Ma to sens jedynie przy rozwiązywaniu adresów hostów, a nie sieci. Mechanizm ten wykorzystuje plik /etc/resolv.conf, opisany w dalszej części tego rozdziału. files Przeszukiwanie pliku lokalnego w poszukiwaniu nazwy hosta lub sieci i odpowiadających im adresów. Ta opcja wykorzystuje tradycyjne pliki /etc/hosts i /etc/ networks. nis lub nisplus Użycie systemu informacji sieciowej (NIS) do rozwiązywania adresów hostów lub sieci. NIS i NIS+ zostały szczegółowo omówione w rodziale 13, System informacji sieciowej. Kolejność, w jakiej są podane, decyduje o porządku zadawania zapytań o rozwiązanie nazwy. Lista kolejności zapytań znajduje się w opisie usługi umieszczonym w pliku /etc/nsswitch.conf. Usługi są zapytywane od lewej do prawej. Domyślnie poszukiwanie kończy się, gdy rozwiązanie nazwy się powiedzie. W przykładzie 6-2 pokazujemy prosty plik, naśladujący naszą konfigurację wykorzystującą starszą bibliotekę standardową libc. Przykład 6-2.?Przykładowy plik nsswitch.conf # /etc/nsswitch.conf # # Przykładowa konfiguracja funkcjonalności GNU Name Service Switch. # Informacje o tym pliku są dostępne w pakiecie 'libc6-doc'. hosts:       dns files networks:      files Zapis taki jak w powyższym przykładzie oznacza, że system poszukuje hostów najpierw przez system nazw domen, a następnie, jeżeli to się nie uda, w pliku /etc/hosts. Poszukiwanie nazw sieci będzie realizowane tylko w oparciu o plik /etc/networks. Możesz bardziej precyzyjnie sterować poszukiwaniami, jeśli skorzystasz z "elementów działania". Podpowiadają one kolejne kroki na podstawie wyników uzyskanych w poprzedniej próbie wyszukiwania. Elementy działania znajdują się pomiędzy specyfikacjami usług i są otoczone nawiasami kwadratowymi []. Ogólna składnia dyrektywy działania jest następująca: [ [!] status = działanie ... ] Istnieją dwa możliwe działania: return Powoduje powrót do programu, który próbował rozwiązać nazwę. Jeżeli próba wyszukiwania się powiodła, resolver zwróci szczegółowe informacje, a w przeciwnym razie zwróci zero. continue Resolver przejdzie do kolejnej usługi na liście i spróbuje za jej pomocą znaleźć nazwę. Opcjonalny znak wykrzyknika (!) mówi, że status powinien być odwrócony przed wykonaniem testu, czyli oznacza "nie". Dopuszczalne wartości statusu, na których możemy operować to: success Żądany adres został znaleziony bez błędu. Domyślne działanie dla tego statusu to return. notfound W wyszukiwaniu nie wystąpił błąd, ale poszukiwany host lub sieć nie mogą być znalezione. Domyślne działanie dla tego statusu to continue. unavail Usługa, do której zostało zadane zapytanie, jest niedostępna. Może to oznaczać, że plik hosts lub networks jest nieczytelny dla usługi files lub że serwer nazw albo serwer NIS nie odpowiadają na usługę dns lub nis. Domyślne działanie dla tego statusu to continue. tryagain Ten status mówi, że usługa jest tymczasowo niedostępna. W przypadku usługi files zwykle oznacza to, że dany plik jest zablokowany przez inny proces. W przypadku innych usług może to oznaczać tymczasową niemożność przyjęcia połączenia. Domyślne działanie dla tego statusu to continue. Prostą ilustrację wykorzystania tego mechanizmu stanowi przykład 6-3. Przykład 6-3.?Przykładowy plik nsswitch.conf wykorzystujący dyrektywę działania # /etc/nsswitch.conf # # Przykładowa konfiguracja funkcjonalności GNU Name Service Switch. # Informacje o tym pliku są dostępne w pakiecie 'libc6-doc'. hosts:       dns [!UNAVAIL=return] files networks:      files W tym przykładzie próbujemy znaleźć nazwę hosta za pomocą systemu usług nazewniczych domen. Jeżeli tylko zwrócony status nie oznacza niedostępności, resolver zwraca to, co znalazł. Jeżeli próba zapytania DNS zwróciła status niedostępności (wyłącznie w tym przypadku), resolver próbuje użyć lokalnego pliku /etc/hosts. Oznacza to, że powinniśmy użyć pliku hosts tylko wtedy, gdy nasz serwer nazw z jakiegoś powodu jest niedostępny. Konfigurowanie poszukiwania przez serwer nazw za pomocą pliku resolv.conf Gdy konfigurujesz bibliotekę resolvera do korzystania z usługi nazewniczej BIND przy rozwiązywaniu nazw, musisz także wskazać serwery nazw, które mają być używane. Do tego celu służy oddzielny plik resolv.conf. Jeżeli plik ten nie istnieje lub jest pusty, resolver zakłada, że serwer nazw znajduje się na twoim hoście lokalnym. Aby uruchomić serwer nazw na hoście lokalnym, musisz go oddzielnie skonfigurować, co wyjaśniamy w kolejnym podrozdziale. Jeżeli pracujesz w sieci lokalnej i masz możliwość wykorzystania istniejącego serwera nazw, nie omieszkaj tak zrobić. Jeżeli używasz komutowanego połączenia IP z Internetem, w pliku resolv.conf zwykle podajesz serwer nazw twojego dostawcy Internetu. Najważniejszą opcją w pliku resolv.conf jest name server, zawierająca adres tego serwera nazw, który ma być używany. Jeżeli podasz kilka serwerów nazw, wpisując kilkukrotnie opcję name server, będą one sprawdzane w zadanej kolejności. W związku z tym najbardziej niezawodne serwery powinieneś umieszczać na początku. Bieżąca implementacja pozwala ci na umieszczenie w pliku resolv.conf trzech dyrektyw name server. Jeżeli nie zostanie podana opcja name server, resolver podejmie próbę połączenia z serwerem nazw na hoście lokalnym. Dwie pozostałe opcje to domain i search, pozwalające na stosowanie skróconych nazw hostów w domenie lokalnej. Zwykle jeśli łączysz się za pomocą telnetu z innym hostem w domenie lokalnej, nie musisz wpisywać pełnej nazwy. Wystarczy podać tylko nazwę krótką typu gauss. Resolver skojarzy ją z pozostałą częścią nazwy: mathematics.groucho.edu. Tak właśnie działa dyrektywa domain. Pozwala podać domyślną nazwę domeny, która ma być dodawana, gdy DNS nie znajdzie nazwy hosta. Na przykład, gdy podamy nazwę gauss, resolver nie znajdzie jej w DNS-ie, ponieważ nie ma takiej domeny podstawowej. Gdy jako domenę domyślną wskażemy mathematics.groucho.edu, resolver powtórzy zapytanie o gauss. Tym razem wyszukiwanie się powiedzie. Pewnie ci się to podoba, ale kiedy wyjdziesz poza domenę wydziału matematyki, musisz powrócić do pełnych nazw domen. Oczywiście chciałbyś mieć również skróty, takie jak quark.physics dla hostów z domeny wydziału fizyki. Tu z pomocą przychodzi lista przeszukiwania. Można ją podać za pomocą opcji search, która jest uogólnieniem dyrektywy domain. Ta druga umożliwia wprowadzenie pojedynczej domeny domyślnej, natomiast ta pierwsza pozwala na podanie listy domen, które będą po kolei sprawdzane, aż poszukiwanie zakończy się powodzeniem. Elementy listy muszą być oddzielone spacjami lub tabulatorami. Dyrektywy search i domain wzajemnie się wykluczają i nie mogą pojawić się w pliku więcej niż raz. Jeżeli zostanie podana któraś z opcji, resolver będzie próbował odgadnąć domyślną domenę na podstawie nazwy lokalnego hosta za pomocą wywołania systemowego getdomainname(2). Jeżeli nazwa hosta lokalnego nie zawiera nazwy domeny, przyjmowana jest domena główna (ang. root domain). Jeżeli zdecydujesz się umieścić dyrektywę search w pliku resolv.conf, powinieneś uważać na to, jakie domeny dodajesz do listy. Biblioteki resolvera wcześniejsze niż BIND 4.9 tworzyły domyślną listę przeszukiwania na podstawie nazwy domeny, jeżeli lista nie została podana. Domyślna lista składała się z samej domeny domyślnej oraz wszystkich jej domen nadrzędnych, aż do domeny głównej. Powodowało to pewne problemy, ponieważ zapytania DNS kończyły się na serwerach nazw, do których nigdy nie powinny dotrzeć. Załóżmy, że jesteś w browarze wirtualnym i chcesz zalogować się do foot.groucho.edu. Przypuśćmy, że omsknął ci się palec i wpisałeś foo zamiast foot, czyli podałeś nazwę hosta, która nie istnieje. Serwer nazw GMU powie ci, że nie zna takiego hosta. W przypadku listy poszukiwań starego typu, resolver próbowałby dołączać do nazwy hosta nazwy vbrew.com i com. Ta ostatnia nazwa może być problematyczna, ponieważ domena groucho.edu.com może istnieć naprawdę. Co więcej, być może w tej domenie serwer znajdzie jakiegoś hosta foo i wskaże nie na to, co potrzeba. Takie fałszywe wyniki poszukiwań mogą zagrażać systemowi bezpieczeństwa niektórych aplikacji. Dlatego zwykle powinieneś zawężać domeny na twojej liście poszukiwań do swojej lokalnej organizacji lub czegoś w tym rodzaju. Na wydziale matematyki uniwersytetu Groucho Marx lista poszukiwań powinna być skonfigurowana na maths.groucho.edu i groucho.edu. Jeżeli zrozumienie domyślnych domen sprawia ci kłopot, przyjrzyj się poniższemu przykładowi pliku resolv.conf dla wirtualnego browaru: # /etc/resolv.conf # Nasza domena domain vbrew.com # # Jako głównego serwera nazw używamy vlager name server 172.16.1.1 Przy rozwiązywaniu nazwy vale, resolverowi nie uda się znaleźć vale, ale znajdzie vale.vbrew.com. Siła resolvera Jeżeli obsługujesz sieć lokalną w obrębie dużej sieci, zdecydowanie powinieneś korzystać z głównych serwerów nazw, jeżeli takie są dostępne. Serwery nazw mają obszerną pamięć podręczną, która przyspiesza odpowiedzi na powtórne zapytania, a wszystkie zapytania są kierowane właśnie do tych serwerów. Jednak ten model ma jedną wadę: gdyby ogień zniszczył kabel szkieletu na uniwersytecie Olafa, nie można byłoby pracować w wydziałowej sieci LAN, ponieważ resolver nie mógłby się skomunikować z żadnym z serwerów nazw. Taka sytuacja powoduje trudności z większością usług sieciowych, takich jak logowanie się z X terminali czy drukowanie. Choć niezbyt często zdarza się, że sieci szkieletowe campusu płoną, to warto zabezpieczyć się przed takim wypadkiem. Jednym z rozwiązań jest skonfigurowanie lokalnego serwera nazw, który rozwiązuje nazwy z domeny lokalnej i przekazuje wszystkie zapytania o inne hosty do głównych serwerów. Oczywiście ma to sens jedynie wtedy, gdy posiadasz własną domenę. Alternatywą może być utrzymywanie zapasowej listy hostów dla twojej domeny czy sieci lokalnej w pliku /etc/hosts. Można to zrobić bardzo łatwo. Po prostu konfigurujemy bibliotekę resolvera tak, aby w pierwszej kolejności zadawała zapytania do DNS-u, a następnie sprawdzała plik hostów. W pliku /etc/host.conf powinieneś wpisać: order bind hosts, a w pliku /etc/nsswitch.conf: hosts: dns files. W ten sposób resolver wykorzysta plik hostów, jeżeli główny serwer nazw będzie nieosiągalny. Jak działa DNS DNS porządkuje nazwy hostów w hierarchii domen. Domena to zbiór ośrodków maszyn, które są jakoś powiązane ze sobą. Na przykład tworzą sieć (tak jak wszystkie maszyny w campusie lub wszystkie hosty sieci BITNET), lub należą do pewnej organizacji (np. rządu Stanów Zjednoczonych), lub leżą blisko siebie. Na przykład uniwersytety są zwykle grupowane w domenie edu, a każdy uniwersytet czy college używa oddzielnej poddomeny, w której są zebrane jego hosty. Uniwersytet Groucho Marx posiada domenę groucho.edu, natomiast sieć lokalna wydziału matematyki znajduje się w poddomenie maths.groucho.edu. W nazwach hostów z sieci wydziału powinny znajdować się domeny, a więc erdos będzie znany jako erdos. maths.groucho.edu. Taka nazwa to pełna nazwa domenowa zwykle identyfikująca dany host w skali świata. Rysunek 6-1 pokazuje podział przestrzeni nazw. Wpis u góry drzewa, po prostu kropka, jest nazywany domeną główną (ang. root domain) i obejmuje wszystkie pozostałe domeny. Aby pokazać, że nazwa hosta jest pełną nazwą domenową, a nie nazwą względną dla jakiejś (ukrytej) domeny lokalnej, czasem jest ona pisana z kropką na końcu. Kropka ta oznacza, że ostatnim członem nazwy jest domena główna. W zależności od położenia nazwy w hierarchii, domena może być nazywana domeną najwyższego poziomu, drugiego poziomu lub trzeciego poziomu. Poziomów jest jeszcze więcej, ale rzadko są używane. Poniższa lista pokazuje te kilka domen najwyższego poziomu, z którymi często się możesz spotkać: Domena Opis edu (Głównie w USA) Instytucje edukacyjne, na przykład uniwersytety. com Organizacje i firmy komercyjne. org Organizacje niekomercyjne. Prywatne sieci UUCP często należą do tej domeny. net Gatewaye i inne hosty administracyjne w sieci. mil Amerykańskie instytucje wojskowe. gov Amerykańskie instytucje rządowe. uucp Oficjalnie, wszystkie nazwy wcześniej używane jako nazwy UUCP bez domen zostały przeniesione do tej domeny. Historycznie pierwsze cztery domeny były przypisane Stanom Zjednoczonym, ale ostatnio w praktyce nazewniczej kładzie się nacisk na globalny charakter tych domen, również w znaczeniu terytorialnym, bo przecież są domenami globalnymi najwyższego rzędu (ang. global Top Level Domains - gTLD). Prowadzone są negocjacje na temat rozszerzenia zakresu gTLD, co może zaowocuje większymi możliwościami wyboru w przyszłości. Poza Stanami Zjednoczonymi, każdy kraj używa domeny najwyższego poziomu w postaci własnego dwuliterowego kodu kraju zdefiniowanego w normie ISO-3166. Na przykład Finlandia używa domeny fi; fr to domena dla Francji, de dla Niemiec, zaś au dla Australii. Na pozostałych poziomach hierarchii (tych poniżej domeny najwyższego poziomu), organizacja NIC każdego kraju może porządkować nazwy hostów dowolnie. Australia posiada domeny drugiego poziomu podobne do międzynarodowych domen najwyższego poziomu, czyli com.au i edu.au. Inne kraje, na przykład Niemcy, nie wykorzystują tego dodatkowego poziomu, a raczej wydłużają nazwę odnoszącą się bezpośrednio do firmy, z którą jest związana dana domena. Nie jest niczym niezwykłym spotkanie domeny ftp.informatik.uni-enlargen.de. Ale to już sprawa Niemców. Rysunek 6-1. Fragment przestrzeni nazw domen http://www.rm.com.pl/upgr/lpas/06-01.tif Oczywiście takie domeny narodowe nie oznaczają, że host w danej domenie znajduje się fizycznie w danym kraju - oznacza to jedynie, że host został zarejestrowany w organizacji NIC danego kraju. Na przykład załóżmy, że szwedzki przemysłowiec ma filię swojej firmy w Australii, ale wszystkie hosty pracujące w tej filii mogą być zarejestrowane w domenie najwyższego poziomu se. Uporządkowanie przestrzeni nazw w hierarchii nazw domen to eleganckie rozwiązanie problemu niepowtarzalności nazw. W DNS-ie wystarczy, że nazwa hosta będzie unikatowa we własnej domenie, a pozostanie taka na całym świecie. Co więcej, pełne nazwy domenowe są łatwe do zapamiętania. Już te kilka faktów przemawia za podziałem dużej domeny na kilka domen podrzędnych. DNS daje ci jeszcze więcej możliwości. Pozwala także na przekazywanie władzy nad poddomenami ich administratorom. Na przykład osoby obsługujące centrum komputerowe uniwersytetu Groucho Max mogą stworzyć poddomenę dla każdego wydziału. Już spotkaliśmy poddomeny math i physics. Kiedy stwierdzą, że sieć na wydziale fizyki jest zbyt duża i trudno nią zarządzać z zewnątrz (w końcu wiadomo, że fizycy to niesforna grupa ludzi), mogą po prostu przekazać kontrolę nad domeną physics.groucho.edu administratorom tej sieci. Administratorzy będą mieli prawo nazywać hosty, jak chcą, i przypisywać adresy IP z ich sieci w dowolnie wybrany przez siebie sposób, bez konieczności uwzględniania jakichkolwiek sugestii z zewnątrz. W tym celu przestrzeń nazw jest podzielona na strefy (ang. zones) oparte na domenach. Zwróć uwagę na subtelną różnicę pomiędzy strefą a domeną: domena groucho.edu zawiera wszystkie hosty z uniwersytetu Groucho Marx, natomiast strefa groucho.edu zawiera jedynie hosty zarządzane bezpośrednio przez centrum komputerowe - na przykład te na wydziale matematyki. Hosty na wydziale fizyki należą do innej strefy, a mianowicie physics.groucho.edu. Na rysunku 6-1 początek strefy jest zaznaczony małym kółkiem przy nazwie domeny. Poszukiwanie nazw w DNS-ie Na pierwszy rzut oka wydaje się, że cały ten podział na domeny i strefy bardzo komplikuje rozwiązywanie nazw. W zasadzie, jeżeli żadna władza centralna nie kontroluje przypisywania nazw hostom, to skąd ma je znać skromna aplikacja? Teraz przejdźmy do naprawdę pomysłowej części DNS-u. Gdybyś chciał znaleźć adres IP hosta erdos, DNS powiedziałby: "Idź, zapytaj ludzi, którzy go obsługują, a oni ci powiedzą". W rzeczywistości DNS to gigantyczna rozproszona baza danych. Jest zaimplementowana w postaci tak zwanych serwerów nazw, które dostarczają informacji o zadanej domenie lub zestawie domen. Każda strefa ma przynajmniej dwa (lub kilka) serwerów nazw, które są źródłem wszelkich informacji o hostach z tej strefy. Aby uzyskać adres IP erdosa, wystarczy skontaktować się z serwerem nazw w strefie groucho.edu, a on zwróci ci wymagane dane. Możesz pomyśleć: łatwo się mówi, ale trudniej to zrobić. Skąd mam wiedzieć, jak znaleźć serwer nazw uniwersytetu Groucho? Jeżeli twój komputer nie jest wyposażony w wyrocznię, znajdującą adresy, może za nią posłużyć także DNS. Gdy twoja aplikacja chce znaleźć informacje o erdosie, kontaktuje się z lokalnym serwerem nazw, który na jej rzecz wykonuje tak zwane zapytania iteracyjne. Rozpoczyna od wysyłania zapytania o adres erdos.maths.groucho.edu do serwera nazw domeny głównej. Serwer nazw domeny głównej rozpoznaje, że nazwa nie należy do strefy będącej w jego władzy, ale należy do domeny edu. Odpowiada naszemu serwerowi nazw, żeby w celu uzyskania dokładniejszych informacji, skontaktował się z serwerem nazw strefy edu, i wysyła listę wszystkich serwerów nazw edu wraz z ich adresami. Twój lokalny serwer nazw działa dalej i wysyła zapytanie do jednego z poleconych serwerów, na przykład a.isi.edu. Podobnie jak serwer nazw domeny głównej, tak i a.isi.edu wie, że ludzie z grouche.edu mają własną strefę i wskazuje ich serwery. Lokalny serwer nazw następnie kieruje zapytanie o erdosa do jednego z nich, który z kolei ostatecznie identyfikuje nazwę jako należącą do jego strefy i zwraca odpowiadający jej adres IP. Wygląda na to, że aby znaleźć jeden marny adres IP, trzeba wygenerować spory ruch, ale to i tak nic w porównaniu z liczbą danych, jaka musiałaby być przesyłana, gdybyśmy wciąż korzystali z pliku HOSTS.TXT. Schemat ten jednak daje się udoskonalić. Aby skrócić czas odpowiedzi na przyszłe zapytania, serwer nazw zapisuje uzyskane informacje w lokalnej pamięci podręcznej. Tak więc, jeżeli ktoś z twojej sieci lokalnej będzie chciał znowu znaleźć adres hosta w domenie groucho.edu, twój serwer nazw skontaktuje się bezpośrednio z serwerem nazw w tej domenie*. Oczywiście serwer nazw nie będzie przechowywał tej informacji wiecznie. Po jakimś czasie ją usunie. Czas jej przechowywania jest nazywany czasem życia (ang. time to live), w skrócie TTL. Wszystkim danym w DNS-ie administrator danej strefy przypisuje TTL. Typy serwerów nazw Serwery nazw, które przechowują wszystkie informacje o hostach z danej strefy, są nazywane autorytatywnymi (ang. authoritative servers) dla tej strefy, a czasami głównymi serwerami nazw (ang. master name servers). Wszelkie zapytania o hosta w danej strefie docierają w końcu do serwerów głównych. Serwery główne muszą być doskonale zsynchronizowane. Tak więc administrator strefy musi stworzyć jeden serwer podstawowy (ang. primary), który ładuje informacje o strefie z plików z danymi, i serwery zapasowe (ang. secondary), które przesyłają dane o strefie z serwera podstawowego w równych odstępach czasu. Dobrze jest mieć kilka serwerów nazw, gdyż można równomiernie rozłożyć obciążenie i zagwarantować lepszą niezawodność. Gdy jedna z maszyn, na której działa serwer nazw w łagodny sposób przestanie działać, na przykład system operacyjny ulegnie awarii lub straci połączenie z siecią, wszystkie zapytania będą kierowane do innych serwerów. Oczywiście taki schemat nie zabezpiecza przed pomyłkami (wynikającymi z błędów w oprogramowaniu lub w samym programie serwera), które powodują błędne odpowiedzi na wszystkie zapytania DNS. Możesz także uruchomić serwer nazw, który nie jest autorytatywny dla danej domeny**. Jest to przydatne, gdyż taki serwer będzie w stanie realizować zapytania DNS dla aplikacji działających w sieci lokalnej i zatrzyma informacje w pamięci podręcznej. Stąd serwery takie są nazywane serwerami pamięci podręcznej (ang. caching-only servers). Baza danych DNS Widzieliśmy, że DNS nie tylko podaje adresy IP hostów, ale także wymienia informacje na temat serwerów nazw. Bazy danych DNS mogą mieć w praktyce wiele różnych typów wpisów. Pojedyncza porcja informacji z bazy DNS nazywa się rekordem zasobu (ang. resource record - RR). Każdy rekord przynależy do jakiegoś typu i klasy rekordów. Typ opisuje rodzaj danych reprezentowanych w rekordzie. Natomiast klasa określa rodzaj sieci, jakiej dotyczy. Klasa służy do obsługi różnych schematów adresowania, jak adresy IP (klasa IN), adresy Hesiod (używane przez system Kerberos MIT) i kilka innych. Prototypowym rekordem zasobu jest rekord A wiążący pełną nazwę domenową z adresem IP. Host może być znany pod więcej niż jedną nazwą. Na przykład możesz mieć komputer, który posiada serwery FTP i WWW dostępne pod dwoma nazwami: ftp.machine.org i www.machine.org. Jednak jedna z tych nazw musi być oficjalną lub kanoniczną nazwą hosta, natomiast pozostałe są po prostu jej aliasami. Różnica polega na tym, że kanoniczna nazwa hosta jest związana z rekordem A, natomiast pozostałe mają jedynie rekord typu CNAME, wskazujący na nazwę kanoniczną. Nie będziemy tu przedstawiać wszystkich typów rekordów, ale podamy krótki przykład. Przykład 6-4 pokazuje część bazy danych domeny, która jest ładowana do serwerów nazw dla strefy physics.groucho.edu. Przykład 6-4. Fragment pliku named.hosts wydziału fizyki ; Authoritative Information on physics.groucho.edu. @  IN SOA niels.physics.groucho.edu. janet.niels.physics.groucho.edu {       1999090200    ; numer wersji       360000       ; odświeżanie 3600 ; ponowna próba 3600000       ; wygaśnięcie 3600 ; domyślny ttl } ; ; serwery nazw       IN   NS   niels       IN   NS   gauss.maths.groucho.edu. gauss.maths.groucho.edu. IN A 149.76.4.23 ; ; fizyka teoretyczna (podsieć 12) niels    IN   A   149.76.12.1       IN   A   149.76.1.12 name server   IN CNAME   niels otto       IN   A   149.76.12.2 quark    IN   A   149.76.12.4 down       IN   A   149.76.12.5 strange    IN   A   149.76.12.6 ... ; Laboratorium Collider (podsieć 14) boson    IN   A   149.76.14.1 muon       IN   A   149.76.14.7 bogon    IN   A   149.76.14.12 ... Poza rekordami A i CNAME, możesz zobaczyć na początku pliku specjalny rekord zajmujący kilka wierszy. Jest to rekord zasobów SOA (lub krócej: rekord SOA); SOA to skrót od angielskiego start of authority - początek władzy). Rekord ten zawiera ogólne informacje o strefie, dla której serwer jest autorytatywny i składa się między innymi z domyślnego czasu życia odnoszącego się do wszystkich rekordów. Zauważ, że wszystkie nazwy w pliku przykładowym, które nie kończą się kropką, powinny być interpretowane względem domeny physics.groucho.edu. Nazwa specjalna (@) użyta w przykładowym rekordzie SOA odnosi się do samej nazwy domeny. Wcześniej zauważyliśmy, że serwery nazw domeny groucho.edu skądś wiedzą o strefie physics, tak że mogą zadawać pytania do jej serwerów nazw. Zwykle robi się to za pomocą pary rekordów: rekordu NS, który podaje pełną nazwę domenową serwera, i rekordu A, który wiąże adres z tą nazwą. Ponieważ te rekordy wiążą przestrzeń nazw, często są nazywane rekordami klejącymi (ang. glue records). Są to jedyne rekordy, w których strefa nadrzędna w rzeczywistości przechowuje informacje o hostach strefy podrzędnej. Rekordy klejące wskazują na serwery nazw domeny physics.groucho.edu, jak pokazano w przykładzie 6-5. Przykład 6-5.?Fragment pliku named.hosts z GMU ; Dane dla strefy groucho.edu @  IN  SOA vax12.gcc.groucho.edu. joe.vax12.gcc.groucho.edu. {       1999070100    ; numer wersji       360000       ; odświeżanie 3600 ; ponowna próba 3600000       ; wygaśnięcie 3600 ; domyślny ttl } ... ; ;rekordy klejące dla strefy physics.groucho.edu physics       IN    NS    niels.physics.groucho.edu.          IN    NS    gauss.maths.groucho.edu. niels.physics    IN    A    149.76.12.1 gauss.maths    IN    A    149.76.4.23 ... Wyszukiwanie odwrotne Znajdowanie adresu IP należącego do hosta jest pewnie najpowszechniejszym zastosowaniem systemu nazw domen, ale czasem chcesz znaleźć kanoniczną nazwę hosta odpowiadającą adresowi. Znajdowanie nazwy hosta jest nazywane odwzorowaniem odwrotnym (ang. reverse mapping) i jest używane przez pewne usługi sieciowe do weryfikacji tożsamości klienta. Wyszukiwanie odwrotne, przeprowadzane w oparciu o plik hosts, polega po prostu na przeszukaniu pliku i znalezieniu w nim hosta, do którego należy poszukiwany adres IP. W przypadku DNS-u skrupulatne przeszukiwanie przestrzeni nazw jest wykluczone. Zamiast tego została stworzona specjalna domena in-addr.arpa, która zawiera adresy IP wszystkich hostów zapisane w odwrotnej notacji kropkowej. Na przykład adres IP 149.76.12.4 odpowiada nazwie 4.12.76.149.in-addr.arpa. Rekord zasobu, który łączą nazwy z odpowiadającymi im kanonicznymi nazwami hostów, jest typu PTR. Tworzenie zarządzanej przez nas strefy zwykle oznacza, że jej administratorzy w pełni kontrolują sposób przypisywania adresów do nazw. Ponieważ zwykle mają w swoich rękach jedną lub więcej sieci lub podsieci IP, odwzorowanie stref DNS na sieci IP jest typu jedna-na-wiele. Na przykład wydział fizyki zawiera podsieci 149.76.8.0, 149.76.12.0 i 149.76.14.0. Oznacza to, że wraz ze strefą physics w domenie in-addr.arpa muszą być stworzone i przekazane administratorom sieci na wydziale nowe strefy: 8.76.149.in-addr.arpa, 12.76.149.in-addr.arpa i 14.76.149.in-addr.arpa. W przeciwnym razie dodanie nowego hosta w laboratorium Collider wymagałoby skontaktowania się z domeną nadrzędną i wprowadzenia nowego adresu do pliku strefy in-addr.arpa. Baza danych strefy dla podsieci 12 została pokazana w przykładzie 6-6. Odpowiednie rekordy klejące w bazie danych strefy nadrzędnej zostały pokazane w przykładzie 6-7. Przykład 6-6. Fragment z pliku named.rev dla podsieci 12 ; domena 12.76.149.in-addr.arpa @  IN SOA  niels.physics.groucho.edu. janet.niels.physics.groucho.edu. {       1999090200 360000 3600 3600000 3600       } 2      IN PTR    otto.physics.groucho.edu. 4      IN PTR   quark.physics.groucho.edu. 5      IN PTR    down.physics.groucho.edu. 6      IN PTR    strange.physics.groucho.edu. Przykład 6-7. Fragment pliku named.rev dla sieci 149.76 ; domena 76.149.in-addr.arpa @  IN SOA  vax12.gcc.groucho.edu. joe.vax12.gcc.groucho.edu. {       1999070100 360000 3600 3600000 3600       } ... ; posieć 4: wydział matematyki 1.4       IN   PTR    sophus.maths.groucho.edu. 17.4       IN   PTR    erdos.maths.groucho.edu. 23.4       IN   PTR    gauss.maths.groucho.edu. ... ; podsieć 12: wydział fizyki, oddzielna strefa 12       IN   NS   niels.physics.groucho.edu.       IN   NS     gauss.maths.groucho.edu. niels.physics.groucho.edu.   IN A 149.76.12.1 gauss.maths.groucho.edu.     IN A 149.76.4.23 ... Strefy systemu in-addr.arpa mogą być tworzone tylko jako nadzbiory sieci IP. Jeszcze poważniejszym ograniczeniem jest to, że maski tych sieci muszą przestrzegać granic bajtowych*. Wszystkie podsieci uniwersytetu Groucho Marx mają maskę sieci 255.255.255.0, a więc strefa in-addr.arpa może być utworzona dla każdej podsieci. Jednak, gdyby maska miała postać 255.255.255.128, utworzenie stref dla podsieci 149.76.12.128 byłoby niemożliwe, ponieważ nie ma sposobu na poinformowanie DNS-u, że domena 12.76.149.in-addr.arpa została podzielona na dwie strefy, gdzie hosty mają numery odpowiednio z zakresów: od 1 do 127 i od 128 do 255. Eksploatacja named named (wymawiaj: nejm-di) umożliwia korzystanie z usługi DNS na większości komputerów uniksowych. Jest to program serwera, oryginalnie stworzony dla BSD, który służy do udostępniania usług nazewniczych klientom oraz innym serwerom nazw. Przez jakiś czas był używany BIND w wersji 4, obecny w wielu dystrybucjach Linuksa. Nowa wersja, o numerze 8 została wprowadzona w większości dystrybucji Linuksa i znacznie różni się od poprzednich wersji*. Ma wiele nowych funkcji, takich jak dynamiczne uaktualnianie DNS-u, powiadomienie o zmianach w DNS-ie, lepsza wydajność i nowa składania pliku konfiguracyjnego. Szczegóły znajdziesz w dokumentacji załączonej do pakietu dystrybucyjnego. Ten podrozdział wymaga rozumienia działania DNS-u. Jeżeli czujesz się jak na tureckim kazaniu, może warto ponownie sięgnąć do poprzedniego podrozdziału Jak działa DNS. named zwykle jest uruchamiany w czasie startu systemu i działa aż do zatrzymania maszyny. Implementacje wcześniejszych wersji BIND pobierały swoje informacje z pliku konfiguracyjnego /etc/named.boot i różnych plików zawierających odwzorowania nazw domen na adresy. Te ostatnie są nazywane plikami stref. Wersje BIND od wersji 8 wzwyż wykorzystują natomiast plik o nazwie /etc/named.conf. Aby uruchomić named, wprowadź: # /usr/sbin/named named uruchomi się i odczyta plik named.boot oraz pliki stref w nim wskazane. Zapisze ID swojego procesu w postaci pliku ASCII o nazwie /var/run/named.pid, ściągnie wszelkie pliki stref z serwerów podstawowych, o ile będzie taka potrzeba, i zacznie nasłuchiwać na porcie 53, oczekując na zapytania DNS. Plik named.boot Plik konfiguracyjny wcześniejszej wersji BIND miał bardzo prostą strukturę. Natomiast ten plik dla wersji 8. ma znacznie trudniejszą składnię, obsługującą wiele nowo wprowadzonych funkcji. Nazwa tego pliku zmieniła się z /etc/named.boot na /etc/named.conf . Skupimy się na konfigurowaniu starszej wersji, ponieważ większość dystrybucji prawdopodobnie wciąż jeszcze jej używa, ale pokażemy także równoważny plik named.conf, żeby zilustrować różnice i powiemy, jak konwertować stary format na nowy. Plik named.boot jest generalnie niewielki i zawiera jedynie kilka wskazań do plików głównych z informacjami o strefie i do innych serwerów. Komentarze rozpoczynają się hashem (#) lub średnikiem (;) i ciągną się do następnego wiersza. Zanim bardziej szczegółowo omówimy format named.boot, przyjrzymy się przykładowemu plikowi z hosta vlager pokazanemu w przykładzie 6-8. Przykład 6-8. Plik named.boot dla hosta vlager ; ; plik /etc/named.boot dla hosta vlager.vbrew.com ; directory   /var/named ; ;       domena             plik ;-------------------- cache    .                named.ca primary    vbrew.com             named.hosts primary    0.0.127.in-addr.arpa    named.local primary    16.172.in-addr.arpa      named.rev Przyjrzyjmy się kolejno każdej dyrektywie. Słowo kluczowe directory informuje program named, że wszystkie dalej wymienione pliki, czyli w tym przykładzie pliki stref, znajdują się w katalogu /var/named. W rezultacie jest nieco mniej pisania. Słowo kluczowe primary widoczne w tym przykładzie ładuje informacje do named. Informacje te są brane z plików głównych podanych jako ostatnie parametry w wierszu. Te pliki zawierają rekordy zasobów DNS, którym przyjrzymy się dalej. W tym przykładzie skonfigurowaliśmy named jako podstawowy serwer nazw dla trzech domen, co pokazują trzy dyrektywy primary. Pierwsza z nich nakazuje programowi named działać jako podstawowy serwer dla domeny vbrew.com i odczytywać dane o strefie z pliku named.hosts. Słowo kluczowe cache ma szczególne znaczenie i powinno być obecne na wszystkich komputerach, na których działa serwer nazw. Powoduje ono, że named włącza swoją pamięć podręczną i ładuje wskazania do serwera nazw domeny głównej (ang. root name server hints) z pliku pamięci podręcznej (w naszym przykładzie named.ca). Wrócimy do tego w poniższej liście. Oto lista najważniejszych opcji, jakich możesz używać w pliku named.boot: directory Ta opcja wyznacza katalog, w którym znajdują się pliki stref. Nazwy plików w innych opcjach mogą być podane względem tego katalogu. Wielokrotnie używając dyrektywy directory, można określić kilka katalogów. Standard systemu plików Linuksa mówi, że powinno się używać katalogu /var/named. primary Ta opcja przyjmuje jako argument nazwę domeny i nazwę pliku oraz mówi, że lokalny serwer jest autorytatywny dla danej domeny. Jako serwer podstawowy, named ładuje informacje o strefie z zadanego pliku głównego. W każdym pliku boot będzie istniał przynajmniej jeden wpis primary dotyczący odwrotnego odwzorowania sieci 127.0.0.0 - lokalnej sieci pętli zwrotnej. secondary Ta dyrektywa jest używana z nazwą domeny, listą adresów i nazwą pliku jako argumentami. Mówi, że lokalny serwer jest serwerem zapasowym (ang. secondary master server) dla danej domeny. Serwer zapasowy także zawiera autorytatywne dane o domenie, ale nie odczytuje ich z plików, tylko próbuje je ładować z serwera podstawowego. W liście adresów należy podać named przynajmniej jeden adres IP serwera podstawowego. Serwer lokalny kontaktuje się kolejno z każdym z nich, aż uda mu się poprawnie skopiować bazę danych stref, która następnie jest zapisywana w pliku zapasowym o nazwie podanej jako trzeci argument. Jeżeli żaden z serwerów głównych nie odpowiada, dane o strefie są odczytywane z pliku zapasowego. named próbuje odświeżać dane o strefie w regularnych odstępach czasu. Proces ten wyjaśniamy dalej w połączeniu z rekordem zasobu SOA. cache Ta opcja wymaga podania nazwy domeny i nazwy pliku jako argumentów. Plik zawiera wskazania do serwerów nazw domeny głównej, czyli listę rekordów z ich nazwami. Rozpoznawane są jedynie rekordy NS i A. domain powinno być ustawione na nazwę domeny głównej, czyli po prostu kropkę (.). Ta informacja jest kluczowa dla named. Jeżeli w pliku startowym nie występuje dyrektywa cache, named nie utworzy w ogóle lokalnej pamięci podręcznej. Taka sytuacja (brak tej funkcji) poważnie zmniejszy wydajność i zwiększy obciążenie sieci, jeżeli przepytywane serwery nie znajdują się w sieci lokalnej. Co więcej, named nie będzie w stanie skontaktować się z żadnym z serwerów nazw domeny głównej, a więc nie będzie mógł rozwiązać adresów innych, niż te, dla których jest autorytatywny. Wyjątkiem od tej reguły są serwery przekazujące (ang. forwarding servers; zobacz opcja forwarders opisana poniżej). forwarders Ta dyrektywa wymaga jako argumentu listy adresów z separatorami w postaci białych znaków. Adresy IP na tej liście odpowiadają serwerom nazw, które named może pytać, jeżeli nie uda mu się odpowiedzieć na zapytanie na podstawie lokalnej pamięci podręcznej. Są one sprawdzane po kolei, aż któryś odpowie na zapytanie. Zwykle w tym miejscu podajesz serwer nazw swojego dostawcy sieci lub inny dobrze znany serwer. slave Ta dyrektywa powoduje, że serwer nazw jest definiowany jako serwer podległy (ang. slave server). Nigdy sam nie realizuje zapytań rekurencyjnych, a jedynie przekazuje je do serwerów określonych w dyrektywie forwarders. Istnieją dwie opcje, których tutaj nie opisujemy: sortlist i domain. W plikach baz danych można używać także dwóch innych dyrektyw: $INCLUDE i $ORIGIN. Ponieważ są one rzadko potrzebne, nie opisujemy ich tutaj. Plik host.conf dla wersji BIND 8 BIND w wersji 8 wprowadza szereg nowych funkcji i wraz z nimi nową składnię pliku konfiguracyjnego. Plik named.boot ze swoimi prostymi, jednowierszowymi dyrektywami został zastąpiony przez plik named.conf, który ma składnię podobną do gated, a więc przypominającą składnię pliku źródłowego w języku C. Nowa składnia jest bardziej skomplikowana, ale na szczęście przygotowano narzędzie, które automatycznie konwertuje starą składnię na nową. W pakiecie źródłowym BIND 8 dodano program named-bootconf.pl napisany w Perlu, który odczytuje istniejący plik named.boot z stdin i konwertuje go na równoważny plik w formacie named.conf, wypisywany na stdout. Aby użyć konwertera, musisz mieć zainstalowany interpreter Perla. Skryptu używa się w następujący sposób: # cd /etc # named-bootconf.pl named.conf Tworzy on plik named.conf, podobny do pokazanego w przykładzie 6-9. Usunęliśmy kilka pomocnych komentarzy, jakie dodaje skrypt, aby lepiej było widać prawie bezpośredni związek pomiędzy starą i nową składnią. Przykład 6-9. Równoważny plik named.conf z serwera vlager dla wersji 8 BIND-a // // plik /etc/named.boot dla serwera vlager.vbrew.com options {       directory "/var/named"; }; zone "." {       type hint;       file "named.ca"; }; zone "vbrew.com" {       type master;       file "named.hosts"; }; zone "0.0.127.in-addr.arpa" {       type master;       file "named.local"; }; zone "16.172.in-addr.arpa" {       type master;       file "named.rev"; }; Jeżeli przyjrzysz się uważniej, spostrzeżesz, że każda z jednowierszowych dyrektyw pliku named.boot została zamieniona w pliku named.conf na dyrektywę w stylu języka C, ujętą w nawiasy {}. Komentarze, które w pliku named.boot były oznaczone średnikiem (;), tutaj są sygnalizowane dwoma ukośnikami (//). Dyrektywa directory została zamieniona na akapit options, w którym znajduje się klauzula directory. Dyrektywy cache i primary zostały zamienione na akapity zone z klauzulami type, wskazującymi odpowiednio na hint i master. Pliki stref nie muszą być w żaden sposób modyfikowane. Ich składnia pozostaje bez zmian. Nowa składnia pliku konfiguracyjnego pozwala na użycie wielu opcji, których tutaj nie omawialiśmy. Jeżeli szukasz informacji na ich temat, najlepszym źródłem jest dokumentacja dostarczana w pakiecie źródłowym BIND-a w wersji 8. Pliki bazy danych DNS Pliki główne związane z named, takie jak named.hosts, zawsze przynależą do jakiejś domeny, która nosi nazwę początkowej (ang. origin). Jest to nazwa domeny określona przez opcje cache i primary. W pliku głównym możesz podawać nazwy domen i hostów względem tej domeny. Nazwy podane w pliku konfiguracyjnym są traktowane jako bezwzględne, jeżeli kończą się kropką - w przeciwnym razie są one odnoszone do domeny początkowej. Do samej domeny początkowej można się odwoływać, używając znaku (@). Dane zawarte w pliku głównym są podzielone na rekordy zasobów (ang. resource records - RR). RR są najmniejszymi jednostkami informacji dostępnymi przez DNS. Każdy rekord zasobu ma typ. Rekordy typu A na przykład wiążą nazwę hosta z adresem IP, a rekordy CNAME zawierają alias oficjalnej nazwy hosta. Możesz to zobaczyć w zamieszczonym dalej przykładzie 6-11, który pokazuje plik główny named.hosts dla browaru wirtualnego. Reprezentacja rekordu zasobu w plikach głównych ma wspólny format: [domena] [ttl] [klasa] typ danerek Pola są oddzielane spacjami lub tabulatorami. Wpis może liczyć kilka wierszy, jeżeli przed pierwszym nowym wierszem i po ostatnim polu pojawią się nawiasy klamrowe. Wszystko pomiędzy średnikiem a znakiem nowego wiersza jest ignorowane. Oto opis pól: domena Jest to nazwa domeny, której dotyczy wpis. Jeżeli nazwa domeny nie jest podana, uznaje się, że RR dotyczy domeny z poprzedniego RR. ttl Aby wymusić na resolverach usuwanie informacji po pewnym czasie, z każdym RR jest związany czas życia (ttl). Pole ttl określa, w sekundach, czas ważności informacji, liczony od momentu jej uzyskania z serwera. Jest to liczba dziesiętna, maksymalnie ośmiocyfrowa. Jeżeli nie zostanie podana wartość ttl, przyjmowana jest domyślna wartość pola minimum poprzedniego rekordu SOA. klasa Jest to klasa adresu, jak IN dla adresów IP czy HS dla obiektów z klasy Hesiod. W sieci TCP/IP musisz podawać IN. Jeżeli nie zostanie podane pole klasy, przyjmowana jest klasa z poprzedniego RR. typ To pole opisuje typ RR. Najczęściej używane typy to A, SOA, PTR i NS. W dalszych podrozdziałach opisano różne typy RR. danerek To pole zawiera dane związane z RR. Format tego pola zależy od typu RR. W dalszej części opiszemy oddzielnie każdy RR. Oto wybiórcza lista RR używanych w plikach głównych DNS. Istnieje jeszcze kilka innych rekordów, których nie będziemy tu opisywać, gdyż są albo eksperymentalne, albo rzadko używane: SOA Ten RR opisuje strefę władzy (SOA oznacza "początek władzy"). Sygnalizuje, że rekordy występujące po tym typie RR zawierają informacje autorytatywne dla domeny. Każdy plik główny wpisany w dyrektywie primary musi zawierać rekord SOA dla danej strefy. Dopuszczalne są następujące pola: origin To pole zawiera kanoniczną nazwę hosta podstawowego serwera nazw dla tej domeny, zwykle pisaną w postaci nazwy bezwzględnej. contact To pole to adres e-mail osoby odpowiedzialnej za utrzymanie domeny; w tym adresie znak @ został zastąpiony kropką. Na przykład, gdyby osobą odpowiedzialną za browar wirtualny była janet, pole miałoby postać janet.vbrew. com. serial To pole zawiera numer wersji pliku strefy wyrażony w postaci jednej liczby dziesiętnej. Gdy dane w pliku strefy zostaną zmienione, numer ten powinien zostać zwiększony. Przyjęło się, że numer ten to data ostatniego uaktualnienia z dodanym numerem wersji - na wypadek kilku uaktualnień w ciągu dnia. Na przykład 2000012600 oznacza uaktualnienie numer 00 z dnia 26 stycznia 2000 roku. Numer jest używany przez zapasowe serwery nazw do rozpoznawania zmian w informacjach o strefie. Aby być na bieżąco, serwery zapasowe co jakiś czas odczytują rekord SOA serwerów podstawowych i porównują numer z własnym rekordem SOA. Jeżeli numer się zmienił, serwery zapasowe ściągają całą bazę danych z serwera podstawowego. refresh To pole określa w sekundach, co jaki czas serwery zapasowe powinny sprawdzać rekord SOA serwera podstawowego. Znów jest to liczba dziesiętna złożona maksymalnie z ośmiu cyfr. Ogólnie rzecz biorąc topologia sieci nie zmienia się zbyt często, a więc ta liczba powinna być ustawiona na około jeden dzień w przypadku większych sieci, a nawet dłużej w przypadku mniejszych sieci. retry Ta liczba określa odstępy czasu, w których serwer zapasowy powinien próbować kontaktować się z serwerem podstawowym, jeżeli nie uda się mu odświeżyć danych o strefie. Nie może być ona zbyt mała, gdyż w razie chwilowej awarii serwera lub sieci serwer zapasowy będzie marnował zasoby sieciowe. Zaleca się odstępy godzinne lub półgodzinne. expire To pole określa czas w sekundach, po którym serwer zapasowy powinien ostatecznie usunąć wszystkie dane o strefie, jeżeli nie był w stanie skontaktować się z serwerem głównym. Zwykle powinieneś zdefiniować to pole na przynajmniej tydzień (604 800 sekund), ale wydłużenie do miesiąca lub większe, także ma sens. minimum To pole zawiera domyślną wartość ttl dla rekordów zasobów, które nie definiują jej jawnie. Wartość ttl określa maksymalny czas, przez jaki inne serwery nazw mogą trzymać RR w swojej pamięci podręcznej. Czas ten dotyczy tylko zwykłych poszukiwań i nie ma nic wspólnego z czasem, po którym serwery zapasowe powinny próbować uaktualnić swoje informacje o strefie. Jeżeli topologia twojej sieci nie zmienia się często, wystarczy, że ustawisz ttl na tydzień, a nawet dłuższy okres czasu. Jeżeli pojedynczy rekord RR zmienia się często, zawsze możesz przypisać mu indywidualnie mały ttl. Jeżeli twoja sieć zmienia się często, możesz zechcieć ustawić minimum na jeden dzień (86 400 sekund). A Ten rekord wiąże adres IP z nazwą hosta. Pole danych zasobu zawiera adres w notacji kropkowej. Może istnieć tylko jeden rekord A dla danego hosta. Nazwa hosta używana w rekordzie A jest uznawana za oficjalną, inaczej kanoniczną, nazwę hosta. Wszystkie pozostałe nazwy hosta to aliasy, które muszą być odwzorowane na nazwę kanoniczną za pomocą rekordu CNAME. Jeżeli nazwa kanoniczna naszego hosta brzmiałaby vlager, mielibyśmy rekord A wiążący tę nazwę z adresem IP tego hosta. Ponieważ czasem chcemy związać z adresem także inną nazwę, powiedzmy news, mamy możliwość stworzenia rekordu CNAME, który wiąże nazwę alternatywną z nazwą kanoniczną. Więcej na temat rekordów CNAME powiemy już wkrótce. NS Rekordy NS są używane do określenia podstawowego serwera strefy i wszystkich jej serwerów zapasowych. Rekord NS wskazuje na główny serwer nazw danej strefy, a pole danych zasobu zawiera nazwę tego serwera. Z rekordami NS spotkasz się w dwóch sytuacjach: po pierwsze, jeżeli przekazujesz władzę strefie podrzędnej, a po drugie, w głównej bazie danych samej strefy podrzędnej. Zestaw serwerów podanych w obu strefach (nadrzędnej i podrzędnej) powinien być taki sam. Rekord NS określa nazwę podstawowego i zapasowego serwera nazw dla strefy. Nazwy te muszą być zamienione na adresy, aby można było z nich korzystać. Czasami serwery należą do domeny, którą obsługują, co rodzi problem "jajka i kury". Nie możemy znaleźć adresu, dopóki serwer nazw jest nieosiągalny, ale też nie możemy dotrzeć do serwera nazw, dopóki nie znajdziemy jego adresu. Aby rozwiązać ten dylemat, możemy skonfigurować specjalne rekordy A bezpośrednio w serwerze nazw strefy nadrzędnej. Rekordy A pozwalają serwerom nazw domeny nadrzędnej rozwiązywać adresy IP serwerów strefy podrzędnej. Te rekordy są powszechnie nazywane rekordami klejącymi, ponieważ dają możliwość powiązania strefy podrzędnej z jej strefą nadrzędną. CNAME Ten rekord wiąże alias z kanoniczną nazwą hosta. Udostępnia on alternatywną nazwę, za pomocą której użytkownicy mogą odwoływać się do hosta, którego nazwa kanoniczna jest podana jako parametr. Kanoniczna nazwa hosta to taka, dla której w pliku głównym istnieje rekord A. Aliasy są po prostu związane z tą nazwą poprzez rekord CNAME, ale nie mają innych własnych rekordów. PTR Ten typ rekordu jest używany do powiązania nazw w domenie in-addr.arpa z nazwami hostów. Służy do odwrotnego odwzorowania adresów IP na nazwy hostów. Podana nazwa hosta musi być nazwą kanoniczną. MX Ten RR określa host wymieniający pocztę (ang. mail exchanger) dla domeny. Hosty wymieniające pocztę są omówione w rozdziale 17, Poczta elektroniczna. Składnia rekordu MX jest następująca: [domena] [ttl] [klasa] MX priorytet host Host to nazwa hosta wymieniającego pocztę dla domeny. Z każdym hostem wymieniającym pocztę związany jest priorytet. Agent transportowy poczty, który chce dostarczyć pocztę do domeny, sprawdza wszystkie hosty, które dla danej domeny mają rekord MX, aż mu się uda z jakimś skontaktować. Najpierw jest sprawdzany host o najniższym priorytecie, a następnie pozostałe - w rosnącej kolejności priorytetów. HINFO Ten rekord zawiera informacje o sprzęcie i oprogramowaniu systemu. Składnia jest następująca: [domena] [ttl] [klasa] HINFO sprzęt oprogramowanie Pole sprzęt identyfikuje sprzęt używany w danym hoście. Do jego opisania stosowane są specjalne konwencje. Lista dopuszczalnych "nazw maszyn" jest podana w RFC Assigned Numbers (RFC-1700). Jeżeli pole zawiera spacje, musi być ujęte w cudzysłów. Pole oprogramowanie opisuje system operacyjny używany przez dany host. Znów dopuszczalne nazwy są opisane w RFC Assigned Numbers. Rekord HINFO opisujący komputer oparty na procesorze Intel z zainstalowanym Linuksem powinien wyglądać następująco: tao   36500   IN HINFO   IBM-PC   LINUX2.2 Natomiast rekord HINFO dla Linuksa działającego na komputerze z procesorem Motorola 68000 mógłby wyglądać tak: cevad    36500   IN HINFO    ATARI-104ST  LINUX2.0 jedd      36500   IN HINFO    AMIGA-3000   LINUX2.0 Konfiguracja named jako serwera pamięci podręcznej Istnieje szczególny typ konfiguracji named, który należy omówić, zanim wyjaśnimy, jak w pełni skonfigurować serwer nazw. Jest to konfiguracja serwera pamięci podręcznej. W rzeczywistości nie obsługuje on domeny, ale działa jako przekaźnik dla wszystkich zapytań DNS wygenerowanych przez hosty. Zaletą takiego schematu jest tworzenie pamięci podręcznej, a więc tylko pierwsze zapytanie o zadane hosty jest w rzeczywistości wysyłane do serwera nazw w Internecie. Odpowiedzi na wszelkie powtórne zapytania będą wysłane bezpośrednio z pamięci podręcznej twojego lokalnego serwera nazw. Może teraz nie wydaje się to zbyt użyteczne, ale zmienisz zdanie, jeżeli zaczniesz łączyć się z Internetem przez telefon, co opisano w rozdziale 7, IP łącza szeregowego, i rozdziale 8, Protokół punkt-punkt. Plik named.boot dla serwera pamięci podręcznej wygląda następująco: ; plik named.boot dla serwera pamięci podręcznej directory                      /var/named primary      0.0.127.in-addr.arpa    named.local ; sieć hosta lokalnego cache      .                named.ca ; serwery domeny głównej Poza powyższym plikiem named.boot, musisz też skonfigurować plik named.ca, w którym będzie się znajdowała poprawna lista serwerów nazw domeny głównej. Możesz skopiować i wykorzystać do tego celu przykład 6-10. Do konfiguracji serwera nazw jako serwera pamięci podręcznej nie są potrzebne żadne inne pliki. Tworzenie plików głównych Przykłady od 6-10 do 6-13 pokazują przykładowe pliki serwera nazw sieci browaru, umieszczonego na hoście vlager. Ze względu na charakter omawianej sieci (pojedyncza sieć lokalna) przykład jest dość prosty. Plik pamięci podręcznej named.ca, podany jako przykład 6-10, pokazuje przykładowe rekordy wskazujące serwer nazw domeny głównej. Typowy plik pamięci podręcznej zwykle zawiera listę kilku serwerów. Aktualną listę serwerów nazw domeny głównej możesz uzyskać za pomocą narzędzia nslookup opisanego w następnym podrozdziale*. Przykład 6-10. Plik named.ca ; ; /var/named/named.ca   Plik pamięci podręcznej dla browaru. ;         Nie jesteśmy podłączeni do Internetu, a więc ;         nie potrzebujemy żadnych serwerów nazw domeny ;         głównej. Aby uaktywnić te rekordy, usuń średniki. ; ;.             3600000   IN NS     A.ROOT-SERVERS.NET. ;A.ROOT-SERVERS.NET.   3600000       A      198.41.0.4 ;.             3600000   IN NS     B.ROOT-SERVERS.NET. ;B.ROOT-SERVERS.NET.   3600000       A      128.9.0.107 ;.             3600000   IN NS     C.ROOT-SERVERS.NET. ;C.ROOT-SERVERS.NET.   3600000       A      192.33.4.12 ;.             3600000   IN NS     D.ROOT-SERVERS.NET. ;D.ROOT-SERVERS.NET.   3600000       A      128.8.10.90 ;.             3600000   IN NS     E.ROOT-SERVERS.NET. ;E.ROOT-SERVERS.NET.   3600000       A      192.203.230.10 ;.             3600000   IN NS     F.ROOT-SERVERS.NET. ;F.ROOT-SERVERS.NET.   3600000       A      192.5.5.241 ;.             3600000   IN NS     G.ROOT-SERVERS.NET. ;G.ROOT-SERVERS.NET.   3600000       A      192.112.36.4 ;.             3600000   IN NS     H.ROOT-SERVERS.NET. ;H.ROOT-SERVERS.NET.   3600000       A      128.63.2.53 ;.             3600000   IN NS     I.ROOT-SERVERS.NET. ;I.ROOT-SERVERS.NET.   3600000       A      192.36.148.17 ;.             3600000   IN NS     J.ROOT-SERVERS.NET. ;J.ROOT-SERVERS.NET.   3600000       A      198.41.0.10 ;.             3600000   IN NS     K.ROOT-SERVERS.NET. ;K.ROOT-SERVERS.NET.   3600000       A      193.0.14.129 ;.             3600000   IN NS     L.ROOT-SERVERS.NET. ;L.ROOT-SERVERS.NET.   3600000       A      198.32.64.12 ;.             3600000   IN NS     M.ROOT-SERVERS.NET. ;M.ROOT-SERVERS.NET.   3600000       A      202.12.27.33 ; Przykład 6-11. Plik named.hosts ; ; /var/named/named.hosts      Hosty lokalne w browarze ;                   domena vbrew.com ; @         IN SOA   vlager.vbrew.com. janet.vbrew.com {                2000012601 ; numer kolejny                86400     ; odświeżanie: raz dziennie 3600       ; ponowna próba: co godzinę 3600000    ; wygaśnięcie: 42 godziny 604800     ; minimum: 1 tydzień }        IN NS   vlager.vbrew.com. ; ; poczta lokalna jest dystrybuowana na vlager         IN MX    10 vlager ; ; adres pętli zwrotnej localhost. IN A     127.0.0.1 ; ; Ethernet browaru wirtualnego vlager     IN A     172.16.1.1 vlager-if1   IN CNAME   vlager ; vlager to także serwer grup dyskusyjnych news         IN CNAME   vlager vstout       IN A       172.16.1.2 vale         IN A       172.16.1.3 ; ; Ethernet winiarni wirtualnej vlager-if2   IN A       172.16.2.1 vbardolino   IN A       172.16.2.2 vchianti     IN A       172.16.2.3 vbeaujolais  IN A       172.16.2.4 ; ; Ethernet wirtualnej fabryki napojów alkoholowych ; (dodatkowych) vbourbon     IN A       172.16.3.1 vbourbon-if1 IN CNAME   vbourbon Przykład 6-12. Plik named.local ; ; /var/named/named.local      Odwzorowanie odwrotne sieci 127.0.0 ;             domena początkowa 0.0.127.in-addr.arpa. ; @           IN SOA   vlager.vbrew.com. joe.vbrew.com. { 1 ; numer kolejny 360000    ; odświeżanie: co 100 godzin 3600 ; ponowna próba: co godzinę 3600000    ; wygaśnięcie: 42 dni 360000    ; minimum: 100 godzin }          IN NS    vlager.vbrew.com. 1          IN PTR   localhost. Przykład 6-13. Plik named.rev ; ; /var/named/named.rev   Odwzorowanie odwrotne naszych adresów IP ;       domena początkowa to 16.172.in-addr.arpa. ; @          IN SOA   vlager.vbrew.com. joe.vbrew.com. { 16 ; numer kolejny 86400    ; odświeżanie: raz dziennie 3600 ; ponowna próba: co godzinę 3600000    ; wygaśnięcie: 42 dni 604800    ; minimum: 1 tydzień }          IN NS    vlager.vbrew.com. ; browar 1.1          IN PTR   vlager.vbrew.com. 2.1          IN PTR   vstout.vbrew.com. 3.1          IN PTR   vale.vbrew.com. ; winiarnia 1.2          IN PTR   vlager-if2.vbrew.com. 2.2          IN PTR   vbardolino.vbrew.com. 3.2          IN PTR   vchianti.vbrew.com. 4.2          IN PTR   vbeaujolais.vbrew.com. Weryfikowanie konfiguracji serwera nazw nslookup jest doskonałym narzędziem do sprawdzania działania twojego serwera nazw. Można go używać zarówno interaktywnie z monitem, jak i w formie polecenia natychmiast wypisującego wynik. W tym ostatnim przypadku po prostu wywołujesz polecenie tak: $ nslookup nazwahosta nslookup zadaje zapytanie o nazwęhosta do serwera nazw określonego w pliku resolv.conf. (Jeżeli w pliku znajduje się więcej niż jeden serwer, nslookup wybiera jakiś losowo). Jednak tryb interaktywny jest dużo ciekawszy. Poza poszukiwaniem poszczególnych hostów, możesz zadawać zapytania o dowolny typ rekordu DNS i przesyłać całe informacje o strefie dla danej domeny. Po wywołaniu nslookup bez argumentów, wyświetla on używany serwer nazw i przechodzi do trybu interaktywnego. Po monicie > możesz wpisać nazwę domeny, o którą chcesz pytać. Domyślnie zadawane są zapytania o klasę rekordów A - tych zawierających adres IP odnoszący się do nazwy domeny. Innych typów rekordów możesz poszukać następująco: > set type=typ gdzie typ to jedna z nazw rekordu zasobu opisanych wcześniej lub dyrektywa ANY. Można sobie wyobrazić następującą sesję z programem nslookup: $ nslookup Default Server: tao.linux.org.au Address: 203.41.101.121 > metalab.unc.edu Server: tao.linux.org.au Address: 203.41.101.121 Name: metalab.unc.edu Address: 152.2.254.81 > Wynik najpierw pokazuje serwer DNS, do którego są kierowane zapytania, a następnie odpowiedź na zapytanie. Jeżeli spróbujesz zapytać o nazwę, z którą nie jest związany adres IP, ale w bazie DNS znajdują się inne rekordy, nslookup zwróci komunikat o treści No type A records found. (nie znaleziono rekordów typu A). Jednak możesz zadać zapytanie nie tylko o rekordy A - trzeba tylko wydać polecenie set type. Aby uzyskać rekord SOA z domeny unc.edu, musisz napisać: > unc.edu Server: tao.linux.org.au Address: 203.41.101.121 *** No address (A) records available for unc.edu > set type=SOA > unc.edu Server: tao.linux.org.au Address: 203.41.101.121 unc.edu      origin = ns.unc.edu      mail addr = host-reg.ns.unc.edu      serial = 1998111011      refresh = 14400 (4H)      retry = 3600 (1H)      expire = 1209600 (2W)      minimum ttl = 86400 (1D) unc.edu name server = ns2.unc.edu unc.edu name server = ncnoc.ncren.net unc.edu name server = ns.unc.edu ns2.unc.edu       internet address = 152.2.253.100 ncnoc.ncren.net   internet address = 192.101.21.1 ncnoc.ncren.net   internet address = 128.109.193.1 ns.unc.edu       internet address = 152.2.21.1 W podobny sposób możesz zapytać o rekordy MX: > set type=MX > unc.edu Server: tao.linux.org.au Address: 203.41.101.121 unc.edu preference = 0, mail exchanger = conga.oit.unc.edu unc.edu preference = 10, mail exchanger = imsety.oit.unc.edu unc.edu name server = ns.unc.edu unc.edu name server = ns2.unc.edu unc.edu name server = ncnoc.ncren.net conga.oit.unc.edu    internet address = 152.2.22.21 imsety.oit.unc.edu   internet address = 152.2.21.99 ns.unc.edu      internet address = 152.2.21.1 ns2.unc.edu     internet address = 152.2.253.100 ncnoc.ncren.net   internet address = 192.101.21.1 ncnoc.ncren.net internet address = 128.109.193.1 Użycie typu ANY zwróci wszystkie rekordy zasobów związane z daną nazwą. Innym praktycznym zastosowaniem nslookup, poza debugowaniem, jest uzyskiwanie aktualnej listy serwerów nazw domeny głównej. W tym celu należy zadać zapytanie o wszystkie rekordy NS związane z domeną główną. > set type=NS > . Server: tao.linux.org.au Address: 203.41.101.121 Non-authoritative answer: (root)   name server = A.ROOT-SERVERS.NET (root)   name server = H.ROOT-SERVERS.NET (root)   name server = B.ROOT-SERVERS.NET (root)   name server = C.ROOT-SERVERS.NET (root)   name server = D.ROOT-SERVERS.NET (root)   name server = E.ROOT-SERVERS.NET (root)   name server = I.ROOT-SERVERS.NET (root)   name server = F.ROOT-SERVERS.NET (root)   name server = G.ROOT-SERVERS.NET (root)   name server = J.ROOT-SERVERS.NET (root)   name server = K.ROOT-SERVERS.NET (root)   name server = L.ROOT-SERVERS.NET (root)   name server = M.ROOT-SERVERS.NET Authoritative answers can be found from: A.ROOT-SERVERS.NET   internet address = 198.41.0.4 H.ROOT-SERVERS.NET   internet address = 128.63.2.53 B.ROOT-SERVERS.NET   internet address = 128.9.0.107 C.ROOT-SERVERS.NET   internet address = 192.33.4.12 D.ROOT-SERVERS.NET   internet address = 128.8.10.90 E.ROOT-SERVERS.NET   internet address = 192.203.230.10 I.ROOT-SERVERS.NET   internet address = 192.36.148.17 F.ROOT-SERVERS.NET   internet address = 192.5.5.241 G.ROOT-SERVERS.NET   internet address = 192.112.36.4 J.ROOT-SERVERS.NET   internet address = 198.41.0.10 K.ROOT-SERVERS.NET   internet address = 193.0.14.129 L.ROOT-SERVERS.NET   internet address = 198.32.64.12 M.ROOT-SERVERS.NET   internet address = 202.12.27.33 Aby zobaczyć pełny zestaw dostępnych poleceń, użyj w nslookup komendy help. Inne przydatne narzędzia Istnieje kilka narzędzi, które mogą pomóc w wypełnianiu obowiązków administratora BIND. Pokrótce opiszemy dwa z nich. Więcej informacji na ten temat znajdziesz w dołączonej do nich dokumentacji. hostcvt pomaga we wstępnej konfiguracji BIND, konwertując plik /etc/hosts na pliki główne dla named. Program generuje wpisy normalne (A) i odwrotne (PTR); obsługuje także aliasy. Oczywiście nie zrobi za ciebie wszystkiego, gdyż musisz chociażby dopasować wartości czasów w rekordzie SOA, czy dodać rekordy MX. Ale i tak zaoszczędzisz sobie kilku tabletek od bólu głowy. hostcvt jest częścią pakietu BIND, ale w linuksowych ośrodkach FTP można go znaleźć także w postaci samodzielnego programu. Po skonfigurowaniu swojego serwera nazw, na pewno będziesz chciał sprawdzić jego konfigurację. Istnieją dobre narzędzia, które znacznie ułatwiają to zadanie: pierwszym z nich jest dnswalk - pakiet w języku Perl. Drugi nazywa się nslint. Oba programy przeglądają bazę DNS w poszukiwaniu popularnych błędów i weryfikują, czy znalezione informacje są spójne. Dwa inne przydatne narzędzia to: host i dig - są to narzędzia ogólnego przeznaczenia do zadawania zapytań do bazy DNS. Możesz je wykorzystać do ręcznego sprawdzania i diagnozowania wpisów w bazie danych DNS. Wymienione narzędzia są dostępne w postaci pakietów. dnswalk i nslint są dostępne w postaci kodu źródłowego pod adresami: http://www.visi.com/~barr/dnswalk/ i ftp://ftp.ee.lbl.gov/nslint.tar.Z. Kody źródłowe narzędzi host i dig można znaleźć pod adresami ftp://ftp.nikhef.nl/pub/network/ i ftp://ftp.is.co.za/networking/ip/dns/dig/. 7 IP łącza szeregowego Rozdział 7: IP łącza szeregowego Protokoły pakietowe, takie jak IP czy IPX, działają w oparciu o to, że host odbierający wie, gdzie się zaczyna i kończy każdy pakiet w strumieniu danych. Mechanizm używany do zaznaczania i wykrywania początku i końca pakietów nazywa się rozgraniczaniem (ang. delimitation). Za działanie tego mechanizmu w sieciach lokalnych odpowiada protokół Ethernet, natomiast w łączach szeregowych - protokoły SLIP i PPP. Stosunkowo mały koszt wolnych modemów komutowanych i sieci telefonicznych spowodował, że protokoły IP łącza szeregowego stały się bardzo popularne, szczególnie do zapewniania łączności użytkownikom końcowym Internetu. Sprzęt potrzebny do uruchomienia SLIP czy PPP jest prosty i łatwo dostępny. Wystarczy mieć modem i port szeregowy z buforem FIFO. Protokół SLIP jest bardzo prosty w implementacji i swego czasu był popularniejszy niż PPP. Obecnie jednak prawie każdy chętniej sięga po protokół PPP, który udostępnia bardziej wyrafinowane funkcje. Ważniejszym z nich przyjrzymy się później. Linux obsługuje sterowniki dla protokołów SLIP i PPP oparte na jądrze. Sterowniki te, które powstały jakiś czas temu, są stabilne oraz niezawodne. W tym i następnym rozdziale omówimy oba protokoły i sposób ich konfiguracji. Wymagania ogólne Aby korzystać z protokołu SLIP lub PPP, musisz skonfigurować podstawowe funkcje sieciowe opisane w poprzednich rozdziałach, a także interfejs pętli zwrotnej i resolver. Przy podłączeniu do Internetu będziesz chciał korzystać z DNS-u. Możliwości wyboru są tu identyczne jak przy PPP: możesz zadawać zapytania DNS, albo przez łącze szeregowe, jeśli wcześniej skonfigurujesz w pliku /etc/resolv.conf adres IP serwera nazw swojego dostawcy Internetu, albo konfigurując serwer nazw pamięci podręcznej zgodnie z opisem w rozdziale 6. Działanie SLIP-a Serwery IP podłączone do łącza komutowanego często udostępniają usługę SLIP przez specjalne konta użytkowników. Po zalogowaniu się na takie konto, nie dostajesz typowej powłoki, tylko uruchamiany jest program lub skrypt powłoki, który włącza sterownik SLIP serwera dla łącza szeregowego i konfiguruje odpowiedni interfejs sieciowy. Następnie musisz zrobić to samo po swojej stronie łącza. W niektórych systemach operacyjnych sterownik SLIP jest programem działającym w przestrzeni użytkownika. W Linuksie jest to część jądra, co powoduje, że działa on dużo szybciej. Prędkość ta jednak wymaga, by łącze szeregowe było jawnie przełączone w tryb SLIP. To przełączenie jest realizowane przez specjalny protokół obsługi łącza tty, SLIPDISC. Gdy tty jest w trybie normalnego protokołu obsługi (DISC0), wymienia dane tylko z procesami użytkownika, używając zwykłych wywołań read(2) i write(2), a sterownik SLIP nie jest w stanie ani zapisywać do tty, ani z niego odczytywać. W trybie SLIPDISC role się odwracają: teraz procesy przestrzeni użytkownika są blokowane przed zapisywaniem do tty lub odczytywaniem z niego, natomiast wszystkie dane przychodzące na port szeregowy są przekazywane bezpośrednio do sterownika SLIP. Sam sterownik SLIP jest w stanie pracować z wieloma odmianami protokołu SLIP. Poza zwykłym SLIP-em rozumie także CSLIP, który realizuje tak zwaną kompresję nagłówków Van Jacobsona wychodzących pakietów IP (opisaną w RFC-1144). Kompresja ta znacznie poprawia przepustowość łącza podczas sesji interaktywnych. Istnieją także sześciobitowe wersje obu tych protokołów. Prostym sposobem na przełączenie łącza szeregowego w tryb SLIP jest użycie narzędzia slattach. Załóżmy, że twój modem jest już podłączony pod /dev/ttyS3 i poprawnie zalogowałeś się do serwera SLIP. Teraz musisz wydać polecenie: # slattach /dev/ttyS3 & Narzędzie to przełączy protokół obsługi ttyS3 na SLIPDISC i podłączy urządzenie do jednego z interfejsów sieciowych SLIP. Jeżeli jest to twoje pierwsze aktywne łącze SLIP, zostanie ono podłączone do sl0. Drugie byłoby podłączone do sl1 i tak dalej. Aktualne jądra obsługują domyślnie maksymalnie 256 jednocześnie aktywnych łączy SLIP. Domyślny protokół obsługi łącza wybierany przez slattach to CSLIP. Możesz wybrać dowolny inny, używając przełącznika -p. Aby użyć zwykłego SLIP-a (bez kompresji), wydaj polecenie: # slattach -p slip /dev/ttyS3 & Dostępne protokoły obsługi są wymienione w tabeli 7-1. Masz także do dyspozycji specjalny pseudoprotokół obsługi o nazwie adaptive, który powoduje, że jądro automatycznie wykrywa, jaka enkapsulacja SLIP jest włączona po drugiej stronie. Tabela 7-1.?Protokoły obsługi SLIP w Linuksie Protokół obsługi Opis slip Tradycyjna enkapsulacja SLIP. cslip Enkapsulacja SLIP z kompresją nagłówków Van Jacobsona. slip6 Enkapsulacja SLIP z kodowaniem 6-bitowym. Metoda kodowania jest podobna do używanej przez polecenie uuencode i powoduje, że datagram SLIP jest konwertowany do drukowalnych znaków ASCII. Konwersja ta jest przydatna, jeżeli nie masz 8-bitowego łącza szeregowego. cslip6 Enkapsulacja SLIP z kompresją nagłówków Van Jacobsona i kodowaniem 6-bitowym. adaptive Nie jest to typowy protokół obsługi, ale powoduje, że jądro próbuje zidentyfikować protokół używany na odległej maszynie i dopasować się do niego. Zauważ, że musisz używać tej samej enkapsulacji co twój partner. Na przykład, jeżeli host cowslip używa CSLIP, ty także musisz go używać. Gdyby twoje połączenie SLIP nie działało, to przede wszystkim powinieneś sprawdzić, czy oba końce łącza uwzględniły używanie kompresji nagłówków. Jeżeli nie jesteś pewien, czego używa drugi koniec, spróbuj skonfigurować swój host na adaptive slip. Być może jądro prawidłowo odgadnie typ. slattach pozwala ci na włączenie nie tylko SLIP-a, ale także innych protokołów wykorzystujących łącze szeregowe, takich jak PPP czy KISS (inny protokół używany przez fanów ham radio). Mimo to nie jest powszechnie stosowany, gdyż są lepsze narzędzia do obsługi tych protokołów. Szczegóły znajdziesz na stronie podręcznika elektronicznego slattach(8). Po przełączeniu łącza na sterownik SLIP, musisz skonfigurować interfejs sieciowy. Znów, robisz to za pomocą standardowych poleceń ifconfig i route. Załóżmy, że połączyliśmy się telefonicznie z hosta vlager do serwera o nazwie cowslip. Na hoście vlager powinieneś napisać: # ifconfig sl0 vlager-slip pointopoint cowslip # route add cowslip # route add default gw cowslip Pierwsze polecenie konfiguruje interfejs jako łącze punkt-punkt do cowslip, a następne dwa polecenia dodają trasę do cowslip i trasę domyślną wykorzystującą cowslip jako gateway. Warto zwrócić uwagę na dwie rzeczy w wywołaniu ifconfig: opcję pointopoint określającą adres drugiego końca łącza punkt-punkt i wykorzystanie vlager-slip jako adresu lokalnego interfejsu SLIP. Wspomnieliśmy, że dla łącza SLIP możesz użyć tego samego adresu, który przypisałeś interfejsowi Ethernet na hoście vlager. W tym przypadku vlager-slip mógłby być po prostu aliasem adresu 172.16.1.1. Jednak możliwe jest również użycie zupełnie innego adresu dla łącza SLIP. Jedną z takich sytuacji jest sieć używająca nie zarejestrowanego adresu IP sieci, tak jak się to dzieje w naszym wirtualnym browarze. Powrócimy do tej sytuacji i opiszemy ją bardziej szczegółowo w następnym podrozdziale. W pozostałej części tego rozdziału zawsze będziemy używać vlager-slip, odwołując się do adresu lokalnego interfejsu SLIP. Przy wyłączaniu łącza SLIP powinieneś najpierw usunąć wszystkie trasy wiodące przez cowslip za pomocą polecenia route z opcją del, a następnie zamknąć interfejs i wysłać programowi slattach sygnał zawieszenia. Następnie musisz rozłączyć modem, używając ponownie programu swojego terminala: # route del default # route del cowslip # ifconfig sl0 down # kill -HUP 516 Pamiętaj, aby 516 zastąpić numerem ID procesu (pokazywanym w wyniku działania ps ax) polecenia slattach kontrolującego urządzenie slip, które chcesz zamknąć. Korzystanie z sieci prywatnych Pewnie pamiętasz z rozdziału 5, Konfigurowanie sieci TCP/IP, że browar wirtualny ma sieć IP wykorzystującą niezarejestrowane numery sieci zastrzeżone do użytku wewnętrznego. Pakiety kierowane z lub do tych sieci nie są rutowane do Internetu. Gdyby vlager łączył się z cowslip i działał jako ruter dla sieci browaru wirtualnego, hosty w sieci browaru nie mogłyby się bezpośrednio komunikować z prawdziwymi hostami z Internetu, ponieważ ich pakiety byłyby po cichu odrzucane przez pierwszy poważniejszy ruter. Aby rozwiązać ten problem, skonfigurujemy vlager tak, aby działał jako swego rodzaju przekaźnik udostępniający usługi internetowe. W świecie zewnętrznym będzie się on przedstawiał jako normalny host podłączony do Internetu za pośrednictwem protokołu SLIP, z zarejestrowanym adresem IP (prawdopodobnie przypisanym przez dostawcę usług, do którego należy cowslip). Każdy, kto zaloguje się do vlagera, może używać programów działających w trybie tekstowym, takich jak ftp, telnet czy nawet lynx, i za ich pomocą korzystać z Internetu. Każdy, kto należy do sieci lokalnej browaru wirtualnego, może zatem wywołać telnet i zalogować się do vlagera, a następnie używać na nim programów. Dla niektórych aplikacji mogą istnieć rozwiązania, które nie wymagają logowania się do vlagera. Na przykład w przypadku użytkowników WWW moglibyśmy na hoście vlager uruchomić tak zwany serwer proxy, który przekazywałby wszystkie żądania od użytkowników do odpowiednich serwerów. Wymóg zalogowania się do vlagera celem korzystania z Internetu jest nieco niewygodny. Ale ma też swoje zalety. Po pierwsze, eliminuje konieczność rejestrowania się w sieci IP, co wymaga wypełniania papierów i jest kosztowne, a po drugie daje dodatkowe korzyści przy konfigurowaniu firewalla. Firewalle są dedykowanymi hostami, które dając ograniczony dostęp do Internetu użytkownikom twojej sieci lokalnej, równocześnie zabezpieczają twoje wewnętrzne hosty przed atakami ze świata zewnętrznego. Prosta konfiguracja firewalla została szczegółowo opisana w rozdziale 9, Firewall TCP/IP. W rozdziale 11, Maskowanie IP i translacja adresów sieciowych, omawiamy funkcję Linuksa zwaną maskowaniem IP, które może być doskonałą alternatywą dla serwerów proxy. Załóżmy, że browar ma przypisany adres IP 192.168.5.74 dla dostępu przez SLIP. Aby uzyskać omówioną powyżej konfigurację, musisz jedynie wprowadzić ten adres do pliku /etc/hosts z nazwą vlager-slip. Procedura włączenia interfejsu SLIP pozostaje bez zmian. Korzystanie z polecenia dip Dotychczas opisane czynności nie były trudne. Niemniej jednak zapewne wolałbyś je zautomatyzować. Dużo lepiej byłoby mieć proste polecenie, które realizuje wszystkie wymienione kroki niezbędne do otworzenia urządzenia szeregowego, zadzwonienia do dostawcy, zalogowania się, włączenia protokołu obsługi SLIP i skonfigurowania interfejsu sieciowego. Takim poleceniem jest dip. Nazwa dip to skrót od angielskiego terminu dialup IP (IP łącza komutowanego). Polecenie to zostało napisane przez Freda van Kempena i rozwinięte dosyć znacznie przez wiele osób. Obecnie prawie wszyscy używają wersji dip337p-uri, która jest dołączana do większości współczesnych dystrybucji Linuksa, a także jest dostępna w archiwum FTP metalab.unc.edu. dip udostępnia interpreter prostego języka skryptowego, który może obsłużyć modem, zmienić tryb SLIP i skonfigurować interfejsy. Język skryptowy jest wystarczająco silny, by sprostać większości konfiguracji. Aby skonfigurować interfejs SLIP, dip potrzebuje przywilejów użytkownika root. Może cię kusić, aby nadać programowi dip prawo setuid root, tak by wszyscy użytkownicy (bez konieczności posiadania uprawnień roota) mogli dzwonić do serwera SLIP. Jest to bardzo niebezpieczne, ponieważ ustawienie fałszywych interfejsów i domyślnych tras za pomocą polecenia dip może uszkodzić ruting w twojej sieci. Co gorsza, da to twoim użytkownikom możliwość podłączenia się do dowolnego serwera SLIP i wykonywania z twojej sieci niebezpiecznych ataków. Jeśli chcesz pozwolić użytkownikom na uruchamianie połączenia SLIP, napisz małe programy dodatkowe dla każdego potencjalnego serwera SLIP i z nich wywołuj dip ze specjalnym skryptem nawiązującym połączenie. Poprawnie napisanemu programowi tego typu można bezpiecznie nadać prawo setuid root*. Alternatywnym, bardziej elastycznym podejściem jest nadanie zaufanym użytkownikom uprawnień roota do dip poprzez program typu sudo. Przykładowy skrypt Załóżmy, że host, z którym łączysz się przez SLIP, to cowslip. Napisaliśmy skrypt dla dipa - cowslip.dip - który realizuje nasze połączenie. Wywołujemy dip z nazwą skryptu jako argumentem: # dip cowslip.dip DIP: Dialup IP Protocol Driver version 3.3.7 (12/13/93) Written by Fred N. van Kempen, MicroWalt Corporation. connected to cowslip.moo.com with addr 192.168.5.74 # Sam skrypt pokazano w przykładzie 7-1. Przykład 7-1: Przykładowy skrypt dip # Przykładowy skrypt dip dzwoniący do cowslip # Ustawienie lokalnych i zdalnych nazw i adresów   get $local vlager-slip   get $remote cowslip   port ttyS3       # wybór portu szeregowego   speed 38400      # ustawienie prędkości na maksimum   modem HAYES      # ustawienie typu modemu reset          # wyzerowanie modemu i tty   flush          # wyczyszczenie bufora modemu # Przygotowanie do dzwonienia   send ATQ0V1E1X1\r   wait OK 2   if $errlvl !=0 goto error   dial 41988   if $errlvl !=0 goto error   wait CONNECT 60   if $errlvl !=0 goto error # Ok, jesteśmy podłączeni   sleep 3   send \r\n\r\n   wait ogin: 10   if $errlvl !=0 goto error   send $vlager\n   wait ssword: 5   if $errlvl !=0 goto error   send knockknock\n   wait running 30   if $errlvl !=0 goto error # Zalogowaliśmy się i po drugiej stronie uruchamiany jest SLIP.   print Connected to $remote with address $rmtip   default       # Ustawienie rutingu domyślnego na to łącze   mode SLIP       # Przechodzimy także do trybu SLIP # tu trafiamy w razie wystąpienia błędu error:   print SLIP to $remote failed. Po podłączeniu do cowslip i włączeniu SLIP, dip odłącza się od terminala i przechodzi do pracy w tle. Możesz zacząć uruchamiać normalne usługi sieciowe na łączu SLIP. Aby zakończyć połączenie, po prostu wywołaj dip z opcją -k, co spowoduje wysłanie sygnału do dip. Wykorzystane zostanie do tego ID procesu, które dip zapisuje w pliku /etc/dip.pid. # dip -k W języku skryptowym polecenia dip słowa kluczowe poprzedzone znakiem dolara oznaczają nazwy zmiennych. dip posiada predefiniowany zestaw zmiennych, które zostaną omówione poniżej. Na przykład $remote i $local zawierają odpowiednio nazwy hostów lokalnego i zdalnego, znajdujących się po obu stronach łącza SLIP. Pierwsze dwie dyrektywy w przykładowym skrypcie to polecenia get, za pomocą których dip definiuje zmienne. Nazwy hostów lokalnego i zdalnego są tu ustawiane odpowiednio na vlager i cowslip. Następne pięć dyrektyw konfiguruje terminal i modem. reset wysyła do modemu ciąg zerujący. Kolejna dyrektywa czyści bufor modemu tak, aby dialog logowania umieszczony w kolejnych kilku wierszach zadziałał poprawnie. Dialog ten jest dosyć prosty: po prostu dzwoni pod numer 41988 (numer telefonu cowslip) i loguje się na konto $vlager za pomocą hasła knockknock. Polecenie wait powoduje, że dip czeka na ciąg znaków podany jako pierwszy argument. Liczba podana jako drugi argument określa, po ilu sekundach kończy się oczekiwanie, jeżeli dany ciąg nie zostanie odebrany. Polecenia if występujące w procedurze logowania sprawdzają, czy nie wystąpił błąd w wykonywanym poleceniu. Ostatnie polecenia wywoływane po zalogowaniu się to: default, ustawiające domyślny ruting na zestawione właśnie łącze SLIP, i mode, włączające tryb SLIP na łączu i konfigurujące interfejs oraz tablicę rutingu. dip W tym podrozdziale podamy opis większości poleceń dip. Listę wszystkich poleceń możesz zobaczyć, wywołując dip w trybie testowym i wprowadzając help. Aby poznać składnię polecenia, możesz je wprowadzić bez żadnych argumentów. Pamiętaj, że nie sprawdzisz tak składni tych poleceń, które nie potrzebują argumentów. Poniższy przykład ilustruje polecenie help: # dip -t DIP: Dialup IP Protocol Driver version 3.3.7p-uri (25 Dec 96) Written by Fred N. van Kempen, MicroWalt Corporation. Debian version 3.3.7p-2 (debian). DIP> help DIP knows about the following commands:   beep       bootp    break    chatkey   config   databits   dec       default   dial      echo   flush    get       goto      help      if   inc       init       mode      modem    netmask   onexit    parity    password  proxyarp  print   psend    port       quit      reset    secureidfixed   securid    send       shell    skey      sleep   speed    stopbits   term      timeout   wait DIP> echo Usage: echo on|off DIP> W kolejnych podrozdziałach przykłady zawierające monit DIP> pokazują, jak wprowadzać polecenia w trybie testowym i jaki dają one wynik. Przykłady bez tego monitu należy traktować jako fragmenty skryptów. Polecenia dotyczące modemu dip udostępnia szereg poleceń konfigurujących łącze szeregowe i modem. Niektóre z nich są oczywiste, np. port, służący do wyboru portu szeregowego, czy speed, databits, stopbits i parity, ustawiające typowe parametry łącza. Polecenie modem wybiera typ modemu. Aktualnie jedynym obsługiwanym trybem jest HAYES (wymagane pisanie dużymi literami). Musisz określić programowi dip typ modemu, gdyż w przeciwnym razie nie będzie możliwe wykonanie poleceń dial i reset. Polecenie reset wysyła ciąg znaków zerujący modem. Stosowany ciąg zależy od wybranego typu modemu. W przypadku modemów kompatybilnych ze standardem Hayesa, ciągiem tym jest ATZ. Polecenie flush może być wykorzystane do usunięcia z bufora wszystkich odpowiedzi wysłanych przez modem do tej pory. W przeciwnym razie skrypt dialogowy występujący po poleceniu reset mógłby zgłupieć, ponieważ odczytałby odpowiedzi OK z poprzednich poleceń. Polecenie init określa ciąg inicjacyjny przekazywany do modemu przed rozpoczęciem dzwonienia. Domyślny ciąg dla modemów Hayesa to ATE0 Q0 V1 X1, włącza on wypisywanie poleceń i dzwonienie na ślepo (bez sprawdzania sygnału na linii). Nowsze modemy posiadają dobrą konfigurację fabryczną, a więc jest to zbędne, choć w niczym nie przeszkadza. Polecenie dial wysyła ciąg inicjacyjny do modemu i dzwoni do zdalnego systemu. Domyślne polecenie dzwonienia dla modemów Hayesa to ATD. Polecenie echo Polecenie echo jest doskonałą pomocą przy debugowaniu. Wywołanie echo on powoduje, że dip powtarza na konsoli wszystko, co wysyła do urządzenia szeregowego. Można to z powrotem wyłączyć, wydając polecenie echo off. dip pozwala także na chwilę wyjść z trybu skryptowego i wejść do trybu terminalowego. W tym trybie używasz dip tak jak zwykłego programu terminala, wysyłając wpisywane znaki na łącze szeregowe, odczytując dane z łącza szeregowego i wyświetlając znaki. Aby wyjść z tego trybu, naciśnij [CTRL+]]. Polecenie get Za pomocą polecenia get dip nadaje wartość zmiennej. Najprostsze jest przypisanie zmiennej stałej wartości, co robiliśmy w skrypcie cowslip.dip. Możesz jednak poprosić użytkownika o wprowadzenie czegoś, używając słowa kluczowego ask zamiast wartości: DIP> get $local ask Enter the value for $local: _ Trzecia metoda to uzyskanie wartości ze zdalnego hosta. W pierwszej chwili wygląda to dziwacznie, ale nieraz się bardzo przydaje. Niektóre serwery SLIP nie pozwolą ci używać własnego adresu IP na łączu SLIP, a po połączeniu będą przypisywać ci adres z puli, wypisując komunikat informujący o otrzymanym adresie. Jeżeli otrzymasz komunikat: "Your address: 192.168.5.74, poniższy fragment kodu dip pozwoli ci przypisać ten adres: # zakończenie logowania się wait address: 10 get $locip remote Polecenie print Jest to polecenie używane do wyświetlania tekstów dip na konsoli, z której został uruchomiony. W poleceniu print mogą być użyte wszystkie zmienne dip. Oto przykład: DIP> print Using port $port at speed $speed Using port ttyS3 at speed 38400 Nazwy zmiennych dip rozumie tylko predefiniowany zestaw zmiennych. Nazwy zmiennych zawsze zaczynają się od znaku dolara i muszą być pisane małymi literami. Zmienne $local i $locip zawierają nazwę i adres lokalnego hosta. Jeżeli w zmiennej $local zapiszesz kanoniczną nazwę hosta, dip będzie automatycznie próbował zamienić nazwę hosta na jego adres IP i zapisać go w zmiennej $locip. Podobny, aczkolwiek odwrotny proces zachodzi, gdy przypiszesz adres IP zmiennej $locip: dip będzie próbował wyszukiwania odwrotnego, czyli będzie chciał zidentyfikować nazwę hosta i zapisać ją w zmiennej $local. Zmienne $remote i $rmtip działają w ten sam sposób dla adresu i nazwy hosta zdalnego. $mtu zawiera wartość MTU dla połączenia. Te pięć zmiennych to jedyne zmienne, którym wartości mogą być przypisywane bezpośrednio za pomocą polecenia get. Szereg innych zmiennych jest ustawianych w wyniku działania poleceń konfiguracyjnych o tej samej nazwie, a mogą one być używane w dyrektywie print. Należą do nich $modem, $port i $speed. $errlvl jest zmienną, przez którą uzyskujesz wynik wykonania ostatniego polecenia. Poziom błędu 0 oznacza poprawne wykonanie, natomiast wartości różne od zera oznaczają błąd. Polecenia if i goto Polecenie if to tradycyjne rozgałęzienie warunkowe, a nie w pełni wyposażona programistyczna dyrektywa if. Składnia jest następująca: if zm op liczba goto etykieta Wyrażenie musi być prostym porównaniem jednej ze zmiennych: $errlvl, $locip lub $rmtip. zm musi być liczbą całkowitą, operator op może być jednym ze znaków ==, !=, <, >, <= i >=. Polecenie goto powoduje, że wykonywanie skryptu jest kontynuowane od wiersza, który następuje po etykiecie. Etykieta musi być pierwszym słowem w wierszu i musi być zakończona dwukropkiem. send, wait i sleep Te polecenia pomagają zaimplementować proste skrypty dialogowe w dip. Polecenie send wysyła argumenty do łącza szeregowego. Nie obsługuje zmiennych, ale rozumie wszelkie sekwencje ze znakami ukośnika odwrotnego znane z języka C, takie jak \n oznaczające nowy wiersz i \b oznaczające cofnięcie. Znak tyldy (~) może być zastosowany jako skrót ciągu znaków: powrót karetki/nowy wiersz. Polecenie wait jako argument przyjmuje słowo i odczytuje wszystkie dane wejściowe na łączu szeregowym, aż wykryje ciąg znaków pasujący do zadanego słowa. Samo słowo nie może zawierać spacji. Opcjonalnie, jako drugi argument, możesz podać w poleceniu wait wartość czasu oczekiwania. Jeżeli oczekiwane słowo nie zostanie odebrane w tym czasie, polecenie zwróci w zmiennej $errlvl wartość 1. Polecenie to jest używane do wykrywania monitu logowania i innych. Polecenie sleep może być używane do odczekania pewnego czasu. Na przykład, aby cierpliwie zaczekać na zakończenie sekwencji logowania. Znów czas jest podawany w sekundach. mode i default Te polecenia są używane do przełączania łącza szeregowego w tryb SLIP i konfigurowania interfejsu. Polecenie mode jest ostatnim poleceniem wykonywanym przez dip przed przejściem w tryb demona. Dopóki nie wystąpi błąd, polecenie nie kończy się. mode przyjmuje jako argument nazwę protokołu. Obecnie dip rozpoznaje SLIP, CSLIP, SLIP6, CSLIP6, PPP i TERM. Jednak aktualna wersja dip nie rozumie trybu adaptive SLIP. Po przełączeniu łącza szeregowego do trybu SLIP, dip wywołuje polecenie ifconfig w celu skonfigurowania interfejsu jako łącza punkt-punkt i polecenie route do skonfigurowania rutingu do zdalnego hosta. Jeżeli skrypt dodatkowo wywoła polecenie default przed poleceniem mode, dip tworzy domyślny ruting wskazujący na łącze SLIP. Działanie w trybie serwera Skonfigurowanie klienta SLIP było trudniejszym zadaniem. Skonfigurowanie twojego hosta, aby działał jako serwer SLIP jest dużo łatwiejsze. Istnieją dwa sposoby skonfigurowania serwera SLIP. Oba wymagają utworzenia jednego konta logowania dla każdego klienta SLIP. Załóżmy, że udostępniasz usługę SLIP Arthurowi Dentowi z dent.beta.com. Dodając poniższy wiersz do twojego pliku passwd, możesz stworzyć konto o nazwie dent: dent:*:501:60:Konto SLIP Arthura Denta:/tmp:/usr/sbin/diplogin Następnie za pomocą polecenia passwd musisz ustawić hasło użytkownika dent. Polecenie dip może być uruchomione w trybie serwera przez wywołanie diplogin. Zwykle diplogin jest dowiązaniem do dip. Jego głównym plikiem konfiguracyjnym jest /etc/diphosts, w którym zwykle wpisujesz adres IP przypisywany użytkownikowi, gdy zadzwoni. Alternatywnie możesz także użyć polecenia sliplogin, narzędzia pochodzącego z BSD i posiadającego bardziej elastyczny schemat konfiguracji pozwalający ci na wywoływanie skryptów powłoki, gdy host się podłącza lub rozłącza. Gdy nasz użytkownik SLIP-a, dent, zaloguje się, dip jest uruchamiany jako serwer. Aby stwierdzić, czy dany użytkownik naprawdę ma prawo używać SLIP-a, szuka on nazwy użytkownika w pliku /etc/diphosts. Plik ten zawiera szczegółowe prawa dostępu i parametry połączenia dla każdego użytkownika SLIP-a. Ogólny format wpisu w /etc/diphosts jest następujący: # /etc/diphosts użytkownik:hasło:adres-zdalny:adres-lokalny:maska:komentarze:protokół,MTU # Każde z pól jest opisane w tabeli 7-2. Tabela 7-2. Opis pól pliku /etc/diphosts Pole Opis użytkownik Pole to określa nazwę użytkownika wywołującego dip. Hasło Drugie pole pliku /etc/diphosts jest używane do zapewnienia dodatkowej warstwy bezpieczeństwa przy łączeniu się na podstawie hasła. Możesz tu umieścić hasło w zaszyfrowanej postaci (tak jak w pliku /etc/passwd), a diplogin poprosi użytkownika o wprowadzenie hasła, zanim pozwoli mu na dostęp SLIP. Zauważ, że jest to hasło uzupełniające, używane obok zwykłego hasła wprowadzanego w monicie login. adres-zdalny Adres, który zostanie przypisany zdalnej maszynie. Adres ten może być podany także w postaci nazwy hosta, która zostanie zamieniona na numer IP, albo bezpośrednio w postaci numeru IP w notacji kropkowej. adres-lokalny Adres IP, który będzie używany dla lokalnego końca połączenia SLIP. Może być podany w postaci nazwy hosta lub numeru IP. maska Maska sieci, która będzie używana do rutingu. Wiele osób źle interpretuje to pole. Maska sieci nie dotyczy samego łącza SLIP, ale jest używana w połączeniu z adresem-zdalnym do utworzenia trasy do zdalnej sieci. Maska sieci powinna być taka sama jak maska używana przez sieć obsługiwaną przez zdalnego hosta. komentarze Jest to pole tekstowe, w którym można wprowadzić dowolny opis i jest ono traktowane jako pomoc w dokumentowaniu pliku /etc/diphosts. Pole to nie ma innych zastosowań. protokół W tym polu określa się, jakiego protokołu obsługi chcesz używać dla danego połączenia. Poprawne wpisy są identyczne z używanymi z argumentem -p polecenia slattach. MTU Maksymalna jednostka transmisji, którą można przesłać przez łącze. To pole opisuje największy datagram przesyłany przez łącze. Każdy datagram rutowany przez urządzenie SLIP, który jest większy niż MTU, zostanie podzielony na datagramy nie większe niż ta wartość. MTU zwykle jest konfigurowane tak samo na obu końcach łącza. Przykładowy wpis dla dent mógłby wyglądać tak: dent::dent.beta.com:vbrew.com:255.255.255.0:Arthur Dent:CSLIP,296 Ten przykład daje naszemu użytkownikowi dent dostęp do SLIP-a bez potrzeby wprowadzania dodatkowego hasła. Będzie mu przypisany adres IP związany z nazwą dent.beta.com i maska sieci 255.255.255.0. Domyślny ruting powinien być przekierowany na adres IP vbrew.com. Połączenie będzie wykorzystywało protokół CSLIP z MTU równym 296 bajtów. Gdy dent się zaloguje, diplogin odczyta informacje na jego temat z pliku diphosts. Gdyby drugie pole zawierało wartość, diplogin poprosiłby o dodatkowe hasło. Wprowadzony przez użytkownika ciąg znaków zostałby zaszyfrowany i porównany z hasłem z pliku diphosts. Gdyby ciągi się nie zgadzały, próba zalogowania nie powiodłaby się. Gdyby pole hasła zawierało ciąg znaków s/key, a dip byłby skompilowany z obsługą S/Key, uruchomione byłoby uwierzytelnianie S/Key. Jest ono opisane w dokumentacji zawartej w pakiecie źródłowym dip. Po poprawnym zalogowaniu się, diplogin przełącza łącze szeregowe w tryb CSLIP lub SLIP i konfiguruje interfejs oraz ruting. Połączenie pozostaje zestawione, dopóki użytkownik go nie rozłączy i modem nie zostanie odłączony od linii telefonicznej. diplogin przywraca łącze szeregowe do normalnego protokołu obsługi i kończy pracę. diplogin wymaga praw użytkownika uprzywilejowanego. Jeżeli dip nie działa z prawem setuid root, powinieneś spowodować, żeby diplogin był oddzielną kopią dip, a nie dowiązaniem. diplogin może wtedy mieć nadane prawo setuid bez zmiany statusu samego dip. 8 Protokół punkt-punkt Rozdział 8: Protokół punkt-punkt Podobnie jak SLIP, protokół PPP jest używany do wysyłania datagramów przez łącze szeregowe, jednak nie ma on wielu wad SLIP-a. Po pierwsze, pozwala na przesyłanie większej liczby protokołów i nie jest ograniczony do protokołu IP. Ma możliwość wykrywania błędów na samym łączu, gdzie SLIP akceptował i przekazywał uszkodzone datagramy, chyba że uszkodzony został nagłówek. Ponadto, pozwala stronom połączenia negocjować na początku opcje, takie jak adres IP i maksymalny rozmiar datagramu, oraz zapewnia uwierzytelnianie klienta. Taka wbudowana możliwość negocjacji pozwala na niezawodną automatyzację przy zestawianiu połączenia, natomiast dzięki uwierzytelnianiu nie są potrzebne sztuczne konta użytkowników, które były stosowane w przypadku SLIP-a. Każda z tych możliwości jest w PPP obsługiwana przez oddzielny protokół. W tym rozdziale krótko omówimy podstawowe moduły PPP. Niniejszy opis PPP jest daleki od kompletności, a więc jeżeli chcesz wiedzieć więcej, zachęcamy cię do przeczytania specyfikacji protokołu w odpowiednim dokumencie RFC i szeregu uzupełniających RFC. Istnieje również cała książka poświęcona temu tematowi: Using & Managing PPP napisana przez Andrew Suna (O'Reilly). Na samym dole PPP znajduje się protokół wysokopoziomowego sterowania łączem danych (High-Level Data Link Control - HDLC), który definiuje granice pojedynczych ramek PPP i zapewnia 16-bitową sumę kontrolną*. W przeciwieństwie dość prymitywnej enkapsulacji SLIP, ramka PPP może zawierać pakiety różnych protokołów, nie tylko IP, czyli na przykład IPX Novella czy AppleTalk. PPP dodaje bowiem do podstawowej ramki HDLC pole protokołu identyfikujące typ pakietu przesyłanego w ramce. Nad HDLC znajduje się protokół sterowania łączem (Link Control Protocol - LCP) negocjujący opcje dotyczące łącza danych, na przykład maksymalną jednostkę odbioru (Maximum Receive Unit - MRU) wyznaczającą maksymalny rozmiar datagramu, jaki jedna strona łącza zgodziła się odbierać. Ważnym krokiem naprzód w konfiguracji łącza PPP jest autoryzacja (uwierzytelnienia) klienta. Choć nie jest ona obowiązkowa, powinna być używana w przypadku linii komutowanych, aby nie dopuścić intruzów do systemu. Zazwyczaj wywoływany host (serwer) prosi klienta o podanie tajnego klucza. Jeżeli host wywołujący nie wygeneruje odpowiedniego klucza, połączenie jest zrywane. W PPP autoryzacja działa w obie strony. Host wywołujący może również poprosić o autoryzację serwera. Te procedury są zupełnie niezależne od siebie. Dla dwóch różnych sposobów autoryzacji istnieją dwa protokoły, które będziemy dokładniej omawiali w tym rozdziale: protokół uwierzytelniania hasłem (Password Authentication Protocol - PAP) i protokół uwierzytelnienia przez uzgodnienie (Challenge Handshake Authentication Protocol -- CHAP). Każdy protokół sieciowy rutowany przez łącze danych (jak IP i AppleTalk) jest konfigurowany dynamicznie za pomocą odpowiedniego  protokołu sterowania siecią (Network Control Protocol - NCP). Aby wysłać datagram IP przez łącze, obie strony uczestniczące w połączeniu PPP muszą najpierw wynegocjować używane przez każdą z nich adresy IP. Protokół sterujący używany w tej negocjacji to protokół sterowania protokołem internetowym (Internet Protocol Control Protocol - IPCP). Poza wysyłaniem standardowych datagramów IP przez łącze, PPP także obsługuje kompresję nagłówków (Van Jacobsona) datagramów IP. Technika ta zmniejsza nagłówki pakietów IP do zaledwie trzech bajtów. Jest ona także stosowana w CSLIP i potocznie nazywa się ją kompresją nagłówków VJ. Użycie kompresji może być również negocjowane za pomocą protokołu IPCP. PPP w Linuksie W Linuksie do funkcjonowania PPP są potrzebne dwie rzeczy: element jądra obsługujący protokoły niskopoziomowe (HDLC, IPCP, IPXCP itp.) i demon pppd działający w przestrzeni użytkownika i obsługujący różne protokoły wyższego poziomu, takie jak PAP i CHAP. Aktualna wersja oprogramowania PPP dla Linuksa zawiera demon pppd i program o nazwie chat, które automatyzują połączenie telefoniczne z systemu zdalnego. Sterownik PPP jądra został napisany przez Michaela Callahana i przerobiony przez Paula Mackerrasa. pppd powstało na podstawie darmowej implementacji PPP* dla Suna i komputerów 386BSD, napisanej przez Drew Perkinsa i innych i utrzymywanej przez Paula Mackerrasa. Zostało przeniesione na Linuksa przez Ala Longyeara. Program chat napisał Karl Fox**. Podobnie jak SLIP, tak i PPP został zaimplementowany przez specjalny protokół obsługi łącza. Aby wykorzystać łącze szeregowe jako łącze PPP, musisz najpierw jak zwykle zestawić połączenie przez modem, a następnie przełączyć łącze w tryb PPP. W tym trybie wszystkie przychodzące dane są przekazywane sterownikowi PPP, który sprawdza poprawność przychodzących ramek HDLC (każda ramka HDLC zawiera 16-bitową sumę kontrolną), rozpakowuje je oraz obsługuje. Obecnie PPP jest w stanie przesyłać zarówno protokół IP, opcjonalnie z kompresją nagłówków Van Jacobsona, jak i protokół IPX. pppd wspomaga sterownik jądra, wykonując obowiązkową fazę inicjacyjną i uwierzytelniającą, zanim rzeczywisty ruch sieciowy zostanie przesłany przez łącze. Zachowanie pppd można regulować szeregiem opcji. Ponieważ PPP jest raczej złożonym protokołem, niemożliwe jest wyjaśnienie wszystkich opcji w jednym rozdziale. Dlatego ta książka nie omawia wyczerpująco pppd, a tylko podaje ogólny zarys. Dokładniejsze informacje znajdziesz we wspomnianej już książce Using & Managing PPP lub na stronach podręcznika elektronicznego pppd oraz we wspomnianych już plikach README pakietu źródłowego pppd. Pomogą ci one odpowiedzieć na większość pytań, które tutaj nie zostały uwzględnione. Pomocny może być także dokument PPP-HOWTO. Prawdopodobnie w konfigurowaniu PPP najbardziej pomogą ci inni użytkownicy tej samej dystrybucji Linuksa. Pytania o konfigurację PPP są dosyć powszechne, a więc sprawdź swoją lokalną grupę dyskusyjną lub kanał linuksowy na IRC-u. Jeżeli masz problemy nawet po przeczytaniu dokumentacji, możesz spróbować je rozwiązać poprzez grupę dyskusyjną comp.protocols.ppp. Jest to miejsce, gdzie spotyka się większość osób zaangażowanych w rozwój pppd. Eksploatacja pppd Gdy chcesz się podłączyć do Internetu przez łącze PPP, musisz skonfigurować podstawowe funkcje sieciowe, jak urządzenie pętli zwrotnej i resolver. Obie zostały omówione w rozdziale 5, Konfigurowanie sieci TCP/IP, i w rozdziale 6, Usługi nazewnicze i konfigurowanie resolvera. Możesz po prostu skonfigurować serwer nazw swojego dostawcy Internetu w pliku /etc/resolv.conf, ale będzie to oznaczało, że każde żądanie DNS jest wysyłane przez łącze szeregowe. Ta sytuacja nie jest optymalna. Im jesteś bliżej (w sensie sieci) swojego serwera nazw, tym szybciej są realizowane wyszukiwania nazw. Alternatywnym rozwiązaniem jest skonfigurowanie serwera nazw pamięci podręcznej na hoście w twojej sieci. Oznacza to, że  pierwsze zapytanie DNS o określonego hosta jest wysyłane przez łącze szeregowe, ale odpowiedź na każde kolejne będzie wysyłana bezpośrednio z twojego lokalnego serwera nazw i będzie realizowana dużo szybciej. Konfiguracja ta jest opisana w podrozdziale Konfiguracja named jako serwera pamięci podręcznej rozdziału 6. Dla potrzeb naszego przykładu realizacji połączenia PPP z pppd załóżmy, że znów jesteś na hoście vlager. Najpierw dzwonisz do serwera PPP, c3po, i logujesz się na koncie ppp. Serwer c3po uruchamia swój sterownik PPP. Po zakończeniu pracy z programem komunikacyjnym używanym do dzwonienia, jest wykonywane następujące polecenie, w którym musisz zastąpić pokazaną nazwę urządzenia szeregowego ttyS3 swoją nazwą. # pppd /dev/ttyS3 38400 crtscts defaultroute Polecenie to przełącza łącze szeregowe ttyS3 na protokół obsługi PPP i negocjuje łącze IP z c3po. Prędkość używana na tym porcie szeregowym wynosi 38 400 bitów na sekundę. Opcja crtscts włącza na porcie uzgadnianie sprzętowe, które jest bezwzględnie wymagane przy prędkościach powyżej 9600 bps. Po uruchomieniu pppd w pierwszej kolejności negocjuje kilka charakterystyk łącza z drugą stroną za pomocą LCP. Zwykle wystarcza domyślny zestaw opcji pppd, a więc nie będziemy tu rozwijać tego tematu. Wystarczy powiedzieć, że ta negocjacja częściowo dotyczy żądania lub przypisania adresów IP dla każdej ze stron połączenia. Na razie zakładamy, że serwer c3po nie wymaga od nas żadnego uwierzytelnienia, a więc faza konfiguracji kończy się pełnym sukcesem. pppd będzie następnie negocjować parametry IP z drugą stroną, używając IPCP - protokołu sterującego IP. Ponieważ wcześniej nie określiliśmy żadnego szczególnego adresu IP dla pppd, to będzie on próbować wykorzystać adres uzyskany od resolvera sprawdzającego lokalną nazwę hosta. Następnie obie strony przekażą sobie wzajemnie swoje adresy. Zwykle w ustawieniach domyślnych nie ma nic złego. Nawet jeżeli twój komputer znajduje się w sieci Ethernet, możesz mieć ten sam adres IP zarówno dla interfejsu Ethernet, jak i PPP. Jednak pppd pozwala używać innego adresu, a nawet zasugerować drugiej stronie użycie jakiegoś określonego adresu. Opcje te omawiamy dalej, w podrozdziale Opcje konfiguracyjne IP. Po przejściu przez fazę konfiguracji IPCP, pppd przygotuje warstwę sieciową twojego hosta do działania w roli łącza PPP. Najpierw konfiguruje interfejs sieciowy PPP jako łącze punkt-punkt, używając ppp0 dla pierwszego aktywnego łącza PPP, ppp1 dla drugiego i tak dalej. Następnie dokonuje wpisu w tablicy rutingu, tak by wskazywał on na hosta po drugiej stronie łącza. W poprzednim przykładzie pppd ustawił domyślny ruting do sieci na c3po, ponieważ podaliśmy go w opcji defaultroute*. Obecność trasy domyślnej upraszcza ruting, gdyż wszelkie datagramy IP nie przeznaczone dla hosta lokalnego są wysyłane do c3po. Ma to sens, ponieważ jest to jedyna trasa, którą można do niego dotrzeć. Istnieje szereg różnych schematów rutingu obsługiwanych przez pppd. Omówimy je szczegółowo w dalszej części tego rozdziału. Używanie plików opcji Zanim pppd dokona analizy składniowej argumentów wiersza poleceń, przegląda kilka plików w poszukiwaniu opcji domyślnych. Pliki te mogą zawierać wszelkie dopuszczalne argumenty wiersza poleceń rozrzucone po wielu wierszach. Znaki hasha (#) oznaczają komentarze. Pierwszym plikiem opcji jest /etc/ppp/options. Jest on zawsze przeglądany podczas uruchamiania pppd. Użycie tego pliku do ustawienia kilku globalnych wartości domyślnych jest dobrym pomysłem, ponieważ pozwala powstrzymać użytkowników od zrobienia pewnych rzeczy, które mogą zagrażać bezpieczeństwu systemu. Na przykład, aby włączyć w pppd wymóg uwierzytelniania (PAP czy CHAP) dla drugiej strony, wystarczy dodać w tym pliku opcję auth. Opcja ta nie może być zmieniona przez użytkownika, a więc niemożliwe staje się zrealizowanie połączenia PPP z jakimkolwiek systemem, który nie znajduje się w autoryzacyjnej bazie danych. Zauważ jednak, że niektóre opcje można zmienić. Dobrym przykładem jest ciąg znaków opcji connect. Inny plik opcji odczytywany po /etc/ppp/options, to .ppprc w katalogu macierzystym użytkownika. Pozwala on każdemu użytkownikowi określić własny zestaw opcji domyślnych. Przykładowy plik /etc/ppp/options mógłby wyglądać tak: # Globalne opcje dla pppd działającego na vlager.vbrew.com lock             # użyj blokowania urządzenia w stylu UUCP auth             # wymóg uwierzytelnienia usehostname       # użyj lokalnej nazwy hosta dla CHAP domain vbrew.com   # nazwa naszej domeny Słowo kluczowe lock powoduje, że pppd obsługuje metodę blokowania urządzenia zgodną ze standardem UUCP. W tej konwencji każdy proces, który ma dostęp do urządzenia szeregowego, na przykład /dev/ttyS3, tworzy w specjalnym katalogu plik blokujący o nazwie postaci LCK..ttyS3 i w ten sposób informuje, że urządzenie jest używane. Jest to jedyna możliwość, aby inne programy, takie jak minicom czy uucico, nie otwierały urządzeń szeregowych używanych przez PPP. Kolejne trzy opcje odnoszą się do uwierzytelniania i co za tym idzie są związane z bezpieczeństwem systemu. Opcje uwierzytelniania najlepiej umieścić w globalnym pliku konfiguracyjnym, ponieważ jest on "uprzywilejowany" i ma wyższy priorytet niż pliki opcji użytkowników ~/.ppprc (nie mogą oni zmieniać ustawionych w nim opcji). Stosowanie chat do automatycznego dzwonienia Jedną z rzeczy w poprzednim przykładzie, która mogła wydać ci się niewygodna, jest to, że musisz ręcznie zrealizować połączenie, zanim będziesz mógł uruchomić pppd. W odróżnieniu od dip, pppd nie ma własnego języka skryptowego pozwalającego na dzwonienie i logowanie się do zdalnych systemów, ale korzysta z zewnętrznego programu lub skryptu powłoki. Polecenie do wykonania może być podane pppd za pomocą opcji wiersza poleceń connect. pppd przekieruje standardowe wejście i wyjście polecenia do łącza szeregowego. Pakiet oprogramowania pppd zawiera bardzo prosty program chat, który może być używany do automatyzacji prostych sekwencji logowania. Polecenie to omówimy bardziej szczegółowo. Jeżeli twoja sekwencja logowania jest złożona, będziesz potrzebował czegoś lepszego niż chat. Na pewno wart rozważenia jest expect, napisany przez Dona Libesa. Ma bardzo wydajny język oparty na Tcl i został przewidziany właśnie do takich zadań. Jeśli masz sekwencję logowania, która wymaga na przykład uwierzytelnienia typu wywołanie/odpowiedź, opatrego na kalkulatorowych generatorach kluczy, przekonasz się, że expect jest wystarczająco dobry, by zrealizować to zadanie. Ponieważ możliwości są tutaj duże, nie będziemy opisywali, jak stworzyć odpowiedni skrypt expecta. Dość powiedzieć, że swój skrypt expect możesz wywołać, podając jego nazwę w opcji connect pppd. Trzeba także wiedzieć, że gdy skrypt zostanie uruchomiony, standardowe wejście i wyjście zostaną podłączone do modemu, a nie do terminala, z którego został wywołany pppd. Jeżeli wymagana jest interakcja z użytkownikiem, powinieneś ją obsłużyć, otwierając dodatkowy wirtualny terminal lub w jakiś inny sposób. Polecenie chat pozwala ci stworzyć skrypt dialogowy w stylu UUCP. Zasadniczo skrypt chat składa się z kolejnych sekwencji ciągów znaków, których oczekujemy od zdalnego systemu, i odpowiedzi, które na nie wysyłamy. Nazywamy je odpowiednio ciągiem oczekiwanym (ang. expect string) i ciągiem wysyłanym (ang. send string). Oto typowy fragment skryptu dialogowego: ogin: b1ff ssword: s3|    [*] Network firewalls    [*] TCP/IP networking    [*] IP: firewalling    [*] IP: firewall packet logging W jądrach 2.4.0 i nowszych powinieneś wybrać poniższe opcje: Networking options --->   [*] Network packet filtering (replaces ipchains)       IP: Netfilter Configuration ---?          .           Userspace queueing via NETLINK (EXPERIMENTAL)          IP tables support (required for filtering/masq/NAT)          limit match support           MAC address match support           netfilter MARK match support          Multiple port match support           TOS match support           Connection state match support           Unclean match support (EXPERIMENTAL)           Owner match support (EXPERIMENTAL)           Packet filtering             REJECT target support             MIRROR target support (EXPERIMENTAL)           .           Packet mangling             TOS target support             MARK target support           LOG target support           ipchains (2.2-style) support         ipfwadm (2.0-style) support Narzędzie ipfwadm Narzędzie ipfwadm (IP Firewall Administration) jest używane do tworzenia reguł firewalla dla wszystkich jąder starszych od wersji 2.2.0. Składnia polecenia bywa zagmatwana, ponieważ może ono realizować wiele skomplikowanych zadań, ale podamy kilka przykładów popularnych zastosowań. Narzędzie ipfwadm jest zawarte w większości współczesnych dystrybucji Linuksa, ale niekoniecznie standardowo. Mogą istnieć szczególne pakiety oprogramowania, które musisz zainstalować, aby mieć to polecenie. Jeżeli nie ma go w twojej dystrybucji, możesz zdobyć pakiet źródłowy z ośrodka ftp.xos.nl z katalogu /pub/linux/ ipfwadm/ i skompilować go samodzielnie. Narzędzie ipchains Podobnie jak ipfwadm, tak ipchains może sprawić na początku nieco kłopotów. Udostępnia całą elastyczność ipfwadm, ale za pomocą poleceń o znacznie uproszczonej składni, a ponadto oferuje mechanizm "łączenia w łańcuchy" (ang. chaining), pozwalający na zarządzanie wieloma zestawami reguł i ich łączenie. Łączenie reguł omówimy w oddzielnym podrozdziale pod koniec tego rozdziału, ponieważ jest to pojęcie zaawansowane. Polecenie ipchains istnieje w większości dystrybucji Linuksa opartych na jądrach 2.2. Gdybyś chciał skompilować je samodzielnie, możesz znaleźć pakiet źródłowy pod adresem: http://www.rustcorp.com/linux/ipchains/. W pakiecie tym znajduje się dodatkowy skrypt ipfwadm-wrapper, który naśladuje polecenie ipfwadm, ale w rzeczywistości wywołuje polecenie ipchains. Migracja istniejącej konfiguracji firewalla jest dużo mniej bolesna, jeżeli posiada się taki skrypt. Narzędzie iptables Składnia narzędzia iptables jest bardzo podobna do ipchains. Różnice wynikają z wprowadzonych udoskonaleń i dają przeprojektowane narzędzie, które jest rozszerzalne przez biblioteki dzielone. Tak jak w przypadku ipchains, tak i przy iptables podamy skonwertowane przykłady, abyś mógł porównać i zestawić składnię tego i innych poleceń. Narzędzie iptables znajduje się w pakiecie netfilter, który jest dostępny pod adresem http://www.samba.org/netfilter/. Będzie także zawarte we wszystkich dystrybucjach Linuksa opartych o jądra serii 2.4. Nieco więcej o netfilter powiemy w jednym z następnych podrozdziałów poświęconych tylko temu pakietowi. Trzy sposoby realizacji filtrowania Rozważmy, w jaki sposób maszyna uniksowa, czy w praktyce dowolna inna obsługująca ruting IP, przetwarza datagramy IP. Rysunek 9-2. Etapy przetwarzania datagramu IP http://www.rm.com.pl/upgr/lpas/09-02.tif Podstawowe kroki, pokazane na rysunku 9-2, to: ˇ Datagram IP jest odbierany (1). ˇ Przychodzący datagram IP jest analizowany w celu ustalenia, czy jest przeznaczony dla tej maszyny. ˇ Jeżeli datagram jest dla tej maszyny, jest przetwarzany lokalnie (2). ˇ Jeżeli nie jest dla tej maszyny, w tablicy rutingu jest poszukiwana odpowiednia trasa. Datagram jest przekazywany do odpowiedniego interfejsu lub odrzucany, jeżeli trasy nie można znaleźć (3). ˇ Datagramy z lokalnych procesów są wysyłane do oprogramowania rutującego w celu przekazania do odpowiedniego interfejsu (4). ˇ Wychodzący datagram IP jest analizowany w celu ustalenia, czy istnieje dla niego odpowiednia trasa; jeżeli nie, jest odrzucany. ˇ Datagram IP jest wysyłany (5). W naszym diagramie, przepływ 1?3?5 przedstawia maszynę rutującą dane pomiędzy hostem w naszej sieci Ethernet a hostem osiągalnym przez łącze PPP. Przepływ 1?2 i 4?5 przedstawia dane przychodzące i wychodzące z programu sieciowego działającego na naszym hoście lokalnym. Przepływ 4?3?2 przedstawia przepływ danych przez połączenie pętli zwrotnej. Oczywiście dane przepływają w obie strony, do i z urządzeń sieciowych. Znak zapytania na diagramie przedstawia punkty, gdzie warstwa IP podejmuje decyzje co do rutingu. Firewall jądra Linuksa może stosować filtry na różnych etapach tego procesu. To znaczy, że możesz filtrować datagramy IP przychodzące do twojej maszyny, albo te datagramy, które są przez nią przekazywane, albo też te, które są gotowe do wysłania. W programach ipfwadm i ipchains reguła wejściowa (Input) dotyczy przepływu 1 na diagramie, reguła przekazywania (Forwarding) - przepływu 3, a reguła wyjściowa (Output) - przepływu 5. Zobaczymy później, przy omawianiu netfilter, że punkty przechwytywania zmieniły się tak, że reguła wejściowa dotyczy przepływu 2, a reguła wyjściowa - przepływu 4. Ma to istotny wpływ na tworzenie reguł, ale ogólne zasady pozostają takie same dla wszystkich wersji firewalla w Linuksie. Na pierwszy rzut oka może to wyglądać na niepotrzebną komplikację, ale zapewnia elastyczność, która pozwala na tworzenie bardzo wyrafinowanych i wydajnych konfiguracji. Oryginalny firewall IP (jądra 2.0) Pierwsza generacja obsługi firewalla IP w Linuksie pojawiła się w serii jąder 1.1. Było to przeniesienie ipfw z BSD dokonane przez Alana Coxa. Obsługa firewalla w jądrach serii 2.0, określana mianem drugiej generacji, została rozszerzona przez Josa Vos, Pauline Middelink i innych. Korzystanie z ipfwadm Polecenie ipfwadm było narzędziem konfiguracyjnym dla drugiej generacji firewalla IP w Linuksie. Najlepiej jest opisać użycie ipfwadm na przykładach. Na początek zakodujmy pokazany wcześniej przykład. Prosty przykład Załóżmy, że mamy w naszej firmie sieć i używamy firewalla na komputerze z Linuksem, przez który łączymy naszą sieć z Internetem. Przyjmijmy też, że chcemy, aby użytkownicy sieci mieli dostęp do serwerów WWW w Internecie, ale nie dopuszczamy żadnego innego ruchu. Zdefiniujemy regułę przekazywania pozwalającą na przepuszczanie na zewnątrz datagramów o adresie źródłowym należącym do naszej sieci i gnieździe docelowym 80 oraz na przekazywanie przez firewall odpowiedzi przesyłanych z powrotem. Załóżmy, że nasza sieć ma 24-bitową maskę (klasa C) i adres 172.16.1.0. Reguły wyglądają tak: # ipfwadm -F -f # ipfwadm -F -p deny # ipfwadm -F -a accept -P tcp -S 172.16.1.0/24 -D 0/0 80 # ipfwadm -F -a accept -P tcp -S 0/0 80 -D 172.16.1.0/24 Argument wiersza poleceń -F mówi ipfwadm, że jest to reguła przekazywania. Pierwsze polecenie mówi ipfwadm, aby usunął wszystkie dotychczasowe reguły przekazywania ze swojej konfiguracji. W ten sposób rozpoczynamy od znanego stanu. Druga reguła określa domyślną politykę przekazywania. Mówimy jądru, by odrzucało lub nie pozwalało na przekazywanie datagramów IP. Bardzo ważne jest ustawienie polityki domyślnej, ponieważ opisuje ona, co się stanie z datagramami, które nie są w żaden szczególny sposób obsługiwane przez inne reguły. Zwykle konfigurując firewall, będziesz ustawiał domyślną politykę na "odmowę", tak jak to pokazano tutaj, po to, aby przez firewalla przechodził tylko dopuszczalny ruch. Trzecia i czwarta reguła implementują nasze wymaganie: - trzecie polecenie pozwala na wysyłanie naszych datagramów, a czwarte - na przyjmowanie odpowiedzi. Przyjrzyjmy się kolejno argumentom: -F Jest to reguła przekazująca. -a accept Reguła z dopisaną polityką "akceptowania" oznacza, że będziemy przekazywać wszystkie datagramy, które do niej pasują. -P tcp Ta reguła dotyczy datagramów tcp (w przeciwieństwie do UDP lub ICMP). -S 172.16.1.0/24 Adres źródłowy musi mieć pierwsze 24 bity odpowiadające adresowi sieci 172.16.1.0. -D 0/0 80 Adres docelowy musi mieć zero bitów pasujących do adresu 0.0.0.0. Tak naprawdę jest to skrótowy zapis "wszystkiego". Port docelowy to 80, co w tym przypadku oznacza WWW. Do opisania portu możesz użyć także wszelkich wpisów znajdujących się w pliku /etc/services, a więc -D 0/0 www działałoby równie dobrze. ipfwadm wymaga maski sieci w postaci, która może nie być ci znana. Zapis /nn oznacza liczbę istotnych bitów w podanym adresie lub rozmiar maski. Bity są zawsze liczone od lewej do prawej. W tabeli 9-1 podano często spotykane przykłady masek. Tabela 9-1. Często spotykane maski sieci Maska sieci Bity 255.0.0.0 8 255.255.0.0 16 255.255.255.0 24 255.255.255.128 25 255.255.255.192 26 255.255.255.224 27 255.255.255.240 28 255.255.255.248 29 255.255.255.252 30 Wcześniej wspomnieliśmy, że ipfwadm implementuje małą sztuczkę, która ułatwia dodawanie tego typu reguł. Ta sztuczka to opcja -b, która sprawia, że polecenie jest dwukierunkowe. Opcja dwukierunkowości pozwala na połączenie naszych dwóch reguł w jedną: # ipfwadm -F -a accept -P tcp -S 172.16.1.0/24 -D 0/0 80 -b Ważna poprawka Przyjrzyj się bliżej naszemu zestawowi reguł. Czy widzisz, że wciąż nie ma zabezpieczenia przed jedną metodą ataku, którą ktoś z zewnątrz może wykorzystać do pokonania naszego firewalla? Nasze reguły pozwalają na przyjmowanie z zewnątrz wszystkich datagramów z portem źródłowym 80. Uwaga! Będą do nich należały także datagramy z ustawionym bitem SYN! Bit SYN oznacza, że jest to datagram TCP z żądaniem połączenia. Jeżeli osoba z zewnątrz miałaby uprzywilejowany dostęp do swojego hosta, mogłaby połączyć się przez nasz firewall z dowolnym z naszych hostów, pod warunkiem, że używają one portu 80. Nie to chcieliśmy osiągnąć. Na szczęście istnieje rozwiązanie tego problemu. Polecenie ipfwadm posiada inną opcję, która pozwala nam budować reguły odfiltrowujące datagramy z ustawionym bitem SYN. Zmieńmy nasz przykład tak, aby uwzględniał tę regułę: # ipfwadm -F -a deny -P tcp -S 0/0 80 -D 172.16.10.0/24 -y # ipfwadm -F -a accept -P tcp -S 172.16.1.0/24 -D 0/0 80 -b Opcja -y powoduje, że reguła pasuje tylko wtedy, jeżeli bit SYN w datagramie jest ustawiony. A więc nasza nowa reguła mówi: "Nie przepuszczaj żadnych datagramów TCP przeznaczonych dla naszej sieci, które pochodzą z jakiegoś miejsca i mają port źródłowy 80 i ustawiony bit SYN" albo "Nie przepuszczaj żadnych żądań od hostów na port 80". Dlaczego umieściliśmy tę szczególną regułę przed regułą główną? Reguły firewalla działają tak, że są dopasowywane kolejno. Obie reguły będą pasowały do datagramów, których nie chcemy przepuścić, a więc musimy być pewni, że reguła deny jest przed regułą accept. Listowanie naszych reguł Po wprowadzeniu naszych reguł możemy je wylistować, wywołując ipfwadm w następujący sposób: # ipfwadm -F -l To polecenie da w wyniku wszystkie skonfigurowane reguły przekazywania. Rezultat powinien być podobny do tego: # ipfwadm -F -l IP firewall forward rules, default policy: accept type prot source       destination       ports deny   tcp   anywhere        172.16.10.0/24      www -> any acc    tcp   172.16.1.0/24   anywhere          any -> www Polecenie ipfwadm będzie próbowało tłumaczyć numer portu na nazwę usługi za pomocą pliku /etc/services, o ile istnieje w nim wpis. W domyślnie pokazywanym wyniku brakuje kilku ważnych dla nas szczegółów. Nie widać tam mianowicie działania argumentu -y. Polecenie ipfwadm potrafi pokazać dokładniejszy wynik, jeżeli podamy także opcję -e (wynik rozszerzony). Nie pokażemy całego wyniku, ponieważ jest zbyt szeroki i nie mieści się na stronie, ale zawiera kolumnę opt (opcje), która pokazuje opcję -y kontrolującą pakiety SYN: # ipfwadm -F -l -e IP firewall forward rules, default policy: accept pkts bytes type prot opt  tosa tosx ifname ifaddress  source ...   0     0 deny tcp  --y- 0xFF 0x00 any    any        anywhere ...   0     0 acc  tcp  b--- 0xFF 0x00 any    any        172.16.1.0/24 ... Bardziej skomplikowany przykład Poprzedni przykład był prosty. Nie wszystkie usługi sieciowe są tak łatwe do skonfigurowania jak WWW. W rzeczywistości typowa konfiguracja firewalla będzie dużo bardziej złożona. Przyjrzyjmy się innemu powszechnie spotykanemu przykładowi, tym razem FTP. Chcemy, aby użytkownicy naszej wewnętrznej sieci mogli logować się do serwerów FTP w Internecie po to, by odczytywać i zapisywać pliki. Nie chcemy jednak, aby ludzie z Internetu logowali się do naszych serwerów FTP. Wiemy, że FTP używa dwóch portów TCP: portu 20 (ftp-data) i portu 21 (ftp), a więc: # ipfwadm -a deny -P tcp -S 0/0 20 -D 172.16.1.0/24 -y # ipfwadm -a accept -P tcp -S 172.16.1.0/24 -D 0/0 20 -b # # ipfwadm -a deny -P tcp -S 0/0 21 -D 172.16.1.0/24 -y # ipfwadm -a accept -P tcp -S 172.16.1.0/24 -D 0/0 21 -b Dobrze? Nie całkiem. Serwery FTP mogą działać w dwóch różnych trybach: w trybie biernym (ang. passive mode) i czynnym (ang. active mode)*. W trybie biernym serwer FTP oczekuje na połączenie od klienta. W trybie czynnym serwer realizuje połączenie do klienta. Tryb czynny jest zwykle domyślny. Różnice ilustruje rysunek 9-3. Wiele serwerów FTP działających w trybie czynnym tworzy połączenie z portu 20, co nieco upraszcza sprawę, ale niestety nie wszystkie tak robią**. Jakie to ma jednak dla nas znaczenie? Przyjrzyjmy się naszej regule dla portu 20, czyli - portu FTP-data. Obecna reguła zakłada, że połączenie będzie inicjowane przez naszego klienta do serwera. Będzie to działało, jeżeli użyjemy trybu biernego. Ale bardzo trudno jest nam skonfigurować poprawną regułę pozwalającą na użycie trybu czynnego, ponieważ nie jesteśmy w stanie z góry przewidzieć, jakie porty będą używane. Jeżeli otworzymy firewall, pozwalając na połączenia przychodzące na dowolny port, narazimy naszą sieć na atak poprzez wszystkie usługi przyjmujące połączenia. W tej sytuacji najlepiej jest wymusić na naszych użytkownikach pracę w trybie biernym. Większość serwerów FTP i wiele klientów FTP działa w ten sposób. Popularny klient ncftp także obsługuje tryb bierny, ale może wymagać niewielkiej zmiany w konfiguracji, by był to jego tryb domyślny. Wiele przeglądarek WWW, takich jak Netsccape, także obsługuje bierny tryb FTP, a więc znalezienie odpowiedniego oprogramowania nie powinno być zbyt trudne. Można też postąpić zupełnie inaczej: użyć serwera proxy FTP, który będzie przyjmował połączenia z sieci wewnętrznej i realizował połączenia z siecią zewnętrzną. Rysunek 9-3. Tryby serwera FTP http://www.rm.com.pl/upgr/lpas/09-03.tif Przy projektowaniu firewalla prawdopodobnie napotkasz niejeden taki problem. Powinieneś zawsze dokładnie przeanalizować, jak naprawdę działa dana usługa, by być pewnym, że umieściłeś odpowiedni zestaw reguł w odpowiednim miejscu. Konfiguracja prawdziwego firewalla może być dość skomplikowana. Podsumowanie argumentów ipfwadm Polecenie ipfwadm ma wiele różnych argumentów odnoszących się do konfiguracji firewalla IP. Ogólna składnia jest następująca: ipfwadm kategoria polecenie parametry [opcje] Przyjrzyjmy się kolejno każdemu z członów. Kategorie Musi być podana jedna i tylko jedna z poniższych kategorii. Kategoria mówi firewallowi, jakiego typu regułę konfigurujesz: -I Reguła wejściowa. -O Reguła wyjściowa. -F Reguła przekazywania. Polecenia Przynajmniej jedno z poniższych poleceń musi być podane i musi się ono odnosić do określonej wcześniej kategorii. Polecenia mówią firewallowi, co ma robić. -a [polityka] Dodanie nowej reguły. -i [polityka] Wstawienie nowej reguły. -d [polityka] Usunięcie istniejącej reguły. -p polityka Ustawienie polityki domyślnej. -l Wylistowanie wszystkich istniejących reguł. -f Usunięcie wszystkich istniejących reguł. Polityki istotne dla firewalla IP i ich znaczenie jest następujące: accept Pozwala na odbiór, przekazywanie lub wysyłanie pasujących datagramów. deny Nie pozwala na odbiór, przekazywanie lub wysyłanie pasujących datagramów. reject Nie pozwala na odbiór, przekazywanie lub wysyłanie pasujących datagramów i wysyła komunikat błędu ICMP do hosta, który przesłał datagram. Parametry Musi być podany przynajmniej jeden z poniższych parametrów. Używaj parametrów do określania datagramów, których dotyczą reguły: -P protokół Może mieć wartość TCP, UDP, ICMP lub all. Przykład: -P tcp -S adres/maska/[port] ?ródłowy adres IP, do którego pasuje ta reguła. Jeżeli nie podasz maski sieci, zostanie przyjęta maska "/32". Opcjonalnie możesz określić, którego portu dotyczy reguła. Musisz także podać protokół za pomocą opisanego wyżej argumentu -P, aby ta opcja zadziałała. Jeżeli nie podasz portu lub zakresu portów, przyjmuje się, że wszystkie porty pasują. Porty mogą być podane w postaci nazwy zgodnej z wpisem w /etc/services. W przypadku protokołu ICMP pole portu jest używane do oznaczenia typu datagramu ICMP. Możliwe jest podanie zakresu portów, a służy do tego następująca składnia: pierwszyport:ostatniport. Oto przykład: -S 172.29.16.1/24 ftp:ftp-data -D adres/maska/[port] Określenie adresu docelowego IP, do którego pasuje ta reguła. Adres docelowy jest zapisywany na tej samej zasadzie co adres źródłowy opisany poprzednio. Oto przykład: -D 172.29.16.1/24 smtp -V adres Określenie adresu interfejsu sieciowego, na którym pakiet jest odbierany (-I) lub z którego jest wysyłany (-O). Pozwala to na stworzenie reguł dotyczących tylko niektórych interfejsów sieciowych komputera. Oto przykład: -V 172.29.16.1 -W nazwa Określenie nazwy interfejsu sieciowego. Ten argument działa w ten sam sposób co -V, ale podajesz nazwę urządzenia zamiast adresu. Oto przykład: -W ppp0 Argumenty opcjonalne Te argumenty są czasem bardzo przydatne: -b Jest używany dla trybu dwukierunkowego. Do tej opcji pasuje ruch w obie strony pomiędzy zadanymi adresami źródłowym i docelowym. Zaoszczędza ci ona tworzenia dwóch reguł: jednej do wysyłania i drugiej do odbierania. -o Pozwala na zapisywanie pasujących datagramów do logu jądra. Wszelkie datagramy pasujące do reguły będą zapisywane jako komunikaty jądra. Jest to użyteczna opcja do wykrywania nieautoryzowanego dostępu. -y Ta opcja jest używana do filtrowania połączeniowych datagramów TCP. Dzięki niej reguła filtruje tylko datagramy podejmujące próbę zestawienia połączeń TCP. Pasować będą jedynie datagramy posiadające ustawiony bit SYN i wyzerowany bit ACK. Jest to użyteczna opcja do filtrowania prób połączeń TCP i ignorowania innych protokołów. -k Jest używana do filtrowania datagramów-potwierdzeń TCP (ang. acknowledgement). Ta opcja powoduje, że do reguły pasują tylko datagramy będące potwierdzeniem odbioru pakietów próbujących zestawić połączenie TCP. Będą pasować jedynie datagramy, które mają ustawiony bit ACK. Opcja ta jest użyteczna do filtrowania prób połączeń TCP i ignorowania wszystkich pozostałych protokołów. Typy datagramów ICMP Każde polecenie konfiguracyjne firewalla pozwala ci określać typy datagramów ICMP. W odróżnieniu od portów TCP i UDP, nie ma odpowiedniego pliku konfiguracyjnego, który zawierałby spis typów datagramów i opisywał ich znaczenie. Typy datagramów ICMP są zdefiniowane w RFC-1700 (RFC Assigned Numbers). Są one także spisane w jednym z plików nagłówkowych standardowej biblioteki C. Typy datagramów można też znaleźć w pliku /usr/include/netinet/ip_icmp.h, należącym do pakietu standardowej biblioteki GNU i używanym przez programistów C do pisania oprogramowania sieciowego wykorzystującego protokół ICMP. Dla twojej wygody pokazaliśmy je w tabeli 9-2. Interfejs polecenia iptables pozwala ci także określać typy ICMP poprzez nazwę, a więc podaliśmy także ich mnemonikę. Tabela 9-2. Typy datagramów ICMP Typ Mnemonika iptables Opis typu 0 echo-reply Powtórzenie odpowiedzi 3 destination-unreachable Cel nieosiągalny 4 source-quench ?ródło nieaktywne 5 redirect Przekierowanie 8 echo-request Żądanie powtórzenia 11 time-exceeded Czas upłynął 12 parameter-problem Problem z parametrem 13 timestamp-request Żądanie znacznika czasu 14 timestamp-reply Wysłanie znacznika czasu w odpowiedzi 15 none Żądanie informacji 16 none Wysłanie informacji w odpowiedzi 17 address-mask-request Żądanie maski adresu 18 address-mask-reply Wysłanie maski adresu w odpowiedzi Łańcuchy firewalla IP (jądra 2.2) Linux rozwija się, by sprostać rosnącym wymaganiom jego użytkowników. Firewall IP nie stanowi tu wyjątku. Tradycyjna implementacja firewalla IP jest dobra, ale może być niewydolna przy konfiguracji bardziej złożonych środowisk. Aby sprostać nowym wymaganiom, opracowano nową metodę konfigurowania firewalla IP i rozwinięto związane z nią właściwości. Ta nowa metoda otrzymała nazwę "Łańcuchy firewalla IP" (w skrócie łańcuchy IP) pierwszy raz została wprowadzona do użytku w jądrze Linuksa 2.2.0. Łańcuchy IP zostały opracowane przez Paula Russella i Michaela Neulinga*. Paul udokumentował oprogramowanie łańcuchów IP w IPCHAINS-HOWTO. Łańcuchy IP pozwalają na tworzenie klas reguł, do których możesz następnie dodawać hosty albo sieci lub je stamtąd usuwać. Łączenie reguł w łańcuchy jest o tyle lepsze, że poprawia wydajność firewalla w konfiguracjach, gdzie używa się wielu reguł. Łańcuchy IP są obsługiwane przez jądra serii 2.2, ale są także dostępne w postaci łat do jąder 2.0.*. Dokument HOWTO podaje, gdzie można zdobyć łaty i zawiera wiele wskazówek, jak efektywnie używać narzędzia konfiguracyjnego ipchains. Używanie ipchains Korzystać z narzędzia konfiguracyjnego ipchains można na dwa sposoby. Pierwszy polega na użyciu skryptu ipfwadm-wrapper, który w zasadzie udaje ipfwadm, bo wywołuje w tle program ipchains. Jeżeli chcesz tak używać ipchains, ten podrozdział nie jest ci potrzebny. Lepiej wrócić do poprzednich, opisujących ipfwadm, i tylko zastąpić go przez ipfwadm-wrapper. Skrypt ten będzie działał, ale nie ma gwarancji, że będzie utrzymywany, a poza tym nie będziesz czerpał korzyści z zaawansowanych funkcji łańcuchów IP. Można też używać ipchains inaczej. Trzeba się nauczyć nowej składni i zmodyfikować istniejącą konfigurację do postaci zgodnej z nową składnią. Chwila zastanowienia i zauważysz, że w czasie konwersji jest możliwe zoptymalizowanie twojej konfiguracji. Składnia ipchains jest prostsza do nauczenia się niż ipfwadm, a więc to dobry wybór. Program ipfwadm do skonfigurowania firewalla musiał operować na trzech regułach. W przypadku łańcuchów IP możesz stworzyć dowolną liczbę zestawów reguł, gdzie każda będzie połączona z inną, ale wciąż są obecne trzy zestawy reguł związane z firewallem. Standardowe zestawy reguł są bezpośrednimi odpowiednikami tych używanych w ipfwadm, poza tym, że mają nazwy: input, forward i output. Najpierw przyjrzymy się ogólnej składni polecenia ipchains, a następnie zobaczymy, jak używać ipchains zamiast ipfwadm, przy czym nie uwzględnianiamy zaawansowanych funkcji łączenia w łańcuchy. Zrobimy to, przeglądając nasze poprzednie przykłady. Składnia polecenia ipchains Składnia polecenia ipchains jest prosta. Przyjrzymy się teraz najważniejszym jej elementom. Ogólna składnia większości poleceń ipchains jest następująca: ipchains polecenie określenie-reguły opcje Polecenia Istnieje szereg sposobów na operowanie na regułach i zestawach reguł za pomocą polecenia ipchains. Istotne dla firewalla IP są: -A łańcuch Dodanie jednej lub kilku reguł na koniec zadanego łańcucha. Jeżeli jest podana nazwa źródłowego lub docelowego hosta i tłumaczy się na więcej niż jeden adres IP, zostanie dodana reguła dla każdego z tych adresów. -I łańcuch numerreguły Wstawienie jednej lub kilku reguł na początek zadanego łańcucha. Znów, jeżeli w określeniu reguły zostanie podana nazwa hosta, będzie dodawana do każdego adresu. -D łańcuch Usunięcie jednej lub kilku reguł z zadanego łańcucha, który pasuje do reguły. -D łańcuch numerreguły Usunięcie reguły znajdującej się na pozycji numerreguły w zadanym łańcuchu. Numeracja reguł zaczyna się od pierwszej reguły w łańcuchu. -R łańcuch numerreguły Zastąpienie reguły na pozycji numerreguły w zadanym łańcuchu podaną regułą. -C łańcuch Sprawdzenie zadanym łańcuchem datagramu opisanego regułą. Polecenie to zwraca komunikat opisujący, jak datagram był przetwarzany przez łańcuch. Jest to bardzo użyteczna opcja to testowania konfiguracji firewalla i nieco później przyjrzymy się jej bardziej szczegółowo. -L [łańcuch] Listowanie reguł zadanego łańcucha lub wszystkich łańcuchów, jeżeli żaden nie zostanie zadany. -F [łańcuch] Usunięcie reguł z zadanego łańcucha lub usunięcie wszystkich reguł, jeżeli żaden łańcuch nie zostanie zadany. -Z [łańcuch] Wyzerowanie liczników datagramów i bajtów dla wszystkich reguł zadanego łańcucha lub wszystkich łańcuchów, jeżeli żaden nie zostanie zadany. -N łańcuch Stworzenie nowego łańcucha o zadanej nazwie. Nie może istnieć drugi łańcuch o tej samej nazwie. W ten sposób tworzone są łańcuchy definiowane przez użytkownika. -X [łańcuch] Usunięcie zadanego łańcucha zdefiniowanego przez użytkownika lub wszystkich łańcuchów zdefiniowanych przez użytkownika, jeżeli żaden nie zostanie zadany. Aby to polecenie zadziałało, nie może być odwołań do zadanego łańcucha z żadnych innych reguł. -P łańcuch polityka Ustawienie domyślnej polityki dla zadanego łańcucha. Dopuszczalne polityki to ACCEPT, DENY, REJECT, REDIR i RETURN. Polityki ACCEPT, DENY i REJECT mają takie samo znaczenie jak w tradycyjnych implementacjach firewalla. REDIR oznacza, że datagram powinien być niewidocznie przekierowany na port firewalla. RETURN powoduje, że kod firewalla IP powraca do tego łańcucha firewalla, który wywołał łańcuch zawierający tę regułę, i kontynuuje dalsze działanie, począwszy od następnej reguły. Parametry określające regułę Na regułę ipchains składa się wiele parametrów, które określają, jakie typy pakietów mają do niej pasować. Jeżeli któryś z tych parametrów zostanie w regule pominięty, zakładana jest jego wartość domyślna. -p [!] protokół Określa protokół datagramu, który będzie pasował do tej reguły. Dopuszczalne nazwy protokołów to tcp, udp, icmp lub all. Możesz także podać numer protokołu. Na przykład mógłbyś użyć 4, aby dopasować protokół enkapsulacji ipip. Jeżeli podasz !, reguła zostanie zanegowana i datagram będzie dopasowywany do wszystkich protokołów poza zadanymi. Jeżeli parametr nie zostanie podany, zostanie przyjęta wartość all. -s [!]adres[/maska][!][port] Określa adres źródłowy i port w datagramie, który ma pasować do tej reguły. Adres może być podany w postaci nazwy hosta, nazwy sieci lub adresu IP. Opcja mask pozwala na zadanie używanej maski sieci, która może być podana albo w tradycyjnej postaci (tj. /255.255.255.0), albo w postaci współczesnej (tj. /24). Opcjonalny port określa port TCP lub UDP albo typ dopasowywanego datagramu ICMP. Numer portu możesz wskazać tylko wtedy, gdy użyłeś wcześniej parametru -p, podając jeden z protokołów: tcp, udp lub icmp. Można też podać zakres portów - jego dolną i górną granicę rozdzielone dwukropkiem. Na przykład 20:25 opisuje wszystkie porty od 20 do 25 włącznie. Znak ! może być wykorzystany do zanegowania wartości. -d [!]adres[/maska][!][port] Określa adres i port docelowy zawarte w datagramie, który ma pasować do tej reguły. Kodowanie tego parametru jest identyczne jak parametru -s. -j cel Określa działanie do wykonania, jeżeli reguła będzie pasowała. Parametr ten możesz sobie przetłumaczyć jako "skocz do" (ang. jump to). Dopuszczalne cele to ACCEPT, DENY, REJECT, REDIR i RETURN. Ich znaczenie opisaliśmy wcześniej. Jednak możesz podać także nazwę łańcucha zdefiniowanego przez użytkownika, w którym będzie wykonywane dalsze przetwarzanie. Jeżeli ten parametr zostanie pominięty, to nawet jeśli datagram pasuje do reguły, nie zostanie podjęte żadne inne działanie, oprócz uaktualnienia datagramu i liczników bajtów. -i[!]nazwa-interfejsu Określa interfejs, który przyjął datagram lub przez który zostanie on wysłany. Znów znak ! odwraca wynik dopasowania. Jeżeli nazwa interfejsu kończy się znakiem +, pasował będzie każdy interfejs, którego nazwa rozpoczyna się zadanym ciągiem. Na przykład, -i ppp+ będzie pasować do dowolnego urządzenia sieciowego PPP, a -i ! eth+ będzie pasować do wszystkich urządzeń poza Ethernetem. [!]-f Mówi, że reguła ta dotyczy wszystkiego poza pierwszym fragmentem datagramu podzielonego na fragmenty. Opcje Poniżej pokazane opcje ipchains są bardziej ogólne. Niektóre z nich sterują raczej ezoterycznymi funkcjami oprogramowania łańcuchów IP: -b Powoduje, że polecenie generuje dwie reguły. Jedna reguła uwzględnia podane parametry, a druga uwzględnia je w odwrotnym kierunku. -v Powoduje, że ipchains wyświetla bogate wyniki, czyli podaje więcej informacji. -n Powoduje, że ipchains wyświetla adres IP i porty jako liczby bez próby ich zamiany na odpowiadające im nazwy. -l Włącza zapisywanie przez jądro pasujących datagramów. Wszystkie datagramy pasujące do reguły są zapisywane przez jądro za pomocą funkcji printk(). Zwykle jest to obsługiwane przez program syslogd zapisujący do pliku log. Funkcja ta przydaje się do oglądania niestandardowych datagramów. -o[maxrozmiar] Powoduje, że oprogramowanie łańcuchów IP kopiuje datagramy pasujące do reguły do urządzenia "netlink", które działa w przestrzeni użytkownika. Argument maxrozmiar ogranicza liczbę bajtów każdego datagramu, która zostanie przekazana do urządzenia netlink. Opcja ta jest najchętniej stosowana przez programistów, ale może być w przyszłości wykorzystana w pakietach oprogramowania. -m wartośćznakowania Powoduje, że pasujące datagramy są oznaczane zadaną wartością. Te wartości to 32-bitowe liczby bez znaku. W obecnych implementacjach opcja ta nie działa, ale w przyszłości może decydować o obsłudze datagramu przez inne oprogramowanie, takie jak na przykład kod rutujący. Jeżeli wartośćznakowania rozpoczyna się od znaku + albo -, jest ona dodawana lub odejmowana od aktualnej wartości znakowania. -t maskaand maskaxor Pozwala na operowanie na bitach "typ usługi" w nagłówku IP każdego datagramu pasującego do reguły. Bity typu usługi są używane przez inteligentne rutery do nadawania priorytetów datagramom, zanim zostaną dalej przekazane. Oprogramowanie rutujące Linuksa potrafi realizować takie nadawanie priorytetów. Wartości maskaand i maskaxor oznaczają maski bitowe, które będą poddawane odpowiednio logicznej operacji AND i OR z bitami typu usługi datagramu. Jest to zaawansowana funkcja, która szczegółowo została omówiona w IPCHAINS-HOWTO. -x Powoduje, że wszelkie liczby w wyniku ipchains są pokazywane dokładnie, bez zaokrąglania. -y Powoduje, że do reguły pasują wszystkie datagramy TCP z ustawionym bitem SYN i wyzerowanymi bitami ACK i FIN. Jest używana do filtrowania żądań nawiązania połączenia TCP. Poprawiona wersja naszego prostego przykładu Powróćmy do przykładu z siecią firmową, w której działa firewall oparty na komputerze z Linuksem. Umożliwia on użytkownikom dostęp do serwerów WWW w Internecie, ale nie pozwala na żaden inny ruch. Gdyby nasza sieć miała 24-bitową maskę (klasa C) i adres 172.16.1.0, użylibyśmy następujących reguł ipchains: # ipchains -F forward # ipchains -P forward DENY # ipchains -A forward -s 0/0 80 -d 172.16.1.0/24 -p tcp -y -j DENY # ipchains -A forward -s 172.16.1.0/24 -d 0/0 80 -p tcp -b -j ACCEPT Pierwsze polecenie czyści wszystkie reguły z zestawu forward, a drugie definiuje domyślną politykę zestawu reguł forward na DENY. Trzecie i czwarte polecenie realizują wymagane przez nas filtrowanie. Czwarte polecenie pozwala datagramom kierowanym do i z serwerów WWW na przechodzenie do naszej sieci, a trzecie zapobiega przyjmowaniu przychodzących połączeń TCP z portem źródłowym 80. Gdybyśmy teraz chcieli dodać reguły pozwalające na dostęp do zewnętrznych serwerów FTP w trybie biernym, musielibyśmy wpisać: # ipchains -A forward -s 0/0 20 -d 172.16.1.0/24 -p tcp -y -j DENY # ipchains -A forward -s 172.16.1.0/24 -d 0/0 20 -p tcp -b -j ACCEPT # ipchains -A forward -s 0/0 21 -d 172.16.1.0/24 -p tcp -y -j DENY # ipchains -A forward -s 172.16.1.0/24 -d 0/0 21 -p tcp -b -j ACCEPT Listowanie reguł za pomocą ipchains Do wylistowania reguł za pomocą ipchains używamy argumentu -L. Podobnie jak to było w ipfwadm, istnieją argumenty kontrolujące liczbę szczegółów pokazywanych w wyniku. W najprostszej postaci ipchains generuje następujący wynik: # ipchains -L -n Chain input (policy ACCEPT): Chain forward (policy DENY): target    prot  opt     source       destination      ports DENY      tcp   -y----  0.0.0.0/0       172.16.1.0/24    80 -> * ACCEPT   tcp   ------  172.16.1.0/24    0.0.0.0/0       * -> 80 ACCEPT    tcp   ------  0.0.0.0/0       172.16.1.0/24    80 -> * ACCEPT    tcp   ------  172.16.1.0/24    0.0.0.0/0       * -> 20 ACCEPT    tcp   ------  0.0.0.0/0       172.16.1.0/24    20 -> * ACCEPT    tcp   ------  172.16.1.0/24    0.0.0.0/0       * -> 21 ACCEPT    tcp   ------  0.0.0.0/0       172.16.1.0/24    21 -> * Chain output (policy ACCEPT): Jeżeli nie podasz nazwy łańcucha, który chcesz obejrzeć, ipchains wyświetli wszystkie reguły ze wszystkich łańcuchów. Argument -n w naszym przykładzie powoduje, że ipchains nie próbuje konwertować adresów i portów na nazwy. Pokazana informacja powinna być oczywista. Bogatsza forma wyniku, uzyskiwana przez opcję -u, pokazuje dużo więcej szczegółów. Dodatkowe pola zawierają liczniki datagramów i bajtów, znaczniki AND i XOR typu usługi, nazwę interfejsu, znakowanie i rozmiar wynikowy. Ze wszystkimi regułami utworzonymi za pomocą ipchains związane są liczniki bajtów i datagramów. W ten sposób jest zaimplementowane liczenie ruchu IP, które zostanie szczegółowo omówione w rozdziale 10. Domyślnie liczniki są pokazywane w postaci zaokrąglonej z przyrostkami K i M oznaczającymi odpowiednio jednostki: tysiąc i milion. Jeżeli zostanie podany argument -x, liczniki są rozwijane do ich pełnej, niezaokrąglonej postaci. Korzystanie z łańcuchów Wiesz już, że polecenie ipchains zastępuje ipfwadm, ma prostszą składnię i kilka ciekawych rozszerzeń, ale bez wątpienia chcesz wiedzieć, gdzie i po co używać łańcuchów definiowanych przez użytkownika. Zapewne jesteś też ciekawy, jak posługiwać się dodatkowymi skryptami towarzyszącymi poleceniu ipchains w pakiecie. Przyjrzymy się teraz tym tematom i postaramy się odpowiedzieć na pytania. Łańcuchy definiowane przez użytkownika Trzy zestawy reguł dla tradycyjnego firewalla IP stanowią mechanizm tworzenia prostych konfiguracji firewalla, którymi łatwo jest zarządzać w małych sieciach o niewielkich wymaganiach wobec systemu bezpieczeństwa. Gdy wymagania konfiguracyjne wzrastają, pojawia się szereg problemów. Po pierwsze, duże sieci często wymagają dużo więcej reguł firewalla, niż tych kilka, z którymi się do tej pory spotkaliśmy. Nieuchronnie rosną potrzeby dodawania do firewalla reguł obsługujących przypadki szczególne. Gdy liczba reguł rośnie, wydajność firewalla pogarsza się, bo na każdym datagramie jest przeprowadzanych coraz więcej testów; problemem staje się też zarządzanie. Po drugie, nie jest możliwe włączanie i wyłączanie zestawu reguł w sposób rozdzielny. Gdy jesteś w trakcie przebudowy zestawu reguł, narażasz sieć na ataki. Zasady budowy łańcuchów IP pomagają złagodzić te problemy, gdyż umożliwiają administratorowi tworzenie dowolnych zestawów reguł firewalla, które można następnie dołączać do trzech wbudowanych zestawów reguł. Do utworzenia nowego łańcucha można użyć opcji -N programu ipchains. Trzeba podać jego nazwę, składającą się z 8 (lub mniej) znaków. (Ograniczenie nazwy do małych liter jest dobrym pomysłem). Opcja -j konfiguruje działanie podejmowane wtedy, gdy datagram pasuje do wymagań reguły. Mówi, że jeżeli datagram będzie pasował do reguły, dalsze testowanie powinno być realizowane w łańcuchu zdefiniowanym przez użytkownika. Pokażemy to na wykresie. Rozważmy następujące polecenia ipchains: ipchains -P input DENY ipchains -N tcpin ipchains -A tcpin -s ! 172.16.0.0/16 ipchains -A tcpin -p tcp -d 172.16.0.0/16 ssh -j ACCEPT ipchains -A tcpin -p tcp -d 172.16.0.0/16 www -j ACCEPT ipchains -A input -p tcp -j tcpin ipchains -A input -p all Domyślną politykę łańcucha wejściowego ustawiamy na deny. Drugie polecenie tworzy definiowany przez użytkownika łańcuch o nazwie "tcpin". Trzecie polecenie dodaje do łańcucha tcpin regułę, do której pasują wszystkie datagramy pochodzące spoza naszej sieci lokalnej. Nie jest podejmowane żadne dodatkowe działanie. Jest to reguła zliczająca i zostanie omówiona bardziej szczegółowo w rozdziale 10. Do następnych dwóch reguł pasują datagramy przeznaczone dla naszej sieci lokalnej na porty ssh lub www. Pasujące datagramy są akceptowane. W następnej regule tkwi prawdziwa magia ipchains. Reguła ta powoduje, że oprogramowanie firewalla sprawdza każdy datagram TCP za pomocą łańcucha tcpin, zdefiniowanego przez użytkownika. Na koniec dodajemy regułę do naszego łańcucha input, do którego pasuje każdy datagram. Jest to kolejna reguła zliczająca. W ten sposób uzyskujemy łańcuchy firewalla pokazane na rysunku 9-4. Nasze łańcuchy input i tcpin są zapełniane regułami. Przetwarzanie datagramu zawsze rozpoczyna się w jednym z łańcuchów wbudowanych. Zobaczymy, jak zdefiniowany przez nas łańcuch jest używany przy przetwarzaniu różnych typów datagramów. Najpierw przyjrzymy się, co się dzieje, gdy zostanie odebrany datagram UDP dla jednego z naszych hostów. Rysunek 9-5 pokazuje przepływ przez reguły. Datagram zostaje odebrany przez łańcuch input, ale nie pasuje do dwóch pierwszych reguł, ponieważ pasują do nich tylko datagramy protokołów ICMP i TCP. Zostaje dopasowany do trzeciej reguły łańcucha input, która nie zawiera celu. Są więc uaktualniane liczniki bajtowy i datagramów, ale nie jest podejmowane żadne inne działanie. Datagram dociera do końca łańcucha input, spełniając warunki jego domyślnej polityki i zostaje odrzucony. Rysunek 9-4. Prosty zestaw reguł łańcucha IP http://www.rm.com.pl/upgr/lpas/09-04.tif Rysunek 9-5. Kolejność sprawdzania reguł dla odebranego datagramu UDP http://www.rm.com.pl/upgr/lpas/09-05.tif Aby zobaczyć zdefiniowany przez nas łańcuch w działaniu, rozważmy, co się dzieje, gdy zostanie odebrany datagram TCP przeznaczony dla portu ssh jednego z naszych hostów. Kolejność pokazano na rysunku 9-6. Rysunek 9-6. Kolejność reguł dla odebranego pakietu TCP dla portu ssh http://www.rm.com.pl/upgr/lpas/09-06.tif Tym razem datagram pasuje do drugiej reguły w łańcuchu input, która kieruje go do celu tcpin - łańcucha zdefiniowanego przez użytkownika. Podanie łańcucha zdefiniowanego przez użytkownika jako celu powoduje, że datagram będzie sprawdzany przez zawarte w nim reguły, a więc następną sprawdzaną regułą będzie pierwsza reguła z łańcucha tcpin. Do tej reguły pasują datagramy, które mają adres źródłowy spoza sieci lokalnej i nie zawierają adresu przeznaczenia, a więc jest to także reguła zliczająca i testowanie przechodzi do następnej reguły. Druga reguła w naszym łańcuchu tcpin pasuje do datagramu i określa cel ACCEPT. Dotarliśmy do celu, a więc nie będzie już żadnego przetwarzania przez firewall. Datagram zostaje przepuszczony. Na koniec zobaczmy, co się stanie, gdy dotrzemy do końca zdefiniowanego przez nas łańcucha. Aby to zobaczyć, musimy pokazać przepływ datagramu TCP przeznaczonego dla portu innego niż dwa przez nas obsługiwane. Pokazujemy to na rysunku 9-7. Rysunek 9-7. Kolejność reguł dla odebranego pakietu TCP dla telnet http://www.rm.com.pl/upgr/lpas/09-07.tif Łańcuchy zdefiniowane przez użytkownika nie mają polityki domyślnej. Gdy wszystkie zawarte w nich reguły zostaną sprawdzone i żadna nie pasuje, firewall działa tak, jakby istniała reguła RETURN, a więc jeżeli nie tego chciałeś, powinieneś na końcu łańcucha użytkownika umieścić żądane działanie. W naszym przykładzie sprawdzanie powraca do reguły z zestawu input następnej po tej, przez którą przeszliśmy do łańcucha zdefiniowanego przez użytkownika. Ostatecznie docieramy do końca łańcucha input, który posiada politykę domyślną i datagram zostaje odrzucony. Ten przykład jest bardzo prosty, ale pokazuje to, o co nam chodziło. W praktyce działanie łańcuchów IP jest dużo bardziej skomplikowane. Nieco bardziej wyrafinowany przykład pokazujemy poniżej, w postaci listy poleceń. # # Ustawienie domyślnej polityki przekazywania na REJECT ipchains -P forward REJECT # # utworzenie naszego łańcucha ipchains -N sshin ipchains -N sshout ipchains -N wwwin ipchains -N wwwout # # Gwarancja odrzucania połączeń w złym kierunku ipchains -A wwwin -p tcp -s 172.16.0.0/16 -y -j REJECT ipchains -A wwwout -p tcp -d 172.16.0.0/16 -y -j REJECT ipchains -A sshin -p tcp -s 172.16.0.0/16 -y -j REJECT ipchains -A sshout -p tcp -d 172.16.0.0/16 -y -j REJECT # # Gwarancja, że wszystko, co dotrze do końca łańcucha # zdefiniowanego przez użytkownika, zostanie odrzucone ipchains -A sshin -j REJECT ipchains -A sshout -j REJECT ipchains -A wwwin -j REJECT ipchains -A wwwout -j REJECT # # Przekierowanie usług www i ssh do odpowiedniego łańcucha # zdefiniowanego przez użytkownika ipchains -A forward -p tcp -d 172.16.0.0/16 ssh -b -j sshin ipchains -A forward -p tcp -s 172.16.0.0/16 -d 0/0 ssh -b -j sshout ipchains -A forward -p tcp -d 172.16.0.0/16 www -b -j wwwin ipchains -A forward -p tcp -s 172.16.0.0/16 -d 0/0 www -b -j wwwout # # Umieszczenie reguł sprawdzających hosty na drugiej pozycji w # zdefiniowanych przez nas łańcuchach ipchains -I wwwin 2 -d 172.16.1.2 -b -j ACCEPT ipchains -I wwwout 2 -s 172.16.1.0/24 -b -j ACCEPT ipchains -I sshin 2 -d 172.16.1.4 -b -j ACCEPT ipchains -I sshout 2 -s 172.16.1.4 -b -j ACCEPT ipchains -I sshout 2 -s 172.16.1.6 -b -j ACCEPT # W tym przykładzie użyliśmy łańcuchów definiowanych przez użytkownika do uproszczenia zarządzania naszym firewallem i do poprawy wydajności w porównaniu z rozwiązaniem wykorzystującym jedynie łańcuchy wbudowane. W naszym przykładzie są tworzone łańcuchy użytkownika dla każdej z usług ssh i www w każdym kierunku połączenia. W łańcuchu wwwout umieszczamy reguły dla hostów, które mogą tworzyć wychodzące połączenia WWW, a w sshin definiujemy reguły dla hostów, które mogą przyjmować przychodzące połączenia ssh. Założyliśmy, że potrzebujemy możliwości przyjmowania i odrzucania połączeń ssh i www tylko dla wybranych hostów w naszej sieci. Jest to pewne uproszczenie, gdyż łańcuchy definiowane przez użytkownika pozwalają na grupowanie reguł według pakietów przychodzących do hosta i wychodzących z niego, a nie na ich mieszanie. Poprawia się wydajność, ponieważ dla każdego datagramu zmniejszyliśmy średnią liczbę testów robionych przed osiągnięciem celu. Wydajność zwiększy się jeszcze bardziej, jeżeli wzrośnie liczba hostów. Gdybyśmy nie mieli łańcuchów użytkownika, potencjalnie musielibyśmy przeszukiwać całą listę reguł, by stwierdzić, czy działanie ma zostać podjęte przy każdym odebranym datagramie. Nawet gdybyśmy założyli, że każda z reguł zawartych na naszej liście pasuje do równej liczby przetworzonych datagramów, wciąż musielibyśmy przeszukiwać średnio połowę listy. Łańcuchy definiowane przez użytkownika pozwalają nam uniknąć sprawdzania dużej liczby reguł, ponieważ testowany datagram musi pasować do prostej reguły wbudowanego łańcucha, aby w ogóle dotrzeć do łańcucha użytkownika. Skrypty pomocnicze ipchains Pakiet oprogramowania ipchains jest dostarczany wraz z trzema dodatkowymi skryptami. Pierwszy z nich już krótko omówiliśmy, natomiast pozostałe dwa zapewniają łatwe i wygodne sposoby zachowywania i odtwarzania konfiguracji firewalla. Skrypt ipfwadm-wrapper emuluje składnię wiersza poleceń ipfwadm, ale wymaga polecenia ipchains do tworzenia reguł. Jest to wygodny sposób na migrację istniejącej konfiguracji firewalla do jądra lub alternatywa dla opanowania składni ipchains. Skrypt ipfwadm-wrapper zachowuje się inaczej niż polecenie ipfwadm pod dwoma względami. Po pierwsze, ipchains nie pozwala na określenie interfejsu przez adres, a ipfwadm-wrapper przyjmuje argument -V, ale próbuje zamienić go na właściwy dla ipchains odpowiednik -W, szukając nazwy interfejsu skonfigurowanej pod zadanym adresem. Skrypt ipfwadm-wrapper zawsze przypomina ci o tym, wypisując komunikat, gdy użyjesz opcji -V. Po drugie, reguły zliczania fragmentów nie są tłumaczone poprawnie. Skrypty ipchains-save i ipchains-restore upraszczają tworzenie i modyfikowanie konfiguracji firewalla. Polecenie ipchains-save odczytuje aktualną konfigurację firewalla i zapisuje uproszczoną postać na standardowe wyjście. Polecenie ipchains-restore odczytuje dane w formacie wyprowadzanym przez ipchains-save i konfiguruje firewall IP zgodnie z odczytanymi regułami. Korzyścią z używania tych skryptów jest możliwość natychmiastowego dynamicznego tworzenia konfiguracji i jej zapisania, czego nie daje bezpośrednie modyfikowanie skryptu konfigurującego firewall i testowanie konfiguracji. Taką konfigurację można następnie odtworzyć, zmodyfikować i zapisać ponownie. Aby użyć tych skryptów i zachować aktualną konfigurację firewalla, musisz napisać coś takiego: ipchains-save >/var/state/ipchains/firewall.state Możesz ją potem odtworzyć, zwykle w czasie uruchamiania systemu, w następujący sposób: ipchains-restore   [*] Network firewalls    [*] TCP/IP networking    ...    [*] IP: accounting lub w jądrach serii 2.4: Networking options --->    [*] Network packet filtering (replaces ipchains) Konfigurowanie liczenia ruchu IP Ponieważ usługa liczenia ruchu IP jest ściśle związana z firewallem IP, do jej konfigurowania służą te same narzędzia, czyli ipfwadm, ipchains lub iptables. Składnia polecenia jest bardzo podobna jak w przypadku reguł firewalla, a więc nie będziemy się na niej skupiać, a omówimy to, czego możesz się dowiedzieć o swojej sieci, używając tej funkcji. Ogólna składnia polecenia liczącego ruch IP dla ipfwadm jest następująca: # ipfwadm -A [kierunek] [polecenie] [parametry] Nowy jest argument kierunku. Przyjmuje on jedną z wartości in, out lub both. Są to kierunki ruchu z punktu widzenia samego komputera z Linuksem, a więc in oznacza dane przychodzące z sieci do komputera, a out oznacza dane wysyłane przez hosta do sieci. Kierunek both stanowi sumę danych przychodzących i wychodzących. Ogólna składnia polecenia dla ipchains i iptables jest następująca: # ipchains -A łańcuch definicja-reguły # iptables -A łańcuch definicja-reguły Polecenia ipchains i iptables pozwalają określić kierunek w sposób bardziej spójny z regułami firewalla. Łańcuchy IP nie pozwalają na konfigurowanie reguł, które obejmują oba kierunki, ale dopuszczają skonfigurowanie reguł w łańcuchu forward, co nie było możliwe w starszej implementacji. W kilku przykładach pokazanych dalej zobaczymy, co z tego wyniknie. Polecenia są w dużym stopniu takie same jak w regułach firewalla, z tą różnicą, że nie używa się tu polityk. Możemy dodawać, wstawiać, usuwać i listować reguły liczenia ruchu. W przypadku ipchains i iptables dopuszczalne są tylko reguły liczenia ruchu, a wszelkie polecenia nie zawierające opcji -j realizują jedynie liczenie ruchu. Parametry w definicji reguły liczenia ruchu IP są identyczne z używanymi dla firewalla IP. Za ich pomocą definiujemy dokładnie, jaki ruch sieciowy chcemy liczyć. Liczenie według adresu Na przykładzie pokażemy, jak korzysta się z funkcji liczenia ruchu IP. Wyobraź sobie, że mamy ruter oparty na Linuksie, który obsługuje dwa wydziały browaru wirtualnego. Ruter ma dwa urządzenia Ethernet, eth0 i eth1, z których każde obsługuje jeden wydział, oraz urządzenie PPP, ppp0, które łączy nas za pomocą szybkiego łącza szeregowego z głównym campusem uniwersytetu Groucho Marx. Wyobraźmy sobie również, że dla celów rozliczeniowych chcemy znać całkowity ruch generowany przez każdy wydział podłączony przez łącze szeregowe, a dla celów zarządzania chcemy znać całkowity ruch generowany pomiędzy wydziałami. Poniższa tabela pokazuje adresy interfejsów, których będziemy używać w naszym przykładzie: iface adres maska sieci eth0 172.16.3.0 255.255.255.0 eth1 172.16.4.0 255.255.255.0 Aby odpowiedzieć na pytanie: "Jak dużo danych na łączu PPP generuje każdy wydział ?", powinniśmy użyć następującego zestawu reguł: # ipfwadm -A both -a W ppp0 -S 172.16.3.0/24 -b # ipfwadm -A both -a W ppp0 -S 172.16.4.0/24 -b lub # ipchains -A input -i ppp0 -d 172.16.3.0/24 # ipchains -A output -i ppp0 -s 172.16.3.0/24 # ipchains -A input -i ppp0 -d 172.16.4.0/24 # ipchains -A output -i ppp0 -s 172.16.4.0/24 i w przypadku iptables: # iptables -A FORWARD -i ppp0 -d 172.16.3.0/24 # iptables -A FORWARD -o ppp0 -s 172.16.3.0/24 # iptables -A FORWARD -i ppp0 -d 172.16.4.0/24 # iptables -A FORWARD -o ppp0 -s 172.16.4.0/24 Pierwsza połowa każdego z tych zestawów mówi: "Licz wszystkie dane przechodzące w obu kierunkach przez interfejs o nazwie ppp0 z adresami źródłowym lub docelowym (pamiętaj o funkcji -b w przypadku ipfwadm i ipchains) 172.16.3.0/24". Druga połowa każdego zestawu reguł jest taka sama, ale dotyczy drugiej sieci Ethernet. Aby odpowiedzieć na drugie pytanie: "Ile danych jest przesyłanych pomiędzy dwoma wydziałami?", potrzebujemy następujących reguł: # ipfwadm -A both -a -S 172.16.3.0/24 -D 172.16.4.0/24 -b lub: # ipchains -A forward -s 172.16.3.0/24 -d 172.16.4.0/24 -b lub: # iptables -A FORWARD -s 172.16.3.0/24 -d 172.16.4.0/24 # iptables -A FORWARD -s 172.16.4.0/24 -d 172.16.3.0/24 Te zestawy reguł liczą wszystkie datagramy, których adres źródłowy należy do sieci jednego wydziału, a adres docelowy - do sieci drugiego wydziału. Liczenie ruchu według portu usługi W porządku, załóżmy teraz, że chcemy wiedzieć coś o tym, jaki rodzaj ruchu jest przesyłany przez nasze łącze PPP. Możemy na przykład dowiedzieć się, jaką część łącza zajmują usługi FTP, smtp i WWW. Skrypt z regułami włączającymi zbieranie tego typu informacji może wyglądać następująco: #!/bin/sh # Zbieranie, za pomocą ipfwadm, statystyk o ruchu FTP, smtp i www #dla danych przesyłanych przez łącze PPP # ipfwadm -A both -a -W ppp0 -P tcp -S 0/0 ftp ftp-data ipfwadm -A both -a -W ppp0 -P tcp -S 0/0 smtp ipfwadm -A both -a -W ppp0 -P tcp -S 0/0 www lub: #!/bin/sh # Zbieranie, za pomocą ipchains, statystyk o ruchu FTP, smtp i www # dla danych przesyłanych przez łącze PPP # ipchains -A input -i ppp0 -p tcp -s 0/0 ftp-data:ftp ipchains -A output -i ppp0 -p tcp -d 0/0 ftp-data:ftp ipchains -A input -i ppp0 -p tcp -s 0/0 smtp ipchains -A output -i ppp0 -p tcp -d 0/0 smtp ipchains -A input -i ppp0 -p tcp -s 0/0 www ipchains -A output -i ppp0 -p tcp -d 0/0 www lub: #!/bin/sh # Zbieranie, za pomocą iptables, statystyk o ruchu FTP, smtp i www # dla danych przesyłanych przez łącze PPP # iptables -A FORWARD -i ppp0 -m tcp -p tcp --sport ftp-data:ftp iptables -A FORWARD -o ppp0 -m tcp -p tcp --dport ftp-data:ftp iptables -A FORWARD -i ppp0 -m tcp -p tcp --sport smtp iptables -A FORWARD -o ppp0 -m tcp -p tcp --dport smtp iptables -A FORWARD -i ppp0 -m tcp -p tcp --sport www iptables -A FORWARD -o ppp0 -m tcp -p tcp --dport www W tej konfiguracji jest kilka ciekawostek. Po pierwsze, określiliśmy protokół. Gdy w regułach podajemy numery portów, musimy także podać protokół, ponieważ TCP i UDP posiadają oddzielne zestawy portów. Ponieważ wszystkie z tych usług są oparte na TCP, podaliśmy go jako protokół. Po drugie, podaliśmy dwie usługi ftp i ftp-data w jednym poleceniu. ipfwadm pozwala na podawanie poszczególnych portów, zakresów portów lub losowych list portów. Polecenie ipchains również pozwala na podawanie poszczególnych portów lub zakresów portów, z czego skorzystaliśmy. Składnia "ftp-data:ftp" oznacza "porty od ftp-data (20) do ftp (21)" i jest to sposób kodowania zakresu portów w poleceniach ipchains i iptables. Gdy w regule zliczającej podasz listę portów, oznacza to, że wszelkie dane odebrane na wskazanych portach będą sumowane przy zliczaniu. Pamiętając, że FTP używa dwóch portów, portu poleceń i danych, podaliśmy je razem, żeby sumować cały ruch FTP. Na końcu podaliśmy adres źródłowy w postaci "0/0", co jest szczególnym zapisem, do którego pasują wszystkie adresy; taki zapis jest wymagany przez polecenia ipfwadm i ipchains, aby można było określić porty. Możemy się nieco bardziej skupić na drugim punkcie, co da nam inne spojrzenie na dane na naszym łączu. Wyobraźmy sobie, że traktujemy ruch FTP, SMTP i WWW jako istotny, a pozostały ruch jako nieistotny. Gdybyśmy chcieli znać stosunek ruchu istotnego do nieistotnego, moglibyśmy użyć czegoś takiego: # ipfwadm -A both -a W ppp0 -P tcp -S 0/0 ftp ftp-data smtp www # ipfwadm -A both -a W ppp0 -P tcp -S 0/0 1:19 22:24 26:79 81:32767 Jeżeli już przejrzałeś swój plik /etc/services, wiesz, że druga reguła obejmuje wszystkie porty poza wymienionymi w pierwszej (ftp, ftp-data, smtp i www). Jak to robimy w poleceniach ipchains i iptables, skoro pozwalają one określić tylko jeden port jako argument? Do liczenia ruchu możemy równie łatwo jak w regułach firewalla wykorzystać łańcuchy definiowane przez użytkownika. Rozważmy następujące podejście: # ipchains -N a-essent # ipchains -N a-noness # ipchains -A a-essent -j ACCEPT # ipchains -A a-noness -j ACCEPT # ipchains -A forward -i ppp0 -p tcp -s 0/0 ftp-data:ftp -j a-essent # ipchains -A forward -i ppp0 -p tcp -s 0/0 smtp -j a-essent # ipchains -A forward -i ppp0 -p tcp -s 0/0 www -j a-essent # ipchains -A forward -j a-noness Tworzymy tutaj dwa łańcuchy definiowane przez użytkownika, jeden o nazwie a-essent, w którym zbieramy dane dla istotnych usług, oraz drugi o nazwie a-noness, w którym zbieramy dane o usługach nieistotnych. Następnie dodajemy reguły do naszego łańcucha przekazywania, który dopasowuje nasze istotne usługi i przechodzi do łańcucha a-essent, gdzie mamy tylko jedną regułę akceptującą wszystkie datagramy i je liczącą. Ostatnia reguła w naszym łańcuchu przekazywania to reguła, która przechodzi do łańcucha a-noness, w którym znów mamy jedną regułę przyjmującą i zliczającą wszystkie datagramy. Do reguły, która przechodzi do łańcucha a-noness, nie dotrze żadna z naszych istotnych usług, gdyż zostaną one zaakceptowane przez ich własny łańcuch. Rejestr istotnych i nieistotnych usług będzie dostępny w regułach tych łańcuchów. Opisaliśmy jeden ze sposobów, w jaki można liczyć ruch istotny i nieistotny - są oczywiście także inne. Nasza implementacja iptables wykorzystuje to samo podejście i przedstawia się tak: # iptables -N a-essent # iptables -N a-noness # iptables -A a-essent -j ACCEPT # iptables -A a-noness -j ACCEPT # iptables -A FORWARD -i ppp0 -m tcp -p tcp --sport ftp-data:ftp -j a-essent # iptables -A FORWARD -i ppp0 -m tcp -p tcp --sport smtp -j a-essent # iptables -A FORWARD -i ppp0 -m tcp -p tcp --sport www -j a-essent # iptables -A FORWARD -j a-noness Wygląda to dość prosto. Niestety występuje tu niewielki, ale nieunikniony problem przy próbie liczenia usług według typu. Pamiętasz, że w poprzednich rozdziałach mówiliśmy o roli, jaką w sieci TCP/IP odgrywa MTU. MTU definiuje największy datagram, jaki może zostać przesłany przez urządzenie sieciowe. Gdy datagram zostanie odebrany przez ruter i jest większy niż MTU interfejsu, który musi go przetransmitować, ruter stosuje sztuczkę nazywaną fragmentacją. Ruter dzieli duży datagram na mniejsze fragmenty, nie większe jednak niż MTU interfejsu, a następnie je przesyła. Ruter tworzy nowe nagłówki, które umieszcza na początku każdego fragmentu. Zdalna maszyna używa ich do odtworzenia oryginalnych danych. Niestety w procesie fragmentacji port jest usuwany ze wszystkich fragmentów poza pierwszym. Oznacza to, że zliczanie IP nie jest w stanie poprawnie obsłużyć datagramów podzielonych na fragmenty. Może poprawnie policzyć tylko pierwszy fragment. Istnieje sztuczka wykonywana przez ipfwadm, która pozwala zliczać dalsze fragmenty, mimo że nie jesteśmy w stanie dowiedzieć się dokładnie, z jakiego portu pochodzą. Wcześniejsze wersje oprogramowania zliczającego dla Linuksa przypisywały fragmentom fałszywy numer portu 0xFFFF, który pozwalał liczyć. Aby mieć pewność, że uwzględniamy drugi i dalsze fragmenty, możemy użyć następującej reguły: # ipfwadm -A both -a -W ppp0 -P tcp -S 0/0 0xFFFF Implementacja łańcuchów IP oferowała nieco bardziej wyrafinowane rozwiązanie, ale wynik był podobny. W przypadku polecenia ipchains mogliśmy użyć: # ipchains -A forward -i ppp0 -p tcp -f a w przypadku iptables: # iptables -A FORWARD -i ppp0 -m tcp -p tcp -f Nie pokaże nam to, jaki był oryginalny port danych, ale przynajmniej będziemy w stanie stwierdzić, ile danych zostało podzielonych na fragmenty i policzyć generowany przez nie ruch. Podczas kompilacji jąder serii 2.2 możesz wybrać opcję, która usuwa cały ten problem, jeżeli twój komputer z Linuksem działa jako pojedynczy punkt dostępu do sieci. Jeżeli w czasie kompilacji jądra włączysz opcję IP: always defragment, wszystkie odebrane datagramy będą składane przez ruter linuksowy, zanim zostaną przerutowane i ponownie wysłane. Ta operacja jest realizowana przed filtrowaniem na firewallu i oprogramowanie zliczające widzi datagram tak, jakby nie był podzielony na fragmenty. W jądrach 2.4 musisz skompilować i załadować moduł netfilter forward-fragment. Zliczanie datagramów ICMP Protokół ICMP nie używa numerów portów usługi i dlatego nieco trudniej jest zbierać szczegółowe dane na jego temat. ICMP wykorzystuje różnego typu datagramy. Wiele z nich jest nieszkodliwych i normalnych, natomiast niektóre powinny pojawiać się tylko w pewnych okolicznościach. Czasami ludzie, którzy mają zbyt wiele czasu, próbują złośliwie zakłócić użytkownikom dostęp do sieci, generując dużą liczbę komunikatów ICMP. Powszechnie nazywa się to zalaniem pingami (ang. ping flooding). Choć za pomocą mechanizmu zliczania ruchu IP nie można zrobić nic, by zapobiec temu problemowi (choć może tu pomóc firewall IP!), możemy przynajmniej stworzyć reguły, które pokażą nam, czy ktoś próbuje takiego działania. ICMP nie używa portów, tak jak TCP czy UDP. Natomiast ma różne typy komunikatów. Możesz stworzyć reguły liczące każdy typ komunikatu ICMP. W tym celu umieszczamy komunikat ICMP i numer typu w polu portu polecenia zliczającego ipfwadm. Typy komunikatów ICMP wymieniliśmy w podrozdziale Typy datagramów ICMP, a więc zajrzyj tam, jeżeli chcesz je sobie przypomnieć. Reguła liczenia ruchu IP zbierająca informacje o liczbie pingów wysyłanych do naszej maszyny i z niej generowanych może wyglądać tak: # ipfwadm -A both -a -P icmp -S 0/0 8 # ipfwadm -A both -a -P icmp -S 0/0 0 # ipfwadm -A both -a -P icmp -S 0/0 0xff lub w przypadku ipchains tak: # ipchains -A forward -p icmp -s 0/0 8 # ipchains -A forward -p icmp -s 0/0 0 # ipchains -A forward -p icmp -s 0/0 -f lub w przypadku iptables tak: # iptables -A FORWARD -m icmp -p icmp --sports echo-request # iptables -A FORWARD -m icmp -p icmp --sports echo-reply # iptables -A FORWARD -m icmp -p icmp -f Pierwsza reguła zbiera informacje o datagramach "ICMP Echo Request" (żądania ping), a druga zbiera informacje o "ICMP Echo Reply" (odpowiedzi na ping). Trzecia reguła zbiera informacje o fragmentach datagramów ICMP. Jest to sztuczka podobna do opisanej w przypadku podzielonych na fragmenty datagramów TCP i UDP. Jeżeli w swoich regułach podasz adres źródłowy i docelowy, możesz wyśledzić, skąd pochodzą pingi, z sieci wewnętrznej czy zewnętrznej. Gdy już ustalisz, skąd przychodzą szkodliwe datagramy, możesz rozważyć, czy chcesz umieścić regułę firewalla, która będzie zapobiegała ich przyjmowaniu, czy też podjąć jakieś inne działania, jak skontaktowanie się z właścicielem sieci, z której one pochodzą i powiadomienie go o problemie, a może nawet wytoczenie sprawy, jeżeli działanie było szczególnie złośliwe. Zliczanie według protokołu Wyobraźmy sobie teraz, że chcemy wiedzieć, jak duży ruch na naszym łączu generują protokoły TCP, UDP i ICMP. Użyjemy do tego celu następujących reguł: # ipfwadm -A both -a -W ppp0 -P tcp -D 0/0 # ipfwadm -A both -a -W ppp0 -p udp -D 0/0 # ipfwadm -A both -a -W ppp0 -p icmp -D 0/0 lub: # ipchains -A forward -i ppp0 -p tcp -d 0/0 # ipchains -A forward -i ppp0 -p udp -d 0/0 # ipchains -A forward -i ppp0 -p icmp -d 0/0 lub: # iptables -A FORWARD -i ppp0 -m tcp -p tcp # iptables -A FORWARD -o ppp0 -m tcp -p tcp # iptables -A FORWARD -i ppp0 -m udp -p udp # iptables -A FORWARD -o ppp0 -m udp -p udp # iptables -A FORWARD -i ppp0 -m icmp -p icmp # iptables -A FORWARD -o ppp0 -m icmp -p icmp Zgodnie z regułami, cały ruch przechodzący przez interfejs ppp0 będzie analizowany pod kątem ustalenia, czy jest to ruch TCP, UDP czy ICMP i będą uaktualniane odpowiednie liczniki dla każdego z protokołów. W przykładzie dla polecenia iptables ruch przychodzący jest oddzielany od wychodzącego, gdyż wymaga tego składnia. Wykorzystywanie wyników zliczania ruchu IP Bardzo dobrze, że zbieramy informacje, ale jak zobaczyć wynik? Aby obejrzeć zebrane dane o ruchu i skonfigurowane reguły zliczające, odwołujemy się do poleceń konfiguracyjnych firewalla, prosząc je o pokazanie listy reguł. W wyniku są pokazywane liczniki pakietów i bajtów dla każdej z naszych reguł. Polecenia ipfwadm, ipchains i iptables różnie obsługują zebrane dane, a więc musimy je pokazać niezależnie. Oglądanie danych za pomocą ipfwadm Najprostszym sposobem na obejrzenie danych o ruchu za pomocą polecenia ipfwadm jest użycie go w następujący sposób: # ipfwadm -A -l IP accounting rules pkts bytes dir prot source          destination    ports 9833 2345K i/o all  172.16.3.0/24       anywhere       n/a 56527   33M i/o all  172.16.4.0/24       anywhere       n/a Widać tu liczbę pakietów wysłanych w obie strony. Gdybyśmy użyli opcji -e do pokazania wyniku w bogatszej postaci (nie pokazujemy tutaj, gdyż nie zmieściłby się na stronie), musielibyśmy podać również odpowiednie opcje i nazwy interfejsów. Większość pól tego wyniku jest oczywista, ale poniższe mogą wymagać wyjaśnienia: dir Kierunek, którego dotyczy reguła. Możliwe wartości to in, out lub i/o, co oznacza oba kierunki. prot Protokoły, których dotyczą reguły. opt Zakodowana postać opcji, których używamy w wywołaniu ipfwadm. ifname Nazwa interfejsu, którego dotyczy reguła. ifaddress Adres interfejsu, którego dotyczy reguła. Domyślnie ipfwadm wyświetla liczniki pakietów i bajtów w skróconej postaci, czyli zaokrąglone do najbliższego tysiąca (K) lub miliona (M). Możemy spowodować, by wyniki były wyświetlane bez zaokrąglania. Robi się to tak: # ipfwadm -A -l -e -x Oglądanie danych za pomocą ipchains Polecenie ipchains nie wyświetli zebranych danych (liczników pakietów i bajtów), dopóki nie podamy argumentu -v. Najprostszy sposób na obejrzenie danych za pomocą ipchains jest następujący: # ipchains -L -v Znów, tak jak w ipfwadm, używając trybu rozszerzonego wyniku, możemy wyświetlić liczniki pakietów i bajtów w dokładnych jednostkach. ipchains do tego celu wykorzystuje argument -x: # ipchains -L -v -x Oglądanie danych za pomocą iptables Polecenie iptables zachowuje się bardzo podobnie jak ipchains. Znów musimy użyć opcji -v, gdy chcemy obejrzeć nasze liczniki. Aby obejrzeć zebrane dane o ruchu, piszemy: # iptables -L -v Tak jak w poleceniu ipchains, możesz użyć argumentu -x do obejrzenia wyniku w rozszerzonej wersji, z liczbami w dokładnej postaci. Zerowanie liczników Liczniki zliczające ruch IP przepełnią się, jeżeli pozostawisz je włączone na dłuższy czas. Gdy się przepełnią, będziesz miał trudności w ustaleniu ich rzeczywistej wartości. Aby uniknąć tego problemu, powinieneś co jakiś czas odczytywać zebrane dane, zapisywać je, a następnie zerować liczniki, by ponownie rozpocząć zbieranie informacji o ruchu przez następny okres zliczeniowy. Polecenia ipfwadm i ipchains udostępniają prosty sposób na zerowanie liczników: # ipfwadm -A -z lub: # ipchains -Z lub: # iptables -Z Możesz także połączyć wyświetlanie i zerowanie, by mieć pewność, że w międzyczasie dane się nie zagubią: # ipfwadm -A -l -z lub: # ipchains -L -Z lub: # iptables -L -Z -v Polecenia powyższe najpierw pokażą dane o ruchu, a następnie natychmiast wyzerują liczniki i rozpoczną zliczanie od nowa. Jeżeli chcesz zbierać i wykorzystywać informacje regularnie, prawdopodobnie umieścisz to polecenie w skrypcie uruchamianym co jakiś czasu przez polecenie cron. Skrypt ten zapisuje wynik i gdzieś go zachowuje. Usuwanie zestawów reguł Ostatnie polecenie, które może być przydatne, pozwala ci usunąć wszystkie skonfigurowane wcześniej reguły zliczające IP. Jest najbardziej przydatne, gdy chcesz radykalnie zmienić zestaw reguł bez ponownego uruchamiania komputera. Argument -f w połączeniu z poleceniem ipfwadm wyrzuci wszystkie reguły danego typu. ipchains obsługuje argument -F, który robi to samo: # ipfwadm -A -f lub: # ipchains -F lub: # iptables -F Powyższe polecenia powodują usunięcie wszystkich skonfigurowanych reguł zliczania ruchu IP, dzięki czemu nie tracisz czasu na usuwanie ich pojedynczo. Zauważ, że takie usuwanie reguł w przypadku ipchains nie powoduje usunięcia żadnego z łańcuchów zdefiniowanych przez użytkownika, a usuwa tylko zawarte w nich reguły. Bierne zbieranie danych o ruchu Ostatnia sztuczka, którą warto poznać: jeżeli twój Linux jest podłączony do Ethernetu, możesz zastosować reguły liczenia ruchu do wszystkich danych z twojego segmentu, a nie tylko do tych, które są przez niego przesyłane lub do niego adresowane. Twoja maszyna może biernie podsłuchiwać wszystkie dane przesyłane w segmencie sieci, do którego jest podłączona i je zliczać. Powinieneś najpierw wyłączyć przekazywanie IP na twoim komputerze z Linuksem, tak by nie próbował on rutować odebranych datagramów*. W jądrach 2.0.36 i 2.2 robi się to za pomocą: # echo 0>/proc/sys/net/ipv4/ip_forward Następnie za pomocą polecenia ifconfig, powinieneś przejść na swojej karcie Ethernet do trybu przechwytywania (ang. promiscuous). Teraz możesz stworzyć reguły liczenia ruchu pozwalające ci zbierać informacje o datagramach przesyłanych w segmencie Ethernet bez włączania rutingu na swoim Linuksie. 11 Maskowanie IP i translacja adresów sieciowych Rozdział 11: Maskowanie IP i translacja adresów sieciowych Nie musisz mieć dobrej pamięci, by pamiętać czasy, gdy tylko duże instytucje mogły pozwolić sobie na połączenie wielu komputerów w sieć LAN. Obecnie technologia sieciowa jest na tyle tania, że możemy zaobserwować dwa zjawiska. Po pierwsze, sieci LAN są teraz powszechne, nawet dostępne w gospodarstwach domowych. Wielu użytkowników Linuksa ma po kilka komputerów połączonych siecią Ethernet. Po drugie, zasoby sieciowe, szczególnie adresy IP, kończą się i choć przyzwyczailiśmy się, że są za darmo, obecnie coraz częściej są kupowane i sprzedawane. Większość posiadaczy sieci LAN zwykle chce także mieć połączenie z Internetem, wykorzystywane przez każdy komputer w sieci. Reguły rutingu IP są dosyć sztywne, jeśli chodzi o działanie w takiej sytuacji. Tradycyjne rozwiązania tego problemu zakładają uzyskanie adresu IP dla sieci, być może klasy C w przypadku mniejszych ośrodków, i przypisanie adresu każdemu hostowi sieci LAN , a następnie podłączenie sieci LAN do Internetu przez ruter. W skomercjalizowanych środowiskach internetowych jest to dość droga propozycja. Po pierwsze, musiałbyś zapłacić za przypisanie twojej sieci adresów IP. Po drugie, musiałbyś zapłacić dostawcy usług internetowych za przywilej posiadania odpowiedniego rutera dla twojej sieci, dzięki któremu reszta Internetu wiedziałaby, jak się do niej dostać. Może być to wciąż praktyczne rozwiązanie dla firm, ale właściciele domowych instalacji zwykle nie są w stanie udźwignąć jego kosztów. Na szczęście Linux oferuje inne rozwiązanie tego problemu. Rozwiązanie to wymaga elementu z grupy zaawansowanych funkcji sieciowych, tak zwanej translacji adresów sieciowych (Network Address Translation - NAT). Jest to proces modyfikacji adresów sieciowych zawartych w nagłówkach datagramu, który zachodzi w czasie ich przesyłania. Na początku może ci się to wydawać dość dziwne, ale zobaczysz wkrótce, że jest to idealne rozwiązanie opisywanego problemu i wiele osób z niego korzysta. Maskowanie IP (ang. IP masquerading) to nazwa nadana jednej z odmian translacji adresów sieciowych, która pozwala hostom z adresem sieci prywatnej przedstawić się w Internecie pod jednym publicznym adresem IP. Maskowanie IP daje możliwość używania adresu IP z sieci prywatnej (zarezerwowanego) w twojej sieci LAN, a twój ruter oparty na Linuksie wykonuje w czasie rzeczywistym pewne inteligentne tłumaczeni