Linux 4
Linux 4
Sander van Vugt
Meer informatie over deze en andere uitgaven kunt u verkrijgen bij: Sdu Klantenservice Postbus 20014 2500 EA Den Haag tel.: 070 378 98 80 fax: 070 378 97 83 © 2007 Sdu Uitgevers bv, Den Haag Academic Service is een imprint van Sdu Uitgevers bv 1e druk, juni 2007 Vormgeving en omslag: Studio Bassa, Culemborg Zetwerk: PROgrafici, Goes ISBN 978 90 395 2548 7 NUR 124
Alle rechten voorbehouden. Alle auteursrechten en databankrechten ten aanzien van deze uitgave worden uitdrukkelijk voorbehouden. Deze rechten berusten bij Sdu Uitgevers bv. Behoudens de in of krachtens de Auteurswet 1912 gestelde uitzonderingen, mag niets uit deze uitgave worden verveelvoudigd, opgeslagen in een geautomatiseerd gegevensbestand of openbaar gemaakt in enige vorm of op enige wijze, hetzij elektronisch, mechanisch, door fotokopieën, opnamen of enige andere manier, zonder voorafgaande schriftelijke toestemming van de uitgever. Voorzover het maken van reprografische verveelvoudigingen uit deze uitgave is toegestaan op grond van artikel 16 h Auteurswet 1912, dient men de daarvoor wettelijk verschuldigde vergoedingen te voldoen aan de Stichting Reprorecht (postbus 3051, 2130 KB Hoofddorp, www.reprorecht.nl). Voor het overnemen van gedeelte(n) uit deze uitgave in bloemlezingen, readers en andere compilatiewerken (artikel 16 Auteurswet 1912) dient men zich te wenden tot de Stichting PRO (Stichting Publicatieen Reproductierechten Organisatie, Postbus 3060, 2130 KB Hoofddorp, www.cedar.nl/pro). Voor het overnemen van een gedeelte van deze uitgave ten behoeve van commerciële doeleinden dient men zich te wenden tot de uitgever. Hoewel aan de totstandkoming van deze uitgave de uiterste zorg is besteed, kan voor de afwezigheid van eventuele (druk)fouten en onvolledigheden niet worden ingestaan en aanvaarden de auteur(s), redacteur(en) en uitgever deswege geen aansprakelijkheid voor de gevolgen van eventueel voorkomende fouten en onvolledigheden. All rights reserved. No part of this publication may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, electronic, mechanical, photocopying, recording or otherwise, without the publisher’s prior consent. While every effort has been made to ensure the reliability of the information presented in this publication, Sdu Uitgevers neither guarantees the accuracy of the data contained herein nor accepts responsibility for errors or omissions or their consequences.
Voorwoord Dit boek is geschreven voor projectmatig onderwijs in Linux in het MBO. Het uitgangspunt van dit boek is dat de lezer in staat is noodzakelijke basiskennis zelf te verwerven, eventueel via het Leerboek Linux deel 1 tot en met 3. In dit boek wordt praktijkgericht beschreven wat nodig is voor leerlingen om projecten op basis van Linux te realiseren. Om die reden concentreren we ons in dit boek niet op het besturingssysteem Linux, maar specifiek op het gebruik van Linux als server. In het eerste hoofdstuk lees je hoe je Linux installeert als server. We bespreken daarbij de installatieprocedures van Fedora en SUSE Linux, maar met de nadruk op wat een installatie een goede installatie maakt als Linux-server. Dit betekent bijvoorbeeld dat we nauwkeurig kijken naar de te installeren packages die in bepaalde omstandigheden wel of niet nodig zijn, en naar de wijze waarop de schijf van de server gepartitioneerd wordt om een goede server te maken. In het tweede hoofdstuk maak je kennis met de beheerinterface van Linux. Dit betekent dat enige aandacht wordt besteed aan oplossingen die door de distributies ter beschikking gesteld worden – denk aan SUSE’s YaST en Fedora/Red Hat’s system-config utilities – maar vooral aan het werken op de prompt. Om een Linuxsysteem te kunnen beheren is nu eenmaal een grondige kennis van de opdrachtregel nodig. Na deze inleiding gaan we in de volgende hoofdstukken naar taken die meer direct te maken hebben met het beheer van een server. Denk daarbij aan het beheer van de gebruikersomgeving, werken met permissies en het beheer van processen. Nadat deze onderwerpen besproken zijn, leer je in de volgende vier hoofdstukken om de belangrijkste typen Linux-server in te richten. In het bedrijfsleven blijkt dat Linux met name ingezet wordt als webserver, mailserver en fileserver. Je leert daarom voor elk van deze servertypen hoe je deze inricht, uiteraard pas nadat nauwkeurig is gekeken naar de wijze waarop de netwerkkaart ingesteld wordt. In de laatste twee hoofdstukken tot slot maak je kennis met beheertaken die je ook vaak tegen zult komen in een serveromgeving: het beheer op afstand en het werken met de Netfilter-firewall.
VI
Linux 4
Bij het schrijven van dit boek is ervoor gekozen te focussen op twee Linux-distributies: SUSE en Fedora/Red Hat. Waar gesproken wordt over Fedora wordt, tenzij nadrukkelijk anders vermeld, ook Red Hat bedoeld. Deze keuze is gemaakt omdat deze twee Linux-distributies momenteel meer dan 80% van de markt van professionele Linux-servers in handen hebben. Nadrukkelijk hebben we er niet voor gekozen om ook Ubuntu mee te nemen. Deze distributie namelijk doet het weliswaar goed als desktopdistributie, maar is als server nog een marginaal verschijnsel. De auteur van dit boek heeft ook een website. Via de website zal, als dat nodig is, aanvullende informatie worden verschaft. Je wordt ook van harte aangemoedigd om contact op te nemen met de auteur als er zaken zijn in dit boek die je niet bevallen of waarvan je denkt dat ze anders moeten. Je vindt de website van de auteur op www.sandervanvugt.nl. Daarnaast is de auteur per e-mail te bereiken op
[email protected]. Sander van Vugt Mei 2007
VII
Inhoud Voorwoord
V
1 1.1 1.2 1.3 1.4 1.5
1 1 3 23 36 37
Installatie Inleiding Installatie van SUSE Linux Installatie van Fedora Core Installeren van VMware Tools Samenvatting
2 Basisvaardigheden 2.1 Inleiding 2.2 Opstarten: LILO en Grub 2.3 Inloggen 2.4 Werken met Linux-opdrachten 2.5 Redirection en piping 2.6 Help opvragen 2.7 Basistaken uitvoeren 2.8 De inrichting van een Linux-bestandssysteem 2.9 Bekijken van inhoud van bestanden en output van opdrachten 2.10 Zoeken naar bestanden en tekst 2.11 Kopiëren, verplaatsen, verwijderen en maken van directory’s 2.12 Nog meer basisopdrachten 2.13 Maken van tekstbestanden 2.14 Afsluiten 2.15 Samenvatting 3 3.1 3.2 3.3 3.4 3.5 3.6
Gebruikers, groepen en permissies Inleiding Beheer van de gebruikersomgeving Beheer van de groepsomgeving Beheer van permissies Werken met sudo Samenvatting
39 39 39 42 44 45 50 60 65 74 75 79 80 81 88 91 93 93 93 102 106 118 120
viii
Linux 4
4 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8
Beheer van processen Inleiding Soorten processen Procesbeheer Schedulen van processen Prioriteit van processen Logging van procesactiviteit Processen en het pseudo-bestandssysteem /proc Samenvatting
121 121 121 124 132 136 137 159 163
5 5.1 5.2 5.3 5.4 5.5 5.6
Configuratie van de netwerkkaart Inleiding Basiskennis TCP/IP Configuratie van een vaste netwerkkaart Configuratie van een PPP-interface De netwerkverbinding testen Samenvatting
165 165 165 180 199 215 222
6 6.1 6.2 6.3 6.4 6.5 6.6 6.7 6.8
Apache Inleiding De werking van een webserver Configuratie van de Apache-server Configuratie van virtuele hosts Beperken van toegang tot de webserver Apache beveiligen met OpenSSL Werken met Apache-modules Samenvatting
223 223 223 227 236 240 244 250 252
7 7.1 7.2 7.3 7.4 7.5 7.6 7.7 7.8
Linux als mailserver Inleiding Architectuur van een mailoplossing De Linux-opdracht mail Postfix-componenten Configuratie van inkomende mail met procmail Herdistributie van mail met qpopper Cyrus IMAPd Samenvatting
253 253 253 255 256 270 271 273 279
8 8.1 8.2
Bestanden delen met Linux Inleiding Linux als NFS-server
281 281 281
Inhoud
ix
8.3 8.4
Linux als Samba-server Samenvatting
289 323
9 9.1 9.2 9.3 9.4 9.5 9.6
Beheer op afstand Inleiding Veilig contact maken met andere computers Authenticatiemethoden Snel aan het werk Configuratie van key-based authenticatie Samenvatting
325 325 325 327 331 338 345
10 10.1 10.2 10.3 10.4 10.5 10.6
De Netfilter-firewall Inleiding Tables en chains Werken met tables en chains Iptables in de praktijk Iptables als Network Address Translator Samenvatting
347 347 348 351 359 364 367
11 11.1 11.2 11.3 11.4 11.5 11.6 11.7 11.8 11.9 11.10 11.11
Shellscripting Inleiding Shellscripts Variabelen bewerken Rekenen in scripts Werken met flow control Werken met de stream editor Werken met functies Opties Afvangen van ongeoorloofde toetsencombinaties Geavanceerde scripts Samenvatting
369 369 369 381 388 398 413 415 416 423 424 427
1
Installatie
Voordat je met Linux aan het werk kunt, zul je Linux moeten installeren. In dit hoofdstuk kun je lezen wat hier bij komt kijken. We bespreken zowel de installatie van OpenSUSE als van Fedora. De nadruk ligt daarbij op de installatie van een server. Naast de algemene stappen die nodig zijn, lees je daarom over aspecten die specifiek zijn bij het installeren van een server. 1.1
Inleiding
Om de procedure die hier beschreven wordt zelf uit te kunnen voeren, heb je OpenSUSE of Fedora nodig. Je kunt OpenSUSE downloaden van www.opensuse.org. Maak je geen zorgen wanneer tegen de tijd dat je dit leest er een nieuwere versie beschikbaar is. SUSE staat erom bekend dat de versienummers elkaar snel opvolgen. De stappen die hier beschreven worden, zullen echter in volgende versies in grote lijnen weinig veranderd zijn. Als dit je eerste kennismaking met Linux is, doe je er dus goed aan dit hoofdstuk toch door te lezen. Ook Fedora kun je gratis downloaden: op fedora.redhat.com of een van de mirror sites. Zowel OpenSUSE als Fedora zijn gratis versies waarop een commercieel product gebaseerd is. Het verschil zit vooral in de ondersteuning die voor de commerciële producten aangeschaft kan worden. Het commerciële product dat bij Fedora hoort, heet Red Hat Enterprise Server. Bij OpenSUSE hoort SUSE Linux Enterprise Server. Als je een server wilt installeren voor gebruik binnen een bedrijf, doe je er goed aan een van deze versies te kopen. De technieken die in dit boek besproken worden, kunnen alle op de servers ook toegepast worden, vaak zelfs een stuk eenvoudiger.
Linux 4
Omdat verschillende Linux-distributies zowel een gratis versie als een commerciële serverversie hebben, moet je weten wat precies de verschillen zijn. Beide versies zijn immers gebaseerd op open source-software en daarom kun je met beide versies hetzelfde doel bereiken. Toch zijn er redenen om Red Hat Enterprise Linux aan te schaffen in plaats van Fedora, of om te werken met SUSE Linux Enterprise Server in plaats van OpenSUSE. De belangrijkste voordelen van het gebruik van een serverversie worden hier genoemd: Een serverversie biedt ondersteuning. Dankzij deze ondersteuning weet je als bedrijf altijd zeker dat je er niet alleen voor staat als zich problemen voordoen. Serverversies worden aangeboden met ondersteuning voor langere tijd. De meeste serverversies bieden op zijn minst vijf jaar ondersteuning. Een serverversie zal ervoor zorgen dat hardware gecertificeerd is. Zo weet je bijvoorbeeld op voorhand zeker dat bepaalde servertypen van IBM, Dell, HP en andere het gewoon doen met jouw Linux-versie. Dit is met een open source-versie altijd nog maar afwachten. Serverversies zijn meer stabiel. Het nieuwste van het nieuwste wordt geboden in de open source-versies. Omdat deze techniek zo nieuw is, kan het voorkomen dat bepaalde functionaliteit nog niet werkt of onstabiel is. De serverversies komen pas als dit soort onregelmatigheden uit de open source-versies verdwenen is en zijn om die reden veel stabieler. Bepaalde softwareleveranciers certificeren hun software voor gebruik op de commerciële servers. Zo weet je bijvoorbeeld zeker dat je zowel op Red Hat als op SUSE gebruik kunt maken van de Oracle-databaseproducten of van SAP. Bovengenoemde argumenten zijn de reden waarom je bij middelgrote tot grote bedrijven geen Debian-servers zult vinden, maar SUSE- of Red Hat-servers. De aanschaf van een serverversie van Linux biedt garanties. Garanties die voor de bedrijven zeer belangrijk zijn omdat op die wijze de continuïteit van de bedrijfsprocessen gegarandeerd kan worden.
1 Installatie
1.2
Installatie van SUSE Linux
Om SUSE Linux te kunnen installeren moet de computer aan bepaalde minimumeisen voldoen. Deze liggen bij Linux over het algemeen erg laag. Het is echter niet realistisch om van het minimum uit te gaan. Je zult immers wel willen dat de gebruikersprocessen met enige snelheid afgehandeld kunnen worden. Wat je hier leest, zijn daarom niet de absolute minimale systeemeisen, maar de eisen die gesteld worden aan een systeem om er prettig mee te kunnen werken als server. Uiteraard geldt hierbij dat het nooit een probleem is wanneer het systeem krachtiger is dan wat hier wordt geadviseerd. Pentium III Processor, 450 MHz of sneller. 256 MB werkgeheugen. 4 GB beschikbare schijfruimte voor installatie van het besturingssysteem. Grafische hardware die een resolutie van 1024x768 aankan. Muis. Cd- of dvd-station. Netwerkkaart. Naast deze algemene systeemeisen zul je in de server wellicht ook bepaalde hardware willen gebruiken die specifiek voor servers ontworpen is. Denk bijvoorbeeld aan een RAID-controller die ervoor zorgt dat meerdere vaste schijven gebundeld worden, of een dubbel uitgevoerde netwerkkaart. Deze onderdelen worden ook goed door de verschillende Linux-versies ondersteund en daarom besteden we er niet specifiek aandacht aan. Nu je weet wat er in een server aan hardware aanwezig moet zijn, kun je beginnen met de installatie. 1. Zorg ervoor dat op de vaste schijf ruimte beschikbaar is die nog niet aan Windows is toegewezen. Als je een serieuze server wilt inrichten, zorg je er natuurlijk voor dat de totale vaste schijf beschikbaar is voor de installatie van SUSE Linux. In deze beschrijving wordt van de laatste optie uitgegaan. Wil je wel de Windowsinstallatie behouden? Geen probleem. SUSE zorgt ervoor dat bestaande Windows-partities verkleind worden en dat je vanuit het opstartmenu nog steeds automatisch Windows kunt starten. In dit
Linux 4
hoofdstuk besteden we echter geen aandacht aan het inrichten van een dualboot-machine. 2. Stel in het BIOS van de computer in dat de pc tijdens het opstarten eerst probeert te booten vanaf een cd of dvd. Op de meeste moderne pc’s is het niet nodig hiervoor het BIOS zelf aan te passen, maar volstaat het tijdens het booten een opstartmenu te activeren. Start dan de installatieprocedure vanaf de installatie-cd. Figuur 1.1 Zorg ervoor dat de pc vanaf het optische medium opstart om met de installatie te beginnen
3. Nadat de pc is opgestart vanaf het optische medium, verschijnt een menu waarin je aangeeft wat er moet gebeuren. In dit menu moet je de tweede optie selecteren om te kunnen beginnen met installatie. Figuur 1.2 Let erop dat je in het bootmenu moet aangeven dat je wilt installeren, de standaardoptie probeert namelijk te booten vanaf de vaste schijf
1 Installatie
4. Er wordt nu een initieel Linux-systeem geladen van waaruit de installatie wordt uitgevoerd. Wacht totdat dit systeem volledig geladen is. Er verschijnt vervolgens een venster waarin je kunt aangeven in welke taal je wilt installeren. Wij gaan hier uit van Nederlands. Selecteer hiervoor in de lijst de optie Nederlands en klik vervolgens op Accepteren. Houd er overigens rekening mee dat de vertaling niet helemaal perfect is. Sommige onderdelen zijn eenvoudigweg niet vertaald en worden daarom in het Engels weergegeven. Taal In verband met de mogelijkheid voor support is het in veel gevallen verstandig te kiezen voor een Engelstalige installatie. Supportorganisaties zijn vaak erg internationaal georiënteerd en iemand die probeert je ondersteuning te bieden vanuit Provo in de Verenigde Staten, zal waarschijnlijk moeite hebben met een Nederlandstalige installatie.
Figuur 1.3 De eerste stap in de installatie van Linux is aangeven in welke taal je wilt installeren
5. Nu moet je aangeven hoe je wilt installeren. Selecteer hiervoor in het kader Installatiemodus de optie Nieuwe installatie (de enige optie die op een nieuw systeem beschikbaar is) en ga dan verder met de installatie.
Linux 4
Figuur 1.4 Op een pc waarop geen Linux geïnstalleerd is, is Nieuwe installatie de enige beschikbare optie
6. In het volgende venster selecteer je de regio waarin je woont. Als je voor de Nederlandse taal gekozen hebt, zal Nederland hier automatisch al geselecteerd zijn. Let vooral ook even op de tijdinstelling. De hardwareklok moet ingesteld staan op Lokale tijd; standaard staat hier UTC. Dit is een soort Greenwich Main Time voor servers. Pc’s staan hier standaard niet op ingesteld, dus deze optie heb je niet nodig. Pas ook de lokale tijd aan voordat je verder gaat en klik op Verder. Figuur 1.5 Let erop dat je aangeeft gebruik te willen maken van lokale tijd
7. Linux staat voor keuze. Vaak zijn er verschillende oplossingen voor eenzelfde taak en dat geldt ook voor de weergave van de gra-
1 Installatie
fische desktop. Standaard installeert SUSE de GNOME-desktop, maar als je dat liever hebt, kun je gebruikmaken van KDE. Ons maakt het niet uit, de configuratie van een server vindt namelijk voor een groot deel plaats vanuit de configuratiebestanden en daar is helemaal geen grafische omgeving voor nodig. In dit boek kiezen wij ervoor SUSE met KDE te installeren. GNOME wordt op Fedora gebruikt, maar zoals gezegd: eigenlijk maakt het niet uit want waarschijnlijk is de volgende stap toch dat je deze grafische omgeving uitzet. Figuur 1.6 In dit venster geef je aan met welke grafische interface je wilt gaan werken
8. Nu kom je in het venster Installatie-instellingen. Hier regel je hoe je precies wilt gaan installeren. In dit venster zijn twee dingen van wezenlijk belang: de partitie-indeling en de software die je gaat installeren. OpenSUSE staat ingesteld als desktopinstallatie, dus hier moet het een en ander aangepast worden. Figuur 1.7 De standaardinstellingen van OpenSUSE zijn niet ideaal voor een serverinstallatie
Linux 4
Niet voor Windows! De stappen over de partitie-indeling voer je alleen uit als je de volledige computer ter beschikking hebt om Linux te installeren. Zoals gezegd, in dit boek bespreken we niet hoe je een dualboot-systeem met Windows installeert. 9. Klik op de link Partitionering. Kies de optie Maatwerkpartiti onering aanmaken en klik op Verder. Nu wordt gevraagd op welke schijf je wilt werken. Kies hier de optie Aangepaste partitionering (voor experts). Dit is namelijk de enige optie die je volledige controle geeft over wat er moet gebeuren. Figuur 1.8 Kies de optie Aangepaste partitionering voor een volledige controle over de schijfinrichting
Eenvoudig houden De handmatige partitie-indeling die hier besproken wordt is vrij ingewikkeld, maar is wel speciaal doordacht voor gebruik op een server. Wil je het liever eenvoudig houden? Laat dan de optie Partitionering met rust en maak gebruik van de standaardinstellingen. Ook met de standaardinstellingen kun je prima een server inrichten.
1 Installatie
10. Er zijn twee manieren om een schijf in te richten. Met behulp van ouderwetse partities of door gebruik te maken van logische volumes. Dit laatste biedt twee belangrijke voordelen: je kunt naderhand vrij eenvoudig de grootte van een logisch volume aanpassen en daarbij is het eenvoudiger om een back-up te maken van een volume waarop alle bestanden in gebruik zijn. Hiervoor gebruik je dan de optie snapshot. Hier lees je hoe je de server inricht voor gebruik van logische volumes. We zullen meerdere volumes maken. Onder Linux koppel je dan een bepaalde specifieke directory aan een van deze volumes; dit proces wordt mounten genoemd. Het voordeel hiervan is dat je verschillende soorten bestanden die in principe niets met elkaar te maken hebben van elkaar gescheiden kunt houden. We maken in deze procedure de volgende volumes aan: /boot
/srv
/var
/usr
Dit is de enige directory die niet op een logisch volume mag. Deze is nodig om van op te starten. We kunnen het klein houden; 100 MB is in de meeste gevallen ruim voldoende en je moet er dus een partitie voor maken. Onder deze directory plaatsen veel servers hun bestanden. Webservers en FTP-servers hebben er bijvoorbeeld hun documentroot. Vooral omdat je aan gebruikers op internet toegang geeft tot deze bestanden, is het handig ze op een apart volume te houden. De grootte is lastig aan te geven en wordt bepaald door wat je ermee gaat doen. Wordt de computer een pure server? Dan mag dit volume heel groot worden: op een schijf van 200 GB kun je er bijvoorbeeld best 150 GB voor gebruiken. In de directory /var verschijnen bestanden die automatisch en ongecontroleerd gemaakt worden door het besturingssysteem. Reden genoeg om er een apart volume van te maken! Als je niets bijzonders doet met /var, is 1 GB een heel redelijke grootte. Als je gecentraliseerde diensten als NIS, DNS of LDAP gaat aanbieden, is het beter er ongeveer 5 GB van te maken en als je de server als drukke mailserver wilt inrichten, is het aan te raden het volume groot te maken; bijvoorbeeld 50 GB. In /usr staan alle programmabestanden op de server. Dit is een bestandssysteem waarop het niet nodig is ook te kunnen schrijven. Juist om die reden is het handig /usr als apart volume aan te maken en read-only te mounten. Wij zullen dat dan ook doen.
10
Linux 4
Schrijfbaar maken Je kunt een volume dat read-only is gemount heel eenvoudig beschrijfbaar maken. Gebruik hiervoor de opdracht mount -o remount,rw /volumenaam. /home
/
Als je een fileserver maakt waarop je bestanden wilt delen voor eindgebruikers, heeft elke eindgebruiker een homedirectory. Deze homedirectory plaats je in de directory /home. /home/alex is bijvoorbeeld de homedirectory van gebruiker alex. Hoe groot deze directory moet zijn, is lastig te zeggen. Neem het aantal gebruikers dat je hebt en vermenigvuldig dit met de hoeveelheid schijfruimte die je per gebruiker wilt spenderen. Het resultaat is de totale grootte die je aan /home toekent. Tot slot is er het volume waarop de rootdirectory (/) staat; het zogenoemde rootvolume. Hierop staan alle andere directory’s en bestanden. Over het algemeen is een grootte van 4 GB meer dan genoeg voor dit volume.
11. Als je bepaald hebt hoe groot elk volume moet worden, is het tijd om aan het werk te gaan. Het uitgangspunt is een venster dat eruit kan zien zoals in figuur 1.9. Figuur 1.9 Als je begint met de partitie-indeling, zie je altijd de huidige schijfindeling
1 Installatie
11
12. Je gaat een server inrichten en alle partities en volumes die nu op de schijf staan, mogen verwijderd worden. Selecteer hiervoor de vaste schijf. In figuur 1.9 staat deze boven in de lijst en heet /dev/ sda. Als je één schijf in je computer hebt, zal deze schijf altijd /dev/ sda of /dev/hda heten. Selecteer dit apparaat in de lijst die je ziet in figuur 1.9 en klik op Verwijderen. Het installatieprogramma vraagt of je het echt zeker weet en als je hier bevestigend op antwoordt, zijn alle bestaande partities en volumes verdwenen. Spijt? Ben je toch niet helemaal zeker dat inderdaad alles weg moet? Klik dan nu op Annuleren, er is namelijk op dit moment nog helemaal niets definitief weggegooid. 13. Nu zie je alleen nog de vaste schijf. Klik op Aanmaken om een bootpartitie aan te maken. Als het installatieprogramma vraagt wat voor type partitie je wilt, kies je voor een Primaire partitie. Kies onder de optie Formatteren het bestandssysteem ext2. Vul dan onder de eindcilinder de waarde 100M in. Kies tot slot onder Mountpunt de directory /boot en klik op OK. Je hebt nu een bootpartitie gemaakt. 14. We hebben een tweede partitie nodig die in zijn geheel voor logische volumes gebruikt kan worden. Klik nogmaals op Aanmaken. Kies de optie Niet formatteren en selecteer het bestandssysteem ID 0x8E Linux LVM. Klik op OK om de partitie voor gebruik door LVM aan te maken. 15. Klik op de knop LVM onder in beeld om te beginnen met het maken van logische volumes. 16. Nu zie je een venster waarin gevraagd wordt of je een volumegroep wilt maken. Klik in dit venster op OK om de standaardsuggesties gewoon te accepteren. Figuur 1.10 Klik hier op OK om de volumegroep aan te maken
12
Linux 4
17. Je ziet het venster waarin je de LVM-partitie toevoegt aan de logische volumegroep die je zojuist hebt gemaakt (zie figuur 1.11). Klik in dit venster op Volume toevoegen. Hiermee zorg je ervoor dat de vaste schijf in zijn geheel wordt toegevoegd aan de volumegroep met de standaardnaam system. Klik op Verder Figuur 1.11 Klik op Volume toevoegen om de vaste schijf toe te voegen aan de volumegroep die je zojuist hebt gemaakt
18. In het venster Logische volumes zie je een schematische weergave van de inhoud van de volumegroep. Klik hier op de knop Toevoegen om het eerste logische volume te maken. Nu zie je het venster Logisch volume aanmaken dat je ook in figuur 1.12 ziet. In dit venster regel je de grootte van het volume, maar ook hoe het volume geformatteerd wordt. Tot slot specificeer je het mountpunt, dit is de naam van de directory waaraan je dit volume gaat koppelen. Voordat we bespreken hoe je een drietal volumes maakt, eerst een paar woorden over bestandssystemen. Bestandssysteem Een bestandssysteem bepaalt hoe het volume geformatteerd wordt. Sommige bestandssystemen zijn beter, andere zijn minder geschikt. We geven een kort overzicht van de bestandssystemen waaruit je kunt kiezen:
1 Installatie
Reiser
Ext4
Ext3
Ext2 XFS
Vfat
Swap
13
Dit was vroeger het standaardbestandssysteem onder SUSE. Dit bestandssysteem is nog steeds de beste keuze voor een server die veel kleine bestanden snel moet kunnen verwerken, zoals het geval is voor een mailserver. In alle andere gevallen is het beter een ander bestandssysteem te gebruiken. Reiser heeft namelijk een probleem met het aantal ontwikkelaars dat er nog aan werkt. Het bestandssysteem ext4 is de opvolger van ext2 en ext3. Alle tekortkomingen van zijn voorgangers moeten in dit bestandssysteem opgelost worden. Op het moment dat dit boek geschreven werd, was ext4 echter nog niet klaar. Ext3 is de opvolger van ext2 en al jarenlang het standaardbestandssysteem op de meeste Linux-distributies. Als je wilt werken met directory’s waarin heel veel bestanden of hele grote bestanden voorkomen, is ext3 langzaam, maar in alle andere gevallen kies je met een gerust hart voor ext3. Ext2 is de voorganger van ext3. Het heeft zin dit bestandssysteem te kiezen op kleine volumes, tot een maximale grootte van 100 MB. XFS is een zwaargewicht onder de bestandssystemen. Voor doorsnee werk is dit zeker niet de snelste, maar als je wilt gaan werken met hele grote bestanden of mappen waarin heel veel bestanden voorkomen, is dit de beste keuze. Ook is XFS uitermate goed in het werken met streaming media; dit is handig om te weten als je een mediaserver wilt gaan inrichten. Er is maar één reden om vfat te gebruiken: als je op één machine zowel Windows als Linux wilt kunnen starten. Bestanden op een vfat-bestandssysteem kunnen namelijk zonder kunstgrepen door beide besturingssystemen gelezen worden. Je kiest Swap niet om bestanden op te slaan. Swap is het bestandssysteem dat gebruikt wordt om een swapvolume aan te maken. Linux swapt standaard namelijk niet naar een bestand, maar naar een partitie of logisch volume.
19. Gewapend met deze kennis over bestandssystemen kun je een aantal logische volumes maken en formatteren. In de komende stappen maken we de volgende bestandssystemen aan:
14
Linux 4
Een swapvolume van 1 GB. Handig om te weten: het heeft in geen enkel geval zin het swapvolume groter te maken dan 1 GB. Een /srv volume van 4 GB. Een /usr volume van 4 GB. De rest wordt toegewezen aan het rootvolume (/). 20. Kies in het kader Formatteren de optie Swap. Vul vervolgens een logische volumenaam in. Swap is in dit geval geen slechte keuze. Bij Grootte typ je 1 GB. Het resultaat ziet er zo uit als in figuur 1.12. Klik op OK om het swapvolume te maken. Figuur 1.12 Standaardinstellingen voor het maken van een swapvolume
21. Je ziet nu in het venster Logische volumes van de volumemanager dat het swapvolume gemaakt is. De naam van het apparaat (device) dat voor dit doel gemaakt is, is /dev/system/swap. Zie je dit inderdaad? Klik dan op Toevoegen om een volume te maken voor de directory /srv. Zorg ervoor dat onder Formatteren het bestandssysteem ext3 gemaakt is. Geef het volume de naam srv en gebruik een grootte van 4 GB. Specificeer tot slot dat het volume onder /srv gemount moet worden en klik op OK om het volume aan te maken. 22. Maak nu het volume /usr. Ook dit volume krijgt een bestandssysteem ext3. Geef het de naam usr en een grootte van 4GB. Vul als mountpunt de directory /usr in. Klik op Fstab opties en selecteer hier de optie Mount read-only. Dit zorgt ervoor dat het voor een
1 Installatie
15
indringer niet mogelijk is bestanden op dit volume te wijzigen. In figuur 1.13 zie je hoe het venster eruitziet waarin je dit opgeeft. Figuur 1.13 Je past een stukje extra beveiliging toe door het /usr volume read-only te mounten
23. Maak tot slot het rootvolume. Dit volume heeft het mountpunt / en gebruikt ook een bestandssysteem ext3. Klik op de knop maximum om alle overgebleven schijfruimte aan dit volume toe te kennen en klik op OK. 24. De schijf is nu ingedeeld. Klik op Verder. Je ziet nu, zoals in figuur 1.14, de zojuist gemaakte partitie- en volume-indeling. Ziet het er min of meer hetzelfde uit, klik dan op Voltooien om door te gaan met de volgende stap. Figuur 1.14 Als je klaar bent met het maken van logische volumes, heb je waarschijnlijk een vrij complexe partitieindeling opgebouwd
16
Linux 4
Heb je ervoor gekozen niet moeilijk te doen en te werken met de standaardvolume-indeling? Dan kun je vanaf dit punt weer verder lezen. 25. Klik op Software. Je ziet nu de lijst met programmatuur die automatisch geïnstalleerd wordt. Zorg ervoor dat in deze lijst in elk geval de volgende opties geselecteerd zijn: Grafisch basissysteem KDE Desktop Environment GNOME-systeem Documentatie en ondersteuning Eenvoudige webserver met Apache LDAP-server en hulpprogramma's Netwerk en server Kernel-ontwikkeling Ervaren gebruiker Vergeten? Vergeten een bepaalde optie te installeren? Geen probleem, het is vrij eenvoudig later alsnog software toe te voegen.
Figuur 1.15 Met deze softwareselectie installeer je een heel aardig basissysteem
26. Klik op Accepteren om te beginnen met de installatie. Mogelijkerwijs krijg je nog enkele licentiemeldingen van specifieke programma’s te zien. Klik ook dan op Accepteren, net zolang totdat je ziet dat de bestandssystemen geformatteerd worden en de softwarepackages naar de computer worden gekopieerd.
1 Installatie
17
27. In het venster Hostnaam en domeinnaam bepaal je hoe de server heet en wat de naam is van het DNS-domein waarin de server voorkomt. Als de server daadwerkelijk aan internet hangt, heb je met een internetprovider geregeld welke domeinnaam je gebruikt. Daarnaast is het van belang dat de server een unieke naam heeft. Het installatieprogramma kent een willekeurige naam aan de server toe, het is niet handig om deze te gebruiken. Typ daarom de nieuwe naam en DNS-naam en zorg ervoor dat de optie Hostnaam via DHCP wijzigen uit staat. Klik vervolgens op Verder. Figuur 1.16 Zorg ervoor dat de server een unieke naam krijgt voordat je verder gaat
28. Nu vul je het wachtwoord voor de gebruiker root in. Zeker als de server aan internet hangt, is het belangrijk hier een veilig wachtwoord voor te gebruiken; root is namelijk als beheerder letterlijk de almachtige op het systeem. Mocht je een voor de hand liggend woord als wachtwoord willen gebruiken, zorg er dan in elk geval voor dat sommige letters systematisch gewijzigd worden door cijfers en leestekens en gebruik zowel hoofd- als kleine letters. Roosendaal wordt in dat geval dus bijvoorbeeld R0o53nd@ a!. Voor jou nog redelijk eenvoudig te onthouden, maar voor een geautomatiseerd programma dat wachtwoorden kraakt nagenoeg onmogelijk om te raden. Het wachtwoord dat je invult, verschijnt overigens niet letterlijk in beeld, maar in plaats daarvan verschijnen er asterisken. Het is immers van belang dat onbevoegden niet zomaar je wachtwoord kunnen uitlezen!
18
Linux 4
Figuur 1.17 Het is van groot belang dat het wachtwoord van de gebruiker root moeilijk te raden is
29. Nu moet je de netwerkverbinding instellen. In het venster Netwerkconfiguratie (zie figuur 1.18) zijn er behoorlijk wat opties die je moet instellen. We behandelen er hier maar vier van, omdat de overige opties minder gebruikelijk zijn. Figuur 1.18 Er worden nogal wat opties geboden om de netwerkverbinding in te stellen
30. Onder Netwerkmodus zie je om te beginnen hoe het netwerk geactiveerd wordt. Je hebt hier twee mogelijkheden voor. Om te beginnen is er de traditionele optie waarbij alles ingesteld wordt in YaST. Als alternatief maak je gebruik van de netwerkmanager. Dit is heel handig als je een laptop installeert met daarop een draadloze netwerkkaart, het ligt echter wat minder voor de hand op een server.
1 Installatie
19
31. De tweede optie waarmee je iets moet doen, is de optie Firewall. Gewoonlijk is het een goed idee gebruik te maken van een firewall die alles tegenhoudt, met uitzondering van die pakketjes waarvoor je aangegeven hebt dat ze wel toegestaan zijn. Wij zorgen er echter op dit moment voor dat de firewall uit staat. Niet omdat we vinden dat je geen firewall moet gebruiken, integendeel! De reden is dat de firewall ook alle serververkeer tegenhoudt. Je leert in dit boek eerst hoe je alles installeert en later hoe je ervoor zorgt hoe de installatie beveiligd wordt. Dit omdat de configuratie van een firewall vrij lastig is en wij er in dit boek voor kiezen deze configuratie in een apart hoofdstuk, hoofdstuk 10, volledig uiteen te zetten. Wel of niet? Is de server direct al met internet verbonden? Negeer dan het voorgaande advies en zorg ervoor dat de firewall wél meteen actief is! Als je tien minuten aan internet verbonden bent, ben je al een keer gehackt en dan is het echt van groot belang dat de server goed beschermd is! 32. De belangrijkste optie in het venster Netwerkconfiguratie is de optie Netwerk interfaces. Hiermee stel je in hoe de netwerkkaart ingesteld moet worden. Zodra je deze optie aanklikt, kom je in het netwerkkaartconfiguratieoverzicht (zie figuur 1.19). Hier zie je waarschijnlijk de netwerkkaart al staan. Figuur 1.19 Gewoonlijk staat de netwerkkaart al in het netwerkkaart configuratieoverzicht
20
Linux 4
33. Aangezien de netwerkkaart vrijwel altijd gewoon gedetecteerd wordt, bespreken we hier alleen hoe je de huidige instellingen van de netwerkkaart aanpast. Selecteer de netwerkkaart en klik op Wijzigen. Het venster Netwerkadres instelling wordt geopend. Hierin zie je twee tabbladen: van deze tabbladen is het tabblad Adres het meest belangrijk. Hierop stel je namelijk in welk adres de netwerkkaart gaat gebruiken. Selecteer hier de optie Statische adres instelling en vul dan het te gebruiken IP-adres en subnetmasker in. Activeer vervolgens de optie Hostnaam en naamserver om het IP-adres van de DNS-naamserver in te vullen en daarna het tabblad Routing om het IP-adres van de router in te vullen. Klik dan tweemaal op Verder om door te gaan. Je komt weer terug in het hoofdvenster met netwerkinstellingen. Figuur 1.20 Een echte server heeft vrijwel altijd een statisch toegekend IP-adres
34. De laatste optie die de moeite waard is, is de optie VNC remote beheer. Hiermee maak je het mogelijk de server op afstand te beheren. Klik op deze knop en selecteer vervolgens de optie Remote beheer toestaan als je ervoor wilt zorgen dat je de desktop van de server van afstand over kunt nemen. Klik dan op Voltooien en daarna op Verder om door te gaan. De instellingen van de netwerkkaart worden nu naar het systeem weggeschreven.
1 Installatie
21
Figuur 1.21 Het aanzetten van VNC remote beheer is erg eenvoudig
35. Nu wordt gevraagd of je de verbinding met internet wilt testen. Dat kun je doen, om vervolgens meteen alle relevante patches binnen te halen. Dit kost echter enige tijd en daarom kiezen de meeste mensen ervoor om op dit moment nog geen verbinding met internet te maken, maar dit op een later tijdstip te doen. Selecteer hier de optie die je wilt en klik op Verder om door te gaan. 36. In het volgende venster geef je aan op welke wijze gebruikers geverifieerd moeten worden. Hoewel er verschillende methoden zijn die voor dit doel kunnen worden ingezet, houden we het in dit geval eenvoudig en kiezen we voor Lokaal (/etc/passwd). Klik op Verder. 37. Aangezien je gekozen hebt voor lokale verificatie van gebruikers en dit een nieuw systeem is, zijn er op dit moment nog geen gebruikers. Daarom moet je in het volgende venster een nieuwe lokale gebruiker toevoegen. Dit doe je door de volledige naam, de gebruikersnaam en tweemaal het wachtwoord voor de betreffende gebruiker in te vullen (zie figuur 1.22). Klik vervolgens op Verder om door te gaan naar de volgende stap. 38. Nu wordt tot slot het een en ander opgeruimd. Denk daarbij aan tijdelijke bestanden die niet langer nodig zijn. Als dat gebeurd is, kun je de (Engelstalige) release notes lezen. Hierin lees je wat er allemaal in deze versie van SUSE Linux veranderd is. Alles gelezen? Klik dan op Verder om door te gaan naar de laatste stap.
Linux 4
22
Figuur 1.22 Je hebt een lokale gebruikersaccount nodig om veilig je werk te kunnen doen
39. In de laatste stap wordt de hardware van de computer geconfigureerd. Hiervoor detecteert het systeem wat je allemaal in de computer aan hardware hebt en probeert hier automatisch de beste stuurprogramma’s voor te installeren. Over het algemeen gaat dit vrij goed. Meestal kun je meteen op Verder klikken om de installatie te voltooien. VMware Installeer je in VMware om Linux eens uit te proberen of werk je in een VMware Server of infrastructuuromgeving? Dan moet je niet nu, maar aan het eind van de installatie de grafische kaart configureren. Dit doe je met behulp van de VMware Tools. In 1.4 leer je hoe je dit doet.
Figuur 1.23 In het algemeen wordt de hardware in het systeem goed gedetecteerd
1 Installatie
23
40. Nu zie je het venster waarin gemeld wordt dat de installatie voltooid is. Klik hier op Voltooien. Het geïnstalleerde systeem wordt gestart en als dat gebeurd is, zie je een venster waarin je je met een gebruikersaccount kunt aanmelden. 1.3
Installatie van Fedora Core
Ook om Fedora te kunnen installeren, moet de computer aan bepaalde minimale systeemeisen voldoen. De eisen om prettig met Fedora Core als server te kunnen werken, zijn als volgt: Pentium III processor of beter. Minimaal 256 MB werkgeheugen voor een installatie zonder grafische onderdelen, bij voorkeur 512 MB of meer voor een grafische installatie. Houd er rekening mee dat vooral bij zwaar gebruikte servers het belangrijk is dat er voldoende werkgeheugen in de server aanwezig is. Minimaal 4 GB vrije schijfruimte voor installatie van alle componenten. Cd-of dvd-station. VGA of betere grafische hardware. Muis. Wanneer de computer aan deze voorwaarden voldoet, kun je beginnen met de installatie:
1. Leg het installatiemedium in de lade van het cd-station en start de computer opnieuw op. Zorg ervoor dat deze tijdens het starten vanaf het optische medium start. Druk vervolgens op Enter om Fedora Core in grafische modus te installeren. Er wordt nu eerst een tekstvenster gestart om het installatiesysteem te starten. 2. Als eerste wordt, voorafgaand aan de installatie, gevraagd of je alle cd’s wilt testen. Gebruik de Tab-toets om de optie Skip te selecteren om deze controle over te slaan. Deze controle duurt namelijk erg lang en in de meeste gevallen zal het toch wel goed gaan. Alleen als je met dezelfde installatiemedia eerder problemen gehad hebt, is het aan te bevelen eerst een controle van de media te doen.
24
Linux 4
Figuur 1.24 Het is meestal niet nodig eerst een controle van al de cd’s uit te voeren voordat je met de installatie begint
3. Er wordt nu een hardwaredetectie uitgevoerd die ervoor zorgt dat al de hardware op de juiste wijze aangestuurd kan worden. Wanneer deze detectie voltooid is, zie je het eerste venster uit de grafische installatieprocedure. Klik hier op Next om te beginnen met de daadwerkelijke installatie. 4. Selecteer de taal. Wij gaan in dit boek uit van de optie Dutch (Nederlands). Figuur 1.25 Ook Fedora kan gewoon in het Nederlands geïnstalleerd worden
5. Nadat je de taal geselecteerd hebt, geef je aan welk type toetsenbord je gebruikt. Let erop dat je hier als Nederlander in de meeste gevallen juist niet voor Nederlands kiest, maar voor V.S. International. Verzeker je ervan dat dit type toetsenbord geselecteerd is en klik op Volgende om verder te gaan.
1 Installatie
25
Figuur 1.26 Als je de Nederlandse taal gekozen hebt, moet je specifiek nog opgeven dat je een V.S. Internationaaltoetsenbord gebruikt
6. Het installatieprogramma probeert nu de vaste schijf uit te lezen om te kijken of er al een bestaande versie van Fedora Core op geïnstalleerd is die bijgewerkt moet worden. Als je op een nieuwe vaste schijf installeert, zie je een melding waarin aangegeven wordt dat de partitietabel onleesbaar was. Niets aan de hand, als er niets bijzonders op de vaste schijf staat waarop je installeert, mag je hier gerust op Ja klikken om het schijfstation te initialiseren. Doe dit echter alleen op een nieuwe schijf, want als er al gegevens op de schijf stonden, raak je die hiermee onherroepelijk kwijt. Figuur 1.27 Als je deze melding ziet op een schijfstation waarop gegevens staan die je wilt bewaren, is het aan te raden onmiddellijk op te houden
26
Linux 4
7. Net als SUSE wil ook Fedora de vaste schijf automatisch voor je inrichten. Ook in dit geval vinden we dat geen idee. De vaste schijf van een server moet namelijk met zorg ingedeeld worden om in een later stadium problemen te voorkomen. Om dit te bereiken willen we gebruikmaken van de volgende schijfindeling. Deze indeling gaat uit van een schijf van 20 GB, op grotere schijven maak je deze partities naar rato groter: Een partitie waarop de directory /boot staat. Deze wordt 100 MB groot. De rest van de schijf wordt ingedeeld in logische volumes. Een logisch volume van 1 GB voor gebruik als swappartitie. Een logisch volume met daarop de directory /srv. Deze wordt 4 GB groot. Een logisch volume met de directory /usr, zodat deze read-only gemount kan worden. Ook deze wordt 4 GB groot. Een logisch volume met daarop de directory /var. Voor gemiddeld gebruik kan deze ingesteld worden op 1 GB. Als een server geïnstalleerd wordt die intensief van deze directory gebruikmaakt, is het soms nodig deze directory veel groter te maken. Een logisch volume voor de directory /home als de server ingericht wordt als fileserver. Bepaal op basis van de behoeften van je gebruikers zelf hoe groot dit volume wordt. De rest wordt toegewezen aan de rootdirectory (/). Figuur 1.28 Kies hier niet de standaardpartitieindeling, maar pas de indeling van de schijf naar eigen wensen aan
8. De standaardoptie in het venster voor de schijfindeling staat op Verwijder Linux partities op de stations en gebruik standaard opmaak. Klik op de keuzelijst om hier de optie Gebruik aangepaste opmaak te selecteren en klik op Volgende om verder te gaan.
1 Installatie
27
9. Nu zie je het venster waarin je zelf de schijfindeling maakt. Klik hier om te beginnen op Nieuw om de bootpartitie te maken. Voer bij Koppelpunt de directory /boot in. Kies het bestandssysteem ext2 en specificeer een grootte van 100 MB. Zorg ervoor dat de schijf gemaakt wordt met een vaste grootte en let er ook op dat de optie Forceren als primaire partitie geselecteerd is. Klik op OK. Figuur 1.29 Maak de bootpartitie volgens deze specificaties
10. Maak nu een partitie waarbinnen je logische volumes maakt. Klik vanuit het hoofdvenster van het schijfindelingsprogramma op Nieuw. Kies de partitie de volgende specificaties en klik vervolgens op OK om verder te gaan: Koppelpunt:
. Type bestandssysteem: physical volume (LVM). Extra grootte-opties: Opvullen tot maximum toegestane grootte. Forceren als primaire partitie: aan 11. Klik op LVM. Het venster LVM Volume Group maken verschijnt (zie figuur 1.30). In dit venster geef je om te beginnen een naam aan de volumegroep. De standaardnaam is VolGroup00, maar als je toch maar één volumegroep maakt, kun je net zo goed voor een meer leesbare naam als System kiezen. Vervolgens geef je de grootte aan voor Physical Extent. Dit zijn de bouwblokken waaruit het volume opgebouwd wordt. De standaardgrootte van 32 MB is vrij groot; als je niet meer dan 256 GB schijfruimte wilt adresse-
Linux 4
28
ren, kun je hier voor betere prestaties ook kiezen voor een Physical Extent van 4 MB. Figuur 1.30 Als je maar één volumegroep maakt, kies dan een duidelijke naam als System
12. Klik nu nog steeds vanuit het venster LVM Volume Group maken op de knop Toevoegen om een logisch volume toe te voegen. Maak de logische volumes volgens de bovenstaande specificaties. De beschikbare opties worden hiervoor als volgt gebruikt: Bij Koppelpunt vul je de naam in van de directory waarvoor dit volume gebruikt wordt. Gebruik bijvoorbeeld /var voor het volume van 1 GB waarop je /var gaat mounten. Bij Bestandssysteem type kies je het bestandssysteem dat je wilt gebruiken. In Fedora kun je alleen kiezen tussen ext2 en ext3. Wil je een ander bestandssysteem gebruiken voor het volume, maak dan wel alvast het volume maar specificeer nog geen koppelpunt, je moet dit dan namelijk later handmatig regelen. Gebruik bij Logical Volume naam de naam van de directory waarop je het volume gaat mounten. Dit ook weer omwille van de duidelijkheid.
1 Installatie
29
Figuur 1.31 De eigenschappen van de logische volumes komen er ongeveer zo uit te zien
13. Nadat je de logische volumes gemaakt hebt, klik je in het hoofdvenster van het schijfindelingsprogramma op Volgende. Je komt in het venster waarin je aangeeft hoe het systeem zal opstarten. In dit venster (zie figuur 1.32) wordt geregeld dat de bootloader Grub geïnstalleerd wordt in de master boot record van de vaste schijf en dat is uitstekend. De enige optie die je mogelijkerwijs aan wilt passen, is de optie Bootloader-wachtwoord gebruiken. Gebruik deze optie als je de server wilt instellen met een boot-wachtwoord. Hiermee zorg je ervoor dat tijdens het opstarten alleen boot-opties opgegeven kunnen worden door personen die eerst het juiste wachtwoord ingevoerd hebben. Handig als extra beveiligingslaag! Figuur 1.32 In het venster waarin de bootloader geconfigureerd wordt, hoef je niets te veranderen
14. In het volgende venster stel je de netwerkkaart en andere belangrijke eigenschappen van de computer in. In dit venster wordt ongeveer alles aangepast. Klik om te beginnen op Aanpassen om de
30
Linux 4
eigenschappen van de netwerkkaart zelf aan te passen. Je ziet het venster uit figuur 1.33. Zet de optie Dynamische IP-configuratie (DHCP) gebruiken uit. Doe dit ook voor de optie IPv6-ondersteuning aanzetten. Vul vervolgens het juiste IP-adres met het bijbehorende subnetmasker (netmask) in voor de netwerkkaart en klik op OK om de wijzigingen op te slaan. Figuur 1.33 Een serieuze server wordt uitgerust met een vast IP-adres
15. Vul in het hoofdvenster van de configuratie van de netwerkkaart eerst de volledige hostnaam voor de computer in. Hierbij is het aan te raden direct ook de naam van het DNS-domein waarin de computer gaat opereren te specificeren. Geef dan de IP-adressen van de gateway (de standaardrouter) op en op zijn minst de eerste DNSserver en klik op Volgende om verder te gaan. Figuur 1.34 Vergeet vooral niet de computer gelijk ook een naam te geven, doe je dat niet dan heet hij namelijk Localhost
1 Installatie
31
16. Nu zie je het venster met de tijdinstellingen. Als je aangegeven hebt in het Nederlands te willen installeren, hoef je hier helemaal niets te veranderen. Als dit niet het geval is, klik dan op de wereldkaart op de gele stip die het dichtste bij de plaats is waar je de server installeert en klik op Volgende om verder te gaan. De optie Systeemklok gebruikt UTC staat in bijna alle gevallen uit; de meeste moderne servers gebruiken lokale tijd en niet de universele Universal Time Coordinated (UTC). Figuur 1.35 Als je ervoor gekozen hebt in het Nederlands te installeren, is automatisch de juiste locatie al ingesteld
17. Vul het wachtwoord in voor de gebruiker root. Onthoud: root is almachtig op de computer dus het is belangrijk voor deze gebruiker een wachtwoord te kiezen dat niet al te zeer voor de hand ligt. Klik op Volgende om verder te gaan. 18. Nu verschijnt het venster waarin je aangeeft waarvoor je de server wilt gaan gebruiken. Fedora is een allround Linux-distributie en standaard is dan ook de optie Kantoor en productiviteit geselecteerd. Zoals je begrijpt is dat niet de bedoeling. Kies om te beginnen de optie Webserver en selecteer onder in beeld de optie Nu aanpassen. Klik dan op Volgende om meer specifiek aan te geven wat je wilt doen.
32
Linux 4
Figuur 1.36 Kies de juiste software voordat je verder gaat, standaard staat Fedora Core namelijk ingesteld als kantoormachine
19. Het venster verschijnt waarin je in detail aangeeft wat je wilt installeren. In feite is niets echt belangrijk om hier op te geven, je kunt later vrij eenvoudig extra software installeren. Toch is het handig alvast een goed uitgangspunt te hebben. Kies om te beginnen alles wat onder de optie Servers voorkomt, dan zul je niet snel een server tegenkomen die niet beschikbaar is. Figuur 1.37 Om te voorkomen dat je later vaak nog extra software moet installeren, is het handig alvast alles onder de optie Servers te installeren
20. Nu worden de afhankelijkheidsrelaties in alle geselecteerde pakketten nagelopen. Hiermee zorgt het installatieprogramma dat ook andere software die nodig is om de selectie te kunnen installeren geïnstalleerd wordt. Als dit gebeurd is, klik je op Volgende om te
1 Installatie
33
beginnen met het kopiëren van de geselecteerde software naar de computer. Tijd om koffie te drinken, want dit duurt over het algemeen wel even. 21. Nadat alle software naar de computer gekopieerd is, gaat het installatieprogramma verder en kun je de installatie afronden. Klik daarvoor om te beginnen op de knop Herstarten. De server wordt opnieuw opgestart. Als dit gebeurd is, verschijnt het programma waarin de installatie voltooid wordt. Figuur 1.38 Voordat de installatie in gebruik genomen kan worden, moet eerst nog een aantal stappen doorlopen worden
22. Om te beginnen is er de onvermijdelijke gebruiksovereenkomst. Hier selecteer je maar beter de standaardkeuze Ja, ik ga akkoord met de gebruiksovereenkomst, want als je dit niet doet, wordt de installatie afgebroken en kun je opnieuw beginnen. Vervolgens mag je aangeven of de firewall al dan niet moet worden ingeschakeld. Gewoonlijk moet je de firewall altijd inschakelen, maar we doen dit nu echter niet omdat we niet willen dat je gehinderd wordt bij je pogingen de Linux-server in gebruik te nemen. In hoofdstuk 10 leer je hoe je de firewall alsnog inschakelt en er daarbij voor zorgt dat vertrouwde services door de firewall heen hun werk kunnen doen. Internet Als je de server meteen met internet verbindt, negeer dan de voorgaande aanwijzingen en laat de firewall ingeschakeld. Het risico is veel te groot als je dit niet doet!
34
Linux 4
Figuur 1.39 Om je niet al te veel dwars te zitten bij de installatie van de server, is het handig de firewall in eerste instantie even uit te schakelen
23. In het volgende venster geef je aan wat je met SELinux wilt doen. Dit systeem zorgt ervoor dat applicaties beveiligd worden, zodat geen ongeoorloofd gedrag is toegestaan. Wij raden je aan de standaardinstelling Enforcing gewoon te laten staan om ervoor te zorgen dat SELinux zijn werk kan doen. Klik daarom in dit venster gewoon op Volgende om verder te gaan. 24. Stel nu de juiste datum en tijd in. Klik vervolgens op het tabblad Netwerk Tijd Protocol. Hier regel je dat de server automatisch periodiek contact opneemt met een server op internet om de tijd te synchroniseren. Selecteer op dit tabblad de optie Netwerk Tijd Protocol gebruiken en klik op Volgende. Het gevolg is dat de server altijd bij de tijd zal zijn en dat is voor sommige beveiligings instellingen erg belangrijk! Figuur 1.40 Als je Netwerk Tijd Protocol gebruikt, zorg je ervoor dat de server altijd bij de tijd is
1 Installatie
35
25. Nu maak je een gebruikersaccount. Zo hoef je niet altijd als root te werken, maar kun je ook af en toe je werk doen als een niet-almachtige gebruiker. Vanuit de optiek van beveiliging zeker aan te bevelen! Maak de gebruiker gewoon met standaardopties, de optie Netwerk login gebruiken is op dit moment nog niet relevant. Figuur 1.41 Om ervoor te zorgen dat je niet alleen als root werkt, is het aan te raden een gebruikersaccount aan te maken
26. Stel tot slot de eigenschappen van de geluidskaart in en klik op Voltooien. Het vers geïnstalleerde systeem wordt nu gestart en je kunt inloggen. Figuur 1.42 Aan het einde van de installatie wordt een fraaie loginprompt getoond
36
Linux 4
1.4
Installeren van VMware Tools
VMware is een populair platform om Linux te installeren. Niet alleen om het uit te proberen, maar in combinatie met VMware Server of VMware Infrastructure zelfs om meerdere virtuele Linux-machines op één computer te gebruiken. Als je echter VMware gebruikt, moet je VMware Tools installeren om volledig te kunnen profiteren van de grafische mogelijkheden van het systeem. Omdat er nogal wat mensen gebruikmaken van VMware, leggen we hier tot slot van dit hoofdstuk uit hoe je deze VMware Tools installeert en configureert. 1. Klik in VMware op het menu VM en selecteer de optie VMware Tools. Klik in het venster dat nu verschijnt op Install om te beginnen met de installatie van de tools. 2. Open een terminalvenster en activeer vanuit dit terminalvenster de map /media. Hierin is een subdirectory gemaakt; doorgaans met de naam VMware_Tools. Activeer deze map. 3. In de map VMware_Tools vind je twee bestanden. Eén daarvan heeft de extensie .rpm. Installeer dit bestand met behulp van de opdracht rpm -ivh, gevolgd door de volledige naam van het rpmbestand. Read-only? Had je /usr als read-only gemount? Dan kreeg je bij stap 3 een foutmelding. Geef de opdracht mount -o remount,rw /usr om het bestandssysteem /usr leesbaar te maken en voer dan stap 3 van deze procedure nogmaals uit. 4. Typ de opdracht vmware-config-tools.pl en kijk naar de aanwijzingen die gegeven worden. In de meeste gevallen hoef je alleen maar aan te geven in welke resolutie je wilt werken. De nieuwe instellingen worden weggeschreven en de volgende keer dat je de grafische omgeving opnieuw start, worden de nieuwe instellingen ook gebruikt. 5. Activeer nogmaals in VMware het menu VM en kies de optie Cancel VMware tools installation. Hiermee krijg je weer toegang tot de normale optische drive.
1 Installatie
1.5
37
Samenvatting
In dit hoofdstuk heb je geleerd hoe je een OpenSUSE of Fedora installeert met als doel er een server van te maken. Je hebt gezien welke opties van belang zijn bij het inrichten van een server en in het bijzonder betreft dit de te gebruiken partitie-indeling. Ook heb je gelezen hoe je de VMware Tools installeert om een testomgeving op basis van VMware op te zetten. In het volgende hoofdstuk leer je hoe je vanaf de opdrachtprompt in Linux je werk doet.
2
Basisvaardigheden
2.1
Inleiding
Wanneer je een nieuw besturingssysteem moet leren kennen, kan dat een behoorlijk indrukwekkende ervaring zijn. Alles is nieuw en het is lastig als leek te bepalen waar je moet beginnen. In dit hoofdstuk helpen we je zo snel mogelijk op weg met Linux. Je leert hier hoe je je kunt redden vanaf de Linux-opdrachtregel. Ook al heeft Linux prachtige grafische interfaces, in dit boek gaan we niet in op de mogelijkheden die vanuit deze interfaces geboden worden. Wat op SUSE namelijk met programmaatje X moet worden gedaan, wordt in Red Hat met oplossing Y opgelost. Daarnaast zul je ontdekken dat er nog steeds behoorlijk wat servers zijn waarop niet eens een grafische interface geïnstalleerd is. Als je beheerder wilt worden van een Linux-server, is het essentieel dat je kunt werken op de opdrachtregel. Daarom in dit hoofdstuk een inleiding daarin. Doel van dit hoofdstuk is zo snel mogelijk en zo veel mogelijk: we willen je snel veel opdrachten leren, zodat je snel met het Linuxsysteem uit de voeten kunt. 2.2
Opstarten: LILO en Grub
Wanneer je het Linux-systeem aanzet, moet de computer erachter zien te komen welk besturingssysteem geladen moet worden. Voor dit doel wordt gebruikgemaakt van een bootloader die in het MBR van de computer genesteld is. Deze bootloader verwijst naar de locatie waarop de kernel staat die gestart moet worden. Zonder bootloader dus geen Linux.
40
Linux 4
Op oudere distributies werd vooral de bootloader LILO gebruikt. Op recentere distributies wordt in plaats van LILO gebruikgemaakt van Grub, de Great Unified Boot Loader. Naast het opstarten van Linux kun je met LILO, wanneer er meerdere besturingssystemen op een computer aanwezig zijn, een keuze maken voor het besturingssysteem waarmee je wilt opstarten. Zo is het mogelijk op een computer zowel Linux als Microsoft Windows XP geïnstalleerd te hebben. Je geeft dan bij het opstarten aan met welk programma je wilt werken. Hiervoor kies je uit het bootmenu het besturingssysteem dat je wilt starten. Vaak is er ook een prompt aanwezig: dit is een regel waarop je opdrachten kunt invoeren die tijdens het opstarten door de kernel uitgevoerd moeten worden. Zo kun je bijvoorbeeld op deze prompt een ‘1’ invoeren om aan te geven dat Linux in Single User Runlevel gestart moet worden: dit kan heel handig zijn als je problemen hebt met normaal opstarten van de distributie. Figuur 2.1 Op de prompt kun je argumenten meegeven die tijdens het opstarten door de kernel uitgevoerd moeten worden
In de meeste gevallen zal de bootloader zo geconfigureerd zijn dat een bepaald besturingssysteem standaard na een paar seconden wordt opgestart.
2 Basisvaardigheden
41
Tip! Als je je wilt voorbereiden op het LPI-1-examen, doe je er goed aan vooral op LILO te letten, ook al gebruikt geen enkele moderne distributie deze bootloader nog. LPI stelt namelijk vragen over LILO en niet over Grub. Naast LILO of Grub kan ook het programma loadlin gebruikt worden om Linux op te starten. Het belangrijkste verschil tussen LILO en loadlin is dat loadlin een opdracht is die zich bevindt in een directory op een DOS-partitie, terwijl LILO vaak geïnstalleerd is in de bootsector van een vaste schijf. Je kunt dus van LILO gebruikmaken zonder eerst een ander besturingssysteem op te starten. Om loadlin te gebruiken zal altijd eerst DOS geactiveerd moeten worden. Omdat de meeste computers tegenwoordig geen DOS meer geïnstalleerd hebben, wordt deze optie echter niet vaak meer gebruikt: LILO werkt namelijk alleen vanuit een pure DOSomgeving en niet vanuit Windows. Tijdens het opstarten van Linux zie je nogal wat systeemmeldingen op het beeldscherm voorbijkomen. Deze meldingen geven informatie over de hardware die op de computer aanwezig is. Om later deze berichten nog eens na te kijken kun je met de toetsencombinatie Shift-PageUp een aantal schermen terug wandelen, zodat je eerder verschenen meldingen kunt bekijken. Het is ook mogelijk om nadat je bent ingelogd een aantal van deze meldingen te bekijken door de opdracht dmesg te gebruiken. Figuur 2.2 Met de opdracht dmesg bekijk je meldingen die tijdens het opstarten door de kernel zijn gegenereerd
42
Linux 4
2.3
Inloggen
Linux is ontworpen als systeem waar je met meerdere gebruikers tegelijk op kunt werken. Vaak zal een aantal van deze gebruikers via telnet over het netwerk inloggen. Het is echter ook mogelijk meerdere sessies op één pc gelijktijdig actief te hebben. Elke gebruiker heeft van de systeembeheerder zijn eigen set restricties meegekregen die ervoor zorgen dat niet iedereen van alle bestanden gebruik kan maken. Daarom dient een gebruiker zichzelf bekend te maken aan het systeem. Dit doe je door je loginnaam en wachtwoord op te geven. Het systeem zal hierom vragen direct nadat je de computer hebt opgestart. Afhankelijk van de wijze waarop de computer is ingesteld, kan dit vanaf een grafische prompt of een tekstregel gebeuren. Daarnaast kun je ook gebruikmaken van de opdracht login om je aan te melden bij het systeem. Je zult deze opdracht echter niet vaak hoeven te gebruiken, omdat het systeem zelf met een loginprompt komt wanneer je je moet aanmelden. Ook als je je afmeldt van de computer, zal deze opnieuw vanzelf een loginprompt genereren. Nadat je succesvol bent aangemeld, kun je gebruikmaken van je account. Een account omvat alle bestanden, resources en informatie die bij een bepaalde gebruiker hoort. Op een nieuw ingericht systeem bestaat slechts een beperkt aantal gebruikers. De meeste van deze standaardgebruikers worden door het systeem voor speciale doeleinden gebruikt. Zo is er bijvoorbeeld meestal een gebruiker genaamd ftp die door een andere computer gebruikt kan worden om je computer met het FTP-protocol te benaderen. Naast deze systeemaccounts bestaat er in elk geval altijd een zogenoemde superuser. Deze superuser is een gebruiker die alle rechten heeft op het systeem. Deze gebruiker logt in met de gebruikersnaam root. Omdat gebruiker root alle rechten heeft op het systeem, is het af te raden altijd gebruik te maken van deze account. Root heeft namelijk ook voldoende rechten om alle bestanden van een systeem te verwijderen. Daarom is het gebruikelijk dat er voor iedereen, inclusief de systeembeheerder, een aparte account bestaat. Aan deze account zijn precies die permissies verbonden die de gebruiker nodig heeft. In hoofdstuk 7 leer je hoe je zelf een account kunt maken.
2 Basisvaardigheden
43
De homedirectory is een van die zaken die zijn gekoppeld aan een account. Elke gebruiker heeft een homedirectory. Meestal is dit een subdirectory van de directory /home met dezelfde naam als de gebruiker waarop de gebruiker volledige permissies heeft/ Alleen de speciale systeemaccounts die gebruikt worden om services te starten op de computer, kunnen hun homedirectory op een andere locatie hebben. Een gebruiker gebruikt de homedirectory om daar al zijn persoonlijke bestanden en instellingen in op te slaan. Linux is zoals gezegd een systeem waarop met meerdere gebruikers gelijktijdig gewerkt kan worden. Vroeger konden meerdere gebruikers gelijktijdig werken op een UNIX-computer doordat elke gebruiker door middel van een terminal verbonden was aan de computer. Dit betekent dat er aan één computer meerdere beeldschermen met bijbehorende toetsenborden gelijktijdig verbonden konden zijn. Deze beeldschermen met bijbehorende toetsenborden werden ‘domme terminals’ genoemd en waren stuk voor stuk door middel van een seriële verbinding aan de computer verbonden. Daarnaast was er het beeldscherm en toetsenbord die direct aan de computer verbonden was. Dit beeldscherm werd gebruikt voor onderhoud en beheer van de computer. Dit is de zogeheten console. Domme terminals worden op moderne Linux-systemen nagenoeg niet meer gebruikt. Wel bestaat de mogelijkheid om meerdere sessies gelijktijdig open te hebben. Hiervoor wordt dan gebruikgemaakt van een verbinding met de computer over het netwerk, zoals bij het programma telnet, of er wordt gebruikgemaakt van virtuele consoles. Als je deze mogelijkheid wilt gebruiken, kan het systeem tot maximaal zes virtuele beeldschermen tegelijkertijd onderhouden. Je kunt tussen deze beeldschermen switchen met de toetsencombinaties Alt-F1– F6 en Ctrl-Alt-F1 – F6 als je in een Xwindowsessie werkt. In dat laatste geval kun je weer terug naar de grafische sessie met de toetsencombinatie Ctrl-Alt-F7. Zo kunnen er door middel van virtuele consoles maximaal zes gebruikers gelijktijdig op het systeem ingelogd zijn. Je kunt deze optie met name handig gebruiken door op de ene virtuele console als root te werken om iets te configureren, wat je op een tweede virtuele console als gebruiker gelijk kunt uitproberen. Nadat je je op het systeem hebt aangemeld, is er slechts één beeldscherm actief, namelijk het beeldscherm dat je ziet. Als je nu de
44
Linux 4
toetsencombinatie Alt-F2 gebruikt, wordt hiermee een nieuw virtueel beeldscherm geopend: de virtuele console. Je moet in dit beeldscherm weer apart inloggen. Dit kun je doen door nogmaals je gebruikersnaam in te voeren, maar er kan ook een andere gebruikersnaam ingevoerd worden. Je kunt dus als meerdere verschillende gebruikers gelijktijdig ingelogd zijn. Je hebt nu naast het beeldscherm waarnaar je zit te kijken (de console) op de achtergrond nog een beeldscherm actief: de virtuele console. Als je nu weer dit eerste beeldscherm wilt bekijken, kun je dit activeren met de toetsencombinatie Alt-F1. Er is trouwens ook nog een andere manier om te werken met virtuele consoles. Als je namelijk in een grafische sessie aan het werk bent, is het mogelijk binnen die grafische sessie meerdere consolevensters tegelijk open te hebben door ze vanuit het KDEof Gnome-menu op te starten. Dit doe je door met behulp van de opdracht xterm deze consoles handmatig te starten. Je wordt dan in elk van deze vensters automatisch aangemeld onder dezelfde gebruikersnaam als waarmee je de grafische sessie gestart had, het is echter geen probleem om een van deze vensters van actieve gebruikers-ID te veranderen door de opdracht su te gebruiken. Verderop in dit hoofdstuk leer je meer over deze opdracht. 2.4
Werken met Linux-opdrachten
De shell interpreteert de opdrachten. Alle Linux-opdrachten hebben een aantal eigenschappen gemeen. Als eerste kan een opdracht zonder opties of parameters gebruikt worden. Bij veel opdrachten gebeurt er dan niet veel of juist veel te veel. Als je bijvoorbeeld de opdracht find invoert, krijg je een overzicht van alle bestanden vanaf het huidige punt te zien. Je bepaalt hoe de opdracht zich precies gedraagt door er opties of parameters bij te gebruiken. Een optie is een tekenreeks die aan een opdracht meegegeven wordt om het gedrag van de opdracht nader te bepalen. Opties zijn in het programma meegeprogrammeerd. Dit betekent dat er een vaststaand aantal opties is waar je zelf niets aan kunt toevoegen. Parameters zijn variabele waarden die aan een bestand meegegeven kunnen worden om het gedrag van een opdracht verder te specificeren. De parameters van een
2 Basisvaardigheden
45
opdracht liggen dus niet vast. Het begrip argument ten slotte wordt gebruikt om alles aan te duiden wat achter een opdracht gezet kan worden. Opties en parameters zijn dus argumenten. Laten we hier eens een voorbeeld van geven. Stel, we gebruiken de opdracht rm –rf * (pas op, niet uitproberen!). In deze opdracht is rm het opdrachtgedeelte. In deze specifieke opdracht is een aantal opties meegeprogrammeerd, waaronder de opties -r en -f. De optie -r (recursive) zorgt ervoor dat de opdracht ook uitgevoerd wordt op subdirectory’s, en de optie -f (force) zorgt ervoor dat niet om een bevestiging gevraagd wordt. Omdat het hier om functionaliteit gaat die is meegeprogrammeerd in de opdracht, spreken we van opties. Daarnaast moet aangegeven worden wat er dan verwijderd moet worden. In dit geval doen we dat door middel van de asterisk die de betekenis ‘alles’ heeft. In plaats daarvan hadden we ook de naam van een of ander bestand kunnen geven. Aangezien hier niet alle mogelijkheden in de opdracht meegeprogrammeerd zijn, hebben we het in dit geval over een parameter. De opties en de parameters samen (ofwel alles wat je achter een opdracht kunt opgeven) benoemen we algemeen met de naam ‘argumenten’. Een andere eigenschap waar je bij gebruik van Linux-opdrachten op moet letten, is dat Linux hoofdlettergevoelig is. Een hoofdletter heeft voor Linux een heel andere betekenis dan een kleine letter. Let er dus op dat je de bedoelde letter typt en dat niet per ongeluk de CapsLock-toets geactiveerd staat.
Linux-opdrachten Hoofdlettergevoelig. Opties bepalen hoe de opdracht zich moet gedragen. Parameters geven aan op welke bestanden, gebruikers, enzovoort. Pas op! De opdracht vraagt niet of je het zeker weet. 2.5
Redirection en piping
Kenmerkend voor Linux-opdrachten is dat je ze als het ware aan elkaar kunt koppelen. Zo kun je de output van de ene opdracht gebruiken als input van een andere opdracht door middel van redirection. Daarnaast is het mogelijk de output van een opdracht te filteren door middel van piping. Door deze twee technieken op de
46
Linux 4
juiste manier te gebruiken kunnen opdrachten en bestanden aan elkaar geknoopt worden en zo kun je complexe taken op één opdrachtregel uitvoeren. 2.5.1 Piping Piping kan handig zijn wanneer de output van een opdracht niet op een scherm past. Wanneer je bijvoorbeeld ls -R /usr typt om de inhoud van de directory /usr op te vragen, zul je zien dat de output over het scherm voorbij schiet. Je kunt hier iets aan doen door de output door te sturen naar de opdracht less. (Je kunt ook gebruikmaken van de opdracht more, maar less doet meer dan more, om het duidelijk te houden.) Deze opdracht zorgt ervoor dat de output van de opdracht scherm voor scherm wordt getoond. Je doet dit door middel van het teken |, de pipe. Voor bovenstaand voorbeeld zou dat dan worden: ls -R /bin | less
Als je dit probeert, zul je de output scherm voor scherm zien. Onder aan elk scherm zie je een aanduiding van de huidige regel staan. Als je nu op de spatiebalk drukt, krijg je het volgende scherm met output te zien. Figuur 2.3 Zonder piping geeft een opdracht al snel te veel resultaat op het scherm
Wanneer piping wordt ingezet, gebeuren er eigenlijk twee dingen. Om te beginnen produceert de eerste opdracht zijn uitvoer. Dan houdt de eerste opdracht op met werken en geeft zijn uitvoer door aan de tweede opdracht. Wanneer je dus de opdracht ls -R /bin
2 Basisvaardigheden
47
typt, werk je in feite in de opdracht less verder met het resultaat van ls -R /bin. Piping is een krachtige feature. Zo is het bijvoorbeeld ook mogelijk om meerdere opdrachten achter elkaar te pipen. Zo had je bijvoorbeeld een alfabetisch gesorteerde lijst met bestanden uit de directory /usr scherm voor scherm op het beeldscherm kunnen krijgen door de opdracht ls –R /usr | sort | less te gebruiken. | less
Figuur 2.4 Door de uitvoer van een opdracht te pipen naar less kun je het resultaat scherm voor scherm zien
2.5.2 Redirection Door middel van piping stuur je de output van een opdracht door naar een andere opdracht. Iets wat hier heel veel op lijkt is redirection. Zoals eerder al is vemeld, stuur je met redirection de output van een opdracht door naar een bestand. Aangezien alle apparaten die voorkomen op een Linux-systeem aangesproken worden door het bijbehorende bestand aan te spreken, kun je heel veel dingen doen met behulp van redirection. Naast het doorsturen van uitvoer naar een bestand, is het ook mogelijk de inhoud van een bestand te gebruiken als input van een opdracht. Hiervoor wordt gebruikgemaakt van de tekens > en <. >
>>
Stuurt het resultaat van een opdracht door naar een bestand. De opdracht ls -l > lstekst maakt een bestand aan met de naam lstekst, waarin zich de output van de opdracht ls -l bevindt. Als er al een bestand bestaat met de naam lstekst, wordt dit bestand overschreven. Stuurt de output van een opdracht door naar een bestand en voegt dat achteraan in het bestand toe. Deze functionaliteit staat bekend als een append van de gegevens.
48
Linux 4
<
Stuurt de inhoud van een bestand door om te gebruiken als input voor een opdracht. Zo kun je bijvoorbeeld met de opdracht mail de inhoud van een tekstbestand naar een collega sturen met een opdracht als mail michelle < bestand.
Zoals gezegd, vrijwel alle randapparaten (devices) op een Linuxsysteem worden aangesproken door gebruik te maken van een bijbehorend bestand en daar kun je bij redirection gebruik van maken. Laten we eerst eens wat voorbeelden geven: /dev/tty1 /dev/pts/0 /dev/had /dev/null /dev/lp0 /dev/hda /dev/sda
Is het beeldscherm waarop je zit te werken als je geen gebruikmaakt van X. Is het eerste shell-venster dat je vanuit een X-sessie opent. Is de vaste schijf. Is het ‘zwarte gat’ op de computer. Is de printer. Is de IDE-vaste schijf. Is de SCSI- of serial ATA-vaste schijf.
Stel bijvoorbeeld dat je het resultaat van het eerder genoemde ls –R /usr niet op het beeldscherm wilt hebben, maar afgedrukt op de printer. In dat geval stuur je het resultaat naar het devicebestand dat bij de printer hoort. De opdracht wordt dan ls –R /usr > /dev/lp0. Redirection in combinatie met devices kan nog veel spectaculairder. Stel je maar eens voor dat je twee identieke vaste schijven in de computer hebt. De primaire schijf op /dev/hda en de secundaire schijf op /dev/hdb. Met behulp van de opdracht cat kun je de inhoud van een bestand uitlezen. Probeer maar eens cat /etc/paswwd: dit zorgt ervoor dat de inhoud van het bestand /etc/passwd getoond wordt. Doe je daarentegen cat /dev/hda, dan wordt de volledige inhoud van de vaste schijf van de computer op het scherm gedumpt. Door deze uitvoer te redirecten naar /dev/hdb kun je heel eenvoudig een kopie maken van de volledige inhoud van de vaste schijf.
2 Basisvaardigheden
49
Figuur 2.5 Met de opdracht cat /dev/hda dump je de totale inhoud van de vaste schijf van de computer op het beeldscherm
Helemaal mooi is dat elke opdracht onderscheid maakt tussen twee soorten resultaat. Er is de normale output en daarnaast zijn er ook de foutmeldingen. Om deze foutmeldingen op een aparte wijze af te kunnen handelen, kun je gebruikmaken van de aanduiding “2”. Laten we eens kijken naar een voorbeeld met de opdracht grep. Deze opdracht kan gebruikt worden om te zoeken naar tekst in bepaalde bestanden. We geven eerst de opdracht grep –l root /etc/*. Deze opdracht toont je de inhoud van alle bestanden in de directory /etc waarin de tekst root voorkomt. Grote kans dat er bij het resultaat van deze opdracht de nodige foutmeldingen getoond worden. Ook andere opdrachten kunnen in hun normale uitvoer foutmeldingen laten zien. Om er nu voor te zorgen dat al deze foutmeldingen niet meer op het scherm getoond worden maar regelrecht worden doorgestuurd naar het ‘zwarte gat’ op de computer, kan in het voorbeeld van grep de opdracht grep –l root /etc/* 2> /dev/null gebruikt worden. In de constructie 2> /dev/null die achter de opdracht geplaatst wordt, verwijst de 2 naar alle fouten die door de opdracht gegenereerd worden. Deze worden met het groterdanteken doorgestuurd naar de nul-device wat als gevolg heeft dat je ze niet op je beeldscherm ziet. Je kunt trouwens ook op een heel andere wijze met deze foutmeldingen omgaan. Geef bijvoorbeeld de opdracht grep –l root /etc/* 2 >> /var/log/messages om alle foutmeldingen weg te schrijven in een of ander logbestand.
50
Linux 4
Het is overigens ook mogelijk in één opdracht de normale uitvoer de ene kant op te sturen en de foutmeldingen de andere kant. Om bij het voorgaande voorbeeld te blijven: je kunt bijvoorbeeld ook de opdracht grep -l root /etc/* 2> /dev/null 1> /dev/tty10 geven. Hierin zorgt 2> ervoor dat foutmeldingen naar /dev/null gestuurd worden en met 1> stuur je daarnaast alle normale uitvoer door naar /dev/tty10. Wil je beide combineren? Ook dat is mogelijk. Gebruik in dat geval 1&2>. 2.6
Help opvragen
Voordat je efficiënt kunt werken met de verschillende opdrachten en programma’s, moet je nog weten hoe je hulp kunt opvragen over het gebruik van opdrachten. Er zijn in Linux verschillende manieren om dit te doen. Ten eerste is er de opdracht man die een vaak zeer volledige beschrijving geeft van het gebruik van een opdracht. Daarnaast kan ook hulp worden opgevraagd met de opdracht info. De hulp die info geeft, is vaak wat uitgebreider dan de beschrijvingen van de opdracht man. De opdracht info kan echter niet voor elke opdracht gebruikt worden en daarnaast is het veel lastiger te gebruiken dan man. Je komt met info namelijk niet in één platte beschrijving van de betreffende opdracht terecht, maar in een hiërarchische beschrijving die opgebouwd is als een webpagina en waarin je regelmatig naar de diverse onderdelen moet manoeuvreren. Het goede nieuws is echter dat de info-hulp steeds meer verdrongen wordt door de hulp die door man geleverd wordt. Tot slot is er op de opdrachtregel de hulp die over interne shellopdrachten opgevraagd kan worden met de opdracht help. Deze hulp is echter beperkt, omdat alleen informatie gegeven wordt over interne shell-opdrachten. Naast deze opdrachten zijn er ook nog documenten waarin vaak uitgebreide hulp geleverd wordt. Je vindt deze documenten bij sommige installaties terug in de directory /usr/doc of /usr/share/ doc. Als dit niet het geval is, kun je ze altijd nog op www.tldp.org terugvinden. Met name de HOWTO’s, zijn de moeite waard. Dit zijn vaak behoorlijk uitgebreide documenten die beschrijven hoe een complexe taak moet worden uitgevoerd. Een voorbeeld is de 4MB-Laptops-HOWTO, die exact beschrijft wat je moet doen om Linux op een laptop met 4MB werkgeheugen te installeren. Ook
2 Basisvaardigheden
51
zijn er HOWTO’s die beschrijven hoe je een ADSL-verbinding moet configureren, of HOWTO’s die beschrijven wat je moet doen als je Belg bent en met Linux wilt werken. Tot slot zijn er op de computer vaak directory’s waarin beschrijvingen worden gegeven van softwarepackages die op het systeem geïnstalleerd zijn. Als ze voorkomen, worden ze doorgaans in de directory /usr/share/ doc/packages geïnstalleerd. De meest recente vorm van al deze documenten kun je trouwens terugvinden op internet. Alle relevante Linux-documentatie wordt daar bijgehouden op www.tldp. org. Misschien is het wat eenvoudiger te onthouden als je weet waar de afkorting voor staat: TLDP is de thuisbasis van The Linux Documentation Project. Figuur 2.6 Op www.tldp.org vind je een schat aan vrij beschikbare Linuxdocumentatie
2.6.1 Man Vroeger werd een UNIX-systeem uitgeleverd met een aantal boeken waarin het systeem gedocumenteerd was. Zo was er onder andere een boek waarin de werking van alle opdrachten beschreven was, de zogenoemde System Programmers Manual. Tegenwoordig wordt deze veelomvattende documentatie niet langer meegeleverd in boekvorm, maar in elektronische vorm. Om deze informatie te kunnen benaderen moet gebruikgemaakt worden van de opdracht man, gevolgd door de naam van de opdracht waarover je meer informatie wilt hebben. Geef bijvoorbeeld de opdracht man man om de man-pagina van de opdracht man op te vragen.
52
Linux 4
In Linux kun je over vrijwel elke opdracht hulp opvragen door gebruik te maken van de opdracht man. Dit werkt vrij simpel: man geeft informatie over gebruik van de gespecificeerde opdracht. Je krijgt deze informatie in een apart scherm te zien. In dit scherm zie je eerst een korte beschrijving van de opdracht. Vervolgens staat in de ‘Synopsis’ aangegeven welke opties er zijn en hoe de parameters gebruikt moeten worden. Dan volgt een iets uitgebreidere beschrijving van de opdracht en daarna een soms zeer uitgebreide beschrijving van hoe alle opties gebruikt moeten worden. Aan het eind van de man-tekst vind je dan vaak nog wat verwijzingen naar andere gerelateerde opdrachten. Als je deze algemene structuur enigszins kunt doorgronden, zul je merken dat je met gemak hulp kunt opvragen over alle denkbare Linux-opdrachten. Figuur 2.7 Vrijwel elke opdracht heeft een man-pagina, onder andere ook de opdracht man zelf
Om te kunnen werken met man is het handig als je op de hoogte bent van enkele toetsen die binnen een man-scherm een speciale functie hebben. Onthoud de betekenis van deze toetsen: ze zijn ontleend aan de opdracht vi en werken dus ook als je met deze opdracht aan het werk bent: Spatiebalk Enter PageUp /tekst ?tekst n N q
Toon het volgende scherm. Toon de volgende regel. Laat het vorige scherm zien. Zoek vooruit naar het voorkomen van tekst. Zoek achteruit naar het voorkomen van tekst. Herhaal de laatste zoekactie. Herhaal de laatste zoekactie in omgekeerde volgorde. Sluit man af.
2 Basisvaardigheden
53
Er zijn vijf conventies betreffende de weergave van de hulp door man: 1. Alle tekst die niet tussen de tekens < > [ ] { } staat, moet letterlijk getypt worden. 2. Alle tekst tussen blokhaken, dit zijn de tekens [ en ], is optioneel. Wanneer je bijvoorbeeld ziet staan who [-imq], betekent dit dat je de tekens tussen blokhaken kunt gebruiken. Wanneer je ze gebruikt, voegt dit een extra optie toe aan de opdracht, maar je hoeft ze niet te gebruiken. Je typt bij gebruik van de opdracht de blokhaken zelf nooit mee. 3. De tekens < en > (punthaken) hebben als betekenis dat de tekst tussen de punthaken moet worden weergegeven door de gespecificeerde tekstsoort. Wanneer je ergens ziet staan more , betekent dit dat je hier de naam van een of ander bestand moet invoeren. Je zult echter merken dat tegenwoordig steeds minder gebruikgemaakt wordt van deze punthaken om te verwijzen naar een bepaalde bestandssoort. 4. Wanneer je tekens tussen { en } (accolades) ziet staan, moet je een van de gespecificeerde tekens gebruiken. De gespecificeerde tekens worden voor de leesbaarheid gescheiden door een |-teken. Dit teken heeft hier niet de functie van een pipe. Wanneer je dus ziet staan opdracht {a|b}, betekent dit dat de betreffende opdracht of een a of een b als argument moet hebben. 5. Een aantal punten staat voor enzovoort. Dit wordt vaak gebruikt om aan te geven dat meerdere bestandsnamen als argument gegeven kunnen worden. Deze conventies kunnen ook in combinaties voorkomen. Zo betekent opdracht [] dat je bij opdracht een bestandsnaam als parameter mee kunt geven, maar het is niet noodzakelijk dat dit gebeurt. Wanneer je de opdracht man gebruikt, krijg je soms niet direct de informatie te zien die je had verwacht. Dit komt omdat de opdrachten waarover man informatie geeft, zijn onderverdeeld in negen secties, de System Programmers Manual is dus eigenlijk onderverdeeld in negen hoofdstukken. Man doorzoekt de secties van sectie 1 tot en met sectie 9 en wanneer het in een bepaalde sectie de opdracht aantreft, houdt het op met zoeken. Dit is een eigenschap waar je rekening mee moet houden, want soms worden opdrach-
54
Linux 4
ten in meerdere secties beschreven. Zo is er bijvoorbeeld zowel in sectie 1 als in sectie 5 een beschrijving voor het item passwd. Aangezien het systeem altijd eerst de passwd in sectie 1 tegenkomt, zal de passwd in sectie 5 nooit getoond worden als je daar niet iets speciaals voor doet. De secties waaruit de man-pagina’s zijn opgebouwd zijn: 1. Uitvoerbare programma’s en shell-opdrachten. 2. System calls: dit zijn functies die gegeven worden door de kernel. 3. Library calls: dit zijn functies die gegeven worden door system libraries. 4. Speciale bestanden, met name bestanden die voorkomen in de directory /dev. 5. Bestandsformaten en conventies; bijvoorbeeld /etc/passwd. 6. Spelletjes. 7. Macropakketten en conventies, zoals man(7) en groff(7). 8. Opdrachten die nodig zijn voor systeembeheer. 9. Kernel-routines. Als je informatie over een bepaalde opdracht uit alle secties wilt hebben, kun je dat opvragen met de opdracht man -a. De opdracht man zal dan niet stoppen met zoeken na de eerste treffer, maar gaat door totdat alle secties zijn doorlopen. Vaak zie je achter een opdracht ook tussen haakjes een getal staan, zoals man(7). Dit getal is een expliciete verwijzing naar de sectie in de man-pagina’s waarin de opdracht beschreven wordt. Als je zeker wilt zijn dat je gebruikmaakt van de informatie over de opdracht zoals beschreven in de gespecificeerde sectie, kun je bij de opdracht man verwijzen naar de sectie waaruit je informatie wilt hebben. Zo vraag je met de opdracht man 7 man informatie op over de macro man en niet over de opdracht man. Als je wilt weten in welke secties een bepaalde opdracht staat beschreven, typ je man –f opdracht. De optie –f zorgt ervoor dat alleen een lijst getoond wordt van alle secties waarin de opdracht voorkomt. Hetzelfde resultaat kan ook bereikt worden met de opdracht whatis. In feite is deze opdracht gewoon een snelkoppeling naar man -f.
2 Basisvaardigheden
55
Een andere handige optie is de optie –k. Deze optie gebruik je wanneer je niet precies weet waarnaar je zoekt. Deze optie zorgt er namelijk voor dat man gaat zoeken op basis van een trefwoord (keyword) dat de gebruiker ingevoerd heeft. Typ bijvoorbeeld man –k password om een lijst te krijgen waarin alle opdrachten staan die iets met een wachtwoord doen. Als alternatief kun je gebruikmaken van de opdracht apropos. Deze opdracht doet exact hetzelfde. De opdrachten man -k en man -f werken op basis van een database waarin korte beschrijvingen staan van systeemopdrachten. Op sommige systemen wordt deze database niet automatisch gemaakt. Je kunt hem dan zelf maken met de opdracht makewhatis. Als het resultaat van een zoekactie op trefwoord vaak geen resultaat geeft, is het de moeite waard om deze opdracht eens uit te proberen om ervoor te zorgen dat de whatis-database helemaal is bijgewerkt. Onthouden over man: De informatie is onderverdeeld in secties. De opdracht stopt na de eerste treffer. Met man –k kun je zoeken op trefwoord. Geef voordat je man –k gebruikt eerst de opdracht makewhatis. Figuur 2.8 Gebruik man -k als je niet precies weet waarnaar je zoekt
56
Linux 4
Tip! De opdracht man kijkt standaard alleen in een bepaald aantal directory’s of daarin man-pagina’s geïnstalleerd zijn. Welke directory’s dat zijn, wordt bijgehouden in de variabele MANPATH. Komt het ooit voor dat je de man-pagina’s van een opdracht maar niet kunt openen? Dan ligt het er waarschijnlijk aan dat dit MANPATH niet goed gedefinieerd is. Om te achterhalen waar de man-pagina van een bepaalde opdracht staat, gebruik je whereis opdracht. Uiteraard moet je opdracht vervangen door de opdracht waarvan je wilt weten waar de man-pagina’s zich bevinden. whereis laat dit vervolgens zien. Je kunt het MANPATH instellen door de directory’s waarin gezocht moet worden op te nemen in het configuratiebestand /etc/man.con fig. 2.6.2 Info Het kan gebeuren dat wanneer je de opdracht man gebruikt, je onder de beschrijving van de opdracht de volgende tekst ziet staan: This documentation is no longer maintained and may be inaccurate or incomplete. The Texinfo documentation is now the authorative source. Als je deze melding ziet – hetgeen overigens steeds minder vaak het geval zal zijn – loop je dus het risico dat je met de opdracht man niet alle beschikbare informatie boven water krijgt. Je kunt dan in plaats van man gebruikmaken van info, wat in feite een andere manier is om hulp te vragen over opdrachten. Voor sommige opdrachten gebruik je man, voor andere info. Er bestaat geen algemene richtlijn wanneer welke opdracht gebruikt moet worden, maar omdat info steeds minder vaak voorkomt, is het de moeite waard altijd eerst de opdracht man te proberen. Als je voor het eerst info gebruikt, is het handig op de hoogte te zijn van een aantal zaken die het gebruik ervan aanzienlijk vereenvoudigen. De informatie die je met info opvraagt, is hiërarchisch geordend in een informatieboom. Als je info zonder argument invoert, kom je bovenaan in de infoboom terecht. Het enige wat je hier ziet, zijn items waarover informatie beschikbaar is. Deze items worden voorafgegaan door een asterisk; dit zijn de infome-
2 Basisvaardigheden
57
nu’s. Meestal past niet alles op het beeldscherm. Je kunt binnen de tekst die door info wordt weergegeven heen en weer bewegen door gebruik te maken van de spatiebalk en de Backspace-toets. De spatiebalk laat je het volgende scherm zien, de Backspace brengt je terug in het vorige scherm. Figuur 2.9 Informatie die wordt weergegeven met info, wordt op een hiërarchische wijze getoond
Boven in het eerste venster dat je ziet als je info activeert, zie je een regel die er als volgt uitziet: File: info, Node: Top, Next: Getting Started, Prev: (dir)... Deze regel geeft aan wat de mogelijkheden zijn. Het item Node toont in welk stuk informatie je je nu bevindt, Next laat zien wat het volgende stuk informatie is en Prev laat je zien wat de vorige informatie was. Het volgende info-onderwerp kun je activeren door op de toets n (Next) te drukken, het vorige onderwerp activeer je door op de toets p (Prev) te drukken. Next en Prev geven je als het ware de gelegenheid om naar het volgende hoofdstuk op hetzelfde niveau in de informatieboom te bladeren. Je kunt info afsluiten met de toets q. Wil je hulp over hoe je info moet gebruiken, dan druk je op de toets h. In info kom je regelmatig menu’s tegen. Je herkent ze aan de asterisk waardoor ze voorafgegaan worden. Als je een menu-item wilt activeren, doe je dat met de toets m. Vervolgens zie je onder in het venster een prompt Menu item: verschijnen. Hier moet je de naam
58
Linux 4
van het menu typen. Je herkent de naam die je kunt invoeren aan het feit dat deze wordt afgesloten met een dubbelepunt. Wanneer je een menu activeert, begeef je je dieper in de info-tree. Met de toets u kun je weer terug naar het punt waar je stond voordat het menuitem geactiveerd werd. Hier volgt een samenvatting van de belangrijkste toetsen die binnen info gebruikt kunnen worden: n Ga naar de volgende node. p Ga terug naar de vorige node. q Sluit info af. h Roep de helpfunctie van info aan. m menunaam Start menu menunaam op. u Ga na het activeren van een menu één niveau omhoog in de hiërarchie. 2.6.3 Help Een derde manier om hulp op te vragen werkt alleen voor een beperkt aantal opdrachten, namelijk de interne opdrachten van de shell. Dit zijn de opdrachten die niet als apart bestand op de vaste schijf van de computer voorkomen, maar die in het geheugen geladen worden op het moment dat je de bash-shell laadt. Als je bash gebruikt, kun je de opdracht help gebruiken om hulp op te vragen over alle interne opdrachten. Als je wilt weten welke opdrachten dit allemaal betreft, typ je gewoon help op de prompt. Je krijgt dan een overzicht van alle opdrachten waarover hulp opgevraagd kan worden met de opdracht help. Je zult echter begrijpen dat met help in vergelijking met de opdracht man niet zo heel erg veel hulp boven water gekregen kan worden. Alle hulp die je met de opdracht help boven water kunt krijgen, kun je overigens ook uit de man-pagina van de bash-shell halen. 2.6.4 Informatie uit documenten Naast de documentatie die je kunt opvragen met man, help en info, wordt er ook nog afzonderlijke documentatie meegeleverd voor de diverse programma’s die op je pc staan geïnstalleerd. Veel standaardinstallaties installeren niet alles van deze informatie. Als het geïnstalleerd is, vind je het terug in de directory /usr/share/doc, als het niet geïnstalleerd is zou je eens een kijkje moeten nemen op www.tldp.org. In deze directory staan enkele subdirectory’s die
2 Basisvaardigheden
59
de naam kunnen hebben van het betreffende programma. Hierin komen verschillende formaten helpbestanden over het programma voor. Dit zijn veel uitgebreidere beschrijvingen dan de beschrijvingen die je met man of info krijgt. Figuur 2.10 In de directory /usr/ share/doc vind je alle Linux-documentatie die op de computer geïnstalleerd is
Naast de specifieke hulp voor opdrachten, zijn er de FAQ’s en de HOWTO’s. Dit zijn documenten waar niet op een beschrijvende, maar op een probleemoplossende manier naar opdrachten gekeken wordt. Deze documenten zijn meestal niet standaard geïnstalleerd, maar bevinden zich vaak op de installatie-cd van de distributie. Voor een bijgewerkt en volledig overzicht van de meest recente HOWTO’s en FAQ’s ga je naar www.sandervanvugt.nl. In de FAQ-documenten worden veelgestelde vragen beantwoord. Het idee van een FAQ is dat een ander waarschijnlijk ook al eens hetzelfde probleem heeft gehad als wat jij nu hebt. Met een beetje geluk wordt het probleem met de bijbehorende oplossing beschreven in de FAQ over je onderwerp. Houd er echter rekening mee dat op Linux niet heel erg veel FAQ’s worden bijgehouden, de HOWTO-documenten zijn dus veel informatiever. Van werkelijk grote waarde zijn de HOWTO-documenten. Dit zijn vaak behoorlijk uitgebreide documenten over hoe een bepaalde complexe taak moet worden uitgevoerd. Zo is er bijvoorbeeld een PPP-HOWTO die exact beschrijft wat je allemaal moet doen om met succes een PPP-connectie met een andere computer tot stand te brengen, een ware aanrader als je ooit onder Linux een modem wilt configureren.
Linux 4
60
Hulp over een opdracht kun je opvragen met man. Als het echt niet anders kan, gebruik je info in plaats van man. De opdracht help werkt alleen op een beperkt aantal opdrachten. In de HOWTO’s vind je beschrijvingen van hoe bepaalde taken uitgevoerd moeten worden. 2.7
Basistaken uitvoeren
Nu je iets meer weet over de algemene eigenschappen van Linuxopdrachten en hoe je daarover hulp kunt opvragen, volgt hier een korte uitleg van een aantal elementaire opdrachten waarmee je basistaken op je Linux-computer kunt uitvoeren. Het doel van deze uitleg is dat je zo snel mogelijk aan het werk kunt met Linux. 2.7.1 Instellen van het wachtwoord Wanneer je voor de eerste keer inlogt op het Linux-systeem, zul je dit doen als een gewone gebruiker met het wachtwoord dat je van de systeembeheerder hebt gekregen. Het kan ook zijn dat je helemaal geen wachtwoord hoeft in te voeren. Voor een goede beveiliging van je bestanden is het verstandig zo snel mogelijk een wachtwoord in te stellen dat jij alleen kent. Je doet dit door de opdracht passwd te gebruiken. Als je de opdracht als een andere gebruiker dan root geeft, zal nu eerst gevraagd worden het oude wachtwoord in te voeren. Vervolgens wordt gevraagd het nieuwe wachtwoord in te voeren. Je voert een nieuw wachtwoord altijd twee keer achter elkaar in, om te voorkomen dat je door een typefout het systeem niet meer inkomt. Voor de veiligheid verschijnt het wachtwoord niet op het beeldscherm wanneer het wordt ingetypt. Als je bent aangemeld als root, kun je ook wachtwoorden van gebruikers wijzigen. Je doet dit door de opdracht passwd te gebruiken met als argument de naam van een gebruiker. Ook biedt deze opdracht de systeembeheerder mogelijkheden om een account onbruikbaar te maken of juist het tegenovergestelde te doen.
2 Basisvaardigheden
61
Tip! Vooral wanneer je een computer moet beheren, is de verleiding heel groot om dat als gebruiker root te doen. Deze gebruiker heeft immers alle rechten op een systeem: root is letterlijk almachtig. Dit is niet verstandig: wanneer je als root onverhoopt een virus activeert, kan dat virus dankzij de onbeperkte rechten het totale systeem slopen. Om die reden moet je altijd inloggen als een gewone gebruiker en alleen wanneer dat nodig is tijdelijk even root worden. 2.7.2 Inloggen onder een andere naam Wanneer je als beheerder met je normale gebruikersaccount bent ingelogd, zul je soms de behoefte hebben om even snel in te loggen onder een andere gebruikersnaam: bijvoorbeeld als root om een aantal beheerstaken uit te voeren. Je kunt hiervoor een nieuwe virtuele console opstarten, maar die is niet altijd beschikbaar. Als alternatief kun je de opdracht su gebruiken; dit staat voor superuser. Als de opdracht zonder argumenten wordt gebruikt, gaat het systeem ervan uit dat je wilt inloggen als gebruiker root. Daarnaast kan aan de opdracht su een gebruikersnaam als argument meegegeven worden. Je meldt je dan aan als die gebruiker. Als je su gebruikt om in te loggen als een andere gebruiker wanneer je bent ingelogd als root, vraagt het systeem niet om een wachtwoord: je bent immers root en dus almachtig. Je moet als root namelijk in staat zijn in te loggen onder een andere gebruikersnaam om de bestanden van die gebruiker te bekijken, of configuratiebestanden van de gebruiker aan te passen en te testen. Als je su gebruikt wanneer je niet bent ingelogd als root, maar onder een andere gebruikersnaam, vraagt het systeem wel om een wachtwoord. Het is immers niet wenselijk dat iedere gebruiker door su te gebruiken zomaar onder een andere naam kan inloggen. Ook met de opdracht login kun je je aanmelden als een andere gebruiker. Het is echter onder Linux niet gebruikelijk deze opdracht handmatig in te voeren: er wordt immers automatisch een nieuwe loginprompt gegenereerd wanneer een gebruiker uitlogt. Er zijn een paar verschillen tussen de opdrachten login en su. Een belangrijk verschil is dat bij gebruik van de opdracht su geen nieuwe login-shell wordt gestart. Dit betekent dat bij gebruik van login
62
Linux 4
alle ingestelde omgevingsvariabelen (tijdelijk) verloren gaan, terwijl ze bij gebruik van su gewoon bewaard blijven. Als je dus aan het werk bent als gebruiker root en tijdens dat werken een aantal omgevingsvariabelen hebt veranderd, ben je deze instellingen kwijt als je inlogt als een andere gebruiker door gebruik te maken van de opdracht login. Als je inlogt als een andere gebruiker door gebruik te maken van de opdracht su, krijg je echter alle omgevingsvariabelen weer terug nadat de su-sessie is afgesloten met de opdracht exit. Ook als je gebruikmaakt van X-windows en je wilt iets doen onder een andere gebruikersnaam, heeft het de voorkeur om su te gebruiken. Je kunt dan namelijk vanuit een terminalvenster aangemeld zijn als de ene gebruiker, terwijl je in een ander terminalvenster met su bent aangemeld als een andere gebruiker. Dit is niet mogelijk als je de opdracht login gebruikt. Tip! Als je vanuit een terminalsessie in X-windows in SUSE su gebruikt en tijdelijk de identiteit van een andere gebruiker wilt aannemen, kun je sux gebruiken. Deze speciale SUSEopdracht zorgt ervoor dat de X-omgeving tijdelijk aangepast wordt aan je nieuwe identiteit. Als je als argument ook nog eens een – meegeeft, zorgt dit er ook voor dat alle gebruikersinstellingen van de nieuwe gebruiker tijdelijk worden meegenomen. 2.7.3 Bekijken van en manoeuvreren in de directorystructuur De opdracht ls wordt gebruikt om informatie op te vragen over het bestandssysteem. Het kan qua werking enigszins vergeleken worden met de DOS-opdracht dir. Beide opdrachten geven de inhoud van een directory weer. Voordat je de opdracht effectief kunt hanteren, moet je natuurlijk eerst iets weten over de structuur van het Linux-bestandssysteem. Het hoogste punt in het Linux-bestandssysteem is de root (er is dus een gebruiker root én er is een root in het bestandssysteem). Daarnaast – voor alle duidelijkheid – heeft de gebruiker root een homedirectory, die natuurlijk ‘root’ heet en voorkomt onder de rootdirectory. Deze rootdirectory wordt weergegeven door een slash (/) en de homedirectory van de gebruiker root is natuurlijk /root. Direct onder deze root (/) komen de diverse directory’s voor. Standaarddirectory’s zijn onder andere usr, bin en etc.
2 Basisvaardigheden
63
Figuur 2.11 Het Linuxbestandssysteem gezien vanuit een grafische omgeving
Een volledige weergave van een directorynaam zal altijd beginnen met het rootteken. Zo spreken we bijvoorbeeld over de directory /usr/bin. Indien een directorynaam niet begint met een slash, zal deze naam door de betreffende opdracht gerelateerd worden aan de huidige directory. Wat de huidige directory is, kun je laten weergeven met de opdracht pwd, dat staat voor print working directory. Wanneer je de huidige directory wilt veranderen, gebruik je daarvoor de opdracht cd. Figuur 2.12 De opdracht pwd laat zien in welke directory je op dat moment bent – als dat nog niet uit de prompt blijkt
64
Linux 4
Als je de opdracht ls gebruikt, is het, zoals bij elke Linux-opdracht, zaak dat je goed let op het gebruik van spaties. Tussen de opdracht en de eventuele opties moet altijd een spatie staan. Hieronder zie je enkele voorbeelden van de mogelijkheden van de opdracht ls. ls Toont de inhoud van de huidige directory. ls -l Geeft een lijst met uitgebreide informatie over ls ls ls ls
ls
de bestanden in de huidige directory. -a Laat alle bestanden in de huidige directory, inclusief verborgen bestanden, zien. -t Laat alle bestanden in de huidige directory zien en sorteert deze op tijd. | less Toont alle bestanden in de huidige directory en stopt na elk scherm met output. -R Laat alle bestanden in de huidige directory zien en toont ook alle bestanden die voorkomen in subdirectory’s van de huidige directory. /etc/a* Geeft een lijst van alle bestanden die beginnen met de letter a in de directory etc.
Tekens met een speciale betekenis In voorgaand overzicht wordt de asterisk (*) gebruikt. De shell interpreteert dit teken als jokerteken. De shell hanteert nog enkele andere tekens met een speciale betekenis: *
? []
De asterisk wordt gebruikt voor een willekeurig aantal tekens. Het is echter niet zo dat wanneer een systeem een * tegenkomt, het systeem dan niet meer verder kijkt. Zo is er een verschil tussen *, *.* en *a.*. Indien toegepast als argument van de opdracht ls, zal ls * alle bestanden tonen, ls *.* alleen die bestanden waar een punt in de naam voorkomt, en ls *a.* Alle bestanden waar een punt in de naam voorkomt en voorafgaand aan een punt een letter a. Het vraagteken wordt gebruikt als jokerteken voor één specifiek teken. Tussen blokhaken kun je alternatieve tekens opgeven; ls wor[dt] laat dus zowel word als wort zien.
2 Basisvaardigheden
~ -
2.8
65
Wanneer je de tilde gebruikt voor de naam van een directory, gaat het systeem op zoek naar de homedirectory van een gebruiker. Een liggend streepje staat voor de vorige directory. Dit teken is met name handig in combinatie met de opdracht cd om snel heen en weer te springen tussen twee directory’s. De inrichting van een Linux-bestandssysteem
Om de opdrachten ls, om de inhoud van directory’s te bekijken, en cd, om van de ene naar de andere directory te manoeuvreren, efficiënt te kunnen gebruiken, is het handig enige kennis te hebben van de wijze waarop een Linux-bestandssysteem is ingericht. Om die reden besteden we daar op dit punt aandacht aan. Net als bij elk ander computersysteem is het Linux-bestandssysteem opgebouwd als een hiërarchische boomstructuur. De volledige directorytree kan uit meerdere delen bestaan, waarbij elk deel voorkomt op een eigen schijf of partitie. Bovenaan in de hiërarchie staat de rootdirectory. Deze wordt weergegeven door een slash (/). Alle bestanden en directory’s op een Linux-systeem komen voor onder deze rootdirectory. Deze gehele bestandsstructuur kan voorkomen op één partitie, maar vaak zal het om meerdere partities en schijven gaan. Elk van deze partities en schijven wordt via de opdracht mount in het bestandssysteem geïmporteerd. Deze opdracht wordt gebruikt om bestanden die voorkomen op andere media beschikbaar te stellen in het rootbestandssysteem. We spreken hierbij over het mounten van een bestandssysteem. Een diskette of cd-rom wordt onder Linux dus niet door middel van een schijfletter benaderd, maar door het apparaat (device) te koppelen aan een directory die ergens onder de rootdirectory voorkomt. 2.8.1 Standaarddirectory’s Net zoals op een Windows-computer een aantal standaarddirectory’s voorkomt (zoals Windows, Mijn Documenten en Programmabestanden), zo kent ook een Linux-systeem een indeling in standaarddirectory’s. We zullen hier een overzicht geven van wat je op de meeste systemen tegenkomt. Aangezien de meeste distributies voor de indeling in directory’s de Linux Standards
66
Linux 4
Base (LSB) volgen waarin beschreven wordt waar welke bestanden zouden moeten staan, geldt de indeling die hier beschreven wordt voor de meeste distributies. /bin In de directory /bin komen opdrachten voor die nodig zijn bij het opstarten van de computer. Gebruikers mogen doorgaans gewoon gebruikmaken van de bestanden in deze directory. De directory /bin komt direct onder de root van het systeem voor, omdat de bestanden die erin staan essentieel zijn en daarom direct na het opstarten beschikbaar moeten zijn. /sbin In de directory /sbin staan systeembestanden die (voornamelijk) voor het beheer van het systeem gebruikt worden. Je moet hier denken aan opdrachten als fdisk, shutdown en de bootloader LILO. Gebruikers zonder beheerrechten mogen alleen gebruikmaken van de bestanden in deze directory als ze daar toestemming voor hebben gekregen van de systeembeheerder. Het gaat hier namelijk meestal om bestanden die bij verkeerd gebruik behoorlijk destructief kunnen zijn voor het systeem. /etc In deze directory staan de configuratiebestanden van het systeem. In feite zijn dit de cruciale bestanden waardoor Linux weet hoe het met het systeem moet omgaan. In deze directory komen bijvoorbeeld de configuratiebestanden passwd en shadow voor, waarin gegevens over gebruikers worden bijgehouden. Ook veel bestanden waarmee de beveiliging van de computer wordt geregeld, staan in deze directory. Daarnaast bevinden zich in de subdirectory rc.d de startupscripts voor Linux. Wanneer je deze directory verwijdert, wordt normaal opstarten van de computer onmogelijk. /lib In de directory /lib staan de belangrijkste gedeelde librarybestanden. Deze bevatten programmacode die door meerdere programma’s gebruikt kunnen worden; vergelijk het maar met DLL-bestanden op een Windows-computer. Dankzij deze gedeelde librarybestanden kunnen de programmabestanden zelf zo klein mogelijk gehouden worden.
2 Basisvaardigheden
67
/dev In de directory /dev staan de devicebestanden. Deze worden gebruikt om contact te maken met de apparaten (devices) die voorkomen in een computer. Elk apparaat in de computer heeft een bestand in de directory /dev waardoor het besturingssysteem dit apparaat kan benaderen. Dit komt omdat elk devicebestand een unieke identificatie bij de kernel heeft in de vorm van een majoren een minornummer. Dankzij deze devicebestanden heeft de kernel een unieke methode om met de verschillende randapparaten te communiceren. Het leuke zit er daarbij in dat de Linux-kernel niet beslist op de hoogte hoeft te zijn van het specifieke apparaat waarmee gecommuniceerd moet worden, maar alleen maar hoeft te weten wat voor soort apparaat het is. Zo is er het bestand /dev/fd0, dat gewoonlijk gebruikt wordt om het eerste diskettestation in het systeem te benaderen. Voor het beheer van het systeem is het zeer belangrijk dat je de devices in deze directory weet terug te vinden. Het is bijvoorbeeld in een pure console-omgeving niet mogelijk een device te benaderen als je niet weet onder welke devicenaam deze bekend is bij het systeem. Vanuit de grafische gebruikersomgeving is dit vaak wat eenvoudiger omdat er grafische koppelingen naar de apparaten bestaan. Naast de apparaten die standaard beschikbaar zijn, is het ook mogelijk met de geavanceerde opdracht mknod zelf devicebestanden toe te voegen; hiervoor is echter wel gespecialiseerde kennis noodzakelijk. De devices die voorkomen in de directory /dev zijn vaak herkenbaar aan hun naam. In het volgende overzicht vind je de devicebestanden waarmee je het meest zult werken. /dev/console /dev/hd
/dev/sd
De system console, oftewel het beeldscherm dat rechtstreeks aan de computer is gekoppeld. De device-interface naar IDE-harddisks. De namen van devices zien eruit als bijvoorbeeld /dev/ hda1; dit staat voor de eerste partitie die is gedefinieerd op de master harddisk die verbonden is aan de primaire IDE-interface. De device-interface naar SCSI-disks. Hier gelden qua naamgeving dezelfde conventies als voor /dev/ hd.
68
Linux 4
/dev/fd /dev/st /dev/scd /dev/tty /dev/pty
De diskettestations; /dev/fd0 is het eerste diskette station, enzovoort. SCSI-tapedevices. SCSI-cd-romdevices. De virtuele consoles die voorkomen op de Linuxcomputer. Dit zijn de consoles die je opstart met de toetsencombinaties Alt-F1 tot en met Alt-F6. Pseudoterminals worden gebruikt om in te loggen op het netwerk, zoals met telnet gebeurt. Naast telnet wordt ook voor elke consolesessie die vanuit het X-windows-system gestart wordt een apart pts-device gebruikt. De ttyp-devices komen ook wel voor onder de naam /dev/pts. Dit is dan een subdirectory waaronder voor elke pseudoterminal weer een afzonderlijke device voorkomt. Zo is bijvoorbeeld /dev/pts/0 een verwijzing naar de eerste pseudoterminal.
Figuur 2.13 Je komt devices overal tegen: zo laat de opdracht who bijvoorbeeld zien op welke terminals gebruikers zijn ingelogd
/dev/ttyS /dev/lp
De seriële interfaces op de computer; ttyS0 komt overeen met com1 onder DOS. De printerdevices. De eerste parallelle printerpoort op een computer wordt aangestuurd door middel van de device /dev/lp0. Tegenwoordig wordt voor de aansturing van printers meestal gebruikgemaakt van USB-devices. De namen van deze devices beginnen met /dev/usb en worden automatisch gemaakt op het moment dat ze nodig zijn.
2 Basisvaardigheden
/dev/nul
/dev/usb
69
Het zwarte gat: alles wat je hiernaartoe stuurt verdwijnt. Je kunt deze device bijvoorbeeld gebruiken om ervoor te zorgen dat de output van een opdracht niet op het beeldscherm verschijnt. Dit is een aparte directory waaronder devicebestanden gemaakt worden voor alle USB-devices die op het systeem kunnen voorkomen. Elke USBdevice heeft hieronder een eigen devicebestand. Zo wordt bijvoorbeeld een USB-printer aangestuurd door middel van /dev/usb/lp0.
Naast de hiervoor genoemde devices kom je meer soorten namen tegen in de directory /dev. Deze zijn vaak te herleiden tot de hiervoor genoemde devices. Zo is er het standaarddevicebestand /dev/ fd0. Nadeel van dit standaardbestand is dat het niets zegt over het formaat van de diskette die gebruikt wordt. Daarom bestaan er bestanden met de naam /dev/fd0H1140, /dev/fd0H360, /dev/fd0D720, enzovoort waardoor op een meer specifieke manier aangegeven kan worden wat de eigenschappen zijn van de device. Zoals gezegd, maakt het de kernel zelf niet zo heel veel uit met wat voor specifieke device gecommuniceerd wordt. Het enige wat voor de kernel echt interessant is om te weten, is op welke manier gegevens naar de device gestuurd moeten worden. Naast het major- en minornummer waarmee devices in categorieën worden onderverdeeld, maakt de kernel dan ook alleen maar onderscheid tussen block- en characterdevices. Op een blockdevice moeten gegevens in de vorm van blokken benaderd worden, zoals dat het geval is op een vaste schijf. Op een characterdevice wordt gewerkt door er een stroom gegevens naartoe te sturen of van binnen te halen. /usr De standaarddirectory’s die tot nu toe genoemd zijn, zijn essentieel om een computer met succes op te kunnen starten. Ze komen daarom doorgaans allemaal voor in dezelfde rootpartitie. Om ervoor te zorgen dat de verschillende soorten bestanden op een systeem elkaar niet in de weg zitten, wordt een aantal wat grotere directory’s vaak op een geheel aparte partitie geplaatst. De eerste van deze directory’s is /usr.
70
Linux 4
De directory /usr bevat alle zaken die gerelateerd zijn aan de gebruiker. Sommige distributies installeren de hele directory /usr op een apart medium, zodat de directory apart gemount kan worden in het bestandssysteem. Het voordeel van deze werkwijze is dat de directory /usr niet het medium waarop het rootbestandssysteem staat vol kan schrijven. De directory /usr bevat een aantal belangrijke subdirectory’s. De exacte indeling in subdirectory’s kan echter ook weer per distributie behoorlijk verschillend zijn. Ten eerste is er /usr/bin. In deze directory komen de meeste opdrachten en programma’s voor die door gebruikers gebruikt mogen worden. Hierbij hoort de directory /usr/lib, waarin de gedeelde librarybestanden staan voor de programmabestanden in /usr/bin. De directory /usr/etc bevat configuratiebestanden die horen bij de bestanden uit /usr/bin. Een derde subdirectory is /usr/man. Hierin bevindt zich de tekst van de help-pagina’s die je met de opdracht man kunt oproepen. Meer documentatie vind je in /usr/info en /usr/ doc. In deze directory’s komt nog meer informatie over het gebruik van het systeem voor. De inhoud van de directory /usr/info wordt gebruikt door de opdracht info. De inhoud van de directory /usr/ doc bevat vaak aanvullende informatie die met de opdracht less gelezen kan worden. Een volgende directory is /usr/sbin. Hierin staan de programma’s die de computer gebruikt om services te verlenen op een netwerk, zoals het bestand lpd waardoor de computer printservices kan verlenen. Een laatste belangrijke directory die voorkomt onder de directory /usr, is X11R6. Alles wat onder deze directory voorkomt, heeft te maken met het grafische X-windowing system. Soms komen er naast X11R6 ook directory’s voor als X11 of X386. Dit zijn dan echter niet meer dan snelkoppelingen naar X11R6. In deze directory vind je alle drivers die nodig zijn voor de grafische hardware in het systeem, daarnaast komt er ook een behoorlijk aantal programmabestanden voor dat onder X gebruikt kan worden. /var De directory /var bevat voornamelijk bestanden van een variabele grootte die meestal door het systeem gebruikt worden en die door de tijd nogal eens willen groeien. Je moet hierbij denken aan bestanden waarin printopdrachten geparkeerd worden voordat ze doorgestuurd worden naar de printer, aan elektronische post en aan
2 Basisvaardigheden
71
systeemlogbestanden. Juist omdat de bestanden onder /var nog wel eens snel en ongecontroleerd kunnen groeien, wordt ook deze directory vaak op een aparte partitie geplaatst. Dit heeft als voordeel dat de bestanden in /var nooit in staat zullen zijn je hele systeem vol te schrijven, ze kunnen hooguit de partitie waarop /var voorkomt volledig vullen. /home De directory /home wordt gebruikt voor de homedirectory’s van gebruikers die op een server gedefinieerd zijn. Elke gebruiker heeft onder /home een privédirectory waarin hij zijn bestanden op mag slaan. Het is min of meer een standaard homedirectory’s onder / home aan te maken. Je bent echter volledig vrij hier indien gewenst van af te wijken. Omdat ook de inhoud van deze homedirectory’s snel kan groeien, komt ook deze directory vaak op een aparte partitie voor. /boot In de directory /boot staan bestanden die nodig zijn voor het opstarten van Linux. Hier bevindt zich onder andere de kernel die geactiveerd wordt tijdens het opstarten. Deze directory is van essentieel belang om het systeem te kunnen starten. Daarnaast is het onder sommige omstandigheden nodig dat de bestanden aan het begin van de vaste schijf staan, dat wil zeggen voor cilinder 1023. Om die reden wordt ook voor de directory /boot vaak een aparte partitie gemaakt van circa 20 MB wat meer dan voldoende is voor de inhoud van deze directory. Bovendien zal dit meestal de eerste partitie op het systeem zijn. /opt Een directory die niet altijd gebruikt wordt, is /opt. Het doel van deze directory is de omvangrijkere programma’s (zoals OpenOffice.org of de KDE Desktop Environment) te scheiden van de kleinere programma’s en opdrachten die voorkomen onder /usr. Ook deze directory wordt vaak op een aparte partitie geplaatst. /proc Een heel ander soort directory is /proc. Het leuke van deze directory is dat hij eigenlijk gewoon niet als directory op de vaste schijf voorkomt. Deze directory wordt namelijk gebruikt als interface naar de datastructuren die door de kernel in het werkgeheugen
72
Linux 4
gebruikt worden. Het doel van het bestandssysteem proc is om het mogelijk te maken snel informatie over processen op te vragen. Een bestand in /proc is dus gewoon een pointer naar een bepaalde locatie in het werkgeheugen van de computer. Het aardige is dat het in bepaalde gevallen ook mogelijk is instellingen van het systeem te wijzigen door direct weg te schrijven in bestanden in het bestandssysteem /proc. Onder de directory /proc komen enkele subdirectory’s voor waarvan de naam bestaat uit een getal. Elk actief proces gebruikt zo’n subdirectory. Het getal is het procesidentificatienummer dat aan elk proces verbonden is. In elk van deze directory’s komen enkele vaste bestanden en directory’s voor, waaronder cmdline. Dit bestand bevat de volledige opdrachtregel waarmee een proces is opgestart. Gewone gebruikers zullen niets te maken hebben met de inhoud van deze directory, voor systeembeheerders kan het echter interessant zijn er gebruik van te maken. Zo kan in /proc bijvoorbeeld achterhaald worden hoe sommige kernelparameters zijn ingesteld. Figuur 2.14 Overzicht van de inhoud van het bestandssysteem /proc
2.8.2 Bestandsnamen Je hebt veel vrijheid in de keuze van tekens die je kunt gebruiken in bestandsnamen. Het is alleen af te raden de tekens die een speciale betekenis hebben voor de shell te gebruiken (! @ # $ % ^ & * ( ) [ ] { } ‘ ` \ / | ; < >). Daarnaast mag een bestandsnaam geen spaties bevatten. Een uitzondering op deze bepalingen kan echter gevormd worden door de bestandsnaam waarin deze tekens
2 Basisvaardigheden
73
gebruikt worden tussen aanhalingstekens te plaatsen. Zo kun je bijvoorbeeld door gebruik te maken van aanhalingstekens een bestand maken met de naam *. De standaard Linux-bestandssystemen ext3 en Reiser staan namen tot een lengte van 256 tekens toe. Als je echter wilt dat je bestanden ook bruikbaar zijn op andere UNIX-systemen, kun je het best een maximale lengte van 14 posities gebruiken; deze lengte wordt door elke UNIX-versie ondersteund. Dit kan bijvoorbeeld nuttig zijn om te weten wanneer je een directory op het Linux-systeem met behulp van NFS wilt delen. Als je een bestand kopieert naar een bestandssysteem dat de lengte van de naam van het bestand niet ondersteunt, wordt alles wat te lang is in de naam afgekapt. Stel dat je een bestand hebt met de naam Ditiseenbestandmeteenhe lelangenaam. Als je dit kopieert naar een bestandssysteem dat namen ondersteunt van maximaal 14 letters, blijft hier niet meer dan Ditiseenbestan van over. Ten slotte nog een laatste opmerking over Linux-bestandsnamen: ze zijn hoofdlettergevoelig. De naam man betekent dus iets heel anders dan Man. Dit is iets wat vooral beginnende Linux-gebruikers nogal eens voor problemen kan stellen. 2.8.3 Soorten bestanden Op een Linux-systeem komen verschillende soorten bestanden voor. Elk van deze bestanden heeft zijn eigen kenmerken die in deze paragraaf worden behandeld. In het begin van dit hoofdstuk hebben we al gesproken over devicebestanden, we zullen dit onderwerp daarom niet nogmaals behandelen. Wel zal hier aandacht worden besteed aan de ‘normale’ bestanden, directory’s en de verschillende soorten links die op een Linux-systeem gemaakt kunnen worden. Gewone bestanden De meeste bestanden die op een Linux-systeem voorkomen, zijn ‘gewone’ bestanden. Om een discussie over het begrip gewoon te vermijden: we noemen hier elk bestand dat gegevens bevat een gewoon bestand. Deze gegevens kunnen uit van alles bestaan: ASCII-tekst, een afbeelding, uitvoerbare code of data van wat voor soort dan ook. Binnen deze bestanden maakt Linux alleen onderscheid tussen uitvoerbare en niet-uitvoerbare bestanden. Een uitvoerbaar bestand is gewoon een bestand dat uitvoerbare code bevat en dat door middel van de execute-permissie uitvoerbaar is
74
Linux 4
gemaakt. Als je wilt weten wat voor soort gegevens er in een bestand voorkomen, kun je gebruikmaken van de opdracht file. Deze opdracht herkent de inhoudspatronen die in een bestand gebruikt worden en kan op basis daarvan aangeven wat voor soort bestand het is. #file * Xrootenv.0:
ASCII text
pamela.jpg:
JPEG image data, JFIF standard
cp: ELF 32-bit LSB executable, Intel 80386, version 1, dynamically linked, stripped passwd:
ASCII text
nsmail:
directory
2.9 Bekijken van inhoud van bestanden en output van opdrachten De opdracht less kan dienen als een filter waarmee tekst op het beeldscherm scherm voor scherm kan worden bekeken. Je kunt less gebruiken om te voorkomen dat de output van een opdracht achter elkaar door rolt over het scherm. Daarnaast kun je deze opdracht gebruiken om de inhoud van een ASCII-bestand scherm voor scherm te bekijken. Om bijvoorbeeld de inhoud van het bestand /etc/passwd te bekijken kun je de opdracht less /etc/ passwd typen. De opdracht less leest vervolgens het bestand /etc/ passwd in zijn geheel in. Het nut hiervan is dat je door op de spatiebalk te drukken de inhoud van het bestand scherm voor scherm kunt bekijken. Om de uitvoer van een opdracht door te sturen naar de opdracht less, zodat het scherm voor scherm getoond wordt, maak je gebruik van piping; hierover heb je al eerder in dit hoofdstuk kunnen lezen. Binnen de opdracht less zijn naast de spatiebalk nog enkele toetsen beschikbaar die je kunnen helpen manoeuvreren binnen de tekst. De belangrijkste is h. Als je deze toets indrukt, krijg je een overzicht van alle beschikbare toetsen in less. Voor de rest kunnen precies dezelfde toetsen gebruikt worden als dat ook gebruikt worden binnen de opdracht man. De opdracht man is namelijk op less gebaseerd.
2 Basisvaardigheden
less
cat tac
head tail more
2.10
75
is niet de enige opdracht waarmee je in bestanden kunt kijken. Andere handige opdrachten die je voor ditzelfde doel kunt gebruiken zijn: Toont de totale inhoud van een bestand op het scherm waarna je weer op de prompt belandt. Toont de totale inhoud van een bestand op het scherm, maar dan in omgekeerde volgorde: de eerste regel wordt dus als laatste getoond. Toont de eerste tien regels van een bestand. Laat je de laatste tien regels van een bestand zien. Dit is de voorganger van less. Het doet ongeveer hetzelfde, maar dan met veel minder mogelijkheden. Zoeken naar bestanden en tekst
Er zijn drie opdrachten die je kunt gebruiken om te zoeken. Met find kun je bestanden op basis van bepaalde criteria terugvinden op het systeem en met de opdracht grep kun je zoeken naar bestanden waarin een bepaalde tekst voorkomt. Daarnaast kun je grep nog voor veel meer gebruiken. Tot slot is er de opdracht locate waarmee je in een speciaal aan te maken database kunt zoeken naar bestanden. locate heeft weinig opties, maar biedt wel het voordeel dat niet de hele vaste schijf fysiek afgezocht hoeft te worden. Houd er rekening mee dat in tegenstelling tot find de opdracht locate gebruikmaakt van een database die wel eerst gemaakt moet worden en ook periodiek moet worden bijgewerkt. Deze database kun je handmatig bijwerken met behulp van de opdracht updatedb. find
Wordt gebruikt om te zoeken naar bestanden die aan bepaalde eigenschappen voldoen. grep Wordt gebruikt om te zoeken in de tekst van bepaalde bestanden en niet naar de naam zoals bij find het geval is. locate Wordt gebruikt om snel de locatie van een bepaald bestand te zoeken. Voordat je locate kunt gebruiken, moet de opdracht updatedb gebruikt worden om de bestandsdatabase zo actueel mogelijk te maken.
76
Linux 4
De opties van find maken het mogelijk eenvoudig een bestand terug te vinden op basis van de bestandsnaam, maar je kunt het ook gebruiken om bestanden te zoeken op basis van criteria zoals grootte, aanmaakdatum en eigenaar. Aan de opdracht find kunnen drie soorten opties worden meegegeven. Deze maken gezamenlijk de expressie. Allereerst zijn er de gewone opties waarmee in zeer algemene zin bepaald wordt hoe de opdracht find zich moet gedragen. Zo is er bijvoorbeeld een optie waarmee je kunt specificeren dat find slechts een beperkt aantal directoryniveaus diep mag gaan. Bijvoorbeeld find -maxdepth 3 specificeert dat slechts drie subdirectory’s diep gezocht zal worden. Het is met name voor de duidelijkheid handig de gewone opties aan het begin van de expressie te plaatsen. Je onderscheidt zo op een duidelijke manier de gewone opties van de condities waaraan de bestanden die je met find wilt vinden, moeten voldoen. Naast de gewone opties zijn er de tests. Met de test bepaal je aan welke kenmerken een bestand moet voldoen. Er zijn vele mogelijkheden voor het gebruik van tests. Om je een idee te geven worden hieronder enkele mogelijkheden genoemd: Het bestand is n-minuten geleden voor het laatst benaderd. -empty Het bestand is leeg. -name bestandsnaam Specificeert, al dan niet door gebruik te maken van wildcards, de naam van het bestand. -user usernaam Specificeert de eigenaar van het bestand. -amin n
De laatste soort optie zijn de acties. Door middel van de acties kun je opdrachten aangeven die moeten worden uitgevoerd op het resultaat van de zoekactie. Zo kun je bijvoorbeeld het resultaat op je beeldscherm weergeven door de actie -print1 te specificeren. Ook is het mogelijk met behulp van de actie -exec opdrachten uit te voeren op de bestanden die door find gevonden zijn. Als je dit wilt doen, gebruik je in de opdracht de tekens { }, die staan voor de huidige bestandsnaam. Alles vanaf -exec tot aan de eerste puntkomma wordt door het systeem geïnterpreteerd als één opdracht. find / -name “a*” -user franck -exec cp {} /root \;
2 Basisvaardigheden
77
Deze opdracht zoekt vanaf de rootdirectory alle bestanden waarvan de gebruiker franck eigenaar is en waarvan de naam begint met de letter a, en kopieert deze vervolgens naar de homedirectory van de gebruiker root. Let hierbij op de manier waarop de opdracht wordt afgesloten: eerst met een backslash en vervolgens een puntkomma. De backslash zorgt ervoor dat niet de shell maar de opdracht find het puntkommateken interpreteert. De puntkomma wordt gebruikt om het eind aan te geven van een opdracht die als argument van de optie -exec is gegeven. Als je meerdere opdrachten achter elkaar wilt gebruiken door middel van de optie –exec, wordt elk -exec-statement van het vorige gescheiden door een puntkomma. De opdracht find kan bestanden en directory’s zoeken waar in de naam een bepaalde tekenreeks voorkomt. De opdracht grep kan gebruikt worden om te zoeken naar bestanden waar in de inhoud een bepaalde tekenreeks voorkomt. Ook kun je met grep in de uitvoer van opdrachten zoeken naar bepaald resultaat. Gebruik van de opdracht grep is vrij eenvoudig. De algemene syntaxis is als volgt: grep [opties] tekenreeks [bestanden] Als je bijvoorbeeld wilt zoeken naar alle bestanden in de huidige directory waarin de tekenreeks xyz voorkomt, kun je de opdracht grep xyz * gebruiken. Het resultaat zal zijn dat elke regel waarin de tekenreeks voorkomt op het beeldscherm wordt afgedrukt, voorafgegaan door de naam van het bestand waarin de regel voorkomt. Omdat het standaardresultaat van de opdracht grep vrij onoverzichtelijk is, kun je opties gebruiken om het resultaat iets duidelijker te maken. -n, --line-number -s, --silent
Drukt het regelnummer af voor elke regel. Onderdrukt alle foutmeldingen. Deze optie zou standaard gebruikt moeten worden, anders krijg je een foutmelding voor elke directory die voorkomt in de directory waarin gezocht wordt. -i, --ignore-case Maakt geen onderscheid tussen hoofd- en kleine letters. -l, --list Laat niet elke regel in de bestanden zien waar de treffer in gevonden is, maar toont alleen de naam van de bestanden.
78
Linux 4
De opdracht grep kan worden gebruikt om tekstbestanden te doorzoeken. Daarnaast kan het ook gebruikt worden om de uitvoer van een opdracht te filteren. Als voorbeeld hiervan kan de opdracht ps –aux | grep httpd genoemd worden. Hiermee wordt in de output van de opdracht ps gezocht naar die specifieke regels waarin de tekst httpd voorkomt. Alleen die regels zullen dan ook getoond worden. Figuur 2.15 Als je de uitvoer van een opdracht met piping doorstuurt naar grep, kun je filteren in de uitvoer van de opdracht
Er zijn twee varianten beschikbaar op de opdracht grep, te weten zgrep en rgrep. Met zgrep kun je zoeken naar tekenreeksen in gecomprimeerde bestanden. De opties die bij zgrep gebruikt kunnen worden, zijn gelijk aan de opties die bij grep gebruikt worden. De opdracht rgrep kan bestanden in een directorystructuur doorzoeken op het voorkomen van een tekenreeks. Deze opdracht heft de beperking van grep op dat alleen gezocht kan worden in bestanden in één aangegeven directory. De opdracht rgrep heeft echter aanzienlijk meer tijd om zijn werk te kunnen doen dan grep. Daarnaast is rgrep niet op alle distributies beschikbaar. Je zult overigens merken dat in plaats van zgrep en rgrep ook gewoon de opties -z en -r gebruikt kunnen worden bij grep. De exacte werkwijze is afhankelijk van de distributie. Gelukkig is het ook mogelijk om hele subdirectorystructuren te doorzoeken door de opdrachten find en grep met elkaar te combineren. Je kunt dit in een van de oefeningen aan het eind van dit hoofdstuk uitproberen.
2 Basisvaardigheden
79
2.11 Kopiëren, verplaatsen, verwijderen en maken van directory’s In deze paragraaf wordt nog even kort aandacht besteed aan enkele opdrachten die gebruikt kunnen worden voor het beheer van bestanden. cp [-opties] bestand bestemming Met de opdracht cp (copy) kunnen bestanden
gekopieerd worden. Als argument geef je de naam van het bestand en de locatie waar het naartoe gekopieerd moet worden. Zoals bijna elke Linux-opdracht heeft ook de opdracht cp veel opties. Hier volgen enkele handige opties: -b, --backup
Maak een back-up van bestanden die overschreven worden door cp. -f, --force Verwijder bestaande doelbestanden als die er zijn of overschrijf een bestand wanneer het al bestaat. -i, --interactive Vraag de gebruiker wat er moet gebeuren als een bestaand bestand overschreven dreigt te worden. -r Kopieer de inhoud van een directory inclusief alle subdirectory’s en hun inhoud. -u, --update Kopieer een bestand niet als op de plaats van bestemming een gelijknamig bestand bestaat met dezelfde of recentere wijzigingsdatum. mv [-opties] bron bestemming De opdracht mv (move) wordt gebruikt
om bestanden te verplaatsen van de ene naar de andere locatie. De opties die bij mv gebruikt kunnen worden, zijn min of meer gelijk aan die van de opdracht cp. rm [-opties] bestandsnaam De opdracht rm (remove) is een
bijzonder krachtige opdracht die gebruikt wordt voor het verwijderen van bestanden. De standaardinstelling is dat rm alleen bestanden en geen directory’s verwijdert. Je dient er rekening mee te houden dat de opdracht rm bij een drastische verwijderingsactie niet altijd zal vragen of je het wel zeker weet! Enkele handige opties zijn:
80
Linux 4
-f, --force
Forceert het verwijderen en vraagt nooit bevestiging aan de gebruiker. -i, --interactive Vraagt de gebruiker bevestiging voor verwijdering. Dit is de standaardinstelling van Red Hat Linux; dit geldt echter niet voor elke distributie. -r, --recursive Verwijdert de inhoud van directory’s en subdirectory’s. - Wordt gebruikt om aan te geven dat alle volgende argumenten geen opties zijn. Als je bijvoorbeeld een bestand hebt met de naam –f, kun je dat bestand niet verwijderen met de opdracht rm -f. Het systeem zal immers de -f interpreteren als een optie. Als je nu toch dit bestand zou willen verwijderen, kun je rm - -f typen. mkdir [-opties] naam Met mkdir kunnen directory’s rmdir [-opties] naam Met rmdir kun je directory’s
2.12
gemaakt worden.
verwijderen.
Nog meer basisopdrachten
Om de parate kennis van Linux-opdrachten nog wat te vergroten volgt hier een kort overzicht van enkele elementaire Linux-opdrachten met een korte omschrijving. cal
clear date
Geeft een eenvoudige kalender weer. Belangrijkste argument is maand en/of jaar; cal 1999 geeft de kalender van 1999, cal 9 1999 geeft de kalender van september 1999. Clear screen: het scherm leegmaken. Weergave en instellen van datum en tijd. De syntaxis voor instellen van de datum is date MMDDhhmm [CC] [YY] [.ss], waarin MM = maand, DD = dag, hh = uur, mm = minuut, CC = eeuw, YY = jaar en ss = seconden. Je gebruikt hiervoor uitsluitend numerieke waarden en altijd twee cijfers per waarde, dus niet date may11815, maar date 05011815.
2 Basisvaardigheden
81
df du
Geeft vrije ruimte op de schijf weer. Geeft ruimte die door gespecificeerde bestanden en directory’s wordt ingenomen. file Geeft weer om wat voor type bestand het gaat. free Toont hoeveel werkgeheugen er nog vrij is. logname Geeft weer onder welke naam je bent ingelogd op het systeem. sort Sorteert de inhoud van een tekstbestand. uname Geeft informatie over het systeem. wc Telt het aantal woorden, tekens of regels in een bestand. wall Stuurt een boodschap naar alle ingelogde gebruikers. Start de boodschap met de opdracht wall, schrijf vervolgens de boodschap en verstuur deze met de toetsencombinatie Ctrl-D. who Toont wie momenteel is ingelogd op het systeem. write Stuurt een boodschap aan een gebruiker. Je opent een write-sessie met write usernaam[@hostnaam]. Vervolgens kun je de boodschap typen en deze zal bij de gebruiker op het beeldscherm verschijnen. De boodschap wordt afgesloten met het end-of-file-teken Ctrl-D. id Geeft het system-id van de gebruiker. Dit is het identificatienummer waaronder een gebruiker bekend is bij het systeem. 2.13
Maken van tekstbestanden
Naarmate je meer ervaren met Linux zult worden, zul je merken dat een groot deel van de configuratie van het systeem vanuit een grafische omgeving gedaan kan worden. De desktop environment en de distributies zorgen ervoor dat er een breed scala aan programma’s hiervoor beschikbaar is. Je zult er echter ook achter komen dat je voor het echte werk een of ander instellingenbestand wilt bewerken. Zeer ervaren Linux-beheerders doen zelfs niet anders. Om die reden is het belangrijk dat je kunt werken met een editor waarmee deze tekstbestanden bewerkt kunnen worden. Er zijn onder Linux zeer veel editors beschikbaar, we zullen ze daarom ook niet allemaal hier bespreken. Er is namelijk maar één editor die echt belangrijk is en dat is de oer-editor vi. Onder Linux wordt van deze klassieker een speciale gebruikersvriendelijke
82
Linux 4
versie met de naam vim (vi improved) geleverd. Toegegeven, het is niet de meest gebruikersvriendelijke editor, maar wel de meest algemene editor. Zonder twijfel kunnen we namelijk melden dat vi op elke UNIX-installatie van na 1975 voorkomt. De meest algemeen voorkomende editor op het UNIX- en Linuxplatform is vi. Als je kunt werken met vi, ben je in staat om op elk Linux- en Unix-systeem ASCII-bestanden aan te maken. Daarnaast kun je ook op Apple aan het werk. Met Apple’s OS X wordt vim namelijk ook meegeleverd. Om die reden zullen we er hier beknopt aandacht aan besteden. Maak je geen illusies, nadat je deze paragrafen bestudeerd hebt, ben je beslist nog geen vi-guru. Deze editor is namelijk zo veelzijdig dat je er alleen al een boek over kunt schrijven (dat is ook gedaan en dat boek is uitgegeven door O’Reilly voor het geval je geïnteresseerd bent. Raadpleeg www.oreilly.com voor meer informatie). We zullen ons hier beperken tot het strikt noodzakelijke. Figuur 2.16 Als je liever in een grafische gebruikersomgeving werkt, hebben wij goed nieuws voor je: onder KDE kun je een grafische versie van vi starten met de opdracht kvim
2.13.1 Geschiedenis Vroeger werd op UNIX-systemen doorgaans niet gewerkt met grafische monitoren, maar met langzame hardcopy-terminals, zoals een printer. Het type editor dat daarvoor als enige geschikt was, was de regelgeoriënteerde editor. Op het moment immers dat een tekstregel op de printer is afgedrukt, is er geen mogelijkheid om nog een regel terug te gaan. In zo’n editor kon slechts één regel tegelijk bewerkt worden. Op hedendaagse UNIX-computers zijn
2 Basisvaardigheden
83
vaak nog twee regelgeoriënteerde editors aanwezig: ed en ex. We zullen daar in dit boek verder geen aandacht aan besteden, omdat ze behoorlijk beperkt zijn in de gebruiksmogelijkheden. Vi was de eerste editor die fullscreen kon werken en dus in zijn tijd (jaren zeventig) een grote stap voorwaarts. Dit betekent dat je met vi één scherm met informatie tegelijk kunt zien in plaats van één regel tegelijk, zoals het geval was met de voorgangers van vi. Bovendien is het in vi mogelijk terug te gaan naar een voorgaande regel. Met vi kun je geen prachtige documenten maken. Wel biedt vi alle mogelijkheden om ASCII-bestanden aan te maken en te bewerken. 2.13.2 Opdrachtmodus en inputmodus Vi kent twee verschijningsvormen: de opdracht- en de inputmodus. In de opdrachtmodus worden alle tekens die je invoert, geïnterpreteerd als opdrachten voor vi. Als je een bestand wilt opslaan, tekens wilt wissen of tekst wilt zoeken, doe je dat in de opdrachtmodus. In de inputmodus kun je tekst typen. Je kunt dus niet in één en dezelfde modus tekst toevoegen en gelijktijdig bewerken. Je moet hiervoor eerst van modus wisselen en dat zorgt dan ook voor veel verwarring bij beginnende (en zelfs zeer gevorderde) vi-gebruikers. Tip! In vim kun je zien of je in de opdracht- of inputmodus zit. In de inputmodus zie je namelijk onder in beeld de aanduiding insert staan. Je kunt vi opstarten door op de prompt de opdracht vi te typen. Je kunt dit eventueel laten volgen door een bestandsnaam, zodat vi wordt gestart en er meteen een bestand wordt geopend. De opdracht vi file1 zorgt ervoor bijvoorbeeld voor dat vi wordt opgestart, waarbij file1 uit de huidige directory wordt geopend. Indien het bestand nog niet bestaat, zorgt vi ervoor dat het wordt gemaakt. Mocht je geen bestandsnaam aangeven bij de opdracht vi, dan wordt het geopend met een helptekst. Ook dat zorgt weer voor verwarring, want dan moet je eerst die helptekst weer afsluiten.
84
Linux 4
Als je na het starten van vi tekst wilt gaan typen, zal dat niet lukken. Standaard staat vi na het opstarten namelijk in de opdrachtmodus. Je zult vi in de inputmodus moeten zetten als je tekst wilt toevoegen. Je kunt dit doen door de opdracht i in te voeren; de toets Ins werkt trouwens ook, maar we zullen ons om het overzichtelijk te houden niet te buiten gaan aan de vele manieren die binnen vi bestaan om een opdracht uit te voeren. Vi verandert hiermee van modus en wacht nu op de tekst die je wilt gaan typen. Nu kan het voorkomen dat je tekst invoert en dat je ziet dat je iets verkeerd hebt getypt. Je bent gewend dat je deze onjuiste tekst weg kunt halen door gebruik te maken van de toetsen Delete en Backspace. In vim zal dat inderdaad lukken. Als je echter gebruikmaakt van een oudere versie van vi, worden er alleen maar rare tekens op het beeldscherm gezet wanneer je gebruik probeert te maken van deze toetsen. Je zult dan eerst terug moeten naar de opdrachtmodus om daar opdrachten te geven die ervoor zorgen dat tekst verwijderd wordt. Om terug te keren naar deze modus kun je gebruikmaken van de toets Escape. Onthouden: om van opdrachtmodus naar inputmodus te gaan, druk je op de toets I en om van inputmodus weer terug te gaan naar opdrachtmodus, druk je op Esc. 2.13.3 Opslaan en afsluiten Als je klaar bent met je werk, wil je het waarschijnlijk opslaan. Om dit te doen moet je allereerst terug naar de opdrachtmodus. Je bereikt dit door op de Escape-toets te drukken. Nu zijn er enkele opdrachten die je kunt gebruiken voor het opslaan van tekst en het afsluiten van vi. :q
:q!
Sluit af zonder de wijzigingen op te slaan. Als je wijzigingen in het bestand hebt aangebracht, geeft vi een melding en doet het niets. Je zult eerst de wijzigingen moeten opslaan voordat je vi kunt afsluiten met de opdracht :q. Sluit vi af, ongeacht eventuele nog niet opgeslagen wijzigingen die je hebt aangebracht in de tekst. Alles wat je nog niet hebt opgeslagen, ben je dus kwijt nadat je vi op deze wijze hebt afgesloten. Als
2 Basisvaardigheden
85
‘noodrem’ kan deze opdracht echter heel handig zijn: soms gebeuren er bij het werken met vi onverklaarbare zaken en je kunt op deze wijze altijd weer terugkeren naar de beginsituatie. :wq Slaat de wijzigingen op in het huidige bestand en sluit dan af. Als je het bestand nog geen naam hebt gegeven, kun je dit alsnog doen door de opdracht : wq filenaam te gebruiken. :x Zelfde als :wq. ZZ Zelfde als :wq. :w Slaat wijzigingen op in het huidige bestand zonder vi af te sluiten. Als je het bestand nog geen naam hebt gegeven, kun je dit alsnog doen door de opdracht :w filenaam te gebruiken. :w! filenaam Deze opdracht, gevolgd door een bestandsnaam, schrijft de wijzigingen naar het gespecificeerde bestand en overschrijft indien nodig het huidige bestand. Tip! Per ongeluk de verkeerde opdracht gegeven? Gebruik dan vanuit de opdrachtmodus de toets u om de laatste bewerking weer ongedaan te maken. 2.13.4 Verwijderen en toevoegen Als bovenstaande oefening goed is gegaan, ben je nu in staat om een eenvoudig bestandje aan te maken met vi. Hier volgen nog wat extra opdrachten, zodat je ook een paar andere bewerkingen kunt uitvoeren: a i o x d$ dd dw
Append: voeg tekst toe op de plaats waar nu de cursor staat. Insert: voeg tekst toe voor de plaats waar nu de cursor staat. Open een nieuwe regel en voeg daar tekst toe. Verwijder het teken op de positie van de cursor. Verwijder tekst van de positie van de cursor tot het eind van de regel. Verwijder de hele regel waarin de cursor staat. Verwijder alles vanaf de positie van de cursor tot het begin van het volgende woord.
86
Linux 4
De optie om tekst te verwijderen kun je ook gebruiken voor meerdere items tegelijk: je moet er dan een getal voor zetten. Zo gooit de opdracht 8dd acht regels weg. Daarnaast kun je een reeks regels wissen door te verwijzen naar de regelnummers. Het is verstandig als hierbij de weergave van regelnummers aan staat. Het aan- en uitzetten van regelnummers gebeurt met de volgende opdrachten: :se number :se nonumber
Geef regelnummers weer. Zet weergave van regelnummers uit.
Bovendien moet je aan vi duidelijk maken dat je verwijst naar regelnummers. Dit kan door de opdracht te beginnen met een dubbelepunt. Als je bijvoorbeeld de regels 9 tot en met 15 wilt weggooien, is dit mogelijk met de opdracht :9,15d. Het systeem geeft vervolgens op de statusbalk een melding over het aantal regels dat je hebt verwijderd. Zou je de dubbelepunt aan het begin van de opdracht vergeten, dan kan vi het niet goed interpreteren en worden de huidige regel en de volgende vijftien regels verwijderd. Vi op zijn allerergst Eigenlijk is vi op Linux best gebruiksvriendelijk. Zeker wanneer gebruikgemaakt wordt van de verbeterde vi-kloon vim; bij veel zaken hoeft dan namelijk nauwelijks nog nagedacht te worden. Een heel ander geval is het op sommige oudere UNIXmachines. Daar kan het zelfs voorkomen dat het systeem je pijltjestoetsen niet eens meer begrijpt. In dat geval is het handig de volgende (opdrachtmodus) opdrachten te kennen: h j k l
Verplaats cursor naar links. Verplaats cursor omlaag. Verplaats cursor omhoog. Verplaats cursor naar rechts.
Logisch toch? 2.13.5 Zoeken, knippen en plakken Met behulp van de volgende opdrachten kun je met vi ook zoeken naar tekst: /woord ?woord
Zoek vooruit naar woord. Zoek achteruit naar woord.
2 Basisvaardigheden
n Shift-n
87
Herhaal de laatste zoekactie in dezelfde richting. Herhaal de laatste zoekactie in de tegengestelde richting.
Als dit je trouwens bekend voorkomt, kan dat kloppen. Je hebt deze toetsen eerder gezien bij de opdrachten less en man. less is namelijk een afgeleidde van vi en man is weer een afgeleidde van less, dus sommige opdrachten zullen in al deze utilities werken. Het is gemakkelijk om tekst te kunnen verwijderen en deze ergens anders in het bestand weer toe te voegen. Je hebt zojuist geleerd hoe je een hele regel tekst (of meer) kunt wissen. Daarnaast heb je gezien dat je deze verwijdering ongedaan kunt maken. Dit komt doordat alles wat je weggooit in een buffer geplaatst wordt. Wat in die buffer staat, kun je ook weer terughalen. Hiervoor gebruik je de opdracht p (paste). Het is uiteraard ook mogelijk om tekst te kopiëren. Dit gebeurt in principe op dezelfde wijze als wissen. Je gebruikt alleen in plaats van de opdracht d de opdracht y (yank). 2.13.6 Algemene instellingen Naast het bewerken van tekst is het ook mogelijk in de opdrachtmodus algemene opties in te stellen. Elk van deze opties moet worden ingesteld met de opdracht :set optie. Een aantal van de opties wordt hieronder weergegeven: ai
Autoindent zorgt ervoor dat automatisch elke regel wordt ingesprongen op hetzelfde niveau als de regel erboven. Deze optie is erg handig wanneer je vi gebruikt om programmabestanden of shell-scripts te schrijven. eb Errorbells zorgt ervoor dat de computer een geluidssignaal geeft wanneer een verkeerde opdracht gebruikt wordt. nu Number zorgt ervoor dat je regelnummers ziet. report Report bepaalt wanneer het systeem een melding gaat geven in verband met een bepaalde ingrijpende wijziging; report=3 zorgt ervoor dat wanneer je drie of meer regels gelijktijdig gaat wijzigen, het systeem een melding geeft. Blijf je onder de drie, dan gebeurt er niets. sm Showmatch toont het corresponderende ‘haakje openen’ wanneer een ‘haakje sluiten’ wordt getypt. Handig voor programmeurs. smd Showmode laat op de statusregel zien in welke editing-
88
Linux 4
warn
modus je bent. Ideaal, zo kun je namelijk heel eenvoudig zien of het programma zich al dan niet in insertmodus bevindt. Warn geeft een melding wanneer je vi wilt verlaten terwijl de wijzigingen nog niet zijn opgeslagen.
Om bijvoorbeeld de optie warn in te stellen, geef je de opdracht : set warn. Als je wilt zien welke opties voor de sessie allemaal van kracht zijn, kun je de opdracht :set all invoeren. Het nadeel van opties instellen in de opdrachtmodus is dat de opties verloren gaan bij het afsluiten van vi. Als je de opties permanent wilt instellen, moet je een bestand met de naam .exrc maken in de homedirectory. De syntax voor de opties die je wilt instellen in ~/.exrc is gelijk aan de syntaxis die hierboven is beschreven. De belangrijkste opdracht die je in vi kunt opgeven, is :help. De meest uitgebreide hulp over het programma vi vind je niet terug in de man-pagina, maar wanneer je :help typt in de vi opdrachtmodus. De hoeveelheid opdrachten die binnen vi gebruikt kunnen worden, kan overweldigend zijn. Je moet je hierdoor niet laten afschrikken: met vi kan al gewerkt worden als je zes opdrachten kent, ingevoerd vanuit de opdrachtmodus: Esc Shift-zz i x dd :q!
2.14
Activeer de opdrachtmodus. Sluit vi af en bewaar alle wijzigingen. Voeg een teken toe op de positie waar de cursor zich bevindt. Verwijder het teken op de positie waar de cursor zich bevindt. Verwijder de huidige regel. Sluit vi af zonder dat wijzigingen worden opgeslagen.
Afsluiten
Wanneer je klaar bent met het werken met Linux, kun je niet zomaar de computer uitzetten. Linux schrijft namelijk niet altijd de
2 Basisvaardigheden
89
gegevens direct weg naar de schijf, maar bewaart ze tijdelijk in het werkgeheugen om ze op een geschikt moment weg te schrijven. Dit proces wordt caching genoemd. Hierdoor loop je het risico dat je gegevens kwijtraakt wanneer de computer gewoon uitgezet wordt. Daarnaast moeten alle gebruikers de gelegenheid krijgen zich af te melden, zodat ze hun werk kunnen opslaan. Daarom is er een speciale opdracht die je moet gebruiken om de computer af te sluiten: shutdown. De opdracht shutdown geeft alle ingelogde gebruikers een melding dat het systeem ‘down’ gaat; het is dan niet langer mogelijk nog in te loggen of verder te werken. Vervolgens krijgen alle actieve processen een signaal dat het systeem gaat afsluiten. Hierdoor krijgen de processen de kans hun data op te slaan. Je kunt aan de opdracht shutdown een aantal opties meegeven die bepalen wat er precies moet gebeuren: shutdown -r sec
De optie -r wordt gebruikt om het systeem na de shutdown opnieuw op te starten. Met de parameter sec kun je een aantal seconden specificeren. In plaats daarvan kun je ook een onmiddellijke shutdown forceren door now als parameter in te voeren. Wanneer er echter gebruikers op het systeem zijn ingelogd, zullen zij je dat niet in dank afnemen. Een alternatief voor shutdown -r now is de toetsencombinatie Ctrl-Alt-Del te gebruiken. Deze heeft namelijk precies hetzelfde effect. Het nadeel van Ctrl-Alt-Del is dat deze manier om opnieuw op te starten voor alle gebruikers werkt terwijl alleen de gebruiker root in de gelegenheid is om de opdracht shutdown te gebruiken. Als je er niet van gediend bent dat iedereen zo de server af kan sluiten, kun je de regel die dit mogelijk maakt uit het configuratiebestand /etc/inittab verwijderen. Naast Ctrl-Alt-Del en shutdown -r now, kun je ook de opdracht reboot gebruiken; ook dit heeft hetzelfde effect als shutdown -r now. shutdown -h now
De optie -h gebruik je wanneer je het systeem na de shutdown ook daadwerkelijk wilt afsluiten. De parameter now veroorzaakt een onmiddellijke shutdown. In plaats van shutdown -h now kan ook de opdracht halt gebruikt worden.
90
Linux 4
Het is niet altijd wenselijk dat elke gebruiker het systeem kan afsluiten door middel van de opdracht shutdown. Je kunt dit voorkomen door een bestand aan te maken met de naam /etc/shutdown. allow. In dit bestand specificeer je de namen van gebruikers die het recht hebben om de opdracht shutdown te gebruiken. Daarnaast is het ook mogelijk om met permissies te regelen dat gebruikers deze opdracht niet kunnen gebruiken. Standaard zal alleen de gebruiker root voldoende rechten hebben een systeem opnieuw op te starten. Als je de toegang tot shutdown hebt beperkt, blijft het echter mogelijk voor gebruikers om door middel van de toetsencombinatie Ctrl-Alt-Del het systeem opnieuw op te starten. Dit voorkom je door in het bestand /etc/inittab de volgende regel uit te schakelen: ca::ctrlaltdel:/sbin/shutdown -t3 -r now
Je kunt deze regels deactiveren door er een # -teken voor te zetten. Ook kun je de opdracht /sbin/shutdown-t3-r now veranderen in een andere opdracht. Deze wijziging wordt echter pas van kracht nadat je het systeem opnieuw hebt opgestart, of nadat de opdracht telinit q gegeven is. Voordat je echter deze opdracht enthousiast onmogelijk gaat maken, moet je je afvragen of je dit werkelijk wilt. Als tijdens het opstarten de computer namelijk vastloopt op het laden van een bepaald proces, is het ook wel heel erg handig dat je met Ctrl-Alt-Del in elk geval nog de computer netjes opnieuw kunt opstarten. Bij het uitvoeren van de opdracht shutdown wordt aan init, het hoofdproces op de computer, verteld dat het zijn runlevel moet veranderen. Daarbij is een runlevel de status waarin het systeem zich op dat moment bevindt. Twee runlevels zijn op alle distributies hetzelfde. Zo is er namelijk altijd het runlevel 0 dat gebruikt wordt om het systeem uit te zetten en het runlevel 6 dat gebruikt wordt om het systeem opnieuw op te starten. Om van huidig runlevel te veranderen kan het gewenste runlevel als argument van de opdracht init gegeven worden. Zo kan als alternatief voor de opdracht shutdown –h now de opdracht init 0 gegeven worden en kan init 6 gebruikt worden als alternatief voor shutdown –r now.
2 Basisvaardigheden
2.15
91
Samenvatting
In dit hoofdstuk heb je geleerd van welke elementaire opdrachten je gebruik kunt maken bij het beheer van Linux vanaf de opdrachtregel. Voor een beheerder is dat heel belangrijk: niet alleen heb je vanaf de opdrachtregel veel krachtige opties ter beschikking, daarnaast kun je er verzekerd van zijn dat deze opdrachten op alle Linux-distributies min of meer hetzelfde zijn. Je hebt kennisgemaakt met de opdrachten die nodig zijn om in het bestandssysteem te manoeuvreren, hulp op te vragen en te zoeken naar bestanden of in de inhoud van bestanden. Ook heb je geleerd hoe je met behulp van de editor vi tekstbestanden kunt maken. In het volgende hoofdstuk maak je kennis met een andere belangrijke basisvaardigheid: hier lees je namelijk hoe de shell het werken met Linux eenvoudiger voor je maakt.
3
Gebruikers, groepen en permissies
3.1
Inleiding
Om een Linux-server te kunnen inrichten krijg je te maken met gebruikersaccounts. Het werken met gebruikersaccounts heeft een goede reden: je hebt ze nodig om permissies uit te kunnen delen op de server. Door middel van deze permissies worden bepaalde taken aan de gebruikers toegekend. In dit hoofdstuk leer je wat erbij komt kijken om een solide gebruikersomgeving in te richten. 3.2
Beheer van de gebruikersomgeving
Al bij de installatie van de server heb je minimaal twee gebruikers gemaakt: de almachtige gebruiker root en een account dat je gebruikt voor de dagelijkse werkzaamheden waarbij rootpermissies niet nodig zijn. Je gaat nu leren waar deze informatie is opgeslagen en hoe je zelf nieuwe gebruikers toevoegt en andere beheerstaken met gebruikers uitvoert. 3.2.1 Configuratiebestanden Zoals bij alles op de Linux-server, worden ook gebruikers opgeslagen in configuratiebestanden. De basis van al deze bestanden is /etc/passwd. Hierin worden essentiële kenmerken van gebruikers opgeslagen, zoals diens naam en identificatienummer (de User ID, UID). Naast /etc/passwd is er het bestand /etc/shadow. Hierin staat het versleutelde wachtwoord en andere instellingen die te maken hebben met de houdbaarheid van het wachtwoord.
94
Linux 4
Figuur 3.1 In /etc/passwd worden alle gebruikersaccounts opgeslagen
Gebruikers op een Linux-systeem hebben altijd een aantal eigenschappen. Deze eigenschappen zijn gedefinieerd in het configuratiebestand /etc/passwd. Het gaat daarbij om de volgende eigenschappen: Gebruikersnaam
Wachtwoord
Figuur 3.2 Wachtwoorden worden opgeslagen in het bestand /etc/shadow
Elke gebruiker heeft een unieke naam. Houd er rekening mee dat gebruikersnamen onder Linux hoofdlettergevoelig zijn, dus wen je aan hier een systematiek in te gebruiken. Zoals gezegd, het wachtwoord van een gebruiker wordt niet langer opgeslagen in het tweede veld van /etc/passwd, maar in een afzonderlijk configuratiebestand met de naam /etc/shadow.
3 Gebruikers, groepen en permissies
95
Identificatienummer Elke gebruiker heeft een uniek gebruikersidentificatienummer, het zogenoemde User ID (UID). De gebruikersidentificatienummers die beschikbaar zijn, variëren van 0 tot en met 65534. De nummers voor normale gebruikers beginnen gewoonlijk bij 500; hogere getallen zijn gereserveerd voor systeemaccounts die nodig zijn voor de verschillende services die op de server aangeboden worden. Het nummer 0 is gereserveerd voor de gebruiker root, de almachtige beheerder van de server. Groepsidentificatie- Op een Linux-systeem moet een gebruiker nummer lid zijn van op zijn minst één groep. Deze groep wordt aangeduid als de zogenoemde primary group. Lidmaatschap van deze groep wordt geregeld door het groepsidentificatienummer (GID) op te nemen in /etc/ passwd. Verderop in dit hoofdstuk lees je meer over het beheer van groepen. Informatie In het volgende veld van /etc/passwd komt algemene informatie voor over de gebruiker. Deze informatie is niet verplicht, je kunt deze informatie bij het maken van gebruikers dus net zo goed achterwege laten. Homedirectory Elke gebruiker heeft een homedirectory. Dit is de map waarin de gebruiker zijn persoonlijke bestanden mag opslaan. Naast de directory /tmp waarin alle gebruikers schrijfrechten hebben, is dit de enige directory waarin een gebruiker bestanden weg mag schrijven. Shell Als een gebruiker op de console van de server inlogt, wordt er een programma gestart. Dit programma wordt aangeduid als de shell van de gebruiker. Standaard is dit de shell /bin/bash, maar je kunt deze shellaanduiding veranderen door een verwijzing naar elk ander willekeurig programma dat je wilt laten starten nadat een gebruiker zich aanmeldt. Houd er echter rekening mee dat het op een moderne server zelden voorkomt dat
96
Linux 4
een gebruiker daadwerkelijk aanmeldt op die server; het belang van deze instelling is dus niet al te groot in de meeste gevallen. Naast het configuratiebestand /etc/passwd is er /etc/shadow waarin ook een aantal gebruikersinstellingen opgeslagen worden. De belangrijkste van deze instellingen is het wachtwoord dat hier in versleutelde vorm teruggevonden wordt. Daarnaast komen er velden in voor die betrekking hebben op de houdbaarheid van het wachtwoord en de noodzaak dit periodiek te wijzigen. Hieronder vind je een samenvatting van de verschillende velden: Loginnaam van de gebruiker. Versleuteld wachtwoord. Het aantal dagen sinds 1 januari 1970 dat het wachtwoord voor het laatst gewijzigd is. Het aantal dagen dat het nog duurt voordat het wachtwoord aangepast mag worden. Het aantal dagen dat een wachtwoord maximaal gebruikt mag worden. Het aantal dagen voordat het wachtwoord verloopt waarop de gebruiker een melding krijgt dat zijn wachtwoord binnenkort verloopt. Het aantal dagen na verloop van het wachtwoord waarop het gebruikersaccount automatisch uitgezet wordt Een gereserveerd veld dat momenteel niet gebruikt wordt. Elke gebruiker hoort in /etc/shadow een versleuteld wachtwoord te hebben. Afhankelijk van het gebruikte algoritme is dit versleutelde wachtwoord minimaal 13 en maximaal meer dan 20 tekens lang. Je kunt als beheerder het inloggen ook onmogelijk maken door het wachtwoordveld met een ! of een * te laten beginnen (beide tekens hebben hetzelfde effect). 3.2.2 Opdrachten voor gebruikersbeheer Je kunt natuurlijk op basis van de hiervoor genoemde informatie al je gebruikers maken door met behulp van de editor vi de betreffende bestanden te bewerken, maar dit raden wij je niet aan. De kans is niet denkbeeldig dat je door een typefout het inloggen voor alle gebruikers ongewild totaal onmogelijk maakt. Als alternatief bevelen wij je aan voor het beheer van gebruikers gebruik te maken van
3 Gebruikers, groepen en permissies
97
een van de opdrachten die voor dit doel wordt meegeleverd. Hierna vind je een lijst met korte gebruiksaanwijzingen voor het gebruik van deze opdrachten. useradd Dit
is de eenvoudigste wijze om een gebruiker aan te maken. Typ gewoon useradd gevolgd door de gebruikersnaam om de gebruiker in kwestie aan te maken; met de opdracht useradd linda bijvoorbeeld maak je een gebruiker met de naam linda. Even opletten: op SUSE Linux moet je de optie -m gebruiken om ook automatisch een homedirectory voor de betreffende gebruiker te maken. passwd Nadat je een gebruiker gemaakt hebt, wil je waarschijnlijk deze gebruiker ook een wachtwoord geven. Hiervoor gebruik je de opdracht passwd. Ook hiervan is het gebruik niet al te ingewikkeld; om gebruiker linda een wachtwoord te geven, typ je passwd linda en dat is alles. userdel Je raadt het al: met de opdracht userdel verwijder je een gebruiker en al zijn instellingen van de computer. Houd er rekening mee dat userdel weliswaar de gebruiker en een aantal van zijn instellingenbestanden weggooit, maar de homedirectory van de gebruiker wordt niet verwijderd. Dit moet je naderhand nog handmatig doen. usermod Als laatste nuttige opdracht om vanaf de opdrachtregels gebruikers aan te maken, is er usermod. Hiermee pas je instellingen van bestaande gebruikersaccounts aan. Deze opdracht heeft een lange lijst met opties die je kunt bekijken door de opdracht usermod --help te typen. Een handige optie bijvoorbeeld is -e voor expire: hiermee geef je aan na hoeveel dagen een gebruikersaccount moet verlopen. 3.2.3 Grafisch gereedschap voor gebruikersbeheer Zowel op Fedora/Red Hat als op SUSE Linux bestaat ook het nodige grafische gereedschap om gebruikersinstellingen te beheren. Op Fedora/Red Hat bestaat geen uniforme utility waarmee je alles doet. In plaats daarvan is er een aantal afzonderlijke utilities. Voor elk van deze utilities geldt dat de naam van het programma begint met system-config en daar komt dan nog wat achter. Open maar eens een console en typ daar system-config, gevolgd door twee
98
Linux 4
tabs. Je ziet vervolgens welke opdrachten er allemaal met systemconfig gestart kunnen worden. Voor het beheer van gebruikers en groepen gebruik je system-config-users. Je ziet vervolgens de interface uit afbeelding 3.3. Figuur 3.3 Op Fedora/Red Hat gebruik je systemconfig-users als grafisch programma voor gebruikersbeheer
Om met dit programma een gebruiker te maken, voer je de volgende procedure uit: 1. Open een console en typ daar de opdracht system-config-users. 2. Klik op Gebruiker toevoegen. Het venster Nieuwe gebruiker maken wordt nu geopend. 3. Vul voor de nieuwe gebruiker op zijn minst een gebruikersnaam en een wachtwoord in. Alle andere zaken worden automatisch geregeld. 4. Klik op OK. De nieuwe gebruiker wordt nu naar het systeem weggeschreven. Waar Red Hat gebruikmaakt van de system-config utilities, wat in wezen een reeks afzonderlijke programma’s zijn, heeft SUSE het algemene beheersprogramma YaST. Met dit programma kun je werkelijk ongeveer alles regelen op een SUSE-systeem, van het maken van gebruikers tot het configureren van DNS-servers en nog veel meer. Je start YaST met behulp van het pictogram dat voor dit doel op de desktop van de computer geplaatst is. Als je dit als gebruiker doet die geen rootpermissies heeft, zul je wel eerst het wachtwoord van de gebruiker root moeten invoeren, anders biedt het programma zeer beperkte mogelijkheden. Nadat YaST gestart is, voer je de volgende procedure uit om een gebruiker te maken.
3 Gebruikers, groepen en permissies
99
1. Klik op Beveiliging en Gebruikers en selecteer de optie Gebruikersbeheer. Dit opent het venster dat je in afbeelding 3.4 ziet. Figuur 3.4 Ook SUSE’s YaST biedt een intuïtieve interface voor het maken van gebruikers
2. Om een nieuwe gebruiker te maken klik je op Toevoegen. 3. Je ziet een venster waarin je de nieuwe gebruiker maakt. Dit venster bestaat uit drie tabbladen. In principe is het voldoende op het tabblad Gebruikersdata de volledige naam, de gebruikersnaam en het wachtwoord van de gebruiker in te vullen. Meer gedetailleerde instellingen vind je op de tabbladen Details en Wachtwoord instellingen. Het betreft hier geavanceerde instellingen; gebruik deze alleen als je zeker weet dat je ze ook inderdaad nodig hebt. Figuur 3.5 Op SUSE Linux zijn de instellingen voor het maken van gebruikers verdeeld over drie tabbladen
100
Linux 4
4. Klik tot slot op Accepteren om de nieuwe gebruiker te maken. 3.2.4 Standaardinstellingen voor gebruikers Bij het maken van gebruikers zijn er waarschijnlijk standaardinstellingen die je wilt gebruiken voor alle gebruikers. Op de meeste Linux-systemen zijn er drie configuratiebestanden waarop je de standaardinstellingen voor gebruikers regelt: /etc/skel /etc/login.defs /etc/default/useradd Om te beginnen is er de directory /etc/skel. Hierin staan alle bestanden die naar de homedirectory van de gebruiker gekopieerd worden als je met useradd of een van de grafische utilties een gebruiker maakt. Als je deze directory opent, zie je dat er vooral veel configuratiebestanden standaard in voorkomen. Wil je een bepaald bestand niet automatisch in de homedirectory van de gebruiker maken of juist wel? Zorg er dan als root voor dat /etc/skel aangepast wordt. Je zult bij het maken van nieuwe gebruikers zien dat de wijzigingen automatisch toegepast worden. Als tweede is er het configuratiebestand /etc/login.defs. Hieronder zie je een voorbeeld van een aantal regels uit dit bestand: # *REQUIRED* #
Directory where mailboxes reside, _ or _ name of file, relative
to the #
home directory.
If you _ do _ define both, MAIL _ DIR takes
precedence. #
QMAIL _ DIR is for Qmail
# #QMAIL _ DIR
Maildir
MAIL _ DIR
/var/spool/mail
#MAIL _ FILE
.mail
# Password aging controls: # #
PASS _ MAX _ DAYS
Maximum number of days a password may
be used. #
PASS _ MIN _ DAYS
Minimum number of days allowed between
3 Gebruikers, groepen en permissies
101
password changes. #
PASS _ MIN _ LEN
Minimum acceptable password length.
#
PASS _ WARN _ AGE
Number of days warning given before a
password expires. # PASS _ MAX _ DAYS
99999
PASS _ MIN _ DAYS
0
PASS _ MIN _ LEN
5
PASS _ WARN _ AGE
7
Zoals je ziet, vind je in dit bestand een behoorlijk aantal standaardinstellingen die door utilties als useradd uitgelezen worden op het moment dat een gebruiker gemaakt wordt. Zo vind je in dit voorbeeld de regels die betrekking hebben op de houdbaarheid van het wachtwoord en wordt ook aangegeven waar de maildirectory standaard wordt gemaakt. Bekijk dit bestand eens, je zult zien dat er veel meer nuttige parameters in voorkomen. Als laatste vind je het bestand /etc/default/useradd. Ook hierin bevinden zich standaardwaarden die in dit geval uitgelezen worden door de opdracht useradd op het moment dat je een gebruiker maakt. Hieronder vind je een voor zich sprekend voorbeeld dat afkomstig is uit Fedora Linux. [root@IDA default]# cat useradd # useradd defaults file GROUP=100 HOME=/home INACTIVE=-1 EXPIRE= SHELL=/bin/bash SKEL=/etc/skel
Een voorbeeld is de optie INACTIVE=-1 die standaard toegepast wordt. Deze optie zorgt ervoor dat inloggen onmogelijk is, tot op het moment dat voor de betreffende gebruiker een wachtwoord is ingesteld. Vind je dat niet nodig? Geef deze parameter dan de waarde 0 om ervoor te zorgen dat de volgende keer een nieuwe gebruiker direct kan inloggen, ook al heeft hij nog geen wachtwoord.
102
Linux 4
3.3
Beheer van de groepsomgeving
Op een Linux-systeem is elke gebruiker lid van op zijn minst één groep. Dit is de zogenoemde primaire groep. Lidmaatschap van de primaire groep wordt geregeld via het gebruikersconfiguratiebestand /etc/passwd waarover je eerder in dit hoofdstuk hebt gelezen. In dit bestand neem je het groepsidentificatienummer op van de groep die je als primaire groep wilt gebruiken. Algemeen gesproken zijn er twee manieren waarop Linux-distributies omgaan met groepslidmaatschap. Er is de strategie waarbij een groep gemaakt wordt met de naam users waarvan elke gebruiker automatisch lid wordt. Deze methode wordt op SUSE Linux gebruikt. Een andere optie is de strategie die standaard op Red Hat gebruikt wordt: elke gebruiker krijgt als primaire groep een groep met dezelfde naam als die gebruiker waarvan ook alleen de betreffende gebruiker lid is. Voor beide manieren om het groepslidmaatschap af te handelen valt iets te zeggen. Het voordeel van de eerste methode is dat het zo eenvoudig gemaakt wordt voor gebruikers om met elkaar samen te werken. Elke gebruiker heeft dan namelijk automatisch rechten om de bestanden van elke andere gebruiker te lezen! Dat lijk misschien handig, maar het heeft ook een nadeel. Misschien willen de gebruikers namelijk hun bestanden wel voor zichzelf houden, zonder dat iedereen standaard leesrechten heeft. Dit wordt bewerkstelligd door de manier waarop Red Hat omgaat met groepslidmaatschap. Onze voorkeur gaat uit naar de laatste optie; je kunt immers niet voorzichtig genoeg zijn als het om beveiliging van een server gaat. /etc/group Net als gebruikers worden ook groepen opgeslagen in een ASCIItekstbestand. De naam van dit tekstbestand is /etc/group. Op sommige distributies wordt dit bestand aangevuld door een bestand /etc/gshadow waarin versleutelde groepswachtwoorden opgeslagen kunnen worden. Het werken met groepswachtwoorden is echter in onbruik geraakt en daarom zul je zien dat op veel moderne distributies ook helemaal geen /etc/gshadow meer bestaat. De opbouw van /etc/group is vrij eenvoudig: er komen slechts vier velden in voor.
3 Gebruikers, groepen en permissies
103
Naam van de groep. Groepswachtwoord. Groepsidentificatienummer. Leden van de groep. 3.3.1 Regelen van groepslidmaatschap Om een Linux-server goed te kunnen beheren moet je weten hoe groepslidmaatschap geregeld wordt. Zoals gezegd, groepslidmaatschap wordt standaard geregeld in het configuratiebestand /etc/ passwd waar iedere gebruiker een primaire groep krijgt toegewezen. Voor een moderne server is dit echter niet voldoende en is het vaak wenselijk dat gebruikers lid zijn van meer groepen. Dit regel je met het vierde veld van /etc/group. Alle gebruikers die lid zijn van een bepaalde groep waarvoor tevens geldt dat het niet hun primaire groep is, moeten opgenomen worden in dit vierde veld van /etc/group. Als dat gebeurd is, kunnen deze gebruikers ook automatisch profiteren van het lidmaatschap van de betreffende groep. 3.3.2 Ownership Ownership hangt nauw samen met groepslidmaatschap. Dit begrip is bijzonder belangrijk om te kunnen bepalen wie er permissies heeft op bepaalde bestanden. Elk bestand en elke directory op een Linux-systeem hebben namelijk owners. Er is altijd een gebruiker die owner is (user), de groep die owner is (group) en dan is er nog de rest van de wereld. Kenmerkend is dat er standaard maar één user-owner is en maar één group-owner. Op basis van ownership krijgen gebruikers uiteindelijk hun permissies. Het besturingssysteem bepaalt elke keer dat een gebruiker een bestand wil benaderen als eerste of de gebruiker eigenaar is van het bestand. Is dat zo? Dan worden de permissies van die gebruiker toegepast en wordt niet verder gekeken. Is de gebruiker niet owner? Dan wordt gekeken of de betreffende gebruiker lid is van de groep die eigenaar is, worden de groepspermissies toegepast en kijkt het besturingssysteem niet verder. Is dit ook niet het geval? Dan krijgt de gebruiker in kwestie automatisch de permissies die aan ‘others’ gegeven zijn. Als je de opdracht ls -l geeft, zie je per bestand en directory wie de huidige owners zijn en welke permissies voor deze owners zijn ingesteld.
104
Linux 4
Match on Exit Op het toepassen van Linux-permissies is het zogenoemde principe Match on Exit van toepassing. Dit betekent dat zodra het besturingssysteem voor een gebruiker permissies vindt die van toepassing zijn, deze permissies toegepast worden en het besturingssysteem dus niet verder kijkt. Als een gebruiker die owner is dus totaal geen permissies heeft, maar ook lid is van een groep die owner is en wel permissies heeft, worden de groepspermissies niet toegepast!
Listing 3.1 De uitvoer van de opdracht ls -l toont de owners voor de betreffende bestanden en directory’s
SFO:/etc # ls -l total 3700 -rw-------
1 root
root
-rw-r--r--
1 root
root
-rw-r--r--
1 root
root
-rw-r--r--
1 root
root
drwxr-xr-x
3 root
root
-rw-r--r--
1 root
root
38 Apr 23
drwxr-xr-x
2 root
root
4096 Apr 23
drwxr-xr-x 16 root
root
4096 Jul
drwxr-xr-x
root
4096 Jun 27 20:14 YaST2
2 root
0 Jun 27 19:35 .pwd.lock 2792 Mar
1
2006 DIR _ COLORS
22 Dec 11 08:11 HOSTNAME 103606 May 4096 May
2 3
2006 Muttrc 2006 NetworkManager 2006 SuSE-release 2006 SuSEconfig
8 13:20 X11
Het geval nu met ownership is dat zodra een gebruiker een bestand maakt, worden altijd de gebruiker zelf en diens primaire groep ingesteld als owners van het betreffende bestand. Dit heeft vervelende gevolgen. Stel je voor dat gebruiker linda naast de primaire groep linda lid is van een additionele groep met de naam verkoop. Op het moment dat linda in de directory /home/verkoop een bestand maakt, wordt niet de groep verkoop owner van dat bestand, maar wordt de groep linda group-owner van het bestand, want dat is haar primaire groep is. Je begrijpt, dit is niet echt handig, maar gelukkig is er wel een aantal oplossingen voorhanden: De ownership achteraf wijzigen. Er zijn twee opdrachten waarmee je achteraf een andere owner kunt instellen. Als root kan dit voor alle bestanden, als gewone gebruiker doe je dit alleen op bestanden waarvan je zelf al owner bent. De opdrachten zijn chown en chgrp. Het gebruik van deze opdrachten is vrij eenvoudig: chown <user> < bestand> en chgrp . Om ervoor te zorgen dat gebruiker linda eigenaar wordt van het bestand bubbels, typ je dus de opdracht chown linda bubbels. Wil je ervoor zorgen dat
3 Gebruikers, groepen en permissies
105
de groep verkoop owner wordt van het bestand rapport, dan gebruik je de opdracht chgrp verkoop rapport. Je zult begrijpen dat hoewel deze methode wel werkt, het toch niet een ideale oplossing is om permanent toe te passen. Je zou immers voortdurend voor zojuist gemaakte bestanden eerst als root actie moeten ondernemen voordat het bestand op de juiste wijze staat ingesteld. Werken met ACL's. Moderne Linux-bestandssystemen maken het mogelijk te werken met Access Control Lists (ACL's). Hiermee kun je meerdere gebruikers en groepen permissies geven op bestanden of directory’s. Ervoor zorgen dat de primaire groep handmatig op de juiste groep ingesteld wordt voordat de betreffende bestanden gemaakt worden in een bepaalde directory. Dit houdt in dat de gebruiker zelf voordat hij bestanden maakt, aangeeft welke groep op dat moment ingesteld staat als zijn primaire groep. Hiervoor wordt de opdracht newgrp gebruikt. Als dus linda met haar primary group linda bestanden wil maken waarvan de groep verkoop eigenaar moet worden, geeft linda eerst de opdracht newgrp verkoop. Op het moment dat ze klaar is, gebruikt ze dan vervolgens de opdracht exit om terug te gaan naar de oude instelling waar linda haar primaire groep weer is. Je zult begrijpen dat deze oplossing niet echt werkbaar is voor de meeste gebruikers. Ervoor zorgen dat automatisch de juiste owner ingesteld wordt: zoals je later in dit hoofdstuk leest, kun je er met behulp van de permissie Set Group ID voor zorgen dat alle bestanden die in een bepaalde directory gemaakt worden automatisch een standaardgroep ingesteld krijgen. 3.3.3 Opdrachten voor groepsbeheer Ook voor het beheer van groepen kan gebruikgemaakt worden van een aantal opdrachten en grafische utilities. We bespreken hier de grafische utilities niet, omdat deze in grote mate gelijk zijn aan het gereedschap voor het beheer van gebruikers. Wel geven we hier een overzicht van de belangrijkste opdrachten en hun gebruik. groupadd groupadd inkoop
Gebruik deze opdracht om groepen toe te voegen. Gebruik bijvoorbeeld Om een groep met de naam inkoop te maken.
106
Linux 4
groupdel
Met behulp van deze opdracht verwijder je groepen. Het gebruik spreekt voor zich: met groupdel inkoop verwijder je de groep inkoop weer van het systeem. groupmod Deze opdracht wordt ingezet om de eigenschappen van groepen aan te passen. Erg handig is de optie -A waarmee je gebruikers aan een groep toevoegt. Gebruik bijvoorbeeld groupmod -A linda,anja,sanne verkoop om de drie genoemde gebruikers lid te maken van de groep verkoop. groups De opdracht groups is handig om te kijken van welke groepen een gebruiker lid is. Als beheerder typ je bijvoorbeeld groups erno om te kijken van welke groepen gebruiker erno lid is. Ook kan een gebruiker zelf de opdracht groups bekijken om een overzicht op te vragen van zijn huidige groepslidmaatschappen. 3.4
Beheer van permissies
In het voorgaande heb je kennisgemaakt met de entiteiten die op een Linux-systeem gebruikt worden voor het toewijzen van permissies: gebruikers en groepen. Je hebt geleerd dat ownership een fundamenteel concept is. Elk bestand heeft een user die owner is, een groep die owner is en dan is er nog de rest van de wereld. Aan elk van deze drie entiteiten worden altijd permissies toegekend. Je kunt dit zien als je in een willekeurige directory de opdracht ls -l gebruikt om te kijken welke permissies staan ingesteld: drwxr-xr-x
3 root
root
-rw-r--r--
1 root
root
4096 Jun 29 09:12 zmd 157 Apr 23
-rw-r--r--
1 root
root
6825 Apr 23
2006 zshenv 2006 zshrc
In de uitvoer van deze opdracht zie je op de eerste positie welk type bestand het betreft. Vervolgens komen drie posities waarmee de permissies van de gebruiker aangegeven worden. Daarna volgen drie posities voor de permissies van de groep en tot slot zijn er drie posities voor de permissies van others. De betekenis van deze permissies wordt in de volgende paragraaf uitgelegd.
3 Gebruikers, groepen en permissies
107
3.4.1 Drie basispermissies Op elke UNIX-versie, dus ook op elke Linux-versie, wordt gebruikgemaakt van drie basispermissies. In de onderstaande tabel vind je een overzicht van deze permissies en hun betekenis indien toegepast op bestanden of op directory’s:
read
write
Toegepast op bestanden
Toegepast op directory’s
Inlezen van de inhoud van een bestand
Opvragen van een lijst van de
in het werkgeheugen van de computer.
namen van bestanden die in
Wijzigen van de inhoud van een be-
de directory voorkomen. Wijzigen van de inhoud van
staand bestand.
een directory. Concreet betekent dit het maken en verwijderen van bestanden
execute
Uitvoeren van het bestand als het
en directory’s. Het activeren van de betref-
bestand uitvoerbare code bevat.
fende directory met behulp van de opdracht cd.
Zoals je ziet, zijn permissies op Linux redelijk rechttoe rechtaan. Onthoud bij het werken met permissies vooral dat het eerste wat geldt de ownership is. Om te bepalen welke permissies je hebt, kijkt het besturingssysteem eerst of je owner bent van het bestand of de directory. Vervolgens wordt gekeken of je lid bent van de groep die owner is en als ook dat niet het geval is, krijg je automatisch de permissies die zijn toegekend aan others. Er is niet zoiets als overerven van rechten. Dit betekent dat het niets wil zeggen als een bestand voorkomt in een directory waarop je zowel read- als write-rechten hebt. Het enige wat bepalend is voor de permissies, is of je via ownership op het betreffende bestand zelf rechten hebt gekregen. Dit heeft een aantal implicaties. We geven een overzicht van enkele belangrijke uitgangspunten: Permissies zijn niet cumulatief. Dit betekent dat als je owner bent van een bestand en ook lid bent van de groep die owner is, de permissies niet bij elkaar opgeteld worden. De eerste permissies die van toepassing zijn, worden gebruikt en dat is alles. Als je owner bent van een bestand of directory, is alleen dat bepalend voor de permissies. Dit betekent dat als je als owner totaal
108
Linux 4
geen permissies hebt op een bestand, terwijl je als lid van de groep wel permissies hebt, je dus uiteindelijk gewoon geen permissies hebt. Om een bestand weg te kunnen gooien heb je geen write-rechten op het bestand nodig. Weggooien van bestanden is iets wat writerechten op de directory vereist en niet op het bestand zelf. Om permissies te kunnen wijzigen moet je owner zijn van het item waarop je de permissies wilt wijzigen. 3.4.2 Drie geavanceerde permissies Naast de drie permissies die in het voorgaande besproken zijn, zijn er ook drie geavanceerde permissies. Dit zijn permissies die alleen in speciale gevallen gebruikt worden. In de volgende tabel vind je een overzicht: Toegepast op bestanden
Toegepast op directory’s
Set User
Indien het een uitvoerbaar bestand
Niet van toepassing.
ID (SUID)
is, wordt het bestand uitgevoerd met de permissies van de owner van het bestand, niet met de permissies van
Set
de gebruiker die het bestand uitvoert. Indien het een uitvoerbaar bestand is,
Bestanden die gemaakt wor-
Group ID
wordt het bestand uitgevoerd met de
den in de betreffende direc-
(SGID)
permissies van de groepsowner van
tory en subdirectory’s daar-
het bestand en niet met de permis-
onder, krijgen automatisch
sies van de gebruiker die het bestand
dezelfde groepsowner als de
uitvoert.
directory zelf. Zo voorkom je dus dat bestanden altijd als groep de primaire groep krijgen van de gebruiker die
Sticky bit
Niet van toepassing.
het bestand maakt. Indien toegepast op een directory mag een gebruiker een bestand alleen verwijderen als hij owner is van het bestand zelf of de directory waarin het bestand voorkomt.
De geavanceerde permissies behoeven wel enige toelichting.
3 Gebruikers, groepen en permissies
109
Om te beginnen is er de permissie SUID. Deze permissie is noodzakelijk voor sommige utilities om hun werk te kunnen doen. Zonder SUID is het bijvoorbeeld voor een gebruiker onmogelijk zijn wachtwoord te wijzigen. Het gewijzigde wachtwoord moet namelijk geschreven worden in /etc/shadow en daarop heeft een gebruiker niet eens leesrechten, laat staan schrijfrechten. Omdat de opdracht passwd de permissie SUID heeft en root als owner heeft, kan deze opdracht zijn taken met rootpermissies uitvoeren. Dit maakt het mogelijk wijzigingen rechtstreeks weg te schrijven in /etc/shadow. Er is echter ook een risico verbonden aan het gebruik van deze permissie. Indien verkeerd toegepast, is het namelijk een gigantisch risico voor de beveiliging van de server. Als de betreffende opdracht een mogelijkheid biedt om vanuit de opdrachtomgeving naar een shell te gaan en de opdracht in kwestie heeft root als owner, zou de gebruiker die de betreffende opdracht uitvoert automatisch ook root worden. Om die reden moet je zeer terughoudend zijn met het gebruik van deze permissie. Het is zelfs aan te raden om periodiek een scan te doen van het hele systeem om te kijken of er bestanden zijn die deze permissie wel hebben en waarvan je het niet verwacht had. Je vindt alle bestanden met de permissie SUID met de opdracht find / -perm +4000. De permissie SGID is net als de permissie sticky bit handig voor directory’s waarin bestanden voorkomen die door leden van een groep gedeeld worden. Als je ervoor zorgt dat de betreffende groep (bijvoorbeeld de groep verkoop) eigenaar is van de betreffende directory (bijvoorbeeld /home/groups/verkoop), krijgen alle nieuwe bestanden in deze directory dezelfde groep als groepsowner. Zeker als het umask ook goed is ingesteld, zodat de groep automatisch write-rechten krijgt, is dit erg handig. Alle leden van de betreffende groep hebben dan namelijk voldoende permissies op deze directory. Naast SGID is ook het sticky bit zeer aan te bevelen op directory’s waarin meerdere gebruikers bestanden maken. Sticky bit zorgt er namelijk voor dat een gebruiker alleen zijn eigen bestanden kan weggooien. Strikt gesproken, kan de gebruiker uit een directory waarop sticky bit is ingesteld een bestand alleen weggooien als aan een van de volgende voorwaarden voldaan is:
110
Linux 4
De gebruiker is owner van het bestand. De gebruiker is lid van de groep die owner is van het bestand. Deze permissie zorgt er onder andere voor dat gebruikers elkaars bestanden niet per ongeluk kunnen verwijderen uit de directory /tmp. 3.4.3 Permissies instellen met chmod Er zijn verschillende manieren om permissies in te stellen. Je kunt het grafische gereedschap gebruiken en daarnaast kun je werken met chmod. Je leest hier hoe je permissies instelt met chmod en op basis van deze informatie zul je er zelf in slagen permissies in te stellen met andere hulpmiddelen. Er zijn twee manieren om permissies in te stellen met chmod. De eerste manier is de zogenoemde relatieve modus. Hierin krijgt chmod als eerste argument een entiteit, als tweede argument een operator en als derde argument de permissies. De volgende opdracht geeft aan hoe je dit kunt gebruiken: chmod u+rx,g=r,o-x bestand
Als je chmod in relatieve modus wilt gebruiken, beschik je over de volgende entiteiten: u g o
user groep others
Daarnaast kun je de volgende operatoren gebruiken: + - =
Voeg toe aan de huidige permissies. Trek af van de permissies die op dit moment zijn toegepast. Stel deze permissies in, ongeacht de permissies die op dat moment al ingesteld zijn.
Tot slot zijn er de permissies: r w
read write
3 Gebruikers, groepen en permissies
x s t
111
execute SUID of SGID sticky bit
Zoals je ziet, kan bij de toe te passen permissies de s twee verschillende betekenissen hebben. Als de s wordt toegepast op de plaats van de user (bijvoorbeeld chmod u+s bestand), gaat het om de permissie SUID. Wordt de s toegepast op de plaats van de groepspermissies (bijvoorbeeld chmod g+s bestand), dan gaat het om de permissie SGID. Zoals je ziet, kan het werken met permissies in relatieve modus onduidelijk zijn. Daarom kiezen de meeste beheerders ervoor permissies toe te kennen in absolute modus. Hierbij wordt als tweede argument een getal gebruikt. Dit getal kan uit maximaal vier posities bestaan. Hierbij verwijst de eerste positie naar de speciale permissies, de tweede positie naar de permissies van de user, de derde positie naar de permissies van de groep en de laatste positie naar de permissies van others. Vervolgens heeft elke permissie een waarde: read write execute SUID SGID sticky
4 2 1 4 2 1
Op basis van deze gegevens zou de volgende opdracht weinig problemen mogen opleveren: chmod 4750 bestand
Zoals je ziet, wordt in deze opdracht gebruikgemaakt van een getal dat uit vier cijfers bestaat. Het eerste getal is het cijfer 4 en verwijst dus naar de speciale permissie SUID. Het tweede getal is het cijfer 7 en hiermee wordt verwezen naar de permissies voor de user. In dit geval worden r, w en x uitgedeeld; 7 is immers gelijk aan de som van 4, 2 en 1. Als derde getal krijgen we voor de groepspermissies een 5, dat weer gelijk is aan 4 + 1 en tot slot krijgen others geen permissies toegekend. Het is overigens in absolute modus ook
112
Linux 4
mogelijk te werken met een getal dat uit drie cijfers bestaat. In dat geval worden er gewoon geen speciale permissies uitgedeeld. 3.4.4 Umask Naast de opdracht chmod die gebruikt wordt om permissies uit te delen, heb je op een Linux-systeem ook te maken met standaardpermissies. Deze permissies worden ingesteld via het umask. Dit is een instelling die voor elke gebruiker geladen wordt tijdens het inloggen. Voor dit doel wordt het instellingenbestand /etc/profile gebruikt. Standaard is umask ingesteld op 022 en dit zorgt ervoor dat op nieuw aan te maken bestanden de permissies ingesteld worden op 644. Op nieuw aan te maken directory’s daarentegen zorgt dit umask ervoor dat 755 de standaardpermissies zijn. In het umask zijn er maar drie waarden die ook echt gebruikt worden: Waarde in
Standaardpermissies
Standaardpermissies op
umask 0
op bestanden rw
directory’s rwx
2
r
rx
7
niets
niets
De algemene manier om een umask in te stellen, is via het algemene inlogscript /etc/profile. Het umask is namelijk een shellinstelling die elke keer bij het aanmelden geladen moet worden. Neem bijvoorbeeld de regel umask 027 op om ervoor te zorgen dat others in het vervolg op geen enkel bestand nog standaardpermissies krijgt. Als je een uitzondering wilt maken voor een enkele gebruiker, is het aan te raden in de homedirectory van die gebruiker een bestand met de naam .profile te maken. In dit bestand neem je vervolgens de umask-regel op. Deze instelling zal dan alleen voor die gebruiker toegepast worden. 3.4.5 Access Control Lists Het systeem van permissies zoals dat tot nu toe beschreven is, is ontworpen in de jaren zeventig van de vorige eeuw en kent nogal wat beperkingen. De belangrijkste beperkingen zijn: Er is geen mogelijkheid permissies te geven aan meerdere gebruikers of aan meerdere groepen op één directory of bestand.
3 Gebruikers, groepen en permissies
113
Er is geen mogelijkheid aan één specifieke groep standaardpermissies uit te delen, maar dan alleen in een bepaalde directory. Deze tekortkomingen worden teniet gedaan door te werken met Access Control Lists (ACL’s). Voordat je enthousiast aan het werk gaat met ACL’s, moet je er eerst voor zorgen dat de bestandssystemen op de server ermee overweg kunnen. De meeste moderne Linux-bestandssystemen hebben geen enkele moeite met ACL’s, maar het moet wel eerst ingeschakeld worden. Dit gebeurt in het bestand /etc/fstab. Dit bestand wordt over het algemeen gebruikt om te bepalen hoe bestandssystemen geactiveerd moeten worden tijdens het opstarten van de server. In het volgende voorbeeld zie je hoe dit bestand er standaard uitziet op Fedora Linux: [root@IDA /]# cat /etc/fstab /dev/System/root
/
ext3
defaults
1 1
LABEL=/boot
/boot
ext2
defaults
1 2
devpts
/dev/pts
devpts gid=5,mode=620 0 0
tmpfs
/dev/shm
tmpfs
defaults
0 0
proc
/proc
proc
defaults
0 0
/dev/System/srv
/srv
ext3
defaults
1 2
sysfs
/sys
sysfs
defaults
0 0
/dev/System/usr
/usr
ext3
defaults
1 2
/dev/System/var
/var
ext3
defaults
1 2
/dev/System/LogVol01
swap
swap
defaults
0 0
Gebrekkige ondersteuning Houd er rekening mee dat veel utilities geen ondersteuning bieden voor ACL’s. Zo gaan ze bijvoorbeeld verloren als je bestanden kopieert met cp of archiveert met tar. In het voorgaande voorbeeld zie je dat een aantal bestandssystemen gemount worden, bijvoorbeeld op de directory’s /, /srv en /var. Deze directory’s gebruiken alle het bestandssysteem ext3. Bij de mountopties die je in de op twee na laatste kolom ziet staan, staat voor al deze bestandssystemen defaults als mountoptie aangegeven. Dit moet je veranderen: zorg ervoor dat hier ACL komt te staan, want zonder dat deze optie hier expliciet vermeld is, kun je
114
Linux 4
geen ACL’s gebruiken. Start vervolgens de computer opnieuw op en je kunt aan het werk met ACL’s op elk bestandssysteem waar je aangegeven hebt dat het als optie gebruikt moet worden. 3.4.6 Werken met standaard-ACL’s Nu de bestandssystemen klaar zijn voor het gebruik van ACL’s kun je aan het werk. Om te werken met ACL’s maak je gebruik van twee opdrachten. De opdracht getfacl wordt gebruikt om te kijken of er al ACL’s staan ingesteld en zo ja, welke ACL’s dat dan zijn. Met de opdracht setfacl stel je zelf nieuwe ACL’s in. We maken voor de rest van deze paragraaf gebruik van een voorbeelddirectory /home/verkoop; de homedirectory van de groep verkoop. Als je de eigenschappen van deze directory met de opdracht ls -ld bekijkt, zien ze er als volgt uit: [root@IDA home]# ls -ld verkoop/ drwxrwx--- 2 root verkoop 4096 dec 9 02:10 verkoop/
In dit geval mogen alleen de gebruiker en de groepsowner (verkoop dus) lezen en schrijven in deze directory. Je kunt deze informatie ook tonen door gebruik te maken van de opdracht getfacl: [root@IDA home]# getfacl verkoop/ # file: verkoop # owner: root # group: verkoop user::rwx group::rwx other::---
Zoals je ziet, dezelfde informatie, alleen op een iets andere wijze weergegeven. Dit komt omdat de normale Linux-permissies automatisch ook opgenomen worden in de ACL. Nu gaan we er door middel van ACL’s voor zorgen dat in deze directory alle leden van de groep boekh ook leesrechten hebben. Hiervoor kunnen we niet zonder ACL’s, want standaardpermissies staan het toe om aan maximaal één groep rechten te geven. Voor dit doel gebruiken we de volgende opdracht: setfacl -m group:boekh:r-x verkoop
3 Gebruikers, groepen en permissies
115
In deze opdracht wordt eerst de optie -m (modify) gebruikt om aan te geven dat je iets wilt wijzigen. Vervolgens wordt met de string group:boekh:r-x aangegeven wat er dan gewijzigd moet worden. Tot slot geeft verkoop aan dat de wijzigingen betrekking hebben op de directory verkoop. Het resultaat van de opdracht getfacl wordt nu als volgt: [root@IDA home]# getfacl verkoop # file: verkoop # owner: root # group: verkoop user::rwx group::rwx group:boekh:r-x mask::rwx other::---
Zoals je ziet, zijn er twee items bij gekomen. Als eerste is er de regel group:boekh:r-x die aangeeft dat de groep boekh de permissies read en execute heeft op deze directory. Er zijn nu dus twee groepen die rechten hebben op de directory. Daarnaast is er een ACL-mask ingesteld. Dit is een enigszins onhandige instelling waarvan wij je het gebruik dringend willen afraden. In het mask staan de permissies die maximaal van toepassing kunnen zijn op de betreffende directory. In dit geval de permissies rwx: het maximale dat je op deze directory kunt hebben, zijn dus de permissies r, w en x. Op het moment dat we het mask zouden wijzigen met setfacl -m m::rx verkoop wordt het mask ingesteld op read en execute. Dit betekent dat de permissies van de groep verkoop en de gebruiker root onmiddellijk aangepast worden, iets wat de opdracht getfacl ook duidelijk laat zien. [root@IDA home]# getfacl verkoop # file: verkoop # owner: root # group: verkoop user::rwx group::rwx group:boekh:r-x mask::r-x other::---
#effective:r-x
116
Linux 4
Wij kunnen echter geen goede reden verzinnen waarom je deze feature zou willen gebruiken en raden je daarom aan: gebruik het niet, je maakt de zaak er alleen maar onoverzichtelijker mee. De opdracht getfacl is overigens niet de enige manier waarop je kunt zien dat er ACL’s zijn ingesteld. Ook als je de opdracht ls -l gebruikt, zie je dat er iets aan de hand is: [root@IDA home]# ls -ld verkoop drwxrwx---+ 2 root verkoop 4096 dec
9 02:10 verkoop
Zoals je kunt zien, wordt door een plusteken aan het eind van de lijst met permissies aangegeven dat er iets gaande is. Welke ACL’s gebruikt worden, kan echter door de opdracht ls niet bepaald worden. 3.4.7 Een standaard-ACL toepassen In het voorgaande heb je geleerd te werken met een standaardACL. Dit is handig, het kan echter nog handiger. Door gebruik te maken van een standaard-ACL bepaal je namelijk dat op nieuw te maken bestanden en subdirectory’s in een bepaalde directory automatisch een ACL gemaakt wordt. Dit is een ideale manier om ervoor te zorgen dat niet alleen een bepaalde groep automatisch owner wordt, maar dat er bovendien ook specifieke permissies voor de betreffende groep toegepast worden. Deze permissies worden opgenomen in een ACL. Om duidelijk te maken hoe standaard-ACL’s precies werken, bekijken we weer een voorbeeld. We willen ervoor zorgen dat in de groep /home/verkoop zowel de groep verkoop als de groep boekh automatisch permissies krijgen. Verkoop krijgt rwx, inkoop krijgt r-x. Je regelt dit met behulp van de volgende opdracht: setfacl -d -m group:verkoop:rwx,group:boekh:r-x verkoop
In deze opdracht zie je twee nieuwe dingen. Om te beginnen wordt de optie -d gebruikt om aan te geven dat het een standaard-ACL betreft. Daarnaast zie je dat nu een komma gebruikt wordt om een ACL in te stellen voor twee verschillende groepen in één opdracht. Het resultaat wordt weer zichtbaar met getfacl:
3 Gebruikers, groepen en permissies
117
[root@IDA home]# getfacl verkoop # file: verkoop # owner: root # group: verkoop user::rwx group::rwx group:boekh:r-x mask::rwx other::--default:user::rwx default:group::rwx default:group:verkoop:rwx default:group:boekh:r-x default:mask::rwx default:other::---
Vanaf dit moment zullen zowel de groepen verkoop als boekh in de ACL toegevoegd worden als rechthebbenden. Let er overigens op dat je hiermee niet bereikt dat de groep verkoop ook automatisch owner wordt van alle subdirectory’s onder de directory /home/verkoop. Om dit voor elkaar te krijgen heb je toch echt de permissie SGID nodig waarover je eerder in dit hoofdstuk gelezen hebt. 3.4.8 Beperkingen van ACL’s Klinken ACL’s te mooi om waar te zijn? Dat zijn ze ook. Zolang bestanden en directory’s waarop ACL’s zijn toegepast gewoon op hun plaats blijven staan, is er niets aan de hand. Dit betekent dat zeker standaard-ACL’s hun nut hebben. Heel veel opdrachten echter kunnen niet met ACL’s overweg. Dit betekent dat je ze niet met een algemene back-upopdracht als tar kunt backuppen en dat de ACL’s zelfs al verloren gaan als je ze kopieert met de verkeerde utility. Ook kunnen ze spontaan verdwijnen bij iets eenvoudigs als het bewerken van een bestand met een editor. Wij raden je daarom aan eerst uitvoerig te testen met ACL’s voordat je de complete infrastructuur op basis van ACL’s gaat inrichten.
118
Linux 4
3.5
Werken met sudo
Tot nu toe hebben we het in dit hoofdstuk gehad over permissies. Naast permissies is er echter nog een ander systeem werkzaam op de Linux-server dat bepaalt wat je wel en wat je niet mag: het systeem van de POSIX-capabilities. De capabilities definiëren beheertaken die buiten de permissies vallen. Er zijn er 32 in totaal en root heeft alle capabilities. Wil je een gebruiker ook laten beschikken over alle capabilities? Dan geef je de gebruiker de UID 0, zodat hij als root taken kan uitvoeren. Veel handiger echter is het om een gebruiker door middel van sudo het recht te geven bepaalde taken als root uit te voeren. Tot besluit van dit hoofdstuk leer je hoe je dit met sudo kunt doen. De basis van een sudo-configuratie is het configuratiebestand /etc/sudoers. Dit configuratiebestand bewerk je met de opdracht visudo, een versie van de roemrijke editor vi die speciaal ontworpen is voor het werken met sudo. Als je de opdracht visudo typt, wordt /etc/sudoers automatisch geopend. In dit bestand geef je vervolgens aan welke gebruiker vanaf welke computer welke taak met rootpermissies mag uitvoeren. Om te beginnen tonen we een eenvoudig voorbeeld waarmee je regelt dat gebruiker linda met rootpermissies de opdracht ifconfig mag uitvoeren: linda
ALL=/sbin/ifconfig
Zoals je ziet, hoeft een sudo-configuratie helemaal niet moeilijk te zijn. Bovenstaande regel uit het configuratiebestand /etc/sudoers bepaalt dat gebruiker linda vanaf alle computers (ALL) de opdracht /sbin/ifconfig uit mag voeren. Om dit ook daadwerkelijk te doen moet linda vervolgens de volgende opdracht typen: sudo /sbin/ifconfig
Vergeet niet alle sudo-opdrachten ook daadwerkelijk met sudo te laten beginnen, anders heeft de shell niet door dat je van andere dan de normale permissies gebruik wilt maken. Afhankelijk van de wijze waarop de distributie standaard geconfigureerd is, moet je nu ofwel het wachtwoord van de gebruiker root, ofwel het wachtwoord van de gebruiker invoeren. Het tweede geval is natuurlijk wat de bedoeling is. Als gevraagd wordt om het wachtwoord van
3 Gebruikers, groepen en permissies
119
de gebruiker root, is dat niet bijzonder handig. De betreffende gebruiker zou in dat geval immers net zo goed al zijn werk als root kunnen doen! Als gevraagd wordt om het wachtwoord van de gebruiker root, moet je de volgende regels in /etc/sudoers opzoeken: Defaults targetpw ALL ALL=(ALL) ALL
Zet vervolgens een commentaarteken (#) voor deze twee regels en in het vervolg hoef je bij het werken met sudo alleen je eigen wachtwoord in te voeren. In het voorgaande heb je een eenvoudig voorbeeld van een sudoconfiguratie gezien. Het kan ook complexer. Bekijk bijvoorbeeld het volgende voorbeeldbestand: User _ Alias
BEHEER
User _ Alias
WEBMASTER = %apache
Cmnd _ Alias
= alex, franck
APACHE = /etc/init.d/apache, /sbin/yast2
apache2 Cmdn _ Alias Cmdn _ Alias BEHEER
UIT = /sbin/shutdown DAGELIJKS = /usr/sbin/passwd, /usr/sbin/fsck
ALL = UIT, DAGELIJKS
WEBMASTER ALL = APACHE
In dit voorbeeld worden eerst aliassen gedefinieerd. Om te beginnen zijn er twee useraliassen. Hiermee worden twee groepen gebruikers gemaakt. In de eerste alias wordt rechtstreeks verwezen naar de namen van twee gebruikers, terwijl in de tweede alias verwezen wordt naar de leden van de groep apache die op het lokale systeem bestaat. Kijk in het bijzonder even naar de opdracht /sbin/yast2 apache. Door in deze opdracht ook het argument apache op te nemen betreft het hier alleen het uitvoeren van de opdracht yast2 met het argument apache. Alle andere argumenten bij deze opdracht zijn dus verboden! Vervolgens zijn er drie opdrachtaliassen waarmee groepen van opdrachten gedefinieerd worden. Tot slot wordt in de laatste twee regels aangegeven welke gebruikers wat precies kunnen doen met rootpermissies; leden van de groep BEHEER kunnen vanaf alle computers de opdrachten
120
Linux 4
uitvoeren die gedefinieerd zijn in UIT en DAGELIJKS en leden van de groep WEBMASTER mogen de opdrachten uitvoeren uit de alias APACHE. 3.6
Samenvatting
In dit hoofdstuk heb je geleerd wat erbij komt kijken om het Linux-systeem te beveiligen. Als eerste hebben we gesproken over gebruikers en groepen. Daarna heb je geleerd hoe permissies gebruikt worden in een Linux-omgeving. Daarbij is ruim de aandacht gegeven aan het werken met uitgebreide permissies in Access Control Lists. Tot slot heb je gelezen over de wijze waarop je taken voor de gebruiker root delegeert naar gewone gebruikers door gebruik te maken van het sudo-mechanisme.
4
Beheer van processen
4.1
Inleiding
Alles wat op een Linux-systeem gebeurt, gebeurt in de vorm van een proces. Een proces is een taak die door het besturingssysteem opgestart wordt en vervolgens processorcapaciteit claimt. Omdat processen een aanslag doen op de resources die in een server aanwezig zijn, is het belangrijk door middel van procesbeheer ervoor te zorgen dat deze resources steeds op de meest optimale wijze gebruikt worden. In dit hoofdstuk bespreken we de eigenschappen van processen. We zullen antwoord geven op vragen als ‘Waar komt een proces vandaan”, hoe kunnen we ervoor zorgen dat een proces volledig automatisch op gezette tijden gestart wordt en vooral ook wat je moet doen als het een keer niet helemaal goed gaat met een proces en je het eigenlijk af moet breken. 4.2
Soorten processen
Er kunnen op een Linux-systeem heel globaal gesproken twee soorten processen actief zijn. Er zijn processen die tijdens het opstarten van de computer geactiveerd worden. Dergelijke processen zijn erg belangrijk, ze zorgen er namelijk voor dat bepaalde soorten functionaliteit op de computer aanwezig zijn. Denk daarbij aan alle services die door de server worden aangeboden en die automatisch gestart worden vanuit de runleveldirectory /etc/init.d. Deze processen die automatisch tijdens het starten van de computer geactiveerd worden, noemen we daemons.
122
Linux 4
Het tweede soort proces dat op een systeem voorkomt, zijn de interactieve processen. Dit zijn alle processen die door gebruikers gestart worden als ze een opdracht intypen. Elke opdracht die je invoert, veroorzaakt een proces. Dit is namelijk de enige manier dat het proces systeembronnen aan de kernel kan vragen. Opdrachten die door een gebruiker worden ingevoerd, worden vanuit de shell van de gebruiker uitgevoerd. De opdracht wordt daarom een child-proces van de shell. Dit is ook zichtbaar te maken met de opdracht pstree. Figuur 4.1 De opdracht pstree toont uit welk proces een proces voortkomt
Wat alle processen met elkaar gemeen hebben, is dat ze allemaal beschikken over een process-ID (PID). Dit is een identificatienummer waarmee het proces bij de kernel bekend is. Dit nummer is erg belangrijk. Je hebt het namelijk nodig als je beheer op het proces wilt uitvoeren, zoals het uitschakelen van het proces. Deze
4 Beheer van processen
123
identificatienummers worden opeenvolgend genummerd. Je kunt dus aan de nummering van het proces zien wanneer het gestart is. Tevens zul je zien dat het proces met PID 1 altijd hetzelfde is, dit is namelijk het proces init dat automatisch door de kernel gestart wordt. Dit proces kun je gerust de moeder van alle processen noemen. Elk ander proces komt namelijk voort uit init. Je kunt op de opdrachtregel een overzicht vragen van alle actieve processen door de opdracht ps aux te geven. Er zijn veel andere opties die bij ps gebruikt kunnen worden. Elk van deze opties zorgt dat een eigen selectie van proceseigenschappen getoond wordt. Ook gewone gebruikers kunnen een overzicht opvragen van processen die in gebruik zijn. Aangezien een gewone gebruiker veel minder rechten heeft op het systeem, zal dit overzicht echter minder uitgebreid zijn dan wanneer root het opvraagt: gewone gebruikers mogen hun eigen processen opvragen en verder niets. Figuur 4.2 De opdracht ps wordt gebruikt om een totaaloverzicht op te vragen van alle processen die actief zijn
De opdracht ps kan gebruikt worden om zeer uitgebreide informatie over processen te tonen. De meeste processen starten meerdere zogenoemde threads op om hun taken uit te kunnen voeren. Deze worker threads zorgen ervoor dat één proces meerdere taken gelijktijdig voor zijn rekening kan nemen. Een alternatief zou zijn om
124
Linux 4
gewoon het proces zelf meerdere malen te laden, maar dat is minder efficiënt met betrekking tot het gebruik van het werkgeheugen van de computer. Als een proces met meerdere threads werkt, kan het als beheerder ook de moeite zijn een overzicht op te vragen van alle threads die een proces gestart heeft. Hiervoor kan de opdracht ps axms gebruikt worden. De uitvoer van deze opdracht is echter complex en vraagt veel kennis van de werking van de processen die actief zijn op de computer om begrepen te worden. Figuur 4.3 Met de opdracht ps is het ook mogelijk informatie op te vragen over alle worker threads die een proces gealloceerd heeft
4.3
Procesbeheer
Het beheer van processen omvat verschillende taken. Om te beginnen moet je in staat zijn de juiste informatie over een proces te tonen. Hiervoor maak je gebruik van de opdracht ps of top. Als daaruit blijkt dat een proces zich misdraagt, moet je als beheerder het proces kunnen afsluiten. Voor dit doel kunnen de opdrachten kill en killall gebruikt worden. Naast de mogelijkheid processen op de voorgrond te draaien, is het ook mogelijk ze op de achtergrond te activeren. In dat geval is de opdracht jobs belangrijk: hiermee vraag je namelijk een overzicht op van alle processen die op de achtergrond actief zijn en heb je ook de mogelijkheid die processen van daaruit te beheren. Je leert in de volgende paragrafen hoe je deze opdrachten kunt gebruiken voor het beheer van processen op de server.
4 Beheer van processen
125
4.3.1 Monitoring van procesactiviteit In het voorgaande heb je kennisgemaakt met de opdracht ps die gebruikt kan worden om het gedrag van processen te monitoren. Zo kan bijvoorbeeld met ps aux een lijst opgevraagd worden van alle actieve processen op het systeem (als je tenminste root bent) en is het mogelijk om door alleen ps als opdracht te geven een lijst op te vragen van alle processen waar de huidige gebruiker eigenaar van is. De opdracht ps zorgt ervoor dat veel relevante informatie over de processen getoond wordt. Onder andere de volgende kolommen kunnen door de opdracht ps getoond worden: USER
Geeft informatie over de gebruiker die het proces gestart heeft. PID Toont het unieke proces-ID (PID) van het proces. %CPU Geeft aan hoeveel werklast het proces in de afgelopen periode op de CPU veroorzaakt heeft. %MEM Geeft aan hoe zwaar de belasting van het proces op het werkgeheugen van de computer is. TTY Toont op welke TTY het proces gebruikt wordt. STAT Laat de status van het proces zien. START Toont wanneer het proces gestart is. COMMAND Misschien wel de belangrijkste kolom: hier zie je met welke opdracht het proces gestart is.
Als alternatief voor de opdracht ps, kan de opdracht top gebruikt worden. Het voordeel van deze opdracht is dat er met top een voortdurend bijgewerkt overzicht gegeven wordt van de meest actieve processen op een systeem. Daarbij wordt het meest actieve proces standaard boven in beeld getoond. Er zijn echter mogelijkheden de uitvoer van top op een andere wijze te sorteren. Onthoud wanneer je met top werkt vooral twee toetsen: de toets h gebruik je om hulp op te vragen over alle opties die met top gebruikt kunnen worden. Om top weer af te sluiten kun je gebruikmaken van de optie q. Een van de belangrijkste dingen die je met top kunt doen, is het monitoren van de activiteit van de server. top vertelt je hoe druk de server het heeft en of de server over voldoende resources beschikt om de taken waarvoor hij is ingericht uit te voeren. Om een beoordeling te maken van de huidige status van de server, gebruik je vooral de eerste en de derde regel met procesinformatie.
126
Linux 4
Figuur 4.4 Met top krijg je een realtime-overzicht van procesactiviteit op de server
Op de eerste regel van de uitvoer van top zie je wat de huidige load average is van de server. Deze load average wordt aangegeven in drie getallen: het belastingsgemiddelde voor de laatste minuut, het belastingsgemiddelde voor de laatste vijf minuten en het gemiddelde voor de laatste vijftien minuten. top ververst deze waarden elke vijf seconden. Je kunt dus heel duidelijk een verloop zien in de belasting van het systeem over langere tijd. Om het belastingsgemiddelde te kunnen begrijpen, moet je weten hoe een Linux-server gebruikt wordt. Om te beginnen is er de proces-queue (wachtrij). Alle processen die tijd nodig hebben op de CPU, doen dit door een opdracht in de queue te zetten. Deze queue wordt afgehandeld door de scheduler, een onderdeel van de kernel dat ervoor zorgt dat het proces de resources toegewezen krijgt die nodig zijn om zijn taak uit te voeren. Uiteindelijk betekent dit onder andere dat het proces in kwestie CPU-tijd toegewezen krijgt. De load average is een aanduiding van de activiteit van de CPU gerelateerd aan het aantal processen in de queue. De ideale waarde hierbij is 1.00. Dit betekent dat de CPU voortdurend bezig is met het afhandelen van opdrachten in de queue, maar dat er geen wachttijd in de queue ontstaat. Met andere woorden: een proces dat in de queue geplaatst wordt, wordt ook direct afgehandeld. Op het moment dat de waarde onder de 1.00 komt, betekent dit dat de CPU overcapaciteit heeft en cycli heeft die niet door een proces gebruikt worden. Je zult in dat geval in de derde regel van de uitvoer
4 Beheer van processen
127
van de opdracht top bij de aanduiding id ook een waarde zien. Deze aanduiding geeft namelijk aan wat de idle-loop aan het doen is. Deze waarde geeft dus eigenlijk gewoon de inactiviteit van de CPU aan. Op het moment dat het belastingsgemiddelde boven de 1.00 uitkomt, wordt het voor de beheerder tijd om op te letten. Bij een systeem met één CPU betekent dit namelijk dat de werklast hoger is dan dat de CPU kan verwerken. Als het systeem twee CPU’s heeft (fysiek of door middel van dual core of hyperthreading), is de waarde 2.00. Wanneer de werklast even boven de 1.00 per CPU komt, is er niets aan de hand. Komt de belasting echter structureel boven de 1.00, dan wordt het tijd om op te letten. In dat geval wordt vooral de derde regel interessant. Hierin wordt namelijk aangegeven wat de CPU dan wel aan het doen is. In de derde regel van top vind je de volgende parameters: us
sy
ni
id
wa
Dit zijn processen in de zogenoemde user space van het systeem. Typisch zijn dit processen die door eindgebruikers gestart zijn, of daemon-processen. Een hoge belasting hier betekent dat je de inrichting van het serverpark eens opnieuw moet bekijken om te zien of bepaalde processen misschien op andere machines geplaatst kunnen worden. Naast de user space kent Linux ook de system space. Hierin draaien processen die deel uitmaken van de kernel en processen die gebruikmaken van drivers (drivers zijn namelijk een onderdeel van de kernel). Als je hier een te hoge belasting vindt, heeft dat niet zelden te maken met een slecht geprogrammeerde driver. Een hoge belasting in system space kan echter ook veroorzaakt worden door een grote kopieeractie waarbij de vaste schijf bijvoorbeeld heel erg actief is. Dit is het percentage belasting van de CPU dat veroorzaakt wordt door processen waarvan de prioriteit is aangepast. Dit is de idle-loop. Deze parameter geeft de inactiviteit van het systeem aan. Een structurele hoge waarde hier betekent dat het systeem eenvoudigweg te krachtig is. Dit is een belangrijke parameter. De afkorting wa geeft aan de CPU wacht voor I/O. In de praktijk betekent dat
128
Linux 4
hi
si
vrijwel altijd dat het systeem wacht op invoer vanaf de vaste schijf. Dit kan een indicatie zijn dat de vaste schijf in de computer het werk niet aankan. Als je structureel een hoge waarde hebt bij deze parameter, zou je moeten overwegen een snellere vaste schijf aan te schaffen. Met deze parameter wordt verwezen naar hardwareinterrupts. Een hardware-interrupt is de communicatie tussen een randapparaat en de CPU. Je kunt deze bijvoorbeeld zien als je grote hoeveelheden data tussen een optisch schijfstation en de vaste schijf verplaatst. Mocht je structureel een zeer hoge hardware-interruptwaarde hebben, dan is het de moeite om de drivers voor de randapparaten eens kritisch te bekijken. De optie si verwijst naar software-interrupts. Deze worden veroorzaakt door programma’s die met de CPU willen communiceren door middel van interrupts. Over het algemeen moet de waarde die je hier terugvindt te verwaarlozen zijn.
4.3.2 Processen op de achtergrond Sommige processen hebben nogal wat tijd nodig voordat ze klaar zijn met hun werk. Als het processen betreft die je vanuit een opdrachtregel wilt starten, is het goed te weten dat processen ook op de achtergrond kunnen worden opgestart. De normale situatie is dat een opgestart interactief proces controle krijgt over het beeldscherm totdat het voltooid is. Gedurende de tijd dat het proces actief is, kun je dus niets anders doen in de betreffende terminal; uiteraard kun je wel een nieuw terminalvenster starten. Als een opdracht geen invoer nodig heeft, kan de opdracht echter net zo goed opgestart worden op de achtergrond. Je doet dit door het &-teken achter de opdracht te plaatsen. Zo kan bijvoorbeeld een zoekactie naar alle bestanden die beginnen met de tekst ‘ab’ als achtergrondproces worden gestart met de opdracht find / -name “ab*” &
De shell antwoordt vervolgens met een bericht als [1] 452
4 Beheer van processen
129
Door deze melding wordt aangegeven dat dit proces vanuit deze shell-sessie het eerste achtergrondproces is. Daarbij zie je wat de PIFD is van het proces. Nu kan het zijn dat je meerdere achtergrondprocessen gelijktijdig actief hebt en daardoor het overzicht kwijtraakt. Je kunt dan met de shell-opdracht jobs een overzicht opvragen van alle processen die op de achtergrond actief zijn. Deze opdracht laat je zien met welke opdracht de achtergrondprocessen gestart zijn en geeft per achtergrondproces ook een job-nummer. Dit job-nummer kun je gebruiken om het achtergrondproces vervolgens weer te beheren. Figuur 4.5 De opdracht jobs geeft een overzicht van alle processen die op de achtergrond actief zijn
Om een proces dat op de achtergrond actief is te beheren, is de opdracht fg erg handig. Hiermee kun je een proces dat op de achtergrond draait, weer op de voorgrond zetten. Vervolgens is het heel eenvoudig er met behulp van een toetsencombinatie een signaal naartoe te sturen om er bijvoorbeeld voor te zorgen dat het proces zijn activiteiten staakt. Om bijvoorbeeld achtergrondproces nummer 3 weer op de voorgrond te krijgen, gebruik je de opdracht fg 3. Daarna kun je het voorgrondproces op een zeer eenvoudige wijze afbreken door bijvoorbeeld de toetsencombinatie Ctrl-C te gebruiken. 4.3.3 Deactiveren van processen Als je een proces wilt deactiveren, zijn daarvoor globaal gesproken drie werkwijzen:
130
Linux 4
Je kunt het proces afbreken met een toetsencombinatie als Ctrl-C. Je kunt de opdracht kill gebruiken om een proces af te breken op basis van zijn PID. Gebruik killall om processen op basis van hun naam af te breken. Van deze drie manieren is de eerste zonder twijfel de meest eenvoudige werkwijze. Het nadeel echter van deze werkwijze, is dat het alleen werkt bij processen die op een terminal actief zijn. Deze kun je zonder probleem met Ctrl-C afbreken. Als een proces echter als achtergrondproces gestart is, is dat een stuk moeilijker. Daarom zijn er de opdrachten kill en killall. Het verschil tussen beide opdrachten is eenvoudig te bevatten: met kill kun je één enkel proces afsluiten door te verwijzen naar de PID van dit proces. Met killall kun je een hele reeks processen afsluiten door te verwijzen naar de naam van het proces. Wellicht denk je dat het veel eenvoudiger is om processen met killall af te sluiten in plaats van met kill en daar heb je dan ook volkomen gelijk in. Soms echter is killall gewoon teveel van het goede. Dit is vooral het geval als een proces meer dan eens gestart is om in staat te zijn verzoeken van meerdere gebruikers gelijktijdig af te handelen. Stel je maar eens voor dat een webserver twintig keer actief is: een keer voor elke gebruiker die er op dat moment gebruik van maakt. Je komt erachter dat één van die twintig zogenoemde instances van het proces een probleem heeft en je wilt dat afsluiten. De opdracht killall httpd is dan echt teveel van het goede: deze zorgt er immers voor dat niet één, maar alle instances van het proces gesloten worden en dat zullen de overige negentien gebruikers van de server je niet in dank afnemen. In zo’n geval is het handig gebruik te maken van kill om alleen die instance te sluiten die je daadwerkelijk zijn nek om wilt draaien. Bij het gebruik van kill en killall kun je ook een zogenoemd signaal (signal) meesturen. Hiermee vertel je een proces op welke wijze het afgesloten moet worden. Gebruik je kill of killall zonder aanduiding van een signaal, dan probeert de opdracht in kwestie het proces op een nette wijze af te sluiten. Dit lukt niet altijd. Dan kan het de moeite waard zijn om het roemruchte signaal -9 (SIGKILL) mee te sturen. Hiermee forceer je het proces te stoppen. Je moet het gebruik van dit signaal echter tot een minimum
4 Beheer van processen
131
beperken: niet alleen zorgt het ervoor dat de gegevens waarmee het proces aan het werk was niet netjes bewaard kunnen worden, ook heeft dit signaal tot gevolg dat het systeem er instabiel door kan worden omdat de kernel niet altijd goed op de hoogte gesteld wordt van processen die op deze wijze zijn afgesloten. Naast -9 is er nog een ander signaal dat vaak in combinatie met killall gebruikt wordt en dat is SIGHUP. Dit signaal kan gebruikt worden om een daemon-proces te forceren opnieuw zijn configuratiebestanden te lezen. Je gebruikt dit signaal nadat je wijzigingen hebt aangebracht in de configuratie van een daemon-proces. Figuur 4.6 De KDE-interface biedt ook een uitstekende interface die je kunt gebruiken voor het beheer van processen
Als je kill gebruikt, is er één ding dat het je moeilijk kan maken: kill werkt namelijk alleen met de PID van een proces en niet met de naam. Gelukkig is het met ps in combinatie met grep eenvoudig te achterhalen welke PID door een bepaald proces gebruikt wordt. Gebruik bijvoorbeeld ps aux | grep httpd om een volledig overzicht te geven van alle processen die actief zijn en daar in het bijzonder het proces httpd uit te filteren.
132
Linux 4
Flexibel processen termineren Soms is het lastig om meerdere processen te termineren, omdat de naam van het programma dat je wilt afsluiten niet gelijk is aan de naam van het proces dat afgesloten moet worden. Als echter de naam van het programma wel voorkomt in de uitvoer van de opdracht ps aux, bestaat er een trucje. Om te beginnen moet je de PID’s te pakken zien te krijgen van alle processen waarin de programmanaam voorkomt. Dit bereik je door de opdrachten ps, grep en awk met elkaar te combineren. In de volgende opdracht zie je bijvoorbeeld hoe je de PID’s te zien krijgt voor alle processen waar het woord ‘evolution’ in het volledige pad voorkomt: ps aux | grep evolution | grep -v grep | awk ‘{ print $2 }’. Vervolgens voer je de uitvoer van deze opdracht aan de opdracht kill. Dit doe je door middel van de opdracht substitutie. De opdracht die uiteindelijk nodig is, wordt dan kill `ps aux | grep evolution | grep -v grep | awk ‘{ print $2}’`. 4.4
Schedulen van processen
Linux biedt ook mogelijkheden om processen in de toekomst uit te laten voeren. Dit gebeurt door gebruik te maken van de functionaliteit van de daemon cron en de opdracht at. Cron is uitermate geschikt om processen meerdere malen ergens in de toekomst uit te voeren, terwijl at heel handig is om een proces één keer in de toekomst uit te voeren. 4.4.1 De daemon cron De daemon cron zorgt ervoor dat processen op gezette tijden worden geactiveerd. Dit gaat op basis van tekstbestanden waarin staat welke processen wanneer moeten worden opgestart. De inhoud van deze bestanden wordt in het geheugen geladen. Cron kijkt eerst of er tekstbestanden met cron-instructies aanwezig zijn in de directory /var/cron/tabs. De bestanden die hierin voorkomen, hebben dezelfde naam als de gebruikers die gedefinieerd zijn in /etc/passwd. Elke gebruiker kan zelf cron-opdrachten definiëren met de opdracht crontab -e. De opdrachten die in deze bestanden voorkomen, zijn aan individuele gebruikers gekoppeld. Vervolgens kijkt cron of in het algemene bestand /etc/crontab nog zaken staan
4 Beheer van processen
133
vermeld en ten slotte bekijkt cron of er bestanden in de directory /etc/cron.d staan. De bestanden die hier voorkomen, kunnen worden beschouwd als uitbreiding op /etc/crontab. De directory /etc/ cron.d is voornamelijk bedoeld voor applicaties waarvoor processen nauwkeurig gescheduled moeten worden. Moderne Linux-distributies maken overigens gebruik van cron-opdrachten die elk uur, elke dag, elke week en elke maand uitgevoerd worden. Deze opdrachten worden in de vorm van scripts geplaatst in de directory’s /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly en /etc/cron.monthly. Deze directory’s worden automatisch gecontroleerd door het cron-proces, omdat hiervoor instructies staan in het algemene cron-configuratiebestand /etc/crontab. Alles wat je als beheerder hoeft te doen, is dus in de betreffende directory’s een script te plaatsen. Tip! Het gebruik van de verschillende bestanden die door cron uitgelezen kunnen worden, maakt de werking van cron best moeilijk te doorgronden. In een niet al te ingewikkelde omgeving is er niets op tegen om met vi gewoon het algemene instellingenbestand /etc/crontab te bewerken en daarin precies aan te geven wat er in de toekomst als proces uitgevoerd moet worden. OK, het is misschien niet echt elegant, maar het werkt net zo goed. Het kan ook iets eleganter: gebruik als root de opdracht crontab -e om een crontab aan te maken voor root. De daemon cron wordt elke minuut actief. Hij kijkt in de crontab-bestanden of er opdrachten zijn die zijn gedefinieerd om op die specifieke minuut uitgevoerd te worden. Als dat het geval is, worden ze uitgevoerd. Alle processen die de daemon cron opstart, worden als achtergrondproces uitgevoerd. Output van de opdrachten wordt door middel van mail doorgestuurd naar de eigenaar van het proces of naar de gebruiker die in het cron-bestand staat gespecificeerd achter de setting MAILTO. Processen die met cron worden uitgevoerd, zijn niet in staat om hun uitvoer ook op een TTY te zetten. Dit komt omdat cron als daemon gestart wordt en daarom niet aan een specifieke TTY gebonden is.
134
Linux 4
Elke regel in een crontab-bestand bestaat uit vijf velden waarmee de tijd van uitvoering van de opdracht wordt gespecificeerd. Daarna volgt een precieze verwijzing naar de gebruiker door wie de opdracht uitgevoerd moet worden; de opdracht die uitgevoerd moet worden, de omgevingsvariabelen die eventueel ingesteld moeten worden of commentaar dat voorafgegaan wordt door een hekje (#). De vijf velden waarmee de tijd wordt aangegeven, staan achtereenvolgens voor: 1. minuten 2. uren 3. dag van de maand 4. maand 5. dag van de week De waarden kunnen worden aangegeven in de vorm van getallen. Dit kan één enkel getal zijn, het kunnen willekeurige getallen zijn van elkaar gescheiden met een komma en het kunnen getallen binnen een bepaald bereik zijn, waarbij het bereik wordt aangegeven met een koppelstreepje. Daarnaast kunnen voor ‘dag van de week’ en ‘maand’ ook de eerste drie letters van de Engelse naam gebruikt worden. Op de plaats van de waarde die niet verder wordt gespecificeerd, kun je een asterisk (*) opnemen. De asterisk heeft dan de betekenis van ‘elke’. Zo kun je bijvoorbeeld de tijdsaanduiding 15 * * * * gebruiken om ervoor te zorgen dat om vijftien minuten over elk uur, op elke dag van de maand, in elke maand en op elke dag van de week iets moet gebeuren. Op basis van het bovenstaande kan een cron-bestand er als volgt uitzien: # gebruik /bin/sh om commando’s uit te voeren. # Hiermee wordt de instelling in /etc/passwd overschreven. SHELL=/bin/sh # Stuur alle output die gegenereerd wordt bij verwerking van # dit bestand door naar michelle. MAILTO=linda # # 5 over 12 ‘s nachts, elke dag
4 Beheer van processen
135
5 0 * * * root /sbin/shutdown -r now # kwart over twee ‘s middags op de eerste van de maand 15 14 1 * * root /usr/bin/cp /etc/passwd /etc/passwd-bak # 10 uur ‘s ochtends, elke werkdag. 0 10 * * 1-5 /usr/bin/wall hallo # dagelijks om 11 minuten over het even uur 11 0-23/2 * * * /usr/bin/logger “het is elf over even”
Voor het maken van een crontab-bestand kun je gebruikmaken van een editor of de opdracht crontab gebruiken. In het eerste geval heb je het probleem dat dit crontab-bestand niet automatisch ook actief wordt. Nadat op deze manier een crontab-bestand is gemaakt, moet je het activeren met de opdracht crontab bestandsnaam. Wanneer je bijvoorbeeld met een editor het bestand /etc/ crontab hebt bewerkt, activeer je het met crontab /etc/crontab. Als alternatief kun je wachten totdat de cron-daemon in het crontab-bestand gaat kijken of er wijzigingen zijn aangebracht. 4.4.2 De opdracht at Door gebruik te maken van at kun je een opdracht eenmalig in de toekomst laten uitvoeren. Wanneer at wordt aangeroepen en er wordt niet door middel van redirection een tekstbestand met opdrachten naartoe gestuurd, wordt een interactieve at-prompt opgestart waar je opdrachten kunt invoeren. Deze interactieve prompt kan worden afgesloten met het EOF-teken (Ctrl-D). Je moet als argument bij at altijd een tijd opgeven waarop de opdracht wordt uitgevoerd. Foutmeldingen en output van de opdracht die door at is gescheduled, worden door middel van mail naar de gebruiker gestuurd. Uitvoering van de opdracht vindt dus volledig op de achtergrond plaats. Het gebruik van de opdracht at kan worden beperkt door een bestand /etc/at.allow te maken, waarin de naam staat van iedereen die at mag gebruiken. Je kunt ook een bestand /etc/at.deny maken met personen die at niet mogen gebruiken. Wanneer je opdrachten in de toekomst wilt laten uitvoeren door gebruik te maken van at, is er een mogelijkheid de opdrachten die gepland staan te beheren. Gebruik hiervoor de volgende opdrachten:
136
Linux 4
at atq
atrm
4.5
Gebruik at om het uitvoeren van een opdracht in de toekomst te plannen. Met behulp van atq kan de gebruiker root een overzicht opvragen van alle opdrachten die op dit moment gepland staan voor toekomstige uitvoering. Een normale gebruiker kan alleen zien welke opdrachten hij zelf gepland heeft. Met behulp van atrm kunnen jobs verwijderd worden uit de queue van opdrachten die in de toekomst uitgevoerd moeten worden. Prioriteit van processen
Gewoonlijk hebben alle processen evenveel prioriteit. Dat wil zeggen dat elk proces evenveel processortijd mag claimen als elk ander proces. Een uitzondering wordt gemaakt voor processen die door de gebruiker worden opgestart met UID 0: deze krijgen hogere prioriteit. Met de opdracht nice is het mogelijk de prioriteit van een proces aan te passen. De prioriteit die wordt gekoppeld aan de opdracht in kwestie, wordt uitgedrukt met een numerieke waarde: een lage waarde geeft een hoge prioriteit aan. Dit houdt in dat de waarde -20 betekent dat het proces de hoogst mogelijke prioriteit krijgt en 19 heeft als betekenis dat het proces de laagst mogelijke prioriteit krijgt. Je kunt dit het best onthouden als: een proces met een hoge prioriteit is niet aardig (nice) voor de andere processen, een proces met een lage prioriteit is dat wel. Daarom zorgt de hoogste nicewaarde voor de laagste prioriteit. Als je nice gebruikt zonder een aanpassing van de prioriteit te specificeren, wordt de prioriteit van de opdracht in kwestie opgehoogd met 4. De syntaxis van nice is als volgt samen te vatten: nice -n xx commando argumenten
Om bijvoorbeeld een lijst op te vragen van bestanden die voorkomen in de root van het bestandssysteem en waarbij de hoogst mogelijke prioriteit aan deze opdracht wordt toegekend, geef je de opdracht nice -n -20 ls /.
4 Beheer van processen
4.6
137
Logging van procesactiviteit
Er zijn twee manieren die op moderne Linux-systemen gebruikt worden om informatie naar logbestanden weg te schrijven. Ten eerste is er het oudere syslog. Daarnaast is inmiddels ook de opvolger van syslog, syslog-ng in gebruik. Omdat je beide tegen zult komen, worden beide in dit hoofdstuk besproken. Om te beginnen lees je hoe syslog geconfigureerd kan worden. Wanneer we het hebben over syslog, hebben we het eigenlijk over twee verschillende processen: syslogd en klogd. Tijdens het opstarten van een computer is er als eerste klogd dat ervoor zorgt dat berichten die door de kernel gegenereerd worden weggeschreven kunnen worden in logbestanden. Klogd wordt al in een zeer vroeg stadium geladen en verzamelt kernelberichten om deze later door te geven aan het logproces syslogd. Dit zorgt ervoor dat de totale logging van een systeem afgehandeld wordt. Hiervoor wordt gebruikgemaakt van instellingen die gedaan worden in het configuratiebestand /etc/syslog.conf. In dit bestand wordt door middel van verschillende regels gedefinieerd wat er moet gebeuren wanneer een evenement van een bepaalde ernst zich voordoet. Hiervoor wordt gebruikgemaakt van verschillende facility’s en priority’s. Een facility definieert een aantal categorieën waarbij iets mis kan gaan, een priority definieert de ernst van het feit dat zich voordoet. Om de werking van syslog te kunnen optimaliseren, is het van groot belang dat je weet hoe je hiermee om moet gaan. 4.6.1 Configuratie van facility’s en priority’s Facility’s hebben betrekking op de verschillende systeemonderdelen die gebruikt worden. De beheerder kan voor facility’s aangeven hoe omgegaan moet worden met de informatie die door een bepaalde systeemcomponent gegenereerd wordt. Zo regel je bijvoorbeeld middels de facility authpriv waar berichten naartoe gestuurd worden die tijdens de authenticatiefase gegenereerd worden. De volgende facility’s kunnen gebruikt worden: auth authpriv
Algemene zaken die met authenticatie te maken hebben. Wordt gebruikt door alle services die iets te maken hebben met systeembeveiliging of authenticatie.
138
Linux 4
cron daemon kern
lpr mail
mark news security syslog user uucp local0 tot en met local7
Wordt onder andere gebruikt voor alle aan PAM gerelateerde berichten en de SSH-daemon. Ontvangt berichten van de processen cron en at. Wordt gebruikt door verschillende daemons die niet hun eigen facility hebben. Heeft betrekking op alle kernelberichten. Voor deze categorie wordt samengewerkt met klogd, zodat ook berichten die tijdens het opstarten gegenereerd worden, afgehandeld kunnen worden. Berichten van het printersysteem. Voor berichten die iets te maken hebben met het mailsysteem. Houd er rekening mee dat een slecht functionerend mailsysteem ervoor kan zorgen dat in deze categorie heel snel heel veel berichten binnen kunnen komen. Kan gebruikt worden om af en toe een markeringssignaal weg te schrijven naar syslog. Dit maakt de resulterende logbestanden gemakkelijker te lezen. Voor berichten van het nieuwssysteem. Ook in deze categorie kunnen bij problemen zeer snel zeer veel meldingen binnenkomen. wordt niet langer gebruikt. De functionaliteit wordt nu overgenomen door auth. Voor intern gebruik door het syslog-proces. Algemene categorie voor zaken die iets met gebruikers te maken hebben. Berichten die gegenereerd worden door het UUCPsysteem. Beschikbaar voor eigen gebruik. Door van deze categorie gebruik te maken kun je nieuwe categorieën definiëren die door bepaalde specifieke programma’s en processen gebruikt worden.
Voor elke facility kan aangegeven worden in welk geval er gelogd moet worden. In sommige gevallen zul je zelfs puur informationele berichten al willen loggen, in andere gevallen zul je willen dat er pas wat gebeurt als systeemfunctionaliteit ernstig bedreigd wordt. Dit regel je door de configuratie van priority’s. Met deze priority’s wordt de urgentie gecategoriseerd. Hieronder vind je een qua urgentie oplopende lijst van de verschillende priority’s. Als je in de syslog-configuratie een bepaalde priority aangeeft, betekent dit
4 Beheer van processen
139
dat niet alleen berichten met die specifieke priority gelogd worden, maar ook alle berichten met een hogere prioriteit. Als je bijvoorbeeld de regel auth
info
opneemt, wordt alles dat betrekking heeft op de authenticatie met een niveau info en hoger gelogd. Dit kun je echter voorkomen door gebruik te maken van het =-teken: auth = info
Voordat we dieper ingaan op de manier waarop deze informatie gebruikt wordt, tref je hieronder een overzicht van de verschillende priority’s: debug
Gebruik deze priority alleen voor debuggingdoeleinden als je er niet in slaagt een service naar behoren te laten werken. Deze priority zorgt ervoor dat werkelijk alles gelogd wordt en dat kan er op zijn beurt weer voor zorgen dat de logbestanden zeer snel worden volgeschreven. info Deze prioriteit zorgt ervoor dat informatieve berichten en alles wat hoger is gelogd worden. notice Dit heeft betrekking op berichten die een normale status van het systeem beschrijven. warning Gebruik deze categorie om afwijkingen van de normale situatie te loggen. In veel gevallen is het zinnig gebruik te maken van deze priority. err Voor serieuze foutmeldingen waardoor de functionaliteit van een systeemonderdeel in het gedrang komt. crit Om kritische situaties met betrekking tot een bepaald programma te loggen. alert Dit heeft betrekking op situaties waar onmiddellijke actie vereist is om het systeem draaiend te houden. emerg Wordt gebruikt om te melden dat het systeem niet langer bruikbaar is.
Onder normale omstandigheden wordt bij de aanduiding van een bepaalde prioriteit gelogd wanneer deze prioriteit zich voordoet en voor alle hogere prioriteiten. Dit is meestal ook wel zo handig, maar er zijn een aantal mogelijkheden om van deze standaardfunctionaliteit af te wijken:
140
Linux 4
Gebruik een = teken Hiermee wordt aangegeven dat alleen actie moet worden ondernomen bij het voorkomen van de betreffende prioriteit en niet ook voor alle hogere prioriteiten die daarop volgen. Gebruik een ! teken Hiermee geef je aan dat bij de betreffende prioriteit én alle hogerliggende prioriteiten juist geen actie moet worden ondernomen. Op deze wijze geef je aan dat je het hebt Gebruik een * over alle categorieën of alle prioriteiten. Gebruik none Hiermee kun je een bepaalde categorie volledig uitsluiten van het logmechanisme. Nadat bepaald is wat er dan gelogd moet worden en bij welke ernst van de situatie er tot logging overgegaan moet worden, moet vervolgens bepaald worden wat er in die gevallen moet gebeuren. In technisch jargon hebben we het hierbij over de specificatie van de target. Hiervoor wordt het tweede veld in de regels in syslog.conf gebruikt. De volgende opties zijn beschikbaar: Wegschrijven naar Geef de naam van het bestand waarnaar weggeschreven moet worden. Om ervoor een bestand te zorgen dat het bestand niet onmiddellijk bijgewerkt wordt na elke gebeurtenis, laat je de naam van dit bestand voorafgaan door een –. Het is handig deze optie te gebruiken voor services waar je grote hoeveelheden logberichten mag verwachten. Dit gebeurt in het volgende voorbeeld: news.*
-/var/log/news
Specificeer een Door de devicenaam van een of ander apparaat te specificeren zorg je ervoor dat devicenaam de melding naar het betreffende apparaat wordt doorgestuurd. Zo is het bijvoorbeeld redelijk gangbaar dat ernstige meldingen weggeschreven worden naar /dev/tty10 met de volgende regel: kern.warn;*.err;authpriv.none
/dev/tty10
4 Beheer van processen
Maak gebruik van een named pipe
141
Een named pipe is een pipe die opengezet wordt tussen een opdracht en een bestemming. Door gebruik te maken van named pipes zorg je er bijvoorbeeld voor dat de logmeldingen in een venster in de grafische omgeving weggeschreven worden. Dit gebeurt bijvoorbeeld in de volgende regel:
kern.warn;*.err;authpriv.none
|/dev/xconsole
Specificeer een lijst Als het terminaltype waarop de gebruiker gebruikersnamen is aangemeld dit ondersteunt, zorg je er op deze wijze voor dat een bericht verstuurd wordt naar gebruikers met de overeenkomstige naam als die op dat moment zijn aangemeld. Om er bijvoorbeeld voor te zorgen dat in alle kritische omstandigheden een bericht verstuurd wordt naar de gebruikers root en linda, gebruik je de volgende regel: *.alert
root,Linda.
Geef de naam van Je kunt er op deze manier voor zorgen dat meldingen doorgestuurd worden naar een een computer andere computer waarop de syslog-daemon actief is. Let er wel op dat de naam van die computer voorafgegaan moet worden door een apenstaartje. Vanuit de optiek van beveiliging is dit een belangrijke optie. Als gelogd wordt naar een andere computer, kan de eventuele inbreker er immers niet meer bij komen. Je moet er echter wel voor zorgen dat het syslog-proces op de andere computer gestart is met de optie –r, zodat logberichten die afkomstig zijn van andere computers geaccepteerd worden. Hiervoor zorg je door deze optie als opstartoptie te specificeren in het bestand /etc/sysconfig/syslog. Gebruik bijvoorbeeld de volgende optie om alle berichten door te sturen naar de computer LAX: *.*
@LAX.sandervanvugt.nl
142
Linux 4
Gebruik een asterisk Hiermee zorg je ervoor dat alle gebruikers die op dat moment ingelogd zijn een melding op hun beeldscherm krijgen. Het is aan te raden deze mogelijkheid alleen te gebruiken als de systeemfunctionaliteit werkelijk kritisch bedreigd wordt. Op basis van deze informatie moet je in staat zijn een werkende syslog-configuratie te maken in het configuratiebestand /etc/syslog.conf. Om je enigszins te inspireren vind je hierna een voorbeeld waarin je ziet hoe logging standaard geconfigureerd is op een Fedora-systeem. [root@IDA etc]# cat syslog.conf # Log all kernel messages to the console. # Logging much else clutters up the screen. #kern.*
/dev/
console # Log anything (except mail) of level info or higher. # Don’t log private authentication messages! *.info;mail.none;news.none;authpriv.none;cron.none
/
var/log/messages # The authpriv file has restricted access. authpriv.*
/var/log/
secure # Log all the mail messages in one place. mail.*
-/var/log/
maillog # Log cron stuff cron.*
/var/log/
cron # Everybody gets emergency messages *.emerg
*
4 Beheer van processen
143
# Save news errors of level crit and higher in a special file. uucp,news.crit
/var/log/
spooler # Save boot messages also to boot.log local7.*
/var/log/
boot.log # # INN # news.=crit
/var/log/news/
news.crit news.=err
/var/log/news/
news.err news.notice
/var/log/news/
news.notice
Zoals gezegd, het voorgaande voorbeeld zal weinig verwondering wekken. Toch is er een aantal zaken dat interessant is. Let vooral op de wijze waarop verschillende criteria met elkaar verbonden worden, zoals in uucp,news.crit, waarin actie ondernomen wordt bij een severity van crit of hoger voor zowel uucp als news. Wanneer je ervoor gezorgd hebt dat het configuratiebestand /etc/ syslog.conf op deze wijze voor jou op bevredigende manier is gemaakt, kun je de wijzigingen activeren. Dit doe je door de syslog-daemon opnieuw op te starten. Gebruik hiervoor de opdracht service syslog restart. Loggen vanuit scripts Leuk natuurlijk dat je gebruik kunt maken van allemaal vooraf gedefinieerde instellingen om te loggen. Soms echter zou je zélf willen bepalen wanneer er iets weggeschreven wordt in een logbestand. Bijvoorbeeld wanneer een script succesvol uitgevoerd wordt. Voor dat soort gevallen is er logger. Met behulp van deze opdracht schrijf je rechtstreeks in de verschillende logbestanden die door syslog onderhouden worden. Je melding komt terecht in het instellingenbestand /var/log/messages. Gebruik bijvoorbeeld logger hallo wereld om deze uiterst zinnige melding naar /var/log/messages te schrijven. Vooral in
144
Linux 4
shell-scripts is het gebruik van logger uitermate nuttig. Je kunt er op deze manier namelijk voor zorgen dat toch een melding gelogd wordt als er tijdens de uitvoering van een script iets niet goed gegaan is. 4.6.2 Syslog-ng Op zich voldoet syslog prima, maar er is één bezwaar: het is namelijk bij het gebruik van syslog een kwestie van alles of niets. Op het moment dat je info-berichten die afkomstig zijn van de firewall wilt loggen, log je op basis van de priority info en is er geen mogelijkheid onderscheid te maken tussen pakketjes die van verschillende hosts afkomstig zijn. Aan dit bezwaar wordt tegemoetgekomen door syslog-ng. Syslog-ng maakt logging namelijk een stuk flexibeler, maar helaas tegelijkertijd ook een stuk lastiger te doorgronden. Om maar met de deur in huis te vallen zie je hierna het configuratiebestand voor syslog-ng dat op OpenSUSE gebruikt wordt: SFO:/etc/syslog-ng # cat syslog-ng.conf # # /etc/syslog-ng/syslog-ng.conf # # Automatically generated by SuSEconfig on Tue Jun 27 20:34:50 CEST 2006. # # PLEASE DO NOT EDIT THIS FILE! # # you can modify /etc/syslog-ng/syslog-ng.conf.in instead # # # # File format description can be found in syslog-ng.conf(5) # and /usr/share/doc/packages/syslog-ng/syslog-ng.txt. # # # Global options. # options { long _ hostnames(off); sync(0); perm(0640); stats(3600); }; #
4 Beheer van processen
145
# ‘src’ is our main source definition. you can add # more sources driver definitions to it, or define # your own sources, i.e.: # #source my _ src { .... }; # source src { # # include internal syslog-ng messages # note: the internal() soure is required! # internal(); # # the following line will be replaced by the # socket list generated by SuSEconfig using # variables from /etc/sysconfig/syslog: # unix-dgram(“/dev/log”); unix-dgram(“/var/lib/dhcp/dev/log”); unix-dgram(“/var/lib/named/dev/log”); # # uncomment to process log messages from network: # #udp(ip(“0.0.0.0”) port(514)); }; # # Filter definitions # filter f _ iptables
{ facility(kern) and match(«IN=») and
match(«OUT=»); }; filter f _ console
{ level(warn) and facility(kern) and not
filter(f _ iptables) or level(err) and not facility(authpriv); }; filter f _ newsnotice { level(notice) and facility(news); }; filter f _ newscrit
{ level(crit)
and facility(news); };
filter f _ newserr
{ level(err)
and facility(news); };
146
Linux 4
filter f _ news
{ facility(news); };
filter f _ mailinfo
{ level(info)
and facility(mail); };
filter f _ mailwarn
{ level(warn)
and facility(mail); };
filter f _ mailerr
{ level(err, crit) and facility(mail); };
filter f _ mail
{ facility(mail); };
filter f _ cron
{ facility(cron); };
filter f _ local
{ facility(local0, local1, local2, local3, local4, local5, local6, local7); };
filter f _ acpid
{ match(‘^\[acpid\]:’); };
filter f _ netmgm
{ match(‘^NetworkManager:’); };
filter f _ messages
{ not facility(news, mail) and not filter(f _
iptables); }; filter f _ warn
{ level(warn, err, crit) and not filter(f _
iptables); }; filter f _ alert
{ level(alert); };
# # Most warning and errors on tty10 and on the xconsole pipe: # destination console
{ file(«/dev/tty10»
group(tty) perm(0620)); };
log { source(src); filter(f _ console); destination(console); }; destination xconsole { pipe(“/dev/xconsole” group(tty) perm(0400)); }; log { source(src); filter(f _ console); destination(xconsole); }; # Enable this, if you want that root is informed immediately, # e.g. of logins: # #destination root { usertty(«root»); }; #log { source(src); filter(f _ alert); destination(root); }; # # News-messages in separate files: # destination newscrit
{ file(«/var/log/news/news.crit» owner(news) group(news)); };
4 Beheer van processen
147
log { source(src); filter(f _ newscrit); destination(newscrit); }; destination newserr
{ file(«/var/log/news/news.err» owner(news) group(news)); };
log { source(src); filter(f _ newserr); destination(newserr); }; destination newsnotice { file(«/var/log/news/news.notice» owner(news) group(news)); }; log { source(src); filter(f _ newsnotice); destination(newsnotice); }; # # and optionally also all in one file: # (don’t forget to provide logrotation config) # #destination news { file(«/var/log/news.all»); }; #log { source(src); filter(f _ news); destination(news); }; # # Mail-messages in separate files: # destination mailinfo { file(«/var/log/mail.info»); }; log { source(src); filter(f _ mailinfo); destination(mailinfo); }; destination mailwarn { file(«/var/log/mail.warn»); }; log { source(src); filter(f _ mailwarn); destination(mailwarn); }; destination mailerr
{ file(«/var/log/mail.err» fsync(yes)); };
log { source(src); filter(f _ mailerr);
destination(mailerr); };
# # and also all in one file: # destination mail { file(“/var/log/mail”); }; log { source(src); filter(f _ mail); destination(mail); }; # # acpid messages in one file: # destination acpid { file(«/var/log/acpid»); }; log { source(src); filter(f _ acpid); destination(acpid); flags(final); };
148
Linux 4
# # NetworkManager messages in one file: # destination netmgm { file(«/var/log/NetworkManager»); }; log { source(src); filter(f _ netmgm); destination(netmgm); flags(final); }; # # Cron-messages in one file: # (don’t forget to provide logrotation config) # #destination cron { file(«/var/log/cron»); }; #log { source(src); filter(f _ cron); destination(cron); }; # # Some boot scripts use/require local[1-7]: # destination localmessages { file(“/var/log/localmessages”); }; log { source(src); filter(f _ local); destination(localmessages); }; # # All messages except iptables and the facility’s news and mail: # destination messages { file(«/var/log/messages»); }; log { source(src); filter(f _ messages); destination(messages); }; # # Firewall (iptables) messages in one file: # destination firewall { file(“/var/log/firewall”); }; log { source(src); filter(f _ iptables); destination(firewall); }; # # Warnings (except iptables) in one file: # destination warn { file(“/var/log/warn” fsync(yes)); }; log { source(src); filter(f _ warn); destination(warn); }; # # Enable this, if you want to keep all messages in one file: # (don’t forget to provide logrotation config)
4 Beheer van processen
149
# #destination allmessages { file(“/var/log/allmessages”); }; #log { source(src); destination(allmessages); };
4.6.3 Input-bestand Het eerste dat opvalt in het hiervoor genoemde voorbeeld, is dat dit weliswaar het algemene syslog-ng-configuratiebestand is, maar dat het op OpenSUSE niet de bedoeling is dat je hierin rechtstreeks wijzigingen aanbrengt. SUSE maakt namelijk gebruik van het mechanisme SuSEconfig. SuSEconfig is een opdracht die automatisch geactiveerd wordt en ervoor zorgt dat bepaalde configuratiebestanden automatisch worden gemaakt. De werkwijze om op elke versie van SUSE Linux (dus ook de enterpriseproducten) wijzigingen aan te brengen in de syslog-ng-configuratiebestanden is als volgt: 1. Maak een configuratiebestand met de naam /etc/syslog-ng/syslogng.conf.in en plaats hierin alle wijzigingen die je wilt aanbrengen. 2. Activeer als root de opdracht SuSEconfig om de wijzigingen die je in dit bestand aangebracht hebt, automatisch weg te schrijven naar het hoofdconfiguratiebestand syslog-ng.conf. Deze werkwijze biedt een belangrijk voordeel: op het moment namelijk dat tijdens een update automatisch een nieuwe syslogng.conf gemaakt wordt, ben je door deze werkwijze niet in één keer al je eigen wijzigingen kwijt. Het input-bestand syslogng.conf.in wordt namelijk niet aangeraakt door een updateprocedure, dus je wijzigingen staan hier altijd veilig. 4.6.4 Opbouw van syslog-ng.conf In syslog-ng.conf, tref je een aantal onderdelen aan. Om het bestand echt te kunnen doorgronden is het van belang dat je weet hoe de verschillende onderdelen aan elkaar gerelateerd zijn. Je zult altijd de volgende onderdelen aantreffen: sources destinations log
Hiermee wordt aangegeven waar een logbericht vandaan komt. Hiermee specificeer je waar een bepaald logbericht naartoe gestuurd moet worden; bijvoorbeeld naar een bepaald logbestand. Dit is de regel waar het uiteindelijk om gaat; in een log specificeer je namelijk wat er wel en wat er niet gelogd moet worden.
150
Linux 4
De plaats waar het in syslog-ng allemaal samenkomt, is in de specificatie van de log. In een abstracte notatie weergegeven, zie je hierna hoe deze constructie eruitziet: destination ergensnaartoe { file(“/var/log/messages”); }; log { source(ergensvandaan); destination(ergensnaartoe); };
Je vindt dit type specificaties altijd onderaan in het syslog-ngconfiguratiebestand. Om daadwerkelijk te begrijpen wat en hoe er gelogd wordt, raden wij je dan ook aan altijd met lezen te beginnen aan de onderkant van het configuratiebestand en vervolgens naar boven te werken. Verder naar boven zie je bijvoorbeeld de definities van de sources, waarbij vervolgens weer andere elementen gebruikt kunnen worden: filter
Hiermee filter je op basis van bepaalde gegevens. Door middel van het juiste filter zorg je er bijvoorbeeld voor dat alleen informatie die van een bepaalde host of gebruiker afkomstig is ook daadwerkelijk gelogd wordt. level Dit zijn de priority’s zoals die ook in syslog bestaan. De levels geven aan bij welke mate van ernst er iets moet gebeuren. facility Dit zijn de facility’s zoals ze ook in syslog bestaan. Door middel van de definitie van een facility geef je aan voor welk systeemonderdeel er gelogd moet worden. match Hiermee zoek je in het logbericht naar bepaalde tekstelementen.
4.6.5 Source Nu de algemene opbouw van syslog-ng.conf besproken is, wordt het tijd eens wat nauwkeuriger te kijken naar de definities van de verschillende elementen die gebruikt worden. Om te beginnen zie je hierna een specificatie van de source src, die standaard altijd aanwezig is. Hiermee wordt aangegeven vanaf welke bronnen logberichten geaccepteerd worden: source src { internal (); unix-dgram(“/dev/log”); unix-dgram(“/var/lib/dhcp/dev/log”); unix-dgram(«/var/lib/named/dev/log»);
4 Beheer van processen
151
De bovenstaande sourcedefinitie wordt als standaard gebruikt om logging van de geijkte bronnen te accepteren. Zou je nu bijvoorbeeld ook logberichten van een specifieke andere host op de server willen afhandelen, dan kun je er een definitie als de volgende bij opnemen: source network { udp(ip(“10.0.0.254”) port(514)); };
4.6.6 Filter Een tweede belangrijk onderdeel zijn de filters. De filters staan het syslog-ng toe om in berichten te kijken en te zien wat er precies aan de hand is. Voor de definitie van filters wordt altijd gebruikgemaakt van log-facility’s en log levels, zodat precies aangegeven wordt waar een bepaald bericht vandaan komt en van welke ernst een bepaald bericht is. Voor syslog-ng zijn dezelfde facility’s beschikbaar als voor syslog; hieronder vind je het overzicht: auth authpriv
cron daemon kern
lpr mail
mark
Algemene zaken die met authenticatie te maken hebben. Wordt gebruikt door alle services die iets te maken hebben met systeembeveiliging of authenticatie. Wordt onder andere gebruikt voor alle aan PAM gerelateerde berichten en de SSH-daemon. Ontvangt berichten van de processen cron en at. Wordt gebruikt door verschillende daemons die niet hun eigen facility hebben. Heeft betrekking op alle kernelberichten. Voor deze categorie wordt samengewerkt met klogd, zodat ook berichten die tijdens het opstarten gegenereerd worden, afgehandeld kunnen worden. Berichten van het printersysteem. Voor berichten die iets te maken hebben met het mailsysteem. Houd er rekening mee dat een slecht functionerend mailsysteem ervoor kan zorgen dat in deze categorie heel snel heel veel berichten binnen kunnen komen. Kan gebruikt worden om af en toe een markeringssignaal weg te schrijven naar syslog. Dit maakt de resulterende logbestanden gemakkelijker te lezen.
152
Linux 4
news security syslog user uucp local0 tot en met local7
Voor berichten van het nieuwssysteem. Ook in deze categorie kunnen bij problemen zeer snel zeer veel meldingen binnenkomen. Wordt niet langer gebruikt. De functionaliteit wordt nu overgenomen door auth. Voor intern gebruik door het syslog-proces. Algemene categorie voor zaken die iets met gebruikers te maken hebben. Berichten die gegenereerd worden door het UUCPsysteem. Beschikbaar voor eigen gebruik. Door van deze categorie gebruik te maken kun je nieuwe categorieën definiëren die door bepaalde specifieke programma’s en processen gebruikt worden.
Naast de verschillende facility’s, zijn er de log-levels, ook wel aangeduid als de priority’s. Ook deze zijn gelijk aan de definities in syslog: debug
info notice warning err crit alert emerg
Gebruik deze priority alleen voor debuggingdoeleinden als je er niet in slaagt een service naar behoren te laten werken. Deze priority zorgt ervoor dat werkelijk alles gelogd wordt en dat kan er op zijn beurt weer voor zorgen dat de logbestanden zeer snel worden volgeschreven. Deze prioriteit zorgt ervoor dat informatieve berichten en alles wat hoger is gelogd worden. Dit heeft betrekking op berichten die een normale status van het systeem beschrijven. Gebruik deze categorie om afwijkingen van de normale situatie te loggen. In veel gevallen is het zinnig gebruik te maken van deze priority. Voor serieuze foutmeldingen waardoor de functionaliteit van een systeemonderdeel in het gedrang komt. Om kritische situaties met betrekking tot een bepaald programma te loggen. Dit heeft betrekking op situaties waar onmiddellijke actie vereist is om het systeem draaiend te houden. Wordt gebruikt om te melden dat het systeem niet langer bruikbaar is.
4 Beheer van processen
153
Op basis van deze facility’s en priority’s vindt de volgende belangrijke stap plaats: de definitie van filters. Hieronder zie je enkele filters die standaard aanwezig zijn op OpenSUSE: filter f _ iptables
{ facility(kern) and match(“IN=”) and
match(“OUT=”); }; filter f _ console
{ level(warn) and facility(kern) and not
filter(f _ iptables) or level(err) and not facility(authpriv); }; filter f _ newsnotice { level(notice) and facility(news); }; filter f _ newscrit
{ level(crit)
and facility(news); };
filter f _ newserr
{ level(err)
and facility(news); };
filter f _ news
{ facility(news); };
Naast levels en facility’s wordt in filters gebruikgemaakt van een aantal andere belangrijke elementen. Zo is er bijvoorbeeld het element match waarmee je kijkt naar het voorkomen van een bepaalde tekenreeks. Daarnaast is het mogelijk gebruik te maken van host om te zoeken naar logberichten die van een specifieke host afkomstig zijn. Hieronder zie je een eenvoudig voorbeeld van een filter waarin gekeken wordt naar logberichten die afkomstig zijn van host “KUL” en waar de tekenreeks ‘deny’ in voorkomt. filter f _ KUL { host(“KUL”) and match(“deny”); };
Als laatste element zijn er vervolgens de destination en de regel waarin bepaald wordt wat er uiteindelijk gelogd moet worden. Hieronder zie je een voorbeeld van een definitie waarin remote logging geregeld wordt: destination tologhost { udp(10.0.0.254 port(514)); }; log { source(src); destination(tologhost); };
4.6.7 Monitoren van logbestanden Als resultaat van wat je aangegeven hebt in syslog of syslog-ng, wordt uiteindelijk een aantal logbestanden gemaakt. Je vindt deze logbestanden over het algemeen in /var/log. Een van de belangrijkste logbestanden is /var/log/messages; hierin wordt door bijna elk proces dat iets met logging doet informatie weggeschreven. Als
154
Linux 4
beheerder van een Linux-server, zou je eigenlijk elke dag aan het begin van de dag even in /var/log/messages moeten kijken om te achterhalen wat er de afgelopen dag gebeurd is. Hierna zie je een stukje tekst uit dit bestand: Jan 27 10:32:49 SFO kernel: /dev/vmmon[5109]: host clock rate change request 1982 -> 1983 Jan 27 10:33:02 SFO kernel: /dev/vmmon[5109]: host clock rate change request 1983 -> 1982 Jan 27 10:35:31 SFO sux: (to root) sander on /dev/pts/2 Jan 27 10:38:44 SFO sux: (to root) sander on /dev/pts/1 Jan 27 10:46:24 SFO dhclient: DHCPREQUEST on eth0 to 192.168.1.254 port 67 Jan 27 10:46:24 SFO dhclient: DHCPACK from 192.168.1.254 Jan 27 10:46:24 SFO dhclient: bound to 192.168.1.74 -- renewal in 1598 seconds. Jan 27 10:51:21 SFO syslog-ng[2557]: STATS: dropped 0 Jan 27 10:51:32 SFO smartd[3413]: Device: /dev/hda, SMART Usage Attribute: 190 Temperature _ Celsius changed from 73 to 70 Jan 27 10:51:32 SFO smartd[3413]: Device: /dev/hda, SMART Usage Attribute: 194 Temperature _ Celsius changed from 27 to 30 Jan 27 10:51:32 SFO smartd[3413]: Device: /dev/hda, SMART Usage Attribute: 195 Hardware _ ECC _ Recovered changed from 68 to 66 Jan 27 10:51:38 SFO zmd: ShutdownManager (WARN): Preparing to sleep... Jan 27 10:51:38 SFO zmd: ShutdownManager (WARN): Going to sleep, waking up at 01/28/2007 09:41:38 Jan 27 11:13:02 SFO dhclient: DHCPREQUEST on eth0 to 192.168.1.254 port 67 Jan 27 11:13:02 SFO dhclient: DHCPACK from 192.168.1.254 Jan 27 11:13:02 SFO dhclient: bound to 192.168.1.74 -- renewal in 1453 seconds.
Om /var/log/messages te kunnen begrijpen is het vooral van belang dat je weet hoe een regel is opgebouwd. Zoals je ziet, is namelijk de opbouw van elke regel gelijk. Vrijwel altijd vind je de volgende onderdelen terug: Datum en tijd: dit is het tijdstip waarop een bericht gegenereerd is. Hostnaam: dit is de naam van de computer waar het bericht vandaan komt.
4 Beheer van processen
155
Servicenaam: dit is de naam van de service die het bericht gegenereerd heeft. Vaak maar niet altijd wordt deze naam gevolgd door de PID van de betreffende service. Bericht: dit is het daadwerkelijke logbericht waarin je leest wat er aan de hand is. Als je de opbouw van het logbestand begrijpt, is het niet al te moeilijk te zien wat er aan de hand was. Zie je bijvoorbeeld wat er in de volgende code die ontleend is aan een webserver mis is? Oct 10 11:55:06 web sshd[5434]: Invalid user telnetd from 222.40.22.42 Oct 10 11:55:10 web sshd[5436]: Invalid user identd from 222.40.22.42 Oct 10 11:55:13 web sshd[5438]: Invalid user gnats from 222.40.22.42 Oct 10 11:55:17 web sshd[5440]: Invalid user jeff from 222.40.22.42 Oct 10 11:55:21 web sshd[5442]: Invalid user irc from 222.40.22.42 Oct 10 11:55:24 web sshd[5444]: Invalid user list from 222.40.22.42 Oct 10 11:55:28 web sshd[5446]: Invalid user eleve from 222.40.22.42 Oct 10 11:55:32 web sshd[5448]: Invalid user proxy from 222.40.22.42 Oct 10 11:55:36 web sshd[5450]: Invalid user sys from 222.40.22.42 Oct 10 11:55:39 web sshd[5452]: Invalid user zzz from 222.40.22.42 Oct 10 11:55:43 web sshd[5454]: Invalid user frank from 222.40.22.42 Oct 10 11:55:46 web sshd[5456]: Invalid user dan from 222.40.22.42 Oct 10 11:55:50 web sshd[5458]: Invalid user james from 222.40.22.42 Oct 10 11:55:53 web sshd[5460]: Invalid user snort from 222.40.22.42 Oct 10 11:55:57 web sshd[5462]: Invalid user radiomail from 222.40.22.42 Oct 10 11:56:01 web sshd[5464]: Invalid user harrypotter from 222.40.22.42 Oct 10 11:56:04 web sshd[5466]: Invalid user divine from 222.40.22.42
Het bestand /var/log/messages is overigens bij lange na niet het enige logbestand dat je op de server aantreft. Afhankelijk van de configuratie van de server zul je talrijke andere logbestanden aantreffen. Hieronder tref je een kort overzicht van mijn persoonlijke favorieten: firewall
Dit is het logbestand van de firewall. Als de firewall een pakketje niet heeft doorgelaten, zul je
156
Linux 4
apache2
boot.log mail
daar in dit bestand een logbericht over vinden. Houd er rekening mee dat dit bestand op een actieve server heel groot kan worden! Dit is niet een logbestand, maar een logdirectory. In deze directory vind je de logbestanden van je Apache-webserver. Als je virtuele hosts aanbiedt, tref je voor elke host een logbestand. Je leest hier precies wie wanneer contact gemaakt heeft met de server. In dit bestand kun je rustig nog eens nalezen wat er tijdens het opstarten van de server allemaal aan logberichten gegenereerd is. Hier zie je de activiteit van de mailserver. Gebruik van dit logbestand is bijvoorbeeld heel handig om te achterhalen of een mailbericht dat je ooit verzonden hebt, überhaupt wel juist door de mailserver is afgehandeld.
4.6.8 Roteren van logbestanden Logging is een mooi iets, maar theoretisch is er ook een schaduwkantje aan verbonden. Een hacker die door heeft dat je in sommige gevallen net iets té enthousiaste logging geconfigureerd hebt, zou door middel van logging de vaste schijf van de computer volledig vol kunnen schrijven. Stresstest Je gelooft niet dat verkeerd geconfigureerde logging inderdaad gevaarlijk kan zijn? Open in dat geval een editor en maak een bestandje met de naam dos. Zorg ervoor dat het bestand de executepermissie heeft en geef het bestand de volgende inhoud: #!/bin/bash while true do m ail -s “hoi” root < . done
Ga nu een kop koffie drinken. Heb je de koffie op? Mooi. Zorg er als je terug bent als eerste voor dat je scriptje gestopt wordt. Dit doe je met de toetsencombinatie Ctrl-C. Typ vervolgens de opdracht mail. Wat is er gebeurd? Kun je dit ook terugvinden in de logbestanden op de computer?
4 Beheer van processen
157
Om te zorgen dat een scenario als het bovenstaande niet voor rampen kan zorgen, worden logbestanden geroteerd. Dit gebeurt door het programma logrotate dat dagelijks kijkt of de logbestanden nog niet te groot zijn geworden. Hiervoor wordt logrotate aangeroepen door de cron-daemon die de bijbehorende configuratie vindt in /etc/cron.daily/logrotate. Als beheerder bepaal je wat er met een logbestand moet gebeuren wanneer aan het gestelde criterium wordt voldaan. Je kunt het bestand laten verwijderen, je kunt het comprimeren en een nieuwe maken en nog veel meer. Wat er precies moet gebeuren, regel je in het configuratiebestand /etc/logrotate.conf. Hierna zie je de inhoud van dit bestand, zoals het gebruikt wordt op Fedora Linux: # see “man logrotate” for details # rotate log files weekly weekly # keep 4 weeks worth of backlogs rotate 4 # create new (empty) log files after rotating old ones create # uncomment this if you wnt your log files compressed #compress # RPM packages drop log rotation information into this directory include /etc/logrotate.d # no packages own wtmp
-- we’ll rotate them here
/var/log/wtmp { monthly create0664 root utmp rotate 1 }
In logrotate-configuratiebestanden kan gebruikgemaakt worden van een groot aantal opties. Een aantal van de belangrijkste opties vind je in de volgende tabel.
158
Linux 4
Optie weekly rotate 4
create
compress
maxage 365
notifempty create 664 root root postrotate … endscript
Beschrijving Geeft aan dat eens per week actie ondernomen moet worden. Hiermee wordt bepaald dat de laatste vier versies van het bestand bewaard moeten worden. Als de optie rotate niet gebruikt wordt, wordt bij het maken van een nieuw logbestand het oude logbestand verwijderd. Het oude bestand wordt onder een nieuwe naam gemaakt en een nieuw leeg logbestand wordt gemaakt. Bij het maken van een nieuw bestand wordt het oude bestand gecomprimeerd opgeslagen. Wanneer een gecomprimeerd logbestand 365 dagen lang bewaard is, wordt het automatisch verwijderd. Als een logbestand leeg is, wordt het mechanisme logrotate er niet op toegepast. Maak na rotatie een nieuw bestand waarvan de modus wordt ingesteld op 640 en gebruiker en groep root eigenaar worden gemaakt. Soms is het na succesvolle rotatie nodig dat een service opnieuw gestart wordt. Deze en andere zaken kunnen geregeld worden met de optie postrotate.
Als laatste kom je in dit bestand een verwijzing tegen naar bestanden in de directory /etc/logrotate.d. In deze directory kunnen door verschillende RPM’s op een systeem op maat gemaakte bestanden worden neergezet die door logrotate verwerkt moeten worden. In deze bestanden vind je opdrachten die door logrotate geïnterpreteerd worden. Houd deze bestanden goed in de gaten, want hier gebeurt de werkelijke configuratie van de wijze waarop rotatie van de logbestanden geregeld moet worden. In deze bestanden wordt eveneens gebruikgemaakt van opties die beschreven zijn in de voorgaande tabel. Als voorbeeld zie je hierna hoe de logrotate-configuratie voor Samba er standaard uitziet: SFO:/etc/logrotate.d # cat samba /var/log/samba/log.nmbd {
4 Beheer van processen
159
compress dateext maxage 365 rotate 99 size=+1024k notifempty missingok copytruncate } /var/log/samba/log.smbd { compress dateext maxage 365 rotate 99 size=+1024k notifempty missingok copytruncate }
Zoals je in dit voorbeeld ziet, wordt in het logrotate-bestand voor Samba een rotatie gedefinieerd voor twee logbestanden. Als eerste voor log.nmbd dat door het nmbd-proces gemaakt wordt en daarnaast ook voor log.smbd dat door het smbd-proces gemaakt wordt. Zo specificeer je heel nauwkeurig per proces wanneer informatie wel en niet geroteerd moet worden en hoe dat moet gebeuren. 4.7
Processen en het pseudo-bestandssysteem /proc
De kernel heeft een methode nodig om informatie op te kunnen vragen over actieve processen. Hiervoor maakt de kernel het pseudo-bestandssysteem /proc aan. Dit bestand bestaat niet op de vaste schijf van de computer, maar is volledig in het werkgeheugen van de computer aanwezig. Om die reden wordt voor de meeste bestanden in /proc ook een grootte van 0 bytes aangegeven. Proc voorziet in een directorystructuur waarin elk proces een subdirectory heeft waarvan de naam overeenkomstig de PID is. In deze subdirectory’s houdt de kernel dynamische informatie bij over de processen. Je kunt deze subdirectory’s beschouwen als een soort notitieblokje
160
Linux 4
waarop de kernel belangrijke informatie over processen bijhoudt. Deze informatie kan soms ook voor een systeembeheerder van belang zijn. Daarom volgt nu een uiteenzetting over de informatie die in het bestandssysteem /proc kan worden teruggevonden. Figuur 4.7 Het pseudobestandssysteem /proc functioneert als een kladblokje van de kernel
/proc/1 Dit is een directory met informatie over het proces met PID 1. Voor elk actief proces bestaat een dergelijke subdirectory waar onder andere de volgende pseudo-bestanden en -directory’s in voorkomen: cmdline
fd
maps
Hierin staat de volledige opdrachtregel waarmee het proces is opgestart. Als het gehele proces uit het geheugen is geswapt, of als het een Zombieproces betreft, is dit bestand leeg. In de subdirectory fd bestaat een entry voor elk bestand dat door het proces wordt gebruikt. Elke entry die voorkomt in deze directory is een symbolische link naar het echte bestand dat door het proces in gebruik is. In het bestand maps staan de adressen van de geheugengebieden die door het proces worden gebruikt.
4 Beheer van processen
stat,
cpuinfo devices dma filesystems interrupts
ioports
kcore
kmsg
loadavg
161
Het bestand stat geeft statusinformatie over het statusproces. De opdracht ps gebruikt deze informatie. Een meer leesbare variant op dit bestand bestaat soms als het bestand status. Het bestand cpuinfo bevat uitgebreide informatie over de processor. In het bestand devices wordt een overzicht gegeven van devicedrivers die in de kernel zijn geconfigureerd. Toont welk DMA-channels op dit moment in gebruik zijn. Het bestand filesystems bevat een lijst van alle bestandssystemen die momenteel bij de kernel in gebruik zijn. Het bestand interrupts geeft een overzicht van de interrupts die in gebruik zijn. Ook staat er voor elke interrupt genoemd hoe zwaar de processorbelasting door de betreffende interrupt is. Het bestand ioports geeft een lijst van de I/O-ports die op dit moment in gebruik zijn en waarbij staat vermeld door welke processen de betreffende port wordt gebruikt. Dit bestand vertegenwoordigt het fysieke geheugen op de computer. De grootte ervan komt overeen met de totale hoeveelheid geheugen in de compu ter. Wanneer het bestand echter alleen voorkomt in de directory /proc, neemt het geen ruimte op de vaste schijf in beslag. Dit bestand kan worden gebruikt als coredump wanneer het gekopieerd wordt naar een ander medium. Dit bestand bewaart berichten die door de kernel worden gegenereerd. Deze berichten worden ook gerouteerd naar de systeemroutine syslog. De inhoud van dit bestand wordt uitgelezen met het programma dmesg. Het bestand loadavg houdt de werklast van het systeem bij. Hierin staat het aantal jobs dat in de afgelopen 1, 5 en 15 minuten in de queue is geplaatst. Opdrachten als uptime maken gebruik van de gegevens uit dit bestand.
162
Linux 4
meminfo
modules net
pci scsi stat sys
uptime
version
In het bestand meminfo wordt bijgehouden hoeveel vrij en gebruikt geheugen er is in het fysieke werkgeheugen en in het swapgeheugen. Ook staat aangegeven hoeveel buffers de kernel in beslag neemt. De gegevens uit dit bestand worden gebruikt door de opdracht free. Hierin staat een lijst van de modules die door het systeem zijn geladen. Het bestand net bevat informatie over de netwerkprotocollen die worden ingezet. De informatie die voorkomt in dit bestand kan worden uitgelezen met de opdracht netstat. Een lijst van alle PCI-devices die in het systeem voorkomen en hun configuratie. Een directory waarin informatie staat over alle SCSI-devices die in het systeem voorkomen. Statistische gegevens over de kernel en het systeem, zoals het aantal interrupts dat ontvangen is sinds het opstarten van het systeem. Bevat een aantal bestanden en directory’s die verwijzen naar kernelvariabelen. Zo komt er een bestand /proc/sys/kernel/hostname voor, waarin de naam van de host wordt bewaard. Sommige variabelen die hier staan, kunnen gewijzigd worden door de inhoud van de bestanden die hier voorkomen te wijzigen. Je kunt bijvoorbeeld het maximumaantal bestanden dat gelijktijdig geopend kan zijn tijdelijk aanpassen met de opdracht echo 4096 > /proc/sys/fs/file-max. In het bestand uptime is in seconden aangegeven hoe lang het systeem aan staat en hoeveel tijd hiervan is besteed aan het idle-proces. Dit geeft de inactiviteit van het systeem aan. Het bestand version ten slotte laat zien welke versie van de kernel momenteel in gebruik is. Deze informatie kan ook opgevraagd worden met de opdracht uname –a.
4 Beheer van processen
4.8
163
Samenvatting
Als beheerder van een computer is het belangrijk dat je de activiteit van processen kunt monitoren en waar nodig in kunt grijpen op de werking ervan. De opdracht ps is daarbij een handig hulpmiddel: niet alleen zie je hiermee door welke gebruiker een proces gestart is, maar ook is het mogelijk te kijken op welke terminal het proces actief is en hoeveel geheugenresources het proces in gebruik heeft. Op basis daarvan kun je waar nodig met kill en killall actie ondernemen. Als een proces als achtergrondproces gestart is, is echter speciale actie nodig. In dit geval is de opdracht jobs handig om achtergrondprocessen weer op de voorgrond te krijgen. Er zijn meer dingen die je als beheerder van processen kunt doen. Zo heb je onder andere geleerd hoe je een proces kunt schedulen met cron en at, zodat het op een bepaald tijdstip wordt uitgevoerd en hoe je de prioriteit van een proces kunt aanpassen met behulp van nice. Tot slot heb je gelezen over de wijze waarop syslog gebruikt wordt om activiteit op het systeem weg te schrijven naar logbestanden en hoe je een kijkje kunt nemen in het functioneren van de kernel met behulp van het pseudo-bestandssysteem /proc.
5
Configuratie van de netwerkkaart
5.1
Inleiding
De configuratie van elke server begint met de configuratie van de netwerkkaart. In dit hoofdstuk lees je hoe je hiervoor te werk gaat. Om te beginnen wordt je kennis van TCP/IP wat opgefrist aangezien dit het belangrijkste protocol is dat binnen een Linuxomgeving gebruikt wordt. Vervolgens leer je hoe je een netwerkkaart configureert voor gebruik van een vast IP-adres. Daarna lees je hoe je zelf een PPP-interface kunt maken. Vervolgens leer je hoe je de configuratie af kunt maken door ook routing en DNS name resolving te regelen. Tot besluit van dit hoofdstuk maak je kennis met enkele handige opdrachten die gebruikt kunnen worden om te testen of de netwerkverbinding naar behoren werkt. 5.2
Basiskennis TCP/IP
Om op een netwerk te kunnen communiceren zijn protocollen nodig. In de loop der jaren zijn er aardig wat verschillende netwerkprotocollen ontworpen. Slechts één daarvan is vandaag de dag nog relevant en dat is TCP/IP. Wanneer we het hebben over TCP/IP, hebben we het over een hele verzameling van protocollen die er samen voor zorgen dat netwerkfunctionaliteit beschikbaar is. Zo is er bijvoorbeeld IP dat ervoor zorgt dat elke netwerkkaart voorzien wordt van een uniek IP-adres, maar ook NNTP dat gebruikt kan worden om nieuwsberichten te versturen op een netwerk. Naast deze twee zijn er nog tal van andere adressen. Om een netwerkkaart te kunnen configureren heb je kennis nodig van de wijze waarop IP-adressen gebruikt worden. Voordat we bespreken hoe je
166
Linux 4
de netwerkkaart zelf kunt inrichten, zetten we eerst de meest relevante feiten over dit protocol uiteen. 5.2.1 Werken met IP-adressen Het Internet Protocol (IP) is sinds 1974 ontworpen om ervoor te zorgen dat alle computers op de wereld voorzien kunnen worden van een uniek IP-adres. In die tijd had niemand het idee dat internet zou uitgroeien tot het gigantische netwerk dat het tegenwoordig is! Het vervelende gevolg daarvan, is dat bij de specificatie van IP nooit rekening gehouden is met de aantallen computers die momenteel verbonden zijn met internet en allemaal hun eigen IPadres nodig hebben met als gevolg dat de IP-adressen die er zijn op dit moment bijna op zijn. Hiervoor zijn echter wel weer oplossingen beschikbaar, zoals Network Address Translation (NAT), waarbij een heel netwerk met één geregistreerd IP-adres het netwerk op kan en IP versie 6 waarmee vele miljarden apparaten voorzien kunnen worden van een IP-adres. Van deze oplossingen is NAT heel populair en wordt IP versie 6 momenteel nog niet op grote schaal toegepast. RFC’s De specificatie van alle protocollen waarmee we tegenwoordig te maken hebben, vindt plaats in de RFC’s, de zogenoemde Request For Comments. Dit zijn voorstellen waarin door wetenschappers en deelnemers uit het bedrijfsleven voorgesteld wordt hoe een protocol zich zou moeten gedragen. De eerste aanzet tot de IP-protocolstack werd gegeven in RFC 675, ‘Specification of Internet Transmission Control Program’ dat in december 1974 geschreven werd door Vint Cerf. Het begon echter pas echt grote vormen aan te nemen in januari 1980 toen J. Postel de eerste documentatie schreef van de DoD-standaard ‘Internet Protocol’. Je vindt een overzicht van alle RFC’s op www.ietf.org/rfc.html. Bij het ontwerp van het Internet Protocol (IP) is rekening gehouden met een aantal zaken. Elke computer op de wereld moet over een uniek adres beschikken. Groepen computers die op hetzelfde fysieke netwerk voorkomen, kunnen voorzien worden van een logisch netwerkadres.
5 Configuratie van de netwerkkaart
167
Communicatie tussen computers op verschillende netwerken kan tot stand gebracht worden. Deze functionaliteit wordt routering genoemd. Een van de belangrijkste zaken die door IP geregeld wordt, is adressering van computers. Voordat je kunt communiceren, moet je immers eerst op basis van een adres contact tot stand kunnen brengen. Om IP-adressen op de juiste wijze toe te kunnen passen is het van belang dat je weet hoe een IP-adres is opgebouwd.. 5.2.2 Opbouw van een IP-adres Een IP-adres bestaat uit vier bytes. Elk van deze bytes heeft een waarde die minimaal gelijk is aan 0 en maximaal aan 255. Het kleinst mogelijke getal dat je met vier bytes kunt vormen, is dus 0.0.0.0. Het grootst mogelijke getal dat je ermee kunt maken, is 255.255.255.255 en in totaal zijn er met deze vier bytes ruim vier miljard combinatiemogelijkheden te maken. Voor de liefhebbers: 4.294.967.296 om precies te zijn. Dat lijkt voldoende om elke computer op de wereld van een adres te voorzien toch? Toch is dat niet het geval. IP-adressen bestaan uit twee delen. Als eerste worden ze gebruikt om het netwerk waar een computer op voorkomt te adresseren en daarnaast worden ze gebruikt om de computer – of beter ‘node’, want er zijn meer dingen dan computers alleen die een adres kunnen hebben – te voorzien van een adres. Je kunt de adressen dus niet alleen gebruiken om computers te adresseren, maar je moet er ook alle netwerken mee van een adres voorzien. Het lastige daarbij is dat de informatie over het te gebruiken netwerk en de te gebruiken node voorkomen in één en hetzelfde IP-adres. Ergens is er dus een systeem nodig om onderscheid te maken tussen het netwerkdeel en het nodedeel in het IP-adres 172.16.15.12. Wat nu precies het netwerk- en wat het nodegedeelte is van een adres, wordt bepaald door het subnetmasker dat bij het IP-adres gebruikt wordt. Om het eenvoudig te maken is er een afspraak gemaakt waardoor snel duidelijk wordt welk deel van een IP-adres verwijst naar het netwerk en welk deel naar de node. IP-adressen worden namelijk verdeeld in klassen en elke klasse heeft zijn eigen standaardsubnetmasker. Daarbij wordt altijd het eerste deel van het adres gebruikt voor adressering van het netwerk en het laatste
168
Linux 4
deel voor adressering van nodes. Om te bepalen wat nu waarvoor gebruikt wordt, moet je kijken naar de eerste byte. In de volgende tabel wordt een overzicht gegeven. eerste byte
netwerkbytes
adresklasse
subnetmasker
0-127
eerste
A
255.0.0.0
128-191
eerste twee
B
255.255.0.0
192-223
eerste drie
C
255.255.255.0
224-255
n.v.t.
D en E
n.v.t.
Om je er alvast aan te laten wennen zijn in de tabel gelijk ook maar de subnetmaskers meegegeven. Achter adressen die beginnen met 224 en hoger staat de aanduiding n.v.t. Je kunt deze namelijk niet gebruiken om een computer van een adres te voorzien. Daarnaast hebben we erbij gezet om welke adresklasse het gaat. Op basis van het getal waarmee een adres begint, wordt het namelijk in een bepaalde klasse ondergebracht. Alle adressen in een adresklasse hebben met elkaar gemeen dat ze dezelfde bytes gebruiken voor adressering van netwerken dan wel nodes. Wellicht vraag je je af hoe deze adresklassen nu in de praktijk gebruikt worden? Welnu, dat is eenvoudig. Op het moment dat je met een of ander programma bijvoorbeeld het IP-adres 10.0.0.1 instelt op een netwerkkaart, wordt op basis van de standaardklasse-indeling van IP-adressen bepaald dat dit een klasse A-adres is. Om die reden wordt het IP-adres automatisch voorzien van het subnetmasker 255.0.0.0. Dat is handig, want zo hoef je hier als beheerder niet verder over na te denken. Als vervolgens alle andere beheerders over alle andere subnetmaskers ook niet nadenken, levert dat toch een werkend resultaat op omdat de subnetmaskers overal hetzelfde zijn. Aan de andere kant blijft het mogelijk om van de standaardafspraak af te wijken: als je het nodig vindt in plaats van het standaardsubnetmasker bijvoorbeeld het subnetmasker 255.255.255.0 te gebruiken bij het IP-adres 10.0.0.1, dan is dat geen probleem en geef je dat gewoon softwarematig op.
5 Configuratie van de netwerkkaart
169
Subnetmaskers Het is van groot belang dat subnetmaskers in alle netwerken gelijk zijn. Als er ergens een node is met een afwijkend subnetmasker, betekent dit dat deze node niet in staat is te communiceren met andere nodes in het netwerk. Let dus altijd op de subnetmaskers. Op een Linux-systeem controleer je de subnetmaskers met behulp van de opdracht ip address show of ifconfig. Volgens de standaardafspraak komen dus de computers met de klasse A-adressen 25.128.3.254 en 25.5.87.199 allebei voor in hetzelfde netwerk, namelijk het netwerk 25. De eerste byte begint met een getal tussen 0 en 127. Alleen de eerste byte wordt dus gebruikt voor adressering van netwerken. Het is trouwens gebruikelijk dat dit netwerk 21 genoteerd wordt als 25.0.0.0. Als je praat over een netwerk als geheel, zet je de nodebytes op nul. Kun je nu zelf vertellen op welke netwerken de computers met adressen 212.128.67.3 en 212.34.199.56 voorkomen? 5.2.3 De noodzaak te registreren Als je met IP-adressen aan het werk gaat, is het belangrijk te weten welke adressen je voor het netwerk kunt gebruiken. Om deze vraag te beantwoorden moet je weten of de computer direct met internet verbonden is en dus voorzien moet worden van een uniek adres, of dat de computer niet direct met internet verbonden is en dus voorzien kan worden van een willekeurig adres. Of eigenlijk moeten we zeggen: van een willekeurig adres uit een voor dit doel gereserveerde reeks. In het eerste geval, waarin computers direct met internet verbonden worden, moet je ervoor zorgen dat elke computer een uniek adres heeft. Neem contact op met de internetaanbieder, deze kan ervoor zorgen dat je een reeks adressen ter beschikking krijgt waarmee je aan het werk kunt. Als je op deze wijze eenmaal een reeks adressen verkregen hebt, zorg je er zelf voor dat de nodes in het netwerk elk een afzonderlijk uniek IP-adres krijgen. Als computers niet direct met internet verbonden worden, kun je gebruikmaken van een willekeurig adres. Het is echter niet verstandig om computers zomaar te voorzien van een lukraak geko-
170
Linux 4
zen adres. Stel je maar eens voor dat de computers later wel met internet verbonden worden, dan moet je alle adressen opnieuw uitdelen. Daarnaast is het bijzonder vervelend wanneer je een adres gebruikt dat door een server op internet ook al in gebruik is. Hoe zou immers het verschil bepaald kunnen worden tussen je eigen server en de server op internet? Om computers op een privénetwerk van een adres te voorzien, is een aantal adressen gereserveerd. Je kunt deze adressen naar hartenlust gebruiken, ze worden op internet namelijk niet verder gerouteerd. Deze adressen zijn de adressen uit de zogenoemde private address ranges die gedocumenteerd zijn in RFC 1918, ‘Address Allocation for Private Internets’. Het gaat om de volgende adressen: Het netwerk 10.0.0.0. De netwerken 172.16.0.0 tot en met 172.35.0.0. De netwerken 192.168.0.0 tot en met 192.168.255.0. 5.2.4 Speciale adressen Naast de hiervoor genoemde adressen is er nog een aantal adressen dat voor speciale doelen gereserveerd is: 0.0.0.0. Dit adres wordt in routingtabellen gebruikt om te verwijzen naar de standaardgateway. Dit is de computer die je nodig hebt om te communiceren met andere netwerken. Het netwerk 127.0.0.0. Dit adres wordt gebruikt voor loopback. Dit is een mechanisme dat op een computer gebruikt wordt zodat verschillende processen op een computer met elkaar kunnen communiceren. Loopback is van zeer groot belang. Zonder loopback doet bijvoorbeeld de X-server het niet. Daarnaast is de computer zelf altijd bereikbaar op het loopbackadres 127.0.0.1. De adressen 224.0.0.0 tot en met 239.255.255.255. Deze adressen zijn gereserveerd voor multicast. Je kunt deze multicast-adressen beschouwen als groepsadressen. Met name speciale apparaten op het netwerk, zoals routers, maken er gebruik van om met elkaar te kunnen communiceren. De adressen 240.0.0.0 en hoger. Deze adressen zijn gereserveerd voor experimentele doeleinden zoals IP versie 6. Het adres 255.255.255.255. Dit is het zogenoemde ‘local broadcast’-adres. Het wordt gebruikt om alle computer op dit netwerk te adresseren. Verder als de lokale router gaat het adres niet, want routers zijn geconfigureerd om broadcasts niet door te laten.
5 Configuratie van de netwerkkaart
171
Adressen waarbij het hostgedeelte de waarde 255 heeft, zoals 15.255.255.255 en 192.168.5.255. Dit zijn zogenoemde ‘directed broadcast’-adressen. Ze worden gebruikt om alle computers op het betreffende netwerk te adresseren. Dit is echter een techniek die maar zelden gebruikt wordt. De meeste routers staan het namelijk botweg gewoon niet toe. 5.2.5 Genoeg adressen In de loop der tijd zijn er aardig wat computers aan internet gekoppeld en al deze computers hebben een uniek adres nodig. Daarnaast zijn hele reeksen adressen gewoon niet beschikbaar, omdat ze al in eigendom zijn van een bedrijf. Dit heeft ertoe geleid dat er niet zo heel veel adressen meer over zijn en dat leidt soms tot problemen. Het komt bijvoorbeeld voor dat een bedrijf een klasse B-adres wil om een paar duizend computers te adresseren, maar dat zo’n klasse B-adres gewoon niet meer beschikbaar is. Er zijn dus andere oplossingen nodig. Naast computers die allemaal een uniek adres willen, komt nog eens dat er een hele generatie apparaten op de markt gebracht wordt die ook voorzien moeten worden van een uniek IP-adres. Denk hierbij bijvoorbeeld aan mobiele telefoons, maar ook aan bijvoorbeeld koelkasten waarvan via een internetverbinding bijgehouden wordt of er nog wel voldoende blikjes cola in staan (dergelijke koelkasten zijn een realiteit, je vindt ze op sommige stations). Zoals je begrijpt, maken deze ontwikkelingen het tekort alleen nog maar nijpender. Om de problemen die wegens het tekort aan IP-adressen te verwachten zijn te voorkomen, is een aantal jaren geleden begonnen met de ontwikkeling van een geheel nieuwe, nog robuustere versie van dit protocol. In de eerste ontwikkelfase werd het IpnG genoemd, wat staat voor IP next generation. Tegenwoordig staat het bekend als IP versie 6. Een van de belangrijkste vernieuwingen van IP versie 6 bestaat eruit dat niet langer 32 maar 128 bits gebruikt worden voor adressering. Afgerond levert dat 3,4e37, ofwel 34 gevolgd door 37 nullen op. Ruim voldoende om elke vierkante meter aardoppervlak meerdere adressen te geven! In de zomer van 1999 is de eerste internetprovider in Japan begonnen deze adressen uit te delen. Het zal echter nog wel een tijdje
172
Linux 4
duren voordat het hele internet over is. Het is namelijk een gigantische klus om alle computers van een IP versie 6-adres te voorzien. Ook anno 2007 loopt het nog niet echt storm met de uitgifte van IPv6-adressen. Toch kan elke Linux-distributie standaard al van deze adressen voorzien worden. Ook is het bij de betere provider mogelijk een IPv6-adres aan te schaffen. 5.2. Subnetten in detail Nog steeds veel te veel problemen op netwerken worden veroorzaakt doordat computers op een verkeerde wijze van IP-adressen worden voorzien, ondanks dat dit steeds vaker geautomatiseerd wordt door gebruik te maken van een DHCP-server. Een belangrijk aandeel in deze fout wordt genomen door het verkeerd gebruik van subnetmaskers. Om je te helpen dergelijke problemen te voorkomen vind je in deze paragraaf een overzicht van de achtergrondkennis die nodig is om op een succesvolle wijze netwerkadressen uit te delen en te gebruiken. Tip! Wil je het LPI-examen gaan doen? Zorg dan dat je kunt toveren met subnetmaskers. Er komen in het LPI-examen namelijk nogal wat vragen over dit onderwerp voor. Raadpleeg www. lpi.org voor meer informatie over de LPI-examens. Als netwerkbeheerder zorg je ervoor dat alle computers op het netwerk elkaar kunnen bereiken. Hiervoor moet gebruikgemaakt worden van een of andere vorm van adressering. Als meerdere netwerken met elkaar verbonden worden, moet uit deze adressering minimaal het volgende blijken: Op welk netwerk komt een computer voor? Wat is het unieke adres van de computer op dat netwerk? Zoals je in het voorgaande hebt gelezen, wordt voor dit doel gebruikgemaakt van subnetmaskers. Om subnetmaskers goed te kunnen begrijpen moet je weten hoe een subnetmasker is opgebouwd uit verschillende bytes die op hun beurt weer opgebouwd zijn uit bits. We gaan nu eerst kijken hoe binaire getallen eigenlijk zijn opgebouwd, zodat je de werking van subnetmaskers kunt doorgronden.
5 Configuratie van de netwerkkaart
173
Een IP-adres bestaat uit vier bytes en één byte bestaat uit acht bits. Een bit kan twee waarden hebben. Vergelijk het maar met een schakelaar, hij staat aan of uit. Binair gezien heeft hij de waarde 1 of de waarde 0. Als je niet weet wat binair is, dat is het getalstelsel waarin elk getal twee waarden, namelijk 0 of 1 kan hebben. Zo is decimaal het getalstelsel waarin elk getal 10 waarden, namelijk 0 tot 9 kan hebben. Als je twee bits met elkaar combineert, kunnen deze twee bits gezamenlijk vier verschillende waarden vormen (2 tot de macht 2 om het wiskundig te zeggen). Dit zijn de volgende binaire waarden 00 01 10 11 Je kunt deze vier binaire waarden ook decimaal opschrijven. De waarden worden dan 0, 1, 2 en 3. Bij elke volgende bit die wordt toegevoegd, wordt het aantal waarden dat erdoor gerepresenteerd wordt verdubbeld. Zo leveren drie bits ( 2 x 2 x 2) de volgende waarden: 000 (0) 001 (1) 010 (2) 011 (3) 100 (4) 101 (5) 110 (6) 111 (7) Voor het gemak hebben we er gelijk de decimale waarde maar achter gezet. Het eerste binaire getal uit dit rijtje heeft de decimale waarde 0. Dat zal iedereen volkomen duidelijk zijn: drie keer nul is immers nog steeds nul. Vervolgens heeft het tweede binaire getal de decimale waarde 5. Zie het zo: als de achterste bit aan staat (gelijk is aan 1), levert dat de decimale waarde 1 op. Zo levert het op een na achterste bit een decimale waarde 2 op als het aan staat. Het uit twee bits bestaande binaire getal 10 is immers gelijk aan het decimale getal 2. Binair gezien is 1+1 dus inderdaad gelijk aan 3.
174
Linux 4
Om nu te bepalen welke decimale waarde gerepresenteerd wordt door een binair getal, is het zaak dat je weet welke decimale waarde een bit heeft als het aan staat. De regel daarbij is dat de laatste bit in een getal een waarde 1 heeft als deze aan staat en elke bit daarvoor het dubbele van die waarde. Dat klinkt cryptisch, laten we het daarom eens in een overzichtje plaatsen door de waarden van alle bits uit een byte te geven: 1
1
1
1
1
1
1
1
128
64
32
16
8
4
2
1
In deze tabel hebben we voor het gemak elke bit even aangezet. De waarde van elke bit moet dus geteld worden om de decimale waarde te kunnen bepalen. Als je nu een binair getal ziet, houd het gewoon even naast deze tabel en tel alle waarden die horen bij de bits die aan staan bij elkaar op. In de volgende tabel zie je hoe dit op een willekeurig binair getal toegepast kan worden: 1
0
1
1
1
0
0
1
128
-
32
16
8
-
-
1
Voor het gemak zijn in deze tabel alleen de waarden weergegeven van de bits die aan staan. De bits die uitstaan zijn niet relevant en hoeven we dus niet mee te tellen. Om nu te achterhalen wat de decimale waarde is van dit getal, tellen we al deze waarden bij elkaar op. In dit geval dus 128 + 32 + 16 + 8 + 5. Dat maakt een totaal van 185. Vind je binair rekenen moeilijk? Wen je dan aan om in alle gevallen gebruik te maken van een tabel zoals hiervoor genoemd. Je kúnt natuurlijk een binaire rekenmachine gebruiken, zoals meegeleverd wordt in vrijwel elk modern besturingssysteem. Wij raden je dit niet aan, als beheerder is het namelijk erg handig als je inzicht hebt in de werking van binaire getallen. Subnetmaskers Zoals gezegd, in een IP-adres wordt op een flexibel getal bepaald welk deel van het adres gebruikt wordt om het netwerk te adresseren en welk deel gebruikt wordt om computers, ook wel hosts of nodes genoemd, te adresseren. De factor die uiteindelijk bepaalt wat nu waarvoor gebruikt wordt, is het subnetmasker. Dit is een getal dat net als een IP-adres uit vier bytes bestaat. Elke bit die in het IP-adres gebruikt wordt voor de adressering van het netwerk,
5 Configuratie van de netwerkkaart
175
heeft de binaire waarde 1 in het subnetmasker. Elke bit die in een subnetmasker gebruikt wordt voor de adressering van hosts, heeft de waarde 0 in het subnetmasker. Als dus in het IP-adres 150.100.19.9 de eerste twee bytes gebruikt worden om het netwerk te adresseren en de laatste twee bytes dus gebruikt worden om nodes te adresseren, wordt het subnetmasker dat hierbij hoort dus 255.255.0.0. Om het leven wat eenvoudiger te maken is ooit besloten dat elk IP-adres een standaardsubnetmasker krijgt. Dit zijn de afspraken waarin de verschillende adresklassen gedefinieerd worden. Je hebt hier al over gelezen, maar we zetten het nog even op een rij. Deze keer proberen we de standaardadresklassen ook binair te verklaren. Als de eerste bit van de eerste byte van een IP-adres uit staat, dus de waarde 0 heeft, wordt alleen de eerste byte van het IP-adres gebruikt om netwerken te adresseren. De rest van het adres wordt gebruikt om nodes te adresseren. Het subnetmasker wordt dan dus 255.0.0.0. We noemen dit een klasse A-adres. Als de eerste bit van de eerste byte van een IP-adres de waarde 1 heeft en de tweede bit van de eerste byte heeft de waarde 0, worden de eerste twee bytes van het adres gebruikt om netwerken te adresseren. Het subnetmasker wordt dan dus 255.255.0.0 en we noemen het een klasse B-adres. Als de eerste twee bits van de eerste byte van een adres de waarde 1 hebben en de derde bit heeft de waarde 0, worden de eerste drie bytes van het adres gebruikt om netwerken te adresseren. Het subnetmasker wordt dan dus 255.255.255.0 en we noemen het een klasse C-adres. Alle andere adressen hebben een speciale betekenis. Ze kunnen niet gebruikt worden om computers mee te adresseren. Laten we voor alle duidelijkheid het hiervoor genoemde nog even weergeven in een tabel:
176
Linux 4
Binaire waarde van
Decimale waarde
Bijbehorend
de eerste byte
van de eerste byte
subnetmask
Klasse
(x = maakt niet uit) 0xxxxxxx
(min-max) 0-127
255.0.0.0
A
10xxxxxx
128-191
255.255.0.0
B
110xxxxx
192-223
255.255.255.0
C
Uit het bovenstaande blijkt dat er dus een beperkt aantal netwerken is waarin heel erg veel nodes geadresseerd kunnen worden, namelijk de klasse A-netwerken. Hierin zijn immers standaard drie bytes gereserveerd voor de adressering van nodes. Er kunnen dus 256 x 256 x 256 –2 = 16777214 computers geadresseerd worden (we zullen het later over de reden van de -2 hebben). Verder is er een wat groter aantal netwerken waarin iets minder computers geadresseerd kunnen worden, namelijk de klasse B-adressen. Tot slot is er een behoorlijk aantal netwerken waarin maar 254 computers geadresseerd kunnen worden. Subnetten en geregistreerde IP-adressen Omdat IP-adressen schaars zijn, is het soms noodzakelijk dat je er op een slimme manier gebruik van maakt. Je ziet dit vooral bij internetaanbieders regelmatig gebeuren. Om dit te doen kan het handig zijn het standaardsubnetmasker, dat bij elk IP-adres gegeven wordt, aan te passen. Stel je bijvoorbeeld voor dat je een klasse B-adres hebt gekregen, bijvoorbeeld 150.100.0.0, maar dat je daarmee 20 netwerken moet adresseren waar in elk netwerk 30 computers voorkomen. Je hebt dan het probleem dat elk netwerk een uniek adres moet hebben. Onoplosbaar? Absoluut niet! Met één klasse B-adres kun je in totaal 65534 computers adresseren. Het is echter fysiek onmogelijk om zoveel computers op één netwerk te hebben. Dat hoeft ook niet, want je hebt 20 netwerken met 30 computers per netwerk. Hoe je dat oplost? Gebruik in dit geval ook de derde byte om netwerken te adresseren. Je houdt dan nog de hele vierde byte over om computers te adresseren. Het komt er hier dus op neer dat je afwijkt van de standaardafspraak voor een klasse C-subnetmasker. Je krijgt dan dus de volgende netwerken met bijbehorende subnetmaskers (we noemen alleen de eerste, het mag duidelijk zijn hoe de rest eruitziet).
5 Configuratie van de netwerkkaart
177
150.100.5.0 (255.255.255.0) 150.100.2.0 (255.255.255.0) 150.100.3.0 (255.255.255.0) 150.100.4.0 (255.255.255.0) Maar wat is hier nu het voordeel van? Neem bijvoorbeeld twee computers: één heeft het adres 150.100.5.1, de andere heeft het adres 150.100.2.2. Als deze computers allebei het subnetmasker 255.255.0.0 gebruiken, komen de computers voor in hetzelfde netwerk, namelijk het netwerk 150.100.0.0. (Voor alle duidelijkheid: als alle nodebits in een IP-adres de waarde 0 hebben, betekent dit dat we het over een netwerkadres hebben.) Als we nu het subnetmasker van deze computers wijzigen in 255.255.255.0, horen deze computers ineens thuis in verschillende netwerken. Het aardige is dat het daarbij niet uitmaakt of de computers inderdaad op verschillende fysieke netwerken voorkomen of niet. Ze zullen elkaar gewoon niet meer kunnen vinden omdat ze volgens het subnetmasker voorkomen in verschillende netwerken. De enige manier waarop ze nog met elkaar kunnen communiceren, is als er een router tussen hangt die de pakketjes van het ene netwerkadres overzet naar het andere netwerkadres.
Figuur 5.1 Door het subnetmasker aan te passen kunnen computers zich logisch gezien ineens in verschillende netwerken bevinden
Dit voorbeeld was redelijk eenvoudig: als je wel voldoende bits hebt om nodes te adresseren, maar onvoldoende bits om netwerken te adresseren, leen je gewoon hostbits om netwerken te adresseren door het subnetmasker aan te passen. Binnen het kader van het geregistreerde netwerkadres dat je hebt, ben je volkomen vrij om dit te doen. Als je een klasse B-adres hebt, is dit niet moeilijk. Je gebruikt dan gewoon de volledige derde byte. Als je echter een klasse C-adres hebt, kun je dit niet doen. Je hebt dan immers maar één byte om nodes te adresseren. Je zult in dat geval genoegen moeten nemen met een aantal bits dat je van deze ene byte leent.
178
Linux 4
Eén klasse C-adres, meer dan één netwerk Zoals gezegd, de kans dat je beschikt over een klasse B-adres dat je vervolgens kunt gebruiken om meerdere netwerken te adresseren, is vrij klein. In de meeste gevallen heb je hooguit een klasse C-adres. Toch is het mogelijk hiermee meerdere netwerken te bedienen, je mag alleen niet te veel computers per netwerk hebben. De oplossing hiervoor blijft in principe hetzelfde als in de vorige paragraaf. Je moet bits van de hostadressen lenen om netwerken mee te adresseren. Je kunt nu alleen niet een hele byte nemen. Je zult zuinig en precies het aantal bits moeten nemen dat je ook daadwerkelijk nodig hebt. Laten we eens uitgaan van een voorbeeld. Stel, je hebt beschikking over het volledige netwerkadres 200.100.100.0. Hiermee moet je een totaal van vijf netwerken van geldige IP-adressen voorzien. Hoeveel bits heb je daar dan voor nodig? Het antwoord op deze vraag is hetzelfde als het antwoord op de vraag hoeveel bits je nodig hebt om een totaal van vijf combinatiemogelijkheden te maken. Is één bit genoeg? Absoluut niet, daarmee kun je immers maar twee combinatiemogelijkheden maken. Zijn twee bits genoeg? Bijna, maar net niet. Met twee bits kun je immers maar vier combinatiemogelijkheden maken. Je hebt dus een totaal van drie bits nodig. Hiermee kun je acht combinatiemogelijkheden maken, dus maximaal acht netwerken adresseren. Drie meer dan dat je nodig hebt, maar dat moet je maar voor lief nemen. Je weet dat het altijd het eerste deel van een IP-adres is dat gebruikt wordt voor de adressering van netwerken. Het zijn dus ook de eerste bits in het subnetmasker die gebruikt worden om aan te geven dat het een netwerk wordt. Binair gezien wordt het subnetmasker voor de vierde byte in dit voorbeeld dus 11100000. Kunnen we dat ook decimaal opschrijven? Natuurlijk! 128 + 64 + 32 = 224. De eerste drie bytes van het subnetmasker blijven gewoon wat ze zijn. We hebben het hier immers over een geregistreerd klasse C-adres. We hebben met andere woorden niets te zeggen over die eerste drie bytes. Het subnetmasker wordt dus 255.255.255.224. Nu is het natuurlijk de hamvraag welke netwerken dit subnetmasker oplevert. Ook dit kun je weer het gemakkelijkst binair bekijken. Een subnetmasker 224 (we hebben het nu alleen even over de relevante vierde byte) betekent dat je de eerste drie bits van deze
5 Configuratie van de netwerkkaart
179
byte kunt gebruiken om netwerken te adresseren. De laatste vijf bits moet je in alle gevallen van afblijven, die mag je immers alleen gebruiken om nodes mee te adresseren. Binair gezien mag je dus met deze vierde byte de volgende netwerken definiëren: 00000000 (0) 00100000 (32) 01000000 (64) 01100000 (96) 10000000 (128) 10100000 (160) 11000000 (192) 11100000 (224) We hebben er voor het gemak gelijk maar even de decimale adressen achter gezet. Wellicht dat je je nu afvraagt: ‘Ja maar leuk, maar waarmee moet ik nu mijn nodes adresseren?’ Deze vraag is eenvoudig te beantwoorden. Per netwerk heb je in principe nog vijf bytes over om nodes te adresseren. Maar let er wel op dat al deze vijf bytes niet de waarde 0 mogen hebben en ze mogen ook niet alle vijf de waarde 1 hebben. Alle hostbits met de waarde 0 wordt immers gebruikt om te verwijzen naar een netwerkadres. Alle hostbits met de waarde 1 is een speciaal adres dat het broadcastadres genoemd wordt. Dit adres wordt gebruikt om alle computers die op een bepaald netwerk voorkomen te adresseren. Maar alle combinaties van 00001 tot en met 11110 zijn dus toegestaan. Om dit maar even concreet te maken: zo zijn dus in het netwerk 200.100.100.32, dat vergezeld gaat van het subnetmasker 255.255.255.224 de adressen 200.100.100.33 tot en met 200.100.100.62 geldige adressen waarmee computers geadresseerd mogen worden. Uit het voorgaande heb je kunnen afleiden dat hoe meer bits je gebruikt om netwerken te adresseren, hoe minder bits er uiteindelijk overblijven om de nodes te adresseren. Je hebt er immers maar acht in totaal. In de tabel wordt dit voor alle duidelijkheid nog eens samengevat in een tabel weergegeven. In de tabel wordt ervan uitgegaan dat het subnet wordt toegepast op de vierde byte van een IP-adres:
180
Linux 4
Aantal bits gebruikt voor
Aantal te adresseren
Aantal nodes dat in een
netwerken 0
netwerken 0
netwerk mag voorkomen 254
1
2
126
2
4
62
3
8
30
4
16
14
5
32
6
6
64
2
7
128
0
8
256
0
Voordat je subnetmaskers gaat toepassen, moet je dus altijd eerst even rekenen. Als je bijvoorbeeld zes netwerken hebt, met 35 nodes per netwerken, heb je aan één geregistreerd klasse C-adres niet genoeg om alle nodes te adresseren. Je zult dan meer adressen moeten aanvragen. 5.2.7 CIDR-notatie Je hebt tot dusver aardig wat kunnen lezen over het werken met subnetmaskers. In de voorbeelden die tot zover gehanteerd zijn, zijn de subnetmaskers steeds volledig uitgeschreven, bijvoorbeeld 255.255.255.0. Er is echter nog een andere manier waarop je een subnetmasker kunt schrijven; de zogenoemde CIDR-methode (Classless Inter Domain Routing). In deze methode schrijf je niet het volledige subnetmasker, maar alleen het aantal bits dat in het subnetmasker gebruikt wordt. In plaats van het volledige subnetmasker 255.255.255.0 kun je dus de CIDR-notatie /24 gebruiken. Je doet dit door de /24 direct achter het te gebruiken IP-adres te plaatsen, bijvoorbeeld 192.168.0.12/24. Omdat luiheid een deugd is voor systeembeheerders en de CIDR-notatie nu eenmaal minder schrijfwerk met zich meebrengt, zul je regelmatig zien dat adressen in deze notatie geschreven worden. 5.3
Configuratie van een vaste netwerkkaart
Elke distributie heeft tegenwoordig zijn eigen manier om een netwerkkaart te configureren. Hetzelfde geldt overigens voor configuratie van modemverbindingen en DSL (wat strikt genomen overigens ook gewoon netwerkkaarten zijn). Vaak kun je blij zijn met
5 Configuratie van de netwerkkaart
181
deze min of meer automatische configuratieprogramma’s, ze maken het leven namelijk een stuk eenvoudiger. De configuratie van een modemverbinding bijvoorbeeld was een jaar of vijf geleden namelijk nog een regelrechte crime waarbij verschillende configuratiebestanden bewerkt moesten worden, een klusje waar zelfs een slimme beheerder al snel een dagje zoet mee was. In paragraaf 5.4 lees je hier meer in detail over. Vandaag de dag is de configuratie van modem, ISDN, netwerkkaart of DSL nauwelijks nog ingewikkeld. Als beheerder echter is het belangrijk dat je weet hoe je een netwerkkaart handmatig moet instellen. Een grafische interface is immers heel leuk, maar ook wanneer de grafische interface om welke reden dan ook niet beschikbaar is, moet je weten hoe je een netwerkkaart kunt configureren. We zullen nu eerst behandelen welke opdrachten gebruikt kunnen worden om de netwerkkaart in te stellen en daarna leer je hoe je ervoor zorgt dat ook de juiste drivers voor de netwerkkaart geladen zijn. 5.3.1 De netwerkkaart configureren met ifconfig Kort samengevat moeten er twee dingen gebeuren om een netwerkkaart te activeren. De netwerkkaart moet beschikbaar zijn en als hij dan beschikbaar is, moet hij aangestuurd worden. Voor wat betreft de beschikbaarheid van de netwerkkaart kunnen we kort zijn: hiervoor moet de netwerkkaart als kernelmodule geladen kunnen worden. Verderop in dit hoofdstuk leer je hier meer over. Als de netwerkkaart op het systeem bekend is, moet er vervolgens voor gezorgd worden dat hij ook aangestuurd wordt. Dit gebeurt met de opdracht ifconfig of met de opdracht ip. We bespreken eerst de werking van de opdracht ifconfig. Tijdens de opstartprocedure zal er gewoonlijk voor gezorgd worden dat deze opdracht automatisch uitgevoerd wordt. Je kunt de opdracht ook handmatig gebruiken. Dit is niet moeilijk: geef de opdracht ifconfig, vervolgens de naam van de interface en tot slot het IP-adres dat gebruikt moet worden. Zo kan bijvoorbeeld met de volgende opdracht een netwerkkaart worden aangestuurd: ifconfig eth0 192.168.0.10
De opdracht ifconfig stuurt vervolgens eth0 aan. De kernel weet dat eth0 gelijk is aan de 3c59x-netwerkkaart. Dit zorgt ervoor dat de bijbehorende module op dat moment dynamisch geladen kan
182
Linux 4
worden. Voor alle overige instellingen wordt de standaardwaarde gebruikt. Op basis van de standaardadresklasse wordt in het voorgaande voorbeeld bijvoorbeeld gebruikgemaakt van het standaardsubnetmasker 255.255.255.0. Als je om welke reden dan ook de netwerkkaart daarna weer down wilt brengen, gebruik je de volgende opdracht: ifconfig eth0 down
5.3.2 Geavanceerde opties van ifconfig Op basis van het voorgaande kun je een netwerkkaart op het systeem activeren. Hierbij worden alle standaardinstellingen gebruikt. Leuk natuurlijk, maar soms wil je meer dan de standaardinstellingen. Maak in dat geval gebruik van een van de vele opties die bij de opdracht ifconfig gebruikt kunnen worden. Ook is het mogelijk met ifconfig een tweede IP-adres aan een interface te verbinden. Dit tweede IP-adres wordt aangeduid als een IP-alias of een secundair IP-adres. Dit is bijvoorbeeld nuttig wanneer de computer binnen een testnetwerk moet kunnen communiceren, maar gelijktijdig ook voorzien moet zijn van een IP-adres waarmee hij op internet kan communiceren. Ook als er op de server een service draait die op een eigen IP-adres bereikt moet kunnen worden, is de optie te werken met secundaire IP-adressen erg handig. Ook hierbij maak je gewoon gebruik van de opdracht ifconfig. Je gebruikt alleen een speciale aanduiding bij de verwijzing naar de netwerkkaart om duidelijk te maken dat het hier een tweede netwerkkaart betreft. Waar je in het voorgaande de opdracht ifconfig eth0 192.168.0.10 gebruikt hebt om de netwerkkaart te voorzien van een IP-adres, gebruik je bijvoorbeeld ifconfig eth0:0 192.168.0.11 om diezelfde computer van een tweede adres te voorzien. Heb je nog meer adressen nodig op dezelfde netwerkkaart? Geen probleem, dan herhaal je gewoon de voorgaande procedure. Het derde netwerkadres koppel je aan eth0:1, het vierde adres aan eth0:2, enzovoort.
5 Configuratie van de netwerkkaart
183
Figuur 5.2 Met ifconfig voeg je op eenvoudige wijze een secundair IP-adres toe aan een netwerkkaart
Naast de mogelijkheid te werken met een secundair IP-adres, biedt ifconfig nog veel meer mogelijkheden. Twee van deze mogelijkheden zul je met name weleens tegenkomen. Om te beginnen is dat de optie netmask. Als je namelijk een ander dan het standaard-netmask wilt gebruiken, geef je het te gebruiken netmask aan met de optie netmask, bijvoorbeeld in ifconfig eth0 10.0.0.1 netmask 255.255.255.0. Er is echter één probleem: bij het instellen van een afwijkend subnetmasker, wordt niet automatisch ook het broadcastadres aangepast. Dit blijkt wanneer je na de opdracht ifconfig eth0 10.0.0.1 netmask 255.255.255.0 de instellingen van de netwerkkaart bekijkt met de opdracht ifconfig eth0: het broadcastadres staat gewoon nog ingesteld op het broadcastadres van een standaardklasse A-netwerk. Om ervoor te zorgen dat ook deze optie goed wordt ingesteld, gebruik je eveneens de optie broadcast. De volledige opdracht wordt dus ifconfig eth0 10.0.0.1 netmask 255.255.255.0 broadcast 10.0.0.255. Let er trouwens even op dat de opdracht ifconfig veel kan, maar dat hij niet gebruikt kan worden om de standaardgateway in te stellen. Daarvoor heb je de opdracht route nodig (route add default gw adres-van-uwgateway om precies te zijn). Later in dit hoofdstuk lees je meer over route. 5.3.3 Werken met de opdracht ip Ondanks dat heel veel beheerders nog dagelijks gebruikmaken
184
Linux 4
van de opdracht ifconfig, doet Linux zelf dat allang niet meer. In plaats van ifconfig wordt tegenwoordig gebruikgemaakt van de opdracht ip. Dit is een zeer uitgebreide opdracht waarmee alle aspecten van de netwerkkaart beheerd kunnen worden. Laten we eens kijken hoe het werkt. Met de opdracht ip maak je opdrachten die eruitzien als complete zinnen. ip address show is nog maar een kort voorbeeld, het kan ook veel langer. De opdracht zelf is opgebouwd uit verschillende onderdelen. Achter elk onderdeel kun je de aanduiding ‘help’ gebruiken om te vertellen dat je meer informatie nodig hebt. Zo kun je direct beginnen met ip help om vervolgens bedolven te worden onder een lading informatie, maar als je nu al weet dat je als tweede onderdeel van de opdracht wilt gaan werken met de specificatie address, kun je ook meteen de opdracht ip address help gebruiken. In dat geval krijg je een lijst te zien van opties die alleen betrekking hebben op de opdrachten die beginnen met ip address. Met betrekking tot het beheer van de netwerkkaart zijn er twee ip-opdrachten die je moet beheersen. Om te beginnen moe je natuurlijk kunnen kijken wat de huidige instellingen van de netwerkkaart zijn. Dit doe je met ip address show. Het resultaat van deze opdracht is een listing zoals je deze hier ziet: BTN:~ # ip address show 1: lo: mtu 16436 qdisc noqueue link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid _ lft forever preferred _ lft forever 2: eth0: mtu 1500 qdisc pfifo _ fast qlen 1000 link/ether 00:18:8b:ac:c9:54 brd ff:ff:ff:ff:ff:ff inet 192.168.1.78/24 brd 192.168.1.255 scope global eth0 inet6 fe80::218:8bff:feac:c954/64 scope link valid _ lft forever preferred _ lft forever 3: sit0: mtu 1480 qdisc noop link/sit 0.0.0.0 brd 0.0.0.0 4: vmnet1: mtu 1500 qdisc pfifo _ fast qlen 1000
5 Configuratie van de netwerkkaart
185
link/ether 00:50:56:c0:00:01 brd ff:ff:ff:ff:ff:ff inet 172.16.4.1/24 brd 172.16.4.255 scope global vmnet1 inet6 fe80::250:56ff:fec0:1/64 scope link valid _ lft forever preferred _ lft forever 5: vmnet8: mtu 1500 qdisc pfifo _ fast qlen 1000 link/ether 00:50:56:c0:00:08 brd ff:ff:ff:ff:ff:ff inet 172.16.210.1/24 brd 172.16.210.255 scope global vmnet8 inet6 fe80::250:56ff:fec0:8/64 scope link valid _ lft forever preferred _ lft forever
Zoals je ziet, zijn er op de computer waarop deze opdracht gebruikt werd in het totaal vijf netwerkkaarten actief. De meest belangrijke is eth0. Je vindt deze bovenaan in de lijst. Achter de aanduiding link/ether staat het MAC-adres van de netwerkkaart, daarnaast zie je achter de aanduiding inet het IP-adres van de netwerkkaart staan. Al het overige is van minder belang. Grote kans overigens dat je op je eigen computer minder informatie ziet staan. Op de computer waar dit voorbeeld genomen is, waren namelijk ook meerdere VMware virtuele netwerkkaarten in gebruik. Naast het bekijken welke adresinformatie is ingesteld, is het ook van belang dat je een nieuw adres kunt toewijzen. Hiervoor gebruik je de opdracht ip address add. Vervolgens heb je nog drie andere opties nodig. Als eerste is dat het te gebruiken IP-adres. Daarna komt de aanduiding dev en deze wordt op zijn beurt weer gevolgd door de aanduiding van de te gebruiken device. Het uiteindelijke resultaat wordt dus een opdracht als ip address add 10.0.0.10 dev eth0. Uiteraard kun je met de opdracht ip ook aangeven wat het te gebruiken netmask is. Het is niet nodig om ook een broadcastadres op te geven. Het juiste broadcastadres volgt namelijk automatisch als je het netmask goed aangegeven hebt. Je doet dit door achter het netwerkadres de netmaskaanduiding in CIDR-aanduiding te geven, bijvoorbeeld ip address add 10.0.0.10/24 dev eth0. En mocht je vervolgens genoeg hebben van het toegewezen IP-adres, dan gebruik je ip address del 10.0.0.10 dev eth0 om het weer weg te gooien. Zoals je ziet, het is misschien even wennen, maar als je het een tijdje gedaan hebt, weet je niet beter meer en wil je ook niet anders.
186
Linux 4
Luiheid is een deugd Zoals we al eerder hebben gezegd, luiheid is een deugd. Daar hebben de makers van de opdracht ip dan ook volledig rekening mee gehouden. Je mag zolang er geen verwarring kan bestaan ook afkortingen gebruiken in plaats van volledige aanduidingen. Dit betekent dat een opdracht als ip address show ook geschreven kan worden als ip a s. Omdat er geen misverstand kan bestaan, zal de opdracht precies weten wat de bedoeling is. Om je te laten wennen aan de werking van de opdracht ip tot besluit van deze paragraaf nog een korte samenvatting. Om te beginnen is er de parameter link. Deze gebruik je om eigenschappen van een interface (link) te bekijken of in te stellen. De volgende opdrachten zijn hier voorbeelden van: ip link show – Toont de huidige configuratie voor alle netwerkkaarten in het systeem. ip link set eth0 down – Zet eth0 uit. ip link set eth0 mtu 1492 – Stelt een maximum transfer unit (maximale pakketgrootte) in van 1492 bytes voor eth0. Vervolgens kun je ip ook gebruiken om adressen toe te kennen. De volgende opdrachten zijn hier voorbeelden van: ip address add 10.0.0.1/24 dev eth0 broadcast+ – Stelt een netwerkadres in met bijbehorend subnetmasker voor interface eth0. Je moet een subnetmasker opgeven zoals hier gebeurt met de CIDR-notatie /24. Als je dit vergeet, wordt namelijk het standaardsubnetmasker 255.255.255.255 ingesteld. ip address add 192.168.0.1/24 broadcast+ dev eth0 label eth0:5 – Deze opdracht toont een kleine variatie op het voorgaande: als extra wordt gebruikgemaakt van de toevoeging label. In dit voorbeeld wordt deze toevoeging gebruikt om een netwerkkaart te voorzien van een extra IP-adres. Tot slot lopen we even vooruit op paragraaf 5.3.6 en tonen we je hoe je de opdracht ip kunt gebruiken om een standaardroute in te stellen: ip route delete default – Als er al een standaardroute ingesteld was, wordt deze met behulp van deze opdracht verwijderd.
5 Configuratie van de netwerkkaart
187
ip route add default via 192.168.0.5 – Voegt de standaardroute toe. Let op de aanduiding via. Deze is echt noodzakelijk om aan te geven via welke router de standaardroute loopt. ip route add 192.168.5.0/24 via 192.168.0.5 – Een variant op de voorgaande opdracht: hiermee voeg je een route toe voor een specifiek netwerk. Pakketjes naar dit netwerk moeten via 192.168.0.1 gerouteerd worden. ip route show – Toont de opbouw van de routingtabel zoals deze op dit moment is. 5.3.3 Linux als DHCP-client Met de opdrachten ifconfig of ip configureer je zelf handmatig met welk IP-adres de computer aan het werk moet gaan. Uiteraard is het ook mogelijk een Linux-computer in te richten als DHCPclient. Hiervoor wordt gebruikgemaakt van de opdracht dhclient. Met behulp van deze opdracht zorg je ervoor dat het netwerk automatisch voorzien wordt van IP-configuratie. Je kunt deze opdracht natuurlijk handmatig uitvoeren, maar in de meeste gevallen echter zal het vanuit de opstartroutine van de computer geactiveerd worden. De naam van deze opdracht wil overigens tussen de verschillende distributies nog weleens afwijken: soms wordt dhclient gebruikt, maar het kan ook voorkomen dat de opdracht anders heet. Gebruik indien nodig de opdracht man –k dhcp om een lijst te tonen van alle opdrachten waarbij DHCP gebruikt wordt. Je ziet dan in een handomdraai wat de juiste opdracht is om de IP-configuratie op te halen bij een DHCP-server. Figuur 5.3 Met de opdracht dhclient kun je vanaf de meeste distributies IPconfiguratie ophalen van een DHCP-server
188
Linux 4
5.3.4 ifup en ifdown In het voorgaande heb je gelezen over afzonderlijke opdrachten die gebruikt kunnen worden om Linux te voorzien van een ‘hard’ IP-adres dat is ingesteld met ifconfig, of een IP-adres dat dynamisch wordt opgevraagd van een DHCP-server met behulp van de opdracht dhclient. In beide gevallen zal het niet voorkomen dat je deze opdrachten zelf moet invoeren. Ze zullen vanuit de opstartprocedure automatisch geactiveerd worden op basis van de configuratie die hiervoor is opgeslagen in configuratiebestanden in de directory /etc/sysconfig. Als je met ifconfig een netwerkinterface down brengt, moet je er op het moment dat hij weer geactiveerd wordt, rekening mee houden dat alle configuratie van de netwerkkaart opnieuw moet worden ingevoerd. Dat is natuurlijk niet echt handig. Om die reden is het handiger gebruik te maken van de opdrachten ifup en ifdown. Wil je eth0 uitzetten? Gebruik dan ifdown eth0. Wil je eth0 weer activeren met zijn gangbare configuratie? Gebruik dan ifup eth0. De huidige configuratie wordt vervolgens ingelezen en je kunt direct weer aan het werk. 5.3.5 Configureren van een draadloze netwerkkaart Als je boft, is je draadloze netwerkkaart voorzien van een stuurprogramma voor Linux en kun je hem zonder problemen installeren. Vaak is dit niet het geval en zul je zelf aan het werk moeten om de netwerkkaart te kunnen gebruiken. In veel gevallen is het zelfs niet eens mogelijk gebruik te maken van de draadloze netwerkkaart, omdat de fabrikant van de netwerkkaart geen code vrijgeeft waarmee de netwerkkaart aangestuurd kan worden. In dat geval ben je aangewezen op software die ervoor zorgt dat je de netwerkkaart onder Linux kunt gebruiken met behulp van het Windows-stuurprogramma dat voor de netwerkkaart verkrijgbaar is. Hiervoor maak je gebruik van het open source-project NdisWrapper of de commerciële software van Linuxant. De eerste vind je soms als onderdeel van de distributie en anders op ndiswrapper.sourceforge.net, de laatste kun je downloaden van www. linuxant.com. Aangezien de Linuxant-software het op dit moment beter doet dan de NdisWrapper, bespreken we hier hoe je door gebruik te maken van deze software de draadloze netwerkkaart aan het werk kunt krijgen. Let wel even op: het betreft hier commerciële software die je voor 20 dollar moet kopen. Voordat je het ook daadwerkelijk koopt, kun je de software eerst dertig dagen uitproberen.
5 Configuratie van de netwerkkaart
189
Tip! Probeer altijd eerst of de netwerkkaart het ook doet met de software van de distributie. Vooral in recente distributies is de ondersteuning van draadloze netwerkkaarten sterk verbeterd en als het op die manier lukt, kun je toch eenvoudig 20 dollar besparen. 1. Ga naar www.linuxant.com, schrijf jezelf in en haal de gratis trialversie van het programma binnen. Let erop dat je de software voor de juiste kernelversie gebruikt, je kunt de versie van de kernel achterhalen door in een consolevenster de opdracht uname –r te geven. 2. Geef de opdracht unzip driverloaderversienummer en vervolgens rpm –i driverloaderversienummer om de driver loader te installeren. 3. Activeer nu de browser en ga naar http://127.0.0.1:18020; dit is de webpagina waarop je de Linuxant-driverloader verder kunt configureren. 4. Zorg er nu voor dat de Windows-stuurprogramma’s voor de draadloze netwerkkaart ergens op het systeem beschikbaar zijn en klik op Upload Windows Driver om de Windows-stuurprogramma’s voor de netwerkkaart te uploaden. 5. Blader nu naar de locatie waar zich het Windows-stuurprogramma voor de netwerkkaart bevindt. Je herkent dit stuurprogramma aan zijn naam: het is een bestand met de extensie .inf dat zich op het installatiemedium van de netwerkkaart bevindt. Let even op: het gaat niet om het bestand autorun.inf, maar om een ander bestand dat zich meestal in een subdirectory op de installatie-cd bevindt. Volg de aanwijzingen om het bestand te downloaden naar de computer. Het kan zijn dat er meer bestanden nodig zijn. Volg de aanwijzingen om ook deze binnen te halen. 6. Als alles goed gegaan is, wordt de netwerkkaart nu herkend. Je zult hem echter nog niet kunnen gebruiken omdat er nog geen licentie beschikbaar is. Klik op de webpagina op Settings om een licentie in te kunnen voeren. Volg hiervoor de aanwijzingen die vanuit de webpagina gegeven worden. Op deze webpagina kun je ook aangeven dat je gebruik wilt maken van de gratis triallicentie. 7. Nadat je hebt aangegeven van wat voor type licentie je gebruik wilt maken, moet je een licensetoken genereren. Klik hiervoor op de betreffende link op de webpagina. De licentie is nu geïnstalleerd.
190
Linux 4
Je keert nu weer terug naar een venster waar je het MAC-adres van de netwerkkaart ziet staan. Klik hier op Proceed om verder te gaan met de installatie van de netwerkkaart. 8. Klik nu ten slotte op Save om de licentie te bewaren en de netwerkkaart in gebruik te nemen. Het kan nodig zijn in het laatste venster dat je ziet nog even op Update te klikken voordat je het stuurprogramma in gebruik kunt nemen. De netwerkkaart is nu aan de computer toegevoegd als wlan0. Aangezien de computer tot nu toe gewend was gebruik te maken van een bekabelde netwerkkaart, wordt de draadloze netwerkkaart niet automatisch gestart. Nu is het zaak de configuratie om te draaien en ervoor te zorgen dat de draadloze netwerkkaart automatisch gestart wordt en de bekabelde netwerkkaart alleen handmatig gestart wordt. Voordat je dit definitief in het systeem gaat doorvoeren, is het aan te raden eerst te controleren of een en ander handmatig aan de praat te krijgen is. In de volgende procedure lees je hoe je de bekabelde netwerkkaart handmatig kunt uitzetten, terwijl je de draadloze netwerkkaart handmatig gaat configureren. 1. Geef de opdracht ifconfig eth0 down. Hiermee zet je de bekabelde netwerkkaart uit. 2. Geef nu de opdracht ifconfig wlan0 192.168.0.100 netmask 255.255.255.0. Uiteraard zorg je ervoor dat het IP-adres dat je gebruikt geldig is op het netwerk. 3. Gebruik nu de opdracht ping om te kijken of je met de router op het netwerk kunt communiceren. Gebruik bijvoorbeeld de opdracht ping 192.168.0.1, maar let er wel even op dat je het juiste IP-adres gebruikt. Krijg je antwoord? Dan is de draadloze netwerkkaart in de lucht. Wanneer deze test geslaagd is, wordt het tijd ervoor te zorgen dat voortaan de bekabelde netwerkkaart alleen handmatig gestart kan worden en de draadloze netwerkkaart automatisch in de lucht komt. Gebruik hiervoor het configuratieprogramma dat met de distributie wordt meegeleverd. Onder SUSE Linux vind je de relevante instellingen bijvoorbeeld wanneer je in YaST2 de netwerkkaart selecteert, de eigenschappen activeert en vervolgens onder de optie Geavanceerd kiest voor Gedetailleerde instellingen. Start de computer opnieuw op wanneer je hiermee klaar bent en controleer of de draadloze netwerkkaart het ook daarna nog doet.
5 Configuratie van de netwerkkaart
191
Gefeliciteerd als je tot hier gekomen bent, dat betekent dat de draadloze netwerkkaart gebruikt kan worden. Je bent er echter nog niet: de netwerkkaart wordt nu namelijk zonder beveiliging gebruikt. Voor een veilig netwerk is het aan te raden gebruik te maken van WEP-encryptie. Wellicht dat tegen de tijd dat je dit leest ook de veel veiliger manier van encryptie WPA gebruikt kan worden. Deze en andere geavanceerde opties kun je instellen vanuit het beheerprogramma van de distributie. In SUSE’s YaST vind je deze instellingen wanneer je de eigenschappen van de draadloze netwerkkaart selecteert. Selecteer vervolgens onder Geavanceerd de optie Hardware Details en klik daarna op Draadloze instellingen. Je ziet nu een venster waarin alle benodigde draadloze instellingen gedaan kunnen worden. Vooral belangrijk zijn de instellingen voor de netwerknaam en de encryptiesleutel. Wanneer je de draadloze communicatie door middel van het WEP-protocol wilt beveiligen, moet je hier een sleutel invoeren die overeenkomt met de sleutel die op het wireless Access Point gebruikt wordt. Als dat nodig is, vind je onder Expert Instellingen nog een aantal opties waarmee je de draadloze verbinding verder kunt configureren. Hier regel je onder andere het draadloze kanaal dat gebruikt moet worden en de bitrate waarmee de gegevens verzonden moeten worden. Gebruik deze opties alleen wanneer je er zeker van bent dat je ze nodig hebt. Als je je afvraagt waarvoor ze dienen, heb je ze niet nodig en kun je ze gewoon links laten liggen. 5.3.6 Instellen van de standaardroute en DNS-server Op basis van het voorgaande kun je nu gebruikmaken van de netwerkverbinding. Eén ding moet echter nog geregeld worden: je kunt weliswaar op het lokale netwerk communiceren, maar je bent nog niet in staat te communiceren met nodes op andere netwerken. Ook kun je nog geen gebruikmaken van namen zoals ze door middel van DNS beschikbaar gesteld worden. Om dit te regelen gebruik je eerst de opdracht route en wijzig je vervolgens de inhoud van het configuratiebestand /etc/resolv.conf. Om ervoor te zorgen dat de computer de weg naar buiten kent, moet je de standaardroute definiëren. Gebruik hiervoor de opdracht route add default gw ip-adres, bijvoorbeeld route add default gw 192.168.0.5. Vervolgens kunnen ook hosts op
192
Linux 4
andere netwerken benaderd worden. Wel even opletten: de instellingen die je met route doet, worden niet standaard ook opgeslagen. Meestal kun je de te gebruiken routes wel wegschrijven in het configuratiebestand /etc/sysconfig/network/routes. Houd er wel rekening mee dat de exacte naam van dit bestand per distributie kan verschillen. Gebruik in geval van twijfel het configuratieprogramma dat met de distributie geleverd wordt. Figuur 5.4 Gebruik het configuratieprogramma dat met de distributie geleverd wordt om te zorgen dat de instellingen die je doet ook onthouden worden
In het voorgaande is besproken hoe je de route kunt instellen met de opdracht route. Er is ook een alternatief, namelijk de opdracht ip waarover we het eerder hebben gehad. Om met deze opdracht een nieuwe route in te stellen gebruik je de opdracht ip route add via . Gebruik bijvoorbeeld ip route add default via 192.168.0.5 als het genoemde IP-adres de standaardrouter is. Nadat je de standaardroute hebt ingesteld, zorg je ervoor dat computers in het netwerk ook op basis van namen bereikt kunnen worden. Natuurlijk kun je het bestand /etc/hosts aanpassen om daar IP-adressen en bijbehorende namen in op te nemen van computers
5 Configuratie van de netwerkkaart
193
waarmee je vaak contact hebt. Dit is vooral handig voor computers op je eigen netwerk waarvoor geen entry in de DNS-database bestaat. Om echter te zorgen dat je ook computers op internet op basis van hun naam kunt bereiken, moet je zorgen dat er een DNSserver teruggevonden kan worden. Dit regel je in het bestand /etc/ resolv.conf. Figuur 5.5 In /etc/hosts neem je IP-adressen en namen op van computers op het lokale netwerk waarmee je regelmatig wilt communiceren
De inhoud van resolv.conf hoeft helemaal niet ingewikkeld te zijn. In zijn meest eenvoudige vorm komt er maar één regel in voor: nameserver
5.2.3.4
Met deze regel wordt het IP-adres gegeven van de DNS-server die je wilt gebruiken. Uiteraard zorg je ervoor dat 5.2.3.4 vervangen wordt door het werkelijke IP-adres van de DNS-naamserver. Dit is overigens een instelling die je niet beslist hoeft te doen met het configuratieprogramma van de distributie. Omdat de waarde wordt opgeslagen in een configuratiebestand, is deze ook nadat de computer opnieuw gestart wordt gewoon nog beschikbaar. 5.3.7 Instellingen bewaren in configuratiebestanden Gelukkig is het niet nodig om de netwerkinstellingen steeds weer opnieuw in te voeren nadat de server gestart is. Je vindt de configuratiebestanden waarin de instellingen standaard bewaard worden in de directory /etc/sysconfig. De directory die je nodig hebt heet network op SUSE en network-scripts op Red Hat/Fedora. In deze directory vind je voor de netwerkkaart een configuratiebestand met parameters die er min of meer als volgt uit zien:
194
Linux 4
[root@georgia network-scripts]# cat ifcfg-eth0 # Realtek Semiconductor Co., Ltd. RTL-8139/8139C/8139C+ DEVICE=eth0 BOOTPROTO=static BROADCAST=192.168.1.255 HWADDR=00:10:A7:0D:7D:60 IPADDR=192.168.1.97 NETMASK=255.255.255.0 NETWORK=192.168.1.0 ONBOOT=yes
De parameters in dit configuratiebestand spreken hopelijk voor zich. In plaats van het gebruik van het beheergereedschap van de distributie, kun je ook met de favoriete editor parameters direct wijzigen. Zo pas je op deze wijze bijvoorbeeld eenvoudig het IPadres van de netwerkkaart aan of verander je een netwerkkaart met een statisch IP-adres naar een dynamisch IP-adres. In het laatste geval wijzig je de optie BOOTPROTO naar dhcp in plaats van static. Vergeet niet vervolgens de netwerkkaart opnieuw te initialiseren met bijvoorbeeld de opdrachten ifdown en ifup en je kunt direct van de nieuwe instellingen gebruikmaken. 5.3.8 De juiste module Soms is het een behoorlijk probleem om de juiste kernelmodule te laden, zodat de netwerkkaart kan worden aangesproken. Dit geldt overigens ook voor andere hardnekkige hardware. Daarom is het nu tijd om eens een kijkje achter de schermen te nemen en te bekijken wat je kunt doen bij een weerbarstige netwerkkaart. De volgende procedure laat redelijk goed zien welke mogelijkheden er zijn, maar realiseer je dat een en ander ook afhankelijk is van kernelversies, enzovoort. Beschouw dit daarom als een aanwijzing, maar niet als de absolute waarheid. 1. Gebruik de opdracht lspci om een lijst op te vragen van alle apparaten die op de PCI-bus gedetecteerd zijn. Het resultaat van deze opdracht is een relatief lange lijst met alle apparaten die direct of indirect aan de PCI-bus verbonden zijn. Deze lijst kan er als volgt uit zien: BTN:/ # lspci 00:00.0 Host bridge: Intel Corporation Mobile 945GM/PM/GMS/940GML
5 Configuratie van de netwerkkaart
195
and 945GT Express Memory Controller Hub (rev 03) 00:01.0 PCI bridge: Intel Corporation Mobile 945GM/PM/GMS/940GML and 945GT Express PCI Express Root Port (rev 03) 00:1b.0 Audio device: Intel Corporation 82801G (ICH7 Family) High Definition Audio Controller (rev 01) 00:1c.0 PCI bridge: Intel Corporation 82801G (ICH7 Family) PCI Express Port 1 (rev 01) 00:1c.1 PCI bridge: Intel Corporation 82801G (ICH7 Family) PCI Express Port 2 (rev 01) 00:1c.2 PCI bridge: Intel Corporation 82801G (ICH7 Family) PCI Express Port 3 (rev 01) 00:1c.3 PCI bridge: Intel Corporation 82801G (ICH7 Family) PCI Express Port 4 (rev 01) 00:1d.0 USB Controller: Intel Corporation 82801G (ICH7 Family) USB UHCI #1 (rev 01) 00:1d.1 USB Controller: Intel Corporation 82801G (ICH7 Family) USB UHCI #2 (rev 01) 00:1d.2 USB Controller: Intel Corporation 82801G (ICH7 Family) USB UHCI #3 (rev 01) 00:1d.3 USB Controller: Intel Corporation 82801G (ICH7 Family) USB UHCI #4 (rev 01) 00:1d.7 USB Controller: Intel Corporation 82801G (ICH7 Family) USB2 EHCI Controller (rev 01) 00:1e.0 PCI bridge: Intel Corporation 82801 Mobile PCI Bridge (rev e1) 00:1f.0 ISA bridge: Intel Corporation 82801GBM (ICH7-M) LPC Interface Bridge (rev 01) 00:1f.2 IDE interface: Intel Corporation 82801GBM/GHM (ICH7 Family) Serial ATA Storage Controller IDE (rev 01) 00:1f.3 SMBus: Intel Corporation 82801G (ICH7 Family) SMBus Controller (rev 01) 01:00.0 VGA compatible controller: nVidia Corporation Unknown device 0297 (rev a1) 03:01.0 FireWire (IEEE 1394): Ricoh Co Ltd Unknown device 0832 03:01.1 Generic system peripheral [Class 0805]: Ricoh Co Ltd R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter (rev 19) 03:01.2 System peripheral: Ricoh Co Ltd Unknown device 0843 (rev 01) 03:01.3 System peripheral: Ricoh Co Ltd R5C592 Memory Stick Bus Host Adapter (rev 0a) 03:01.4 System peripheral: Ricoh Co Ltd xD-Picture Card Controller
196
Linux 4
(rev 05) 09:00.0 Ethernet controller: Broadcom Corporation NetXtreme BCM5752 Gigabit Ethernet PCI Express (rev 02) 0c:00.0 Network controller: Broadcom Corporation Unknown device 4328 (rev 01)
De interessante informatie hier voor wat betreft de netwerkkaarten, vind je in de laatste regels. Deze regels bevatten namelijk de PCI-ID van de netwerkkaart. Zo zie je bijvoorbeeld dat er een device is op PCI-ID 09:00.0 en een device op 0c:00.0. Beide devices zijn van Broadcom en de kans is dus groot dat ze betrekking hebben op de netwerkkaart. 2. De tweede stap is te kijken of er een driver geladen is voor de device die je gevonden hebt. Dit achterhaal je in het sysfs-bestandssysteem; onder /sys/bus/pci/drivers vind je een lijst van alle drivers die geladen zijn voor een device op een bepaalde PCI-interface. Door bijvoorbeeld vanuit deze directory een find te doen op (een deel van) de PCI-ID, vind je heel snel of een module voor het betreffende apparaat geladen is of niet. Probeer maar eens find . -name “09:00*” om te bekijken of deze PCI-ID op het systeem onder drivers bekend is. Grote kans dat je een match hebt onder de subdirectory van de betreffende driver. Voor een apparaat waarvoor de driver ontbreekt, gaat dat echter niet lukken. De volgende stap beschrijft wat je dan wel moet doen. 3. Activeer in /sys/bus/pci/devices de subdirectory met de PCI-ID van het apparaat waar je een probleem mee hebt. In de hiervoor genoemde output zie je bijvoorbeeld dat het apparaat op PCI-ID 0c:00.0 onbekend is. Om meer informatie over dit apparaat te krijgen ga je naar de directory met de overeenkomstige PCI-ID onder /sys/bus/pci/devices. Activeer nu deze directory. Je vindt hierin twee belangrijke bestanden. Als eerste het bestand met de vendorID en daarnaast het bestand met de device-ID. In ons voorbeeld gaat het om de volgende informatie: BTN:/sys/bus/pci/devices/0000:0c:00.0 # cat vendor 0x14e4 BTN:/sys/bus/pci/devices/0000:0c:00.0 # cat device 0x4328
4. Op basis van de vendor en de device-ID kun je op zoek naar de driver in de kernel die ondersteuning biedt voor dit apparaat. Om
5 Configuratie van de netwerkkaart
197
dit te doen moeten de kernelsources geïnstalleerd zijn. Controleer dit eerst door een kijkje te nemen in /usr/src/Linux. Als je hier een aanzienlijke lijst bestanden vindt, zijn de kernelsources geïnstalleerd. Gewoonlijk ziet de inhoud van deze directory eruit als in de volgende listing: BTN:/usr/src/linux # ls .gitignore
MAINTAINERS
arch
include
lib
security COPYING release
Makefile
block
init
localversion-rpm-
sound
CREDITS
README
crypto
ipc
mm
Documentation
README.SUSE
drivers
kdb
net
Kbuild
REPORTING-BUGS
fs
kernel
scripts
usr
5. Nu moet je in de kernel kijken in de directory include. Ergens in deze directory vind je een bestand waarin alle PCI-ID’s voorkomen die de kernel kent. De volledige naam van dit bestand is in de meeste gevallen /usr/src/linux/include/linux/pci_ids.h. Om nu te achterhalen om welke vendor het gaat, gebruik je de opdracht grep om dit bestand te doorzoeken op de vendor-ID. In ons geval wordt dat dus de volgende opdracht met het onderstaande resultaat: BTN:/usr/src/linux/include/linux # grep -i 0x14e4 pci _ ids.h #define PCI _ VENDOR _ ID _ BROADCOM
0x14e4
We weten nu dus dat het om een Broadcom-device gaat. Met een beetje geluk vind je de device-ID ook in dit bestand terug. Dit blijkt uit het resultaat van de volgende opdracht: BTN:/usr/src/linux/include/linux # grep -i 0x4328 pci _ ids.h
Geen resultaat? Dan kan het zijn dat het apparaat gewoon nog niet ondersteund wordt, maar zelfs dan is het wél de moeite waard om even verder te kijken in de kernelsources. 6. We weten nu dat het apparaat dat we nodig hebben van Broadcom is. Om te kijken welke support er in de kernelsources is voor Broadcom-apparaten, voer je nu vanuit /usr/src/linux/drivers de volgende opdracht uit:
198
Linux 4
BTN:/usr/src/linux/drivers # grep -Rl BROADCOM * ieee1394/oui.db net/b44.c net/bnx2.c net/tg3.c net/tulip/de4x5.c net/tulip/de4x5.h net/tg3.h net/wireless/bcm43xx/bcm43xx _ phy.c net/wireless/bcm43xx/bcm43xx _ radio.c net/wireless/bcm43xx/bcm43xx _ main.c net/cassini.h net/cassini.c
Zoals je ziet, levert dit een lijst met bestanden op. Deze bestanden moeten we vervolgens doorzoeken op het voorkomen van de device-ID. Dat kun je doen door stuk voor stuk elk bestand te openen en te bekijken, maar je kunt het ook doen door er een klein scriptje op los te laten (lees hoofdstuk 11 voor meer informatie over Bashshellscripting): #!/bin/bash for i in `grep -Rl BROADCOM *` do grep -il 0x4328 $i done
7. Nu zijn er twee mogelijkheden. De eerste mogelijkheid is dat je resultaat ziet. In dat geval is er een andere driver die ondersteuning biedt voor de device. In dat geval ga je verder met stap 6 van deze procedure. Als je nu geen resultaat vindt, is er dus geen ondersteuning en doe je er goed aan op internet te zoeken of er inmiddels een nieuwere kernel is of een nieuwere driver die deze ondersteuning wel biedt. Als je geen bestand gevonden hebt met daarin de device-ID van de driver, stopt de procedure hier voor je. 8. Je hebt een bestand gevonden waarin de device-ID voorkomt? Dat is mooi, want dan kun je deze nu in gebruik nemen. Dit doe je door in de driver te compileren. Gebruik eerst make menuconfig om het kernelconfiguratiemenu te tonen. Als je dit gevonden hebt, selecteer de driver en gebruik dan make module modules _ install om de driver te installeren. Vanaf dat moment is de driver beschikbaar.
5 Configuratie van de netwerkkaart
199
9. Nu de driver beschikbaar is, moet je er nog voor zorgen dat deze ook gebruikt kan worden. Op moderne Linux-kernels is dit de verantwoordelijkheid van udev. Als het udev-proces actief wordt, scant het alle hardware die in het systeem aanwezig is. Op basis van deze scan worden de juiste drivers geladen. Vervolgens wordt het bestand /etc/udev/rules.d gelezen om te kijken of er een regel is voor het laden van drivers voor het betreffende type apparaat. Voor netwerkkaarten is bijvoorbeeld /etc/udev/rules.d/30-net_persistent_names.rules van belang. Dit bestand heeft de volgende inhoud: SUBSYSTEM==”net”, ACTION==”add”, SYSFS{address}==”00:18:8b:ac:c9:54”, IMPORT=”/lib/udev/rename _ netiface %k eth0”
In deze regel wordt een bepaald MAC-adres gebonden aan een interfacenaam. Omdat op het testsysteem waar dit bestand bekeken is maar één netwerkkaart voorkomt, zie je hier maar één regel waarin eth0 gedefinieerd wordt. Komen er echter meerdere netwerkinterfaces voor, dan vind je hier voor elke interface een regel waarin de eth-naam gekoppeld wordt aan de devicenaam. Wil je dat standaard een andere dan de hier genoemde eth-naam gebonden wordt aan een bepaald MAC-adres? Dan kun je dat dus ook hier regelen. Udev bekijken Als je werkt met hot-pluggable devices zoals USB-devices, kun je in realtime bekijken wat er gebeurt. Gebruik voor dit doel de opdracht udevmonitor en verbind vervolgens het apparaat in kwestie met de computer. Je ziet dan direct een overzicht van alle acties die ondernomen worden om het apparaat in werking te stellen. 5.4
Configuratie van een PPP-interface
Net als netwerkkaarten kunnen ook modems op twee manieren geconfigureerd worden: door de nodige configuratiebestanden handmatig te bewerken of met behulp van grafische configuratieprogramma’s. Wij vertrouwen erop dat je jezelf wel kunt redden met de grafische hulpmiddelen. Daarom lees je in deze paragraaf alles over handmatige modemconfiguratie waarbij de nodige scripts ge-
200
Linux 4
configureerd moeten worden. We gaan hier uit van een ouderwetse modem waarbij ingebeld wordt over een telefoonlijn. Realiseer je echter dat de besproken configuratie niet zó ouderwets is. Voor het configureren van bepaalde typen WAN-verbinding moet namelijk exact dezelfde procedure gevolgd worden. 5.4.1 Handmatige configuratie van de PPP-interface PPP is een algemene interface die gebruikt wordt op WAN-verbindingen, waaronder modemverbindingen. Omdat modems eenvoudiger te verkrijgen zijn als Frame Relay-interfaces, lees je in het volgende voornamelijk over modems. Veel van de hier besproken informatie is echter ook relevant voor de configuratie van andere typen WAN-interface. Voordat je begint met pogingen om een modem aan te sturen, is het belangrijk even bij het volgende stil te staan. Vanuit de Linuxoptiek zijn er twee soorten modems. Als eerste zijn er de echte modems en daarnaast bestaan er ook apparaten die doen alsof ze een modem zijn. Deze laatste categorie modems hebben om te kunnen werken onderdelen van het Microsoft Windows-besturingssysteem nodig en zullen het in veel gevallen niet doen onder Linux. Helaas horen veel PCI-modems in deze categorie thuis. Concreet betekent dit dus gewoon dat er een aantal modems is dat niet bruikbaar is onder Linux. Als je er zeker van wilt zijn dat de modem wel met Linux te gebruiken is, schaf dan een externe modem aan. Je kunt tevens lijsten met ondersteunde modems vinden op http://www. linmodems.org. De softwarematige configuratie van de modem bestaat uit twee stappen: de seriële poort moet geconfigureerd worden en vervolgens moet je er door middel van speciale modemopdrachten voor zorgen dat de modem op de juiste manier aangestuurd kan worden. Configuratie van de seriële poort Vaak wordt al tijdens de installatie de vraag gesteld of je een modem wilt configureren. Als je hierop met ‘yes’ antwoordt, wordt er een bestand /dev/modem gemaakt. Dit bestand wordt vervolgens gelinkt naar de communicatiepoort waarop de modem aangesloten is, doorgaans ttyS0, ttyS1, ttyS2 en ttyS3; de verschillende seriële poorten die beschikbaar zijn op de computer. Als gebruikgemaakt wordt van een USB-modem, wordt in plaats van een ttyS* device
5 Configuratie van de netwerkkaart
201
verwezen naar een van de devicebestanden die gemaakt is onder /dev/usb. Je kunt de huidige instelling van de seriële poorten bekijken met de opdracht setserial. Om de instellingen van USB-devices te bekijken gebruik je (afhankelijk van de gebruikte Linuxdistributie de opdracht lsusb of lspci. Als je niet zeker weet op welke seriële poort de modem zich bevindt, gebruik je de opdracht setserial. Op het moment dat deze opdracht toont dat er een UART-chip gebruikt wordt op een van de aanwezige seriële poorten, is dit de poort waarop zich de modem bevindt. Je ziet hiervan een voorbeeld in de volgende listing waar de modem zich bevindt op seriële poorten ttyS0/ttyS2. # setserial -g /dev/ttyS* /dev/ttyS0, UART: 16550A, Port: 0x03f8, IRQ: 4 /dev/ttyS1, UART: unknown, Port: 0x02f8, IRQ: 3 /dev/ttyS2, UART: 16550A, Port: 0x03e8, IRQ: 4 /dev/ttyS3, UART: unknown, Port 0x02f8, IRQ: 3
Configuratie van de modem Als de modem eenmaal fysiek geïnstalleerd is, moet deze verder geconfigureerd worden zodat hij op de juiste manier aangestuurd kan worden. Deze configuratie houdt in dat je de juiste instellingen koppelt aan de modem. Voor deze instellingen worden initialisatieopdrachten gebruikt die afkomstig zijn uit de AT-opdrachtenset. Deze opdrachtenset voorziet in een universele taal voor configuratie van modems. De configuratie van de modem kan gebeuren met een klassiek communicatieprogramma, zoals Minicom, Seyon of Kermit. Het is aan te raden om na de configuratie eerst door middel van het communicatieprogramma te proberen contact te maken met de internetaanbieder. In de volgende paragrafen wordt uiteengezet hoe je dat kunt doen met behulp van het communicatieprogramma Minicom. Ondanks dat het een oud programma is, kun je ook op heel veel moderne Linux-distributies nog gewoon gebruikmaken van Minicom. Om de modem te configureren open je in het communicatieprogramma het menu waarmee je de seriële poort kunt configureren. In Minicom gebruik je hiervoor de toetsencombinatie Ctrl-A, Z.
202
Linux 4
Eerst stel je de snelheid (bitrate) van de seriële poort in. Maak deze altijd hoger dan de feitelijke snelheid van de modem. Hiermee voorkom je dat de seriële poort de vertragende factor wordt. Er is geen bezwaar de seriële poort in te stellen op een snelheid van 115.200 bps (bits per seconde). Daarnaast stel je voor modems sneller dan 9600 baud (alle moderne modems dus) hardware-flowcontrol in met de optie RTS/CTS. Hierdoor kan de modem parameters uitwisselen met de andere modem over hoe de communicatie zo goed mogelijk tot stand kan worden gebracht. Vervolgens moet je controleren of in de initialisatiestring van de modem de volgende instellingen uit de AT-opdrachtenset aan staan. (Houd er rekening mee dat de instellingen per modem verschillend kunnen zijn; raadpleeg de handleiding van de modem voor de juiste instellingen.) &K3 E1 Q0 S0=0 &S0
Figuur 5.6 Om een modem te configureren maak je gebruik van een algemeen communicatie programma zoals minicom
Zet hardware-flowcontrol aan. Dit is nodig voor alle modems die sneller zijn dan 9600 baud. Echo on Zonder deze instelling kan het programma chat, dat je nodig hebt voor de PPP-configuratie, niet werken. Laat resultaat codes zien. Ook deze instelling is essentieel voor het programma chat. Zorgt ervoor dat de modem niet automatisch antwoord geeft op binnenkomende telefoontjes. Data Set Ready: altijd aan. Dankzij deze instelling kan de modem aan de remote modem laten weten dat hij klaar is voor verzenden en ontvangen van gegevens.
5 Configuratie van de netwerkkaart
203
Als je de juiste instellingen hebt ingevoerd, kun je deze wegschrijven naar de processor die voorkomt op de modem, of je kunt ze opnemen in een initialisatiebestand dat steeds wanneer het communicatieprogramma wordt opgestart, wordt geactiveerd. Als je meerdere besturingssystemen op de computer gebruikt, heeft de laatste optie de voorkeur. De instellingen die voor Linux wenselijk zijn, kunnen immers voor gebruik onder een ander besturingssysteem niet wenselijk zijn. Je kunt het communicatieprogramma weer opstarten wanneer je de bovenstaande instellingen hebt aangebracht. Met de opdrachten uit de AT-opdrachtenset kun je kijken of de modem werkt. Als eerste geef je de opdracht AT om te kijken of de modem actief is. Hierop hoort de modem te antwoorden met OK. Als dit het geval is, kun je een telefoonnummer opgeven om te bellen. Mocht de modem niet reageren op de opdracht AT, dan is de kans aanwezig dat de verkeerde initialisatieopdracht is gegeven. Je dient dan instellingen voor de initialisatiestring voor de modem op te zoeken in de handleiding en deze string in te voeren in het communicatieprogramma. Let er in elk geval op dat ook de hiervoor vermelde instellingen in de initialisatiestring voorkomen. Met Minicom kun je deze string instellen in het menu Configure Minicom. Dit menu roep je aan met de toetsencombinatie Ctrl-A, O. Uitgebreide informatie over de configuratie van de modem en de seriële poort vind je in de Serial-HOWTO en de Modem-HOWTO. De verbinding testen Voordat je verder gaat, moet je eerst controleren of de modem werkt. Je kunt nu proberen de internetaanbieder te bellen. Je gebruikt hiervoor in het communicatieprogramma de opdracht ATDT123456789 waarin 123456789 het telefoonnummer is van de internetaanbieder. Als het opbouwen van een connectie lukt, moet je exact noteren welke meldingen op het beeldscherm verschijnen en welke antwoorden je moet geven om in te loggen. Je hebt deze informatie in een later stadium nodig. Er zijn twee zaken die je moet achterhalen: gebruikt de ISP PAP of CHAP en wordt PPP automatisch opgestart als je bent aangemeld bij de ISP, of moet je daar zelf nog iets voor doen? Of een server wel of niet PAP of CHAP gebruikt, kun je zien wanneer je contact hebt gemaakt. Als de server wel PAP/CHAP gebruikt, krijg je
204
Linux 4
namelijk geen loginprompt te zien, maar machinecode. Het is dan zaak dat je een bestandje opstuurt naar de server waarin de gebruikersnaam en het wachtwoord staan. Als je een loginprompt te zien krijgt, mag je ervan uitgaan dat de server geen gebruikmaakt van PAP/CHAP. Daarnaast moet je kijken of de server automatisch PPP start of niet. Als de PPP-server automatisch wordt opgestart, krijg je op het beeldscherm iets te zien wat eruitziet als ~y}#.!}!}!} }9}!}$}%U}Ó}&}Ó} } }0 } } }%}& ...}’}Ó}(}Ó} . ~~y}
Krijg je niet vanzelf iets dergelijks te zien, dan is het mogelijk dat de server wacht totdat je er een teken naartoe stuurt. Vaak is dat een willekeurig teken, soms moet je op Enter drukken. Als je op het beeldscherm ziet dat de server PPP start, kun je de modem afsluiten. Hiervoor gebruik je de string +++ gevolgd door de opdracht ATH0. 5.4.2 Protocolconfiguratie Als het hiervoor genoemde allemaal goed is gegaan, werkt de modem zoals het hoort. Nu kun je beginnen met het maken van enkele bestanden die nodig zijn voor het juist functioneren van DNS en PPP: /etc/resolv.conf en enkele aan PPP gerelateerde bestanden. /etc/resolv.conf Het eerste bestand dat je moet maken is /etc/resolv.conf. Hiermee zorg je ervoor dat de DNS-resolver contact kan maken met een DNS-server. Dit bestand krijgt een inhoud die eruit komt te zien als: nameserver
192.168.195.1
nameserver
172.17.180.12
De permissies van dit bestand worden ingesteld op -rw-rw-rw-, zodat iedereen ze kan gebruiken. De gebruiker en groep van dit bestand zijn de gebruiker en de groep root. PPP Om ook iets te kunnen doen met de modem, heb je PPP nodig. Voordat je aan het werk kunt met PPP, moet je controleren of PPP-
5 Configuratie van de netwerkkaart
205
functionaliteit wel door de kernel wordt ondersteund. Dit doe je door de opdracht pppd te geven. Als PPP-functionaliteit niet door de kernel wordt ondersteund, krijg je daar een duidelijke melding van. Als PPP-functionaliteit beschikbaar is, verschijnen op het scherm tekenreeksen die eruitzien als: ~ij}#A!}!}!} }4}Ó}&} } } } }%}&MQE}’}Ó}(}
Vrijwel elke distributie heeft standaard ondersteuning voor ppp. Ook moet je ervoor zorgen dat iedereen gebruik kan maken van het programma pppd. Gewoonlijk mag namelijk alleen de gebruiker root dit programma activeren. De handigste manier om dit te veranderen is door de User-ID-bit aan het programma te koppelen. Gebruik hiervoor de opdracht chmod u+s /usr/sbin/pppd. Vervolgens moet een algemeen instellingenbestand voor PPP worden gemaakt. Hiervoor wordt het bestand /etc/ppp/options gebruikt. De inhoud ervan is afhankelijk van de vraag of de ISP al dan niet PAP of CHAP gebruikt voor validatie van gebruikers. De laatste regel in het volgende voorbeeldbestand hoeft alleen te worden toegevoegd wanneer de ISP gebruikmaakt van PAP/CHAP. #voorbeeld /etc/ppp/options #Maak van pppd geen background proces: -detach #Gebruik de modeminstellingen: modem #Laat pppd de communicatiepoort exclusief gebruiken door #er een lock op te plaatsen. De lock komt voor als het bestand #/var/lock/LCK..ttySx: lock #Gebruik hardware flowcontrol voor data die binnenkomt #op de seriële poort. Alleen doen als de modem sneller is #dan 9600 baud: crtscts #voeg voor de duur van de verbinding de remote host #toe aan de routing table als default router zodat alle #IP-verkeer doorgestuurd wordt naar internet: defaultroute #Maak geen gebruik van “escaped” control-tekens: asyncmap 0
206
Linux 4
#Stel de maximale grootte van uitgaande pakketjes in op 552: mtu 552 #Stel de maximum receive unit (mru) in op 552 bytes. Hoe #langzamer de verbinding, hoe lager de waarde die voor mtu #en mru staat ingesteld moet zijn. Bij een langzame verbinding #dient de waarde voor mru en mtu te staan ingesteld op 296, de #richtlijn voor een niet al te langzaam modem is 542. De waarde #1500 dient alleen voor vaste netwerkverbindingen gebruikt te #worden. mru 552 #Alleen bij gebruik van PAP/CHAP: zorg ervoor dat PPPD je #ISP-gebruikersnaam als hostnaam gebruikt: name <je gebruikersnaam>
De algemene instellingen in dit voorbeeldbestand kunnen voor de meeste computers die niet in een netwerk opgenomen zijn, worden gebruikt. Alleen als de internetaanbieder tijdens de inlogprocedure gebruikmaakt van PAP of CHAP, moet je nog wat extra werk doen. Je moet dan een secretsfile maken: een bestand waarin de informatie staat die je nodig hebt om je aan te melden door PAP of CHAP. Het bestand heet /etc/ppp/pap-secrets; het moet als eigenaar de gebruiker en groep root hebben en als permissie-modus 740. Als het echter de bedoeling is dat iedereen gebruik kan maken van dit bestand, moeten de permissies worden ingesteld op 744. Het bestand /etc/ppp/pap-secrets komt eruit te zien als: /etc/ppp/pap-secrets: #Secrets for authentication using PAP #client
server
secret
acceptable _
local _ IP _ addresses caroline
*
geheim
In pap-secrets geef je eerst aan onder welke naam je aangemeld wilt worden bij de internetaanbieder. In het hiervoor genoemde voorbeeldbestand is de gebruikersnaam ingesteld op caroline. Het tweede veld is bedoeld om de naam van de server op te geven.
5 Configuratie van de netwerkkaart
207
Aangezien je over het algemeen maar één internetaanbieder zult gebruiken, kun je hier een asterisk neerzetten. Het derde veld wordt gebruikt om het wachtwoord op te geven. In het vierde veld kun je opgeven welke IP-adressen acceptabel voor je zijn. Dit veld kun je over het algemeen leeg laten. Behalve van PAP kan het PPP-protocol ook nog gebruikmaken van CHAP voor authenticatie. Als dit het geval is, moet een bestand genaamd chap-secrets worden gemaakt. Aangezien CHAP ervan uitgaat dat er aan wederzijdse validatie van gebruikersgegevens wordt gedaan, moet in chap-secrets behalve de naam van de lokale computer ook de naam van de computer waarop wordt ingelogd, worden opgenomen. Daarbij moet van beide computers het wachtwoord vermeld worden. Als de lokale computer de naam ‘Azlan’ heeft en het wachtwoord ‘training’, en de computer waarop wordt ingelogd ‘Akam’ en ‘Education’, komt het bestand /etc/ppp/chap-secrets er als volgt uit te zien: /etc/ppp/chap-secrets #Secrets for authentication using CHAP #client
server
secret
acceptable local IP
addresses Azlan
Akam
training
Akam
Azlan
education
Dit bestand maakt het mogelijk dat niet alleen de computer ‘Azlan’ zich aanmeldt op de computer ‘Akam’, maar dat ook het omgekeerde kan gebeuren. Dit is mogelijk omdat in /etc/ppp/chap-secrets ook de remote computer bekend wordt gemaakt. Omgekeerd dient ook op de remote computer een bestand /etc/ppp/chap-secrets te worden gemaakt, waarin de computers die inbellen bekend worden gemaakt. Dit zal door de ISP geregeld worden. Handmatig tot stand brengen van de PPP-connectie Nu is het tijd om te kijken of je alles goed hebt gedaan: je gaat handmatig contact maken met de ISP en vervolgens PPP opstarten. Om dit succesvol te kunnen doen is het belangrijk dat je het communicatieprogramma kunt afsluiten zonder de modem daarbij te
208
Linux 4
resetten. In Minicom doe je dit met de toetsencombinatie Ctrl-A, Q. Je begint met de modem te laten bellen naar de internetaanbieder. Nadat je succesvol bent aangemeld op de server van de internetaanbieder en daar een PPP-sessie voor je is opgestart, kun je het communicatieprogramma afsluiten en de volgende opdracht geven: pppd -d -detach /dev/ttySx 115200 &
Let erop dat je hierbij niet /dev/ttySx, maar ttyS0, ttyS1 typt, overeenkomstig de poort waaraan de modem geconfigureerd is. Je kunt nu kijken of het werkt; gebruik hiervoor de opdracht ifconfig. Deze opdracht zou een ppp-device moeten laten zien. De uitvoer van ifconfig moet een resultaat geven dat lijkt op ppp0
Link encap:Point-to-Point Protocol
inet addr:192.168.195.11 P-t-P:192.168.195.3 Mask...
UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1524
...
Nadat je met een opdracht als ping gecontroleerd hebt dat de verbinding goed werkt, mag je ervan uitgaan dat alles wat je tot nu toe geconfigureerd hebt klopt. Start nu het communicatieprogramma weer op en zorg ervoor dat de modem wordt ‘opgehangen’. Als hiervoor geen menuoptie beschikbaar is, kun je hiervoor de opdracht +++ gevolgd door ATH0 (nul) gebruiken. Om het hierna nog een keer te proberen moet je ook de lockfile, die is gemaakt in /var/lock, verwijderen. Deze lockfile heeft een naam als LCK.. ttyS5. 5.4.3 Automatiseren van de connectie met scripts Als het hiervoor genoemde is gelukt, kun je nu het tot stand brengen van de verbinding automatiseren. Dit doe je door een script te maken waarin een aantal omgevingsvariabelen wordt ingesteld en pppd wordt opgestart, waarbij automatisch het programma chat geactiveerd wordt om de remote host te bellen. In de volgende paragrafen is uitgewerkt welke bestanden je hiervoor moet maken. Het eerste bestand is /etc/ppp-on, dat zaken als loginnaam, wachtwoord en telefoonnummer kan instellen. Tevens wordt in dit bestand pppd opgestart.
5 Configuratie van de netwerkkaart
209
Het tweede bestand dat wordt gemaakt, is een algemeen instellingenbestand waarin de parameters die door chat gebruikt worden, staan gespecificeerd. Dit bestand wordt geplaatst op een locatie waar iedereen erbij kan. In het volgende voorbeeld wordt het pppon-dialer genoemd. Het derde bestand moet ervoor zorgen dat PPP ook weer wordt afgesloten. Ook dit bestand kan geplaatst worden in een directory waar iedereen bij kan. In het volgende voorbeeld heet het ppp-off. Elk van deze scripts moet in elk geval zijn voorzien van de execute-permissie voor de gebruiker die eigenaar is en voor ieder ander die er gebruik van moet kunnen maken. ppp-on Het bestand ppp-on moet worden gemaakt in de homedirectory van elke gebruiker die het recht heeft om de modem aan te sturen of in een directory waar iedereen die er gebruik van mag maken het kan benaderen om het te starten. De inhoud is als volgt: #!/bin/sh TELEPHONE=0991111111 ACCOUNT=ppp:uwnaam@uwisp PASSWORD=hiergewoonuittelezen LOCAL _ IP=0.0.0.0 REMOTE _ IP=0.0.0.0 export TELEPHONE ACCOUNT PASSWORD DIALER _ SCRIPT=/etc/ppp/ppp-on-dialer exec /usr/sbin/pppd debug /dev/ttyS1 115200 \
$LOCAL _ IP:$REMOTE _ IP \
connect $DIALER _ SCRIPT
Het meest interessante in dit script is dat een aantal omgevingsvariabelen wordt gedefinieerd. Deze variabelen worden vervolgens met de bash-opdracht export ook buiten het script beschikbaar gesteld. Daarna wordt, ook weer door middel van een omgevingsvariabele, aangegeven op welke locatie het script met chat-parameters zich bevindt. Als laatste wordt pppd opgestart, waarbij de seriële poort waaraan de modem zich bevindt, wordt aangegeven en een verwijzing wordt gegeven naar het script met chat-parameters.
210
Linux 4
Ook worden in het hiervoor genoemde script, indien bekend, de IP-adressen gegeven. Het is gebruikelijk dat het adres van de andere computer hier op 0.0.0.0 staat, tenzij je absoluut zeker weet dat je altijd aan dezelfde computer bent verbonden. Meestal is dit niet het geval. Tevens kan het lokale IP-adres – als het bekend is – worden gespecificeerd. Als gebruik wordt gemaakt van IP-adressen die dynamisch door de remote host worden uitgedeeld, moet hier 0.0.0.0 staan. Als de internetaanbieder gebruikmaakt van PAP of CHAP voor validatie van gebruikersgegevens, hoeft in het script ppp-on geen informatie opgenomen te worden over gebruikersnaam en wachtwoord. Deze informatie staat dan immers gespecificeerd in /etc/ ppp/pap-secrets of /etc/ppp/chap-secrets. ppp-on-dialer Het volgende script dat geschreven moet worden, is dat waarin de chat-parameters staan gespecificeerd. Dit wordt ook wel het chat-script genoemd. Hierin staat aangegeven hoe de communicatie plaatsvindt en wat er gecommuniceerd wordt. Het chat-script bestaat uit strings waarvan het eerste deel aangeeft wat verwacht wordt dat binnenkomt, en het tweede deel wat daarop geantwoord moet worden. Een regel uit een chat-script zou eruit kunnen zien als: ogin: mijnloginnaam ssword: zeergeheim
In deze regel wordt gespecificeerd dat chat een string ogin verwacht. Als deze string binnenkomt, wordt daarop geantwoord met de string mijnloginnaam. Vervolgens wacht chat op een string ssword, waarop geantwoord wordt met zeergeheim. In de strings die verwacht worden, zijn in de hiervoor genoemde regel de eerste letters weggelaten. Dit om ervoor te zorgen dat niet direct een fout gegenereerd wordt als het eerste teken niet goed binnenkomt. De status van het inbellen wordt vaak door een modem gerapporteerd door middel van een string als CONNECTED, NO CARRIER of BUSY. Wanneer er bij dergelijke berichten van de modem actie moet worden ondernomen, kan het keyword ABORT opgenomen worden. In het script ziet dat eruit als:
5 Configuratie van de netwerkkaart
211
ABORT ‘BUSY’ ABORT ‘NO CARRIER’ ‘‘ ATZ OK ATDT111234 CONNECT
Hier wordt de modem eerst opnieuw ingesteld met de opdracht ATZ. Als de modem daarop antwoordt met OK, gaat dit script bellen door de opdracht ATDT. Als hierop een BUSY of NO CARRIER volgt, wordt het script afgebroken. Wanneer een CONNECT volgt, wordt de rest van het script uitgevoerd. Met het keyword ECHO kan op het beeldscherm getoond worden wat er gaande is. Met ECHO ON wordt alles wat er in het script gebeurt, getoond. Met ECHO OFF wordt het script afgehandeld zonder dat resultaten op het beeldscherm getoond worden. Het keyword TIMEOUT kan in een script gebruikt worden om op te geven hoe lang maximaal op een bepaalde string gewacht wordt. Zo kun je het script onderbreken wanneer je te lang op een bepaalde string wacht. Het statement REPORT CONNECT ten slotte kan ervoor zorgen dat de snelheid van de connectie wordt weergegeven nadat deze tot stand is gekomen. Om dit statement te kunnen gebruiken is het wel noodzakelijk dat je de opdracht chat activeert met de optie -r. Naast de hiervoor genoemde keywords kunnen ook enkele Escapereeksen in een script gegeven worden: ‘‘ \b \c \d \K \n \r \s \t \\
Verwacht of stuur een string zonder inhoud. Hierop volgt als antwoord het Enter-teken. Backspace. Onderdruk het newline-teken dat aan het eind van elke string wordt meegestuurd. Wacht één seconde. Voeg een BREAK toe. Stuur een newline-teken. Stuur of verwacht een Carriage-Return. Staat voor een spatie. Staat voor een tab. Stuur of verwacht een backslash.
Het chat-script komt er als volgt uit te zien:
212
Linux 4
#!/bin/sh /usr/sbin/chat -v -r
\
TIMEOUT 3
ABORT
‘\nBUSY\r’
\ \
ABORT
‘\nNO ANSWER\r’
\
ABORT
‘\nRINGING\r\n\r\nRINGING\r’
‘‘
\rAT
\
‘OK-+++ \c-OK’
ATH0
\
TIMEOUT 30
OK
CONNECT ‘‘
\
ogin:Ñogin:
$ACCOUNT \
assword: \q$PASSWORD
\
‘‘
‘‘
REPORT CONNECT
\
ATDT$TELEPHONE \
In dit script wordt allereerst aangegeven dat de shell /bin/sh gebruikt moet worden om voorkomende scriptopdrachten uit te voeren. Vervolgens wordt op de tweede regel het programma chat geactiveerd. De optie -v zorgt ervoor dat alle meldingen die door het script worden gegenereerd, worden opgeslagen in de standaardsystem-logfile (meestal /var/log/messages). Deze regel wordt afgesloten met een backslash om aan chat te laten weten dat op de volgende regel de specificatie van argumenten gewoon doorgaat. Nu wordt een time-out gegeven. Hierdoor blijft het systeem niet eindeloos wachten totdat er iets gebeurt, maar kan het script bij een voorkomende fout worden afgesloten. De time-out wordt ingesteld op drie seconden. De volgende drie regels specificeren condities op basis waarvan het script kan worden afgebroken. Dit kan gebeuren als de lijn bezet is (BUSY), als de remote host niet antwoordt (NO ANSWER) of als je gebeld wordt (RINGING). Als geen van deze drie foutcondities voorkomt, kan overgegaan worden tot het echte werk. Dit wordt gestart met ‘‘, wat betekent dat niets van de modem verwacht wordt. Het systeem begint vervolgens de conversatie door de opdracht AT naar de modem te sturen. Het antwoord dat hierop wordt verwacht, is OK-+++\c-OK. Dit houdt in dat de modem OK terug moet sturen. Als de modem dat niet doet, wordt de string +++ naar de modem gestuurd. De modem moet hierop antwoorden met OK. Ten slotte wordt het Hang-up-sig-
5 Configuratie van de netwerkkaart
213
naal naar de modem gezonden. De modem is daardoor klaargezet om te gaan bellen. Nu wordt een nieuwe time-out-waarde ingesteld. Hierdoor mag het langer duren voordat op de volgende activiteiten een reactie volgt. Dit is handig omdat in de volgende regels contact wordt opgebouwd met de ISP. Het systeem communiceert daarbij niet meer met de modem die lokaal is aangesloten, maar over een telefoonverbinding met de ISP. Daar kan wat meer tijd overheen gaan. Nadat het signaal OK van de modem is ontvangen, stuurt het script de waarde van de omgevingsvariabele TELEPHONE naar de modem. Deze variabele is ingesteld in het vorige script (ppp-on). De modem moet hierop reageren met het signaal CONNECT. Als dit signaal is ontvangen, stuurt de modem als antwoord een leeg pakketje terug ( ‘ ‘). Vervolgens wordt de string ogin: verwacht, waarop de inhoud van de variabele ACCOUNT wordt gestuurd. Nu wordt de string assword: verwacht, waarop de inhoud van de variabele PASSWORD wordt gezonden. De \q die hieraan voorafgaat, zorgt ervoor dat het wachtwoord niet wordt afgedrukt in de logfiles van de lokale computer. Daarna wordt gewacht op een leeg pakketje dat door de remote computer verstuurd wordt, waarop geantwoord wordt met een pakketje zonder inhoud. Deze regel is nodig voor remote computers die wachten op een toetsaanslag voordat PPP op de remote machine wordt opgestart. Als laatste wordt de connectiesnelheid op het beeldscherm afgedrukt. Als de ISP gebruikmaakt van PAP of CHAP, wordt het chat-script veel eenvoudiger. Alles na de regels OK
ATDT$TELEPHONE \
CONNECT
‘‘
kan dan namelijk weggelaten worden. Authenticatie wordt immers afgehandeld door het bestand /etc/ppp/pap-secrets of /etc/ppp/ chap-secrets. ppp-off Het laatste script dat wordt gemaakt, moet de PPP-verbinding weer netjes afsluiten. Hiervoor wordt een vrij complex shell-script gebruikt dat twee dingen doet. In de eerste plaats gaat het op zoek
214
Linux 4
naar een bestand ppp0.pid. De deamon pppd zorgt ervoor dat dit bestand aanwezig is terwijl het proces actief is. In dit bestand staat het PID van de pppd-daemon. Dit bestand achterhaalt de PID van pppd, waardoor het proces opgeruimd kan worden met de opdracht kill. Daarnaast worden de locks die op de communicatiepoort staan, weggegooid. Hieronder volgt een voorbeeld van een ppp-off. #!/bin/sh if [ “$1” = “” ]; then
DEVICE=ppp0
else
DEVICE=$1
fi if [ -r /var/run/$DEVICE.pid ]; then
kill -INT ‘cat /var/run/$DEVICE.pid’
rm -f /var/lock/LCK..*
if [ ! “$?”= “0”]; then
rm -f /var/run/$DEVICE.
pid
echo “ERROR: Removed
stale pid-file”
exit 1
fi
echo “PPP link to $DEVICE terminated”
exit 0
fi echo “ERROR: PPP link is not active on $DEVICE” exit 1
De ppp-scripts testen Als de scripts allemaal zijn gemaakt, kun je kijken of het werkt. Je moet dan eerst de logfile van het systeem op één terminal openen met de opdracht tail -f /var/log/messages. Hierdoor kun je nagaan wat er allemaal gebeurt. Op een andere terminal geef je de opdracht ppp-on &. Nu ga je terug naar het scherm waar de laatste regels van het bestand messages getoond worden. Je ziet hier iets als het volgende:
5 Configuratie van de netwerkkaart
215
Jul 2 13:20:12 laetitia pppd[211]: pppd 2.3.5 started by root Jul 2 13:20:12 laetitia chat[216]: abort on (BUSY) Jul 2 13:20:12 laetitia chat[216]: abort on (NO CARRIER) Jul 2 13:20:12 laetitia chat[216]: expect ( ) Jul 2 13:20:12 laetitia chat[216]: warning: read() on stdin returned 0 Jul 2 13:20:12 laetitia chat[216]: Failed Jul 2 13:20:13 laetitia chat[216]: Can’t restore terminal parameters: Input/output error
In het logbestand is te zien waar en in welk proces er iets fout ging. In bovenstaand logfile treedt een foutmelding op nadat twee abort-condities wel goed zijn gegaan. Om de fout op te lossen moet dus gekeken worden in het script met chat-parameters en wel op de regel die volgt op de definitie Abort on NO CARRIER. Doet alles het naar behoren? Dan kun je voortaan de inbelverbinding activeren met behulp van de opdracht wvdial. 5.5
De netwerkverbinding testen
Als je denkt dat je de netwerkverbinding naar behoren hebt ingericht, wordt het tijd voor de laatste fase: testen dat het werkt. Hiervoor staan je verschillende opdrachten ter beschikking: Gebruik ping om een verbinding tussen twee computers te testen. Gebruik traceroute om te controleren of alle routers naar behoren werken. Gebruik netstat om de status van alle netwerkverbindingen te controleren. 5.5.1 Een netwerkverbinding testen met ping Een van de belangrijkste en tevens een van de eenvoudigste tools die je in kunt zetten om een verbinding tussen twee computers te testen, is de opdracht ping. Je gebruikt deze opdracht om de verbinding tussen twee computers te testen en daarbij maakt het niets uit waar deze computers precies voorkomen. Heb je twijfel of de IP-stack op een computer naar behoren is geconfigureerd? Dan is ping de oplossing. Je gebruikt deze opdracht echter niet alleen om de bereikbaarheid van computers op basis van hun IP-adres te testen, je kunt ook de DNS-naam van een computer als argument opgeven.
216
Linux 4
Wanneer je met ping een pakketje verstuurt, wordt er een zogenoemd ICMP-datagram verstuurd. ICMP is een hulpprotocol dat zich qua niveau naast IP bevindt: dit betekent dat er geen UDP of TCP voor nodig is om een ping-pakketje te versturen. Dit heeft een belangrijk voordeel: ping blijft hierdoor heel eenvoudig en is prima in staat om problemen op het netwerk op te lossen. Bij het versturen van een eenvoudig ping-pakketje naar een andere computer, wordt veel informatie duidelijk. Als je bijvoorbeeld met de opdracht ping www.novell.com de bereikbaarheid van de genoemde host wilt testen, gaat ping onafgebroken pakketjes sturen naar deze host. Dit versturen van pakketjes houdt op wanneer je het met de toetsencombinatie Ctrl-C onderbreekt. Uit het resultaat van ping, worden verschillende zaken duidelijk. Figuur 5.7 Met het versturen van ping-pakketjes wordt niet alleen duidelijk dat een host bereikbaar is, maar ook hoe deze host dan bereikbaar is
Als eerste zie je een aanduiding van het volgnummer van het pakketje dat je verstuurt. In figuur 5.7 wordt dit weergegeven met de aanduiding icmp _ seq. Deze informatie is niet zo bar interessant, buiten dat je ermee kunt zien hoeveel ping-pakketjes er tot zover verstuurd zijn. Vervolgens zie je iets wat wel interessant is: de Time To Live-waarde (TTL). Hieraan kun je zien hoeveel tussenliggende routers er gepasseerd zijn om dit ping-pakketje te versturen. Het principe van een TTL is eenvoudig: op Linux wordt de standaard meestal ingesteld op 64 en elke router die door een pakketje gepasseerd wordt, haalt daar 1 van af. Als er dus tien routers tussen de verzender en de uiteindelijke bestemming voorkomen, houd je een TTL van 54 over. Tot slot zie je hoe lang het duurt om de betreffende host te bereiken. In de afbeelding wordt een pak-
5 Configuratie van de netwerkkaart
217
ketje verstuurd naar het andere eind van de wereld, in dat geval is een snelheid van gemiddeld 200 milliseconden niet echt slecht, zeker niet als je je realiseert dat in die 200 ms het pakketje heenen teruggestuurd is. Dit heen- en terugsturen wordt overigens de round trip genoemd. Als je pakketjes verstuurt naar een host die voorkomt op hetzelfde netwerk, zou je echter een betere doorvoersnelheid moeten krijgen. Tot slot zie je ook nog een statistische samenvatting van het totale ping-verkeer tussen de computer en de bestemming. Houd er overigens rekening mee dat de opdracht ping niet zaligmakend is. Omdat een host die een ping-pakketje ontvangt daar ook op moet antwoorden, betekent het versturen van ping-pakketjes ook dat daarmee de host waarnaar je pingt, belast wordt. Door gelijktijdig heel veel ping-pakketjes te versturen zou je dus een leuke Denial of Service (DoS)-aanval kunnen uitvoeren. Om die reden komen er op internet aardig wat hosts voor die niet antwoorden op ping-pakketjes. Wanneer het versturen van een ping-pakketje niet lukt, kunnen er verschillende foutmeldingen optreden. Er gebeurt niets. Probeer bijvoorbeeld maar eens de host www.microsoft.com te pingen. Er verschijnt in dat geval geen foutmelding, je krijgt gewoon geen antwoord. In de meeste gevallen is dit een teken dat er op de host waarnaar je pingt gefilterd wordt. Je krijgt de melding Destination Host Unreachable. Dit betekent dat de host waarmee je contact probeert te maken, niet bereikt kan worden. Meestal komt het erop neer dat de standaardgateway plat ligt of dat de host in kwestie gewoon echt niet bereikt kan worden. Het kan ook zijn dat een slimme netwerkbeheerder zijn firewall zo geconfigureerd heeft dat dit antwoord gegeven wordt op elke host die je probeert te pingen, terwijl deze gewoon wel bereikt kan worden. Je krijgt de melding Network Unreachable. Dit komt voor wanneer het netwerk in kwestie niet bereikt kan worden. Dit betekent vrijwel altijd dat er een probleem is met de standaardgateway. Het kan ook zijn dat er ergens op de route op internet tussen je computer en die van de bestemming een netwerkprobleem is. Je pingt op naam en krijgt de melding Unknown Host. In dit geval kan het IP-adres dat bij de betreffende host hoort niet achterhaald
218
Linux 4
worden. Dit duidt meestal op een probleem met de DNS-configuratie. Naast deze redelijk vaak voorkomende foutmeldingen, kunnen nog andere foutmeldingen gegenereerd worden, bijvoorbeeld wanneer je probeert te pingen met een pakketje dat te groot is. Deze situaties doen zich minder vaak voor en worden hier om die reden niet verder behandeld. Figuur 5.8 Bij het versturen van pakketjes met ping kunnen verschillende soorten foutmeldingen gegenereerd worden
Met de opdracht ping kan ook een aantal opties gegeven worden om het gedrag van ping verder te bepalen. Hieronder volgt een overzicht van een aantal nuttige opties. Parameter -c getal
Beschrijving Geeft aan hoeveel ping-pakketjes er verstuurd moeten worden. -I adres Hiermee kun je op een computer met meerdere netwerkkaarten een ping-pakketje via een specifieke netwerkkaart versturen. -i seconden Gebruik deze optie om tussen het versturen van ping-pakketjes een aantal seconden te wachten. Dit kan handig zijn om de instellingen van bepaalde firewalls te omzeilen. -f Alleen root kan deze optie gebruiken om een pingflood te starten. Deze optie zorgt ervoor dat er minimaal honderd pakketjes per seconde verstuurd worden. -n Vertaal in het antwoord van een host het binnenkomende IP-adres niet in een DNS-naam. Met behulp van deze optie kun je de belasting van de opdracht ping minimaliseren.
5 Configuratie van de netwerkkaart
-t ttl -b
219
Geeft aan welke waarde voor de TTL gebruikt moet worden. Maakt het mogelijk ping-pakketjes te versturen naar het Broadcast-adres van een netwerk.
5.5.2 Functionaliteit van routers testen met traceroute Als er een probleem is met de routering van pakketjes, kun je de opdracht traceroute inzetten. Met behulp van deze opdracht analyseer je de route die gevolgd wordt wanneer een pakketje naar een bepaalde bestemming op internet verstuurd wordt. Dit is een zeer nuttige opdracht om meer te leren over hoe internet in elkaar zit en daarnaast kan hij ook nog gebruikt worden om problemen op te sporen. Houd er echter wel rekening mee dat op sommige sites een firewall actief is die de werking van traceroute tegenhoudt; je ziet in dat geval maar een beperkt gedeelte van de weg die daadwerkelijk wordt afgelegd. Wanneer je de opdracht traceroute gebruikt, verstuurt deze opdracht een paar pakketjes met een TTL-waarde van 1 in de richting van de host die je wilt tracen. Aangezien elke router 1 aftrekt van de huidige TTL, komt de TTL bij de eerste router op 0 te staan. Een pakketje met een waarde van 0 wordt als onbestelbaar geïnterpreteerd en daarom krijgt de verzender van het pakketje (jij dus) een foutmelding dat het pakketje niet verstuurd kon worden. Dat is mooi, want zo heb je wel inmiddels geleerd wat de eerste router is die je op weg naar de bestemming tegenkomt. Vervolgens wordt het proces herhaald met een TTL-waarde van 2 waarop de tweede router zal reageren en dit herhaalt zich net zo lang totdat de uiteindelijke bestemming bereikt is. Het resultaat hiervan is dat je een mooi lijstje ziet van alle routers tussen de computer en de uiteindelijke bestemming. traceroute heeft echter wel een nadeel: als er te actief gefilterd wordt (bijvoorbeeld door een firewall op je eigen computer), zie je helemaal niets. 5.5.3 De status van netwerkverbindingen controleren met netstat Een van de meest veelzijdige opties die je kunt gebruiken om problemen op de netwerkverbinding op te lossen, is netstat. De opdracht is zelfs zo veelzijdig dat door zijn veelzijdigheid veel beheerders niet goed weten hoe ze het nu precies moeten gebruiken. Kort samengevat gebruik je netstat om de status van alle net-
220
Linux 4
werkverbindingen te bekijken. Het gaat dan om openstaande connecties (handig om te detecteren of iemand op het systeem aan het werk is), de routingtable en netwerkinterfaces. Het verwarrende van netstat echter is dat je niet alleen informatie te zien krijgt over openstaande netwerkverbindingen, maar over sockets die in gebruik zijn. Dit betekent dat netstat wanneer je het zonder argumenten aanroept ook heel veel informatie laat zien over interne processen die actief zijn. Als je echter netstat gebruikt in combinatie met de opdracht grep waarmee je informatie kunt filteren, krijg je vaak wel met netstat de juiste connectie-informatie boven water. Figuur 5.9 Als je het zonder argumenten aanroept, geeft netstat informatie over letterlijk alle netwerkverbindingen die open staan
Netstat wordt echter wel een heel erg handige opdracht wanneer je een aantal opties gebruikt om te bepalen welke informatie precies getoond moet worden. Met name de opties –t (toont TCP-connecties) en –u (toont UDP-sockets) zijn erg handig om te achterhalen welke netwerkverbindingen momenteel open staan. Daarnaast kun je de optie –r gebruiken om de routingtabel uit te lezen, maar die informatie kun je natuurlijk ook op andere manieren boven water krijgen.
5 Configuratie van de netwerkkaart
221
Figuur 5.10 Met de optie –t toont netstat je in een handomdraai welke verbindingen er naar de computer open staan
Netstat gebruiken om een verbinding te verbreken Stel, je weet dat er op dit moment een hacker actief is op het systeem en je wilt hem direct van het systeem verwijderen. Hoe werkt dat dan? Om te beginnen moet je de hacker identificeren. Dit doe je door middel van de opdracht netstat patune, eventueel gecombineerd met de opdracht grep als je weet op welke poort de hacker binnengekomen is. Begin echter niet te snel met greppen, want soms is niet direct duidelijk van welke poort een bezoeker gebruikmaakt. Zelfs als de service gebruikmaakt van een bepaalde poort, wil dat niet direct zeggen dat de bezoeker ook dezelfde poort gebruikt. Je ziet dit bijvoorbeeld in de volgende regel waarin eerst grep gebruikt is op ssh. BTN:/etc/sysconfig # netstat -patune | grep ssh tcp LISTEN
0 0
0 :::22 11231
:::* 4094/sshd
Deze regel laat niet zien wat er werkelijk gebeurt, want pas als je iets nauwkeuriger kijkt, zie je dat er een bezoeker is op poort 22 (dit had je overigens wel voor elkaar kunnen krijgen door te greppen op poort 22 in plaats van de naam van het proces):
222
Linux 4
tcp
0
0 192.168.1.78:22
ESTABLISHED 0
56351
192.168.1.97:57874 7708/2
De belangrijkste informatie die de voorgaande opdrachten geven, vind je in de laatste kolom. Hier zie je namelijk het procesidentificatienummer dat je nodig hebt; in de laatste regel is dat PID 7708. Eventueel kun je nog gebruikmaken van de opdracht lsof om te kijken welke bestanden dit proces open heeft. In dit voorbeeld zou je dat bijvoorbeeld kunnen doen met lsof -p 7708. Dit dient dan vooral om zeker te zijn van je zaak. Op het moment dat je zeker bent, is de rest eenvoudig en gebruik je de opdracht kill om het proces in kwestie te termineren. 5.6
Samenvatting
In dit hoofdstuk heb je geleerd hoe je een netwerkverbinding moet opzetten. Hierbij is aandacht besteed aan de configuratie van een netwerkkaart met een IP-adres en de wijze waarop je ervoor zorgt dat de host ook op basis van een DNS-naam kan communiceren met hosts op andere netwerken. Tevens heb je geleerd hoe nu eigenlijk IP-adressen en subnetmaskers gebruikt moeten worden. Vervolgens heb je kunnen lezen over de wijze waarop handmatig een PPP-verbinding tot stand gebracht moet worden. Tot slot heb je kennisgemaakt met een aantal van de drie belangrijkste hulpmiddelen die ingezet kunnen worden wanneer een verbinding niet naar wens tot stand gebracht kon worden.
6
Apache
6.1
Inleiding
De toepassing waar Linux nog steeds het meest voor wordt ingezet, is als webserver. Daarom tillen we in dit hoofdstuk een tipje van de sluier op en leer je hoe je een webserver op Linux installeert. De bedoeling van dit hoofdstuk is geenszins om volledig te zijn, dat zou een boek op zich vereisen. Wel willen we je voldoende inzicht geven om in te kunnen schatten hoe een webserver georganiseerd is, zodat je op basis van deze informatie zelf verder kunt gaan om een complete Apache-webserver in te richten. 6.2
De werking van een webserver
Met het risico te verzanden in zaken die je allang weet, besteden we voordat we beginnen even aandacht aan het concept webserver. Een webserver is een server die gebruikmaakt van het Hyper Text Transfer Protocol (HTTP) om bestanden aan te bieden die zijn gemaakt in Hypertext Markup Language (HTML). Deze bestanden worden ingelezen door gebruikers die voor dit doel gebruikmaken van een browser. Kort door de bocht is een webserver dus een server waarmee bestanden toegankelijk gemaakt worden, een soort veredelde fileserver dus. Het verschil zit hem er echter in dat een webserver qua functionaliteit heel erg uitgebreid gemaakt kan worden door er allerhande modules aan toe te voegen. Deze modules zorgen ervoor dat de webserver bijvoorbeeld ook interactief kan worden met de gebruiker en ervoor kan zorgen dat scripts geïnterpreteerd worden en nog veel meer.
224
Linux 4
In de begindagen van de webserver waren de bestanden die aangeboden werden door een webserver voornamelijk statisch van aard. Het waren feitelijk niet meer dan veredelde tekstbestanden waarin wat opmaakcodes opgenomen waren. Tegenwoordig is een HTMLpagina veel meer dan dat. Vanuit de HTML-pagina zelf kunnen verschillende programmeertalen als PHP, ASP en Java gebruikt worden om dynamisch gegevens te genereren of op te halen uit een database. In een Linux-omgeving kom je als meest favoriete database die voor dit doel gebruikt wordt MySQL tegen. De combinatie Linux-Apache-MySQL-PHP is inmiddels dusdanig populair dat er een woord voor is: LAMP. Dit in tegenstelling overigens tot WAMP waarbij een ander platform gebruikt wordt, maar nog wel steeds de Apache-server die samenwerkt met MySQL en PHP. In dit hoofdstuk echter hebben we het uitsluitend over Apache. De domeinen van PHP en MySQL behoren meer toe aan de webdeveloper en blijven om die reden in dit boek buiten beschouwing. HTML-kennis Als Linux-beheerder heb je geen HTML-kennis nodig. Toch zul je als beheerder van een eigen webserver al heel snel merken dat je eigenlijk niet zonder kunt. Daarom willen we je met het volgende voorbeeld toch enig inzicht geven in de wijze waarop een HTML-document is opgebouwd. Zoals gezegd, is de basis van een webserver het HTML-document. Omdat het prettig is als je – al was het alleen maar voor testdoeleinden – zelf met de server een HTML-document kunt aanbieden, zie je hieronder een eenvoudig opgemaakt document. Dit document is overigens afkomstig van www.novellcourses.com, een van de websites van de auteur van dit boek. Novellcourses.com <meta name=”keywords” content= “Novell, SUSE, CLP, CLE, Open Enterprise Server, cletrainer, clptrainer, Sander van Vugt, Leerboek Linux, Definitive Guide to SUSE Linux Enterprise Server, Novell training, Novell course material, Novell certification”/> <meta name=”description” content=”Novellcourses.com is the only resource you need for Novell training and Certification. On this
6 Apache
225
website, you’ll find course exercises, exam crams and lots of tips that help you in mastering all important Novell products.”/> <meta name=”robots” content=”all”> <strong>Novellcourses.com
The only resource you need for everything you need about Novell training.
This website is under construction. We are working on it on an allmost daily basis. Check out later for changes!
Click here for everything you need to prepare for the Novell CLP test
Click here for everything you need to prepare for the Novell CLE test
Click here for access to Novell OES course materials and information.
I recommend using VMware virtual machines for all the labs described on this website and related websites. Specific virtual machines are available for purchase. You can run these virtual machines using VMware Player which is available here. For your convenience, I have created two empty VMware virtual machines that are available as a free download. You can use these machines to build your own Linux server in VMware:
Click here to download an empty virtual machine for use in a Windows environment.
Click here to download an empty virtual machine for use in a Linux environment.
To use these virtual machines, a minimum of 512 MB RAM is needed, as well as 4 GB free space on your hard drive to complete an installation of Linux.
Click here to contact me
226
Linux 4
Figuur 6.1 Voorbeeld van een eenvoudige website
In het hiervoor genoemde document zie je de HTML-code waaruit de website uit figuur 6.1 bestaat. Het eerste dat de moeite waard is waar te nemen, is dat in de HTML-code heel veel elementen een opening hebben dat daarna ook weer netjes wordt afgesloten. Zo begint het document met hetgeen wordt afgesloten met html>. Deze twee zogenoemde tags vertellen aan de webserver dat dit HTML-code is. In het voorbeelddocument worden verder de tags gebruikt. Dit zijn de opmaakopdrachten die de webserver aan de browser doorgeeft en op basis waarvan de browser ervoor kan zorgen dat er een fraaie webpagina getoond kan worden: ...
Hier neem je de titel van de website op. Dit stijlelement zorgt ervoor dat in de titelbalk van de browser de naam van de website opgenomen wordt. ... Dit is de header van de website. In dit geval wordt de header niet gebruikt om informatie op te nemen die aan de eindgebruiker getoond wordt, maar informatie die ervoor zorgt dat de website het beter doet. <meta name=”keywords” content= “...”/> Deze constructie wordt gebruikt voor de zogenoemde meta-tags. Dit zijn sleutelwoorden die in de website opgenomen worden. Deze sleutelwoorden zijn vooral bedoeld voor zoekmachines. Zoekmachines laten namelijk deze sleutelwoorden meewegen om te bepalen hoe een website geïndexeerd wordt. <meta name=”description” content=”...”/> Deze tag wordt
6 Apache
227
ook gebruikt als meta-informatie. In dit geval gaat het erom dat in een zoekmachine een korte beschrijving van de website gegeven kan worden. <meta name=”robots” content=”all”> Dit is het laatste element uit de header waarmee aan zoekrobots die door zoekmachines gebruikt worden, verteld wordt dat alle inhoud van de website geïndexeerd mag worden. <strong> ... Hiermee zorg je ervoor dat tekst vet wordt weergegeven. Als alternatief kan gebruikgemaakt worden van ... .
Dit is een break. Hiermee zorg je ervoor dat een einderegelteken gebruikt wordt.
Gebruik deze tag om een horizontale lijn op te nemen in de pagina. De waarde tussen de aanhalingstekens bepaalt hoe dik de lijn uiteindelijk wordt. Deze tag zorgt ervoor dat een lijst met bolletjes getoond wordt. Deze tag is vooral erg handig voor het opnemen van opsommingen. ... Deze constructie gebruik je om hyperlinks op te nemen in de tekst van de website. Op de plaats van de eerste ... komt een verwijzing naar het type hyperlink. Op de plaats van de tweede ... komt de tekst te staan die als hyperlink weergegeven wordt. Door op deze tekst te klikken krijg je toegang tot het element waarnaar verwezen wordt. In dit voorbeelddocument is gebruikgemaakt van de volgende typen: http://www.cletrainer.com: dit type wordt gebruikt om te verwijzen naar een andere website. ./emptyvm-win.zip: dit type wordt ingezet om een document te openen dat ergens in de directorystructuur van de site voorkomt. mailto:[email protected]: met dit type maak je een link waarmee een mailbericht verstuurd kan worden. 6.3
Configuratie van de Apache-server
Om tot een elementaire configuratie van een Apache-webserver te komen is niet bijzonder veel nodig. Er zijn drie componenten die een rol spelen en als je deze drie componenten alle drie kunt terugvinden, ben je al in staat een eenvoudige webserverconfiguratie te maken:
228
Linux 4
Het proces – Dit is het proces dat ervoor zorgt dat de Apache-server gestart wordt. De naam van het proces is httpd en je start het door gebruik te maken van een van de initscripts die je vindt in /etc/init.d. Zoek in deze directory naar iets dat http of apache heet of iets wat erop lijkt; dit is wat je nodig hebt. De documentroot – Dit is de locatie waarin je de HTML-documenten plaatst. In de Apache-configuratiebestanden wordt bepaald waar deze documentroot zich bevindt. Op Fedora vind je de documentroot in /var/www/html en op SUSE wordt voor dit doel gebruikgemaakt van /srv/www. Overigens is dit een directory die om performance-redenen als het even kan op een aparte partitie geplaatst wordt. De configuratiebestanden – Wat dit betreft bestaan er aanzienlijke verschillen tussen de distributies. Als overeenkomst is er altijd wel een bestand met de naam httpd.conf dat als startpunt van de configuratie functioneert. Daarnaast kunnen tal van andere configuratiebestanden inbegrepen worden. Op sommige distributies is er maar één configuratiebestand en op andere distributies wordt het een bonte verzameling van configuratiebestanden die door middel van includes aan elkaar verbonden zijn. 6.3.1 Een eenvoudige configuratie De wijze waarop je te werk gaat om Apache te installeren, hangt af van de distributie die je gebruikt. Main-stream-distributies, zoals Fedora en SUSE, leveren kant-en-klare RPM’s waarmee je de Apache-server in een handomdraai geïnstalleerd hebt. Als je gebruikmaakt van een distributie die Apache RPM’s levert, raden wij je aan om van deze methode gebruik te maken. Hiermee voorkom je immers dat de installatiepoging voortijdig strandt, omdat er een aantal dependencies niet aanwezig is. Alleen wanneer je geen kant-en-klare installatiebestanden voorhanden hebt, of natuurlijk wanneer het voor jou noodzakelijk is de allerlaatste versie van de Apache-webserver te gebruiken, kun je een tarball downloaden van www.apache.org en de bestanden hieruit installeren. Houd er bij het werken met Apache rekening mee dat er twee versies zijn die beide nog vrij algemeen gebruikt worden. Om te beginnen is er versie 1 waarvan subversie 1.3 het laatste onderdeel is. Deze versie is lange tijd op grote schaal ingezet. Al geruime tijd echter is ook versie 2 van de Apache-webserver beschikbaar. Veel distributies leveren beide naast elkaar. De reden hiervoor is dat
6 Apache
229
veel organisaties nog steeds behoefte hebben aan Apache versie 1.3 vanwege achterwaartse compatibiliteit. Als toepassingen ontwikkeld zijn samen te werken met Apache 1.3, is het lastig om zo maar even over te gaan naar versie 2. In dit boek echter besteden we uitsluitend aandacht aan Apache versie 2. De reden hiervoor is eenvoudig: Apache versie 1.3 kent een aantal serieuze beveiligingsproblemen en zou om die reden echt niet meer gebruikt moeten worden. Nadat je de Apache-webserver geïnstalleerd hebt door de betreffende RPM’s op het systeem weg te schrijven, kun je hem verder configureren. Om te beginnen doe je dat door aan te geven welke directory als documentroot gebruikt moet worden. De documentroot is de directory waarin je alle HTML-documenten plaatst die door de Apache-server aangeboden moeten worden. De standaarddirectory die hiervoor gebruikt wordt, verschilt per distributie. Op SUSE Linux wordt de directory /srv/www/htdocs voor dit doel gebruikt. Na installatie van de Apache-webserver vind je in deze directory alleen nog maar enkele voorbeeldbestanden. Een van deze bestanden is het bestand index.html. Dit is het bestand dat standaard aangeboden wordt door de Apache-webserver wanneer hij door een gebruiker benaderd wordt. Je kunt overigens in het Apache-configuratiebestand aangeven dat voor dit doel een ander bestand gebruikt moet worden als je dat wenst. Als beheerder van de Apache-webserver moet je ervoor zorgen dat hier ook andere bestanden geplaatst kunnen worden. Als je ooit gebruik zou willen maken van een andere dan de standaarddocumentroot, zorg er dan in elk geval voor dat de gebruiker wwwrun rechten heeft in deze directory; dit is namelijk de gebruikers-ID waarvan de Apache-webserver standaard gebruikmaakt. Ook kun je in deze directory subdirectory’s maken. Deze subdirectory’s kunnen vervolgens door gebruikers in de URL gespecificeerd worden. Om bijvoorbeeld het bestand index.html te benaderen dat op de webserver is opgeslagen in /srv/www/htdocs/Sales, geeft de gebruiker in zijn browser de URL http://uwserver/sales. Het wordt natuurlijk echt mooi als de gebruiker gewoon in het hoofddocument op een link kan klikken om deze subdirectory te activeren, maar dat hoeft niet. Zonder deze link is het maken van subdirectory’s een heel aardige manier om informatie op de server te verstoppen. Met deze link is het voor gebruikers juist handig om informatie terug te vin-
230
Linux 4
den. Voor het geval dát je het graag wilt, laat het volgende brokje HTML-code zien hoe een hyperlink met de naam fotos gemaakt wordt om te verwijzen naar het bestand fotos/index.html. Klik hier voor mijn foto’s. Check vooral de BrainShare 2007 foto’s en kijk of je er op staat!
Zonder index.html Als er in een subdirectory geen bestand met de naam index. html staat, krijgt de bezoeker een lijst met documenten te zien. Handig als je in een bepaalde subdirectory alleen bestanden neer wilt zetten die door gebruikers gedownload kunnen worden. Een ander handig alternatief om met de webserver veel informatie aan te bieden, is door gebruik te maken van virtuele servers. Dit betekent dat één Apache-server meerdere webservers aanbiedt. We spreken dan van virtuele servers. Verderop in dit hoofdstuk lees je in detail hoe je deze virtuele servers inricht. 6.3.2 Structuur en configuratiebestanden van de Apachewebserver Versie 1 van de Apache-webserver maakte gebruik van één configuratiebestand van waaruit alles geregeld werd: het bestand httpd. conf. Daarnaast kon voor wat additionele configuratie ook gebruikgemaakt worden van de configuratiebestanden access.conf en smr.conf, maar veel beheerders gaven er de voorkeur aan om alles vanuit httpd.conf te regelen. Voor Apache 2 is de situatie iets anders. Het bestand httpd.conf speelt nog steeds een hoofdrol, maar vanuit dit bestand kan door middel van het statement include een groot aantal secundaire configuratiebestanden aangeroepen worden. Op SUSE Linux vind je alle Apache-configuratiebestanden in de subdirectory /etc/apache2 en op Fedora komen ze voor onder /etc/httpd/conf. De organisatie van configuratiebestanden is op Fedora vrij eenvoudig: vrijwel alles gebeurt vanuit het hoofdconfiguratiebestand httpd.conf. Op SUSE Linux is de situatie anders en kom je in de directory met configuratiebestanden een aanzienlijk aantal bestanden tegen.
6 Apache
https.conf
default-server.conf
vhost.d/
uid.conf
listen.conf
server-tuning.conf
error.conf ssl-global.conf.
231
Dit is het meest belangrijke configuratiebestand. Vanuit dit configuratiebestand worden alle andere configuratiebestanden aangeroepen. Hier vind je de standaardsetup van de webserver. De inhoud van dit bestand kan echter overschreven worden door andere configuratiebestanden. In deze directory wordt de configuratie voor virtuele hosts opgeslagen. Later in dit hoofdstuk leer je meer over het werken met virtuele hosts. In dit bestand wordt bepaald van welke UID en GID Apache gebruikmaakt. Na een standaardinstallatie zijn dit de gebruiker wwwrun en de groep www. Hierin wordt aangegeven op welke poort de Apache-websesrver luistert. Standaard luistert de Apache-webserver op alle aanwezige netwerkkaarten naar poort 80. In dit bestand wordt de werking van de Apache-webserver geoptimaliseerd. In de meeste gevallen voldoen de standaardwaarden uitstekend, alleen voor zwaar belaste webservers kan het de moeite zijn parameters in dit bestand aan te passen. Hier wordt bepaald wat de Apache-webserver moet doen wanneer zich een fout voordoet. Dit configuratiebestand bevat de configuratie die gebruikt wordt wanneer je gebruik wilt maken van SSL-encryptie.
Eén of veel? De keuze tussen één of meer Apache-configuratiebestanden is in feite natuurlijk gewoon een kwestie van smaak. Toch gaat onze voorkeur ernaar uit om een aantal configuratiebestanden te maken. De reden? Het blijft allemaal wat overzichtelijker. Bekijk bijvoorbeeld eens de Apache-configuratie op een standaard geïnstalleerd Fedora-systeem. Je zult zien dat dit eigenlijk té groot is om nog overzichtelijk te zijn.
232
Linux 4
In welke bestanden de Apache-configuratie standaard geregeld wordt, staat overigens niet vast. De beheerder van de server kan dit allemaal zelf naar wens inrichten door in /etc/apache2/httpd.conf met Include-regels te werken. De regels waarin dit gebeurt, worden directives genoemd. Let er overigens op dat deze directives hoofdlettergevoelig zijn: als je Include bedoelt, moet je dus niet include schrijven. Door een Include-directive op te nemen wordt vanuit het hoofdconfiguratiebestand een extra bestand met configuratie aangeroepen. Zo wordt bijvoorbeeld een bestand aangeroepen waarin wordt aangegeven welke modules er bij het laden van de Apache-server mee geladen moeten worden: Includes Sommige mensen vinden includes handig, anderen vinden het maar niets. Dus: waarom zou je met includes willen werken? Wij denken dat er een heel goede reden is: het werken met includes maakt de configuratie naast meer overzichtelijk ook flexibeler. Stel dat je een tiental virtuele servers host op de server. Voor elk van deze servers zul je bepaalde parameters telkens terug willen laten komen. Je kunt ze dan elke keer opnieuw invoeren in het configuratiebestand van de desbetreffende virtuele server; een hoop werk. Als alternatief kun je ervoor kiezen te werken met includes waarin de algemene code voorkomt. Hierdoor beheer je de code op één plaats in het configuratiebestand en dat maakt het een stuk eenvoudiger als je ooit eens wijzigingen door moet voeren.
# generated from APACHE _ MODULES in /etc/sysconfig/apache2 Include /etc/apache2/sysconfig.d/loadmodule.conf
Bij het werken met directives komt het vaak voor dat deze gegroepeerd worden. Door directives te groeperen kun je ze toepassen voor een specifieke set parameters. Zo zie je hierna een voorbeeld waarin een directive gedefinieerd wordt die alleen instellingen doet voor de directory /srv/www/htdocs: Options None
6 Apache
233
AllowOverride None Order allow,deny Allow from all
Let even op de wijze waarop het groeperen plaatsvindt: de groepering begint met het keyword Directory en wordt afgesloten met hetzelfde keyword, maar dan wordt dit keyword voorafgegaan door een slash. Dit is dezelfde notatiewijze als dat in een HTMLdocument gebruikt wordt. Deze notatiewijze kom je overigens niet alleen tegen in het Apache-configuratiebestand, maar bijvoorbeeld ook in alle HTML-code die je schrijft. Ook andere talen, zoals XML, maken er gebruik van. Een ander algemeen element dat in de Apache configuratiebestanden opgenomen kan worden, is het commentaarteken. Het zal je niet verbazen dat ook de Apache-server hiervoor de # gebruikt. Herstarten De Apache-webserver is niet zo slim dat hij er automatisch achter komt wanneer je iets gewijzigd hebt. Je moet dit zelf duidelijk maken door de server opnieuw te starten. Geef hiervoor de opdracht /etc/init.d/apache2 restart. Wil je controleren of je het Apache-configuratiebestand op de juiste wijze hebt gemaakt? Gebruik dan de opdracht service apache2 configtest op SUSE of service httpd configtest op Fedora. Deze opdracht controleert de Apache-configuratie op eventueel voorkomende fouten in de syntaxis. Als er een probleem is, wordt daar duidelijk melding van gemaakt en weet je ook precies waar je het probleem moet oplossen. Is alles in orde, dan wordt de boodschap Syntax OK gegeven. 6.3.3 Inrichting van httpd.conf Het bestand httpd.conf is de aangewezen locatie waar de configuratie van een Apache-webserver gedaan wordt. Aangezien de Apache-webserver ook heel flexibel is, is dit echter geen vaststaand gegeven: zo gebeurt op SUSE Linux bijvoorbeeld het grootste deel van de configuratie in default-server.conf. Welk bestand er precies gebruikt wordt, maakt niet zo heel veel uit, als je uitein-
234
Linux 4
delijk maar weet hoe deze bestanden aangepast moeten worden. Hiervoor maak je gebruik van een aantal standaard-directives. In de tabel vind je een overzicht van veelgebruikte directives en andere constructies die je in deze bestanden tegen kunt komen. Zorg ervoor dat je met deze directives overweg kunt, ze vormen de basis van elke Apache-webserver: Directive
Toepassing
DocumentRoot
Geeft aan in welke directory alle documenten van de
Directory “naam”
webserver geplaatst worden. Wordt gebruikt om een uitzondering te definiëren voor
/Directory Include
een bepaalde directory. Roept een bestand aan waarin additionele configura-
Options
tie gedaan wordt. Wordt gebruikt om opties toe te voegen aan een uitzondering die gedefinieerd is, zoals een speciale
AllowOverride
directory. Bepaalt of het is toegestaan dat instellingen in een directive overschreven worden door een lokaal
Alias “naamvandealias”
configuratiebestand met de naam .htaccess. Maakt een alias naar een directory met een bepaalde
“echtenaam” ScriptAlias
naam. Maakt een alias naar een directory waarin scripts voorkomen die ervoor zorgen dat webpagina’s dynamisch gegenereerd worden.
Dit is slechts een beperkt overzicht van beschikbare directives. Een volledig overzicht kun je vinden in de documentatie van de Apache server op http://www.apache.rog/docs-2.0/mod/directives.html. Hieronder zie je een voorbeeld van de belangrijkste parameters van de website www.novellcourses.com waarmee je eerder in dit hoofdstuk kennis hebt kunnen maken. Deze server draait overigens als virtuele host. Dit kunnen we op dit moment nog even negeren. Verderop in dit hoofdstuk leer je wat de voordelen zijn van het gebruik van een virtuele host. Ongeacht of je een virtuele host gebruikt, de parameters blijven wel altijd hetzelfde. ServerAdmin [email protected] ServerName www.novellcourses.com
6 Apache
235
DocumentRoot /srv/www/vhosts/novellcourses.com ErrorLog /var/log/apache2/novellcourses.com-error _ log CustomLog /var/log/apache2/novellcourses.com-access _ log combined HostnameLookups Off UseCanonicalName On ServerSignature On
ScriptAlias /cgi-bin/ “/srv/www/vhosts/novellcourses.com/cgi-bin/” Alias /images/ “/srv/www/vhosts/novellcourses.com/images/” AllowOverride None Options +ExecCGI -Includes Order allow,deny Allow from all
UserDir public _ html Include /etc/apache2/mod _ userdir.conf
Options Indexes FollowSymLinks AllowOverride None Order allow,deny Allow from all
In deze configuratie wordt een virtual host gedefinieerd. Deze host is te benaderen op poort 80 op het gespecificeerde IP-adres. Om te beginnen wordt wat informatie gegeven over deze server zelf. Zo wordt eerst de directive ServerAdmin gebruikt om het mailadres van de beheerder van de server te geven. Vervolgens volgt met de belangrijke parameter ServerName een aanduiding van de naam van deze server. Daarna volgt een verwijzing naar de Documentroot, de error-log en het algemene logbestand. Na de logbestanden is er een drietal regels dat aangeeft hoe omgegaan moet worden met namen. Als eerste staat de parameter HostNameLookups uit. Dit zorgt ervoor dat niet voortdurend een
236
Linux 4
DNS-lookup gedaan hoeft te worden voor hostnamen. De directives UseCanonicalName en ServerSignature zorgen er vervolgens voor dat de hostnaam goed wordt weergegeven. Na het algemene stuk code waarin het gedrag van de server bepaald wordt, volgen drie blokjes specifieke code. Om te beginnen is er het blok waarin de ScriptAlias gedefinieerd wordt. Daarbij wordt verwezen naar de directory /cgi-bin die voor kan komen in de DocumentRoot van de webserver. Als deze directory bestaat, is het de typische locatie waarin scriptfiles geplaatst worden. Voor deze directory wordt vervolgens een aantal opties gezet. Deze opties zorgen ervoor dat de scripts door iedereen uitgevoerd mogen worden. In het tweede blokje code wordt aangegeven wat er moet gebeuren als de Apache-module userdir.c gebruikt wordt. Door middel van deze module kan een stuk extra code ingevoerd worden. In dit geval zorgt de module ervoor dat een gebruikersdirectory gemaakt kan worden. Als dit het geval is, wordt door middel van een Include de informatie uit het configuratiebestand mod_userdir.conf ingelezen. Tot slot is er de specificatie van opties die van toepassing zijn voor de documentroot zelf. De standaardopties zorgen ervoor dat een index gemaakt wordt en ook gewerkt kan worden met symbolic=links. Daarnaast heeft elke gebruiker toegang tot deze directory. 6.4
Configuratie van virtuele hosts
Nadat een standaardinstallatie van een Apache-webserver is uitgevoerd, kan deze bereikt worden op het adres van de server waarop hij geïnstalleerd is door dit adres aan te roepen vanuit een browser die begint met de aanduiding http:// gevolgd door het serveradres. Nadat de gebruiker op deze wijze zijn server benadert, worden de bestanden getoond die in de directory staan die als DocumentRoot gedefinieerd is in de Apache configuratiebestanden. Dit systeem werkt prima, zolang er per server maar één Apache-webserver geïnstalleerd is. Wanneer een bedrijf de behoefte heeft meerdere Apache-webservers in te richten, worden de nadelen van dit sy-
6 Apache
237
steem zichtbaar: er zou dan immers voor elke afzonderlijke webserver een afzonderlijke computer nodig zijn. Dit probleem wordt opgelost door gebruik te maken van virtuele hosts. Als gebruikgemaakt wordt van virtuele hosts, wordt een entry opgenomen in de DNS-database voor elke virtuele Apache-webserver. Een virtuele host wordt in dat geval dus bereikbaar op basis van zijn naam. Op basis van de DNS-naam die een gebruiker invoert, wordt hij vervolgens doorgestuurd naar de juiste virtuele webserver. Het contact met een virtuele host wordt op de volgende wijze tot stand gebracht: 1. Vanuit de webbrowser wordt een URL opgegeven. De DNS-naam die in deze URL gebruikt wordt, wordt vervolgens omgezet in een IP-adres door contact op te nemen met de DNS-server. 2. Op basis van dit IP-adres kan de browser contact opnemen met de juiste fysieke machine. 3. Er wordt nu een http-pakketje naar de server verstuurd waarop de virtuele host actief is. In dit http-pakketje wordt verwezen naar de naam van de virtuele host. 4. Op basis van deze hostnaam die gebruikt wordt, is de Apachewebserver in staat het verzoek door te sturen naar de juiste virtuele host. De wijze waarop virtuele hosts gedefinieerd worden, verschilt per gebruikte Linux-distributie. In het onderstaande zie je hoe de configuratie van virtuele hosts in het algemene configuratiebestand httpd.conf geregeld kan worden. Dit is bijvoorbeeld de wijze waarop het op Fedora Linux gebeurt: BindAddress Listen
*
192.168.1.1:8080
Documentroot /var/apache/mijnwebserver ServerName www.mijnwebserver.nl ServerAdmin [email protected] ErrorLog logs/mijnwebserver.nl-error-log CustomLog logs/mijnwebserver.nl-custom-log Documentroot /var/apache/jouwwebserver
238
Linux 4
Servername www.jouwwebserver.nl ServerAdmin [email protected] ErrorLog logs/jouwwebserver.nl-error-log CustomLog logs/jouwwebserver.nl-custom-log
In deze regels wordt eerst gedefinieerd dat de webserver benaderd kan worden via elke netwerkkaart in het systeem. Dit hoeft overigens niet apart vermeld te worden. De standaardwaarde zorgt er namelijk ook al voor dat dit mogelijk is, maar het is leuk dat je zo deze parameter ook eens tegenkomt. Vervolgens wordt geregeld dat de webserver naast de standaardpoort 80 ook luistert naar verzoeken die binnenkomen op poort 8080, maar dat geldt alleen voor de host die draait op IP-adres 192.168.1.1. Daarna worden twee virtuele hosts gedefinieerd. De regels waarin dit gebeurt, zullen duidelijk zijn. Per virtuele host is er een extra blokje met configuratieregels. Je ziet dat specifieke parameters, zoals het mailadres van de beheerder van de server en de locatie van logbestanden, ook per virtuele host gedefinieerd worden. Waar je vooral goed op moet letten, is dat je in DNS ook een voorziening geregeld hebt voor deze virtuele hostnamen. Om te kunnen werken met virtuele hosts moet de naam van die host door middel van een CNAME-record in DNS gedefinieerd zijn. Als je gebruikmaakt van SUSE Linux, moet je een iets andere werkwijze betrachten om virtuele hosts te kunnen definiëren. Je maakt in dit geval namelijk voor elke virtuele host die je wilt definiëren een apart configuratiebestand aan in de directory /etc/apache2/vhosts.d. Hoe dit configuratiebestand heet, maakt formeel niet uit, als de naam ervan maar eindigt op .conf. In de praktijk raden wij je echter met klem aan om de naam van de virtuele host terug te laten komen in dit configuratiebestand. Om het werken met een dergelijk configuratiebestand iets te vereenvoudigen, vind je in /etc/apache2/vhosts.d een voorbeeldbestand met de naam vhost.template. In het configuratiebestand voor een virtuele host kunnen de volgende directives worden opgenomen:
6 Apache
239
Directive
Betekenis
ServerAdmin
Het mailadres waarop de beheerder van de virtuele
ServerName
host bereikt kan worden. De naam van de virtuele host. Deze naam moet op
DocumentRoot
dezelfde wijze in DNS geconfigureerd zijn. De documentroot die gebruikt wordt door de betreffende virtuele host. Deze directory moet in elk geval
ErrorLog
leesbaar zijn voor de gebruiker wwwrun. Het bestand dat gebruikt moet worden voor het loggen van foutmeldingen. Dit bestand moet schrijfbaar
CustomLog
zijn voor de gebruiker wwwrun. De naam van het algemene logbestand. Dit bestand moet beschreven kunnen worden door de gebruiker
ScriptAlias
wwwrun. Deze directive kan gebruikt worden om te verwijzen naar een directory waarin scripts voorkomen die gebruikt worden om de inhoud van webpagina’s dynamisch te genereren. Als geen gebruikgemaakt wordt
van scripts, heb je deze directive niet nodig. Dit blok gegevens kan gedefinieerd worden indien gebruikgemaakt wordt van een aparte scriptdirectory. In dat geval plaats je hier de instellingen die voor deze directory van toepassing zijn.
Nadat je de instellingen voor virtuele hosts hebt aangepast, moet de Apache-webserver opnieuw geladen worden. Vergeet ook niet te controleren dat de DNS-configuratie op het systeem in orde is, zodat de virtuele host herkend wordt. Bij het configureren van virtuele hosts is er een instelling die in het bijzonder aandacht behoeft: de instelling NameVirtualHost. Hiermee regel je namelijk dat een Apache-server met verschillende namen kan omgaan. Om te beginnen moet er in de algemene configuratie een NameVirtualHost-verwijzing voorkomen. Vervolgens moet je voor elke afzonderlijke virtuele host door middel van een VirtualHost-tag bepalen waarnaar deze virtuele host moet luisteren. Op een Fedora-systeem regel je dit allemaal in het algemene configuratiebestand httpd.conf. Op SUSE Linux moet je op verschillende plaatsen aan het werk. Hieronder beschrijven we de procedure die op SUSE Linux gevolgd moet worden:
240
Linux 4
1. Open het bestand /etc/apache2/listen.conf. Zorg ervoor dat in dit bestand de volgende regel wordt opgenomen: NameVirtualHost *.80
2. Activeer nu de directory /etc/apache2/vhosts.d. Open stuk voor stuk elk configuratiebestand dat in deze directory voor virtuele hosts voorkomt en zorg ervoor dat door middel van de VirtualHost-directive aangegeven wordt dat de virtuele host op dezelfde IP-adressen luistert. Dit doe je door de volgende regel op te nemen in het begin van elk configuratiebestand:
Je kunt overigens in de configuratiebestanden van de afzonderlijke virtuele hosts in plaats van een * ook een specifiek IP-adres opnemen. Dit laatste is met name handig als de server meerdere IP-adressen heeft en je aan elk IP-adres een afzonderlijke virtuele host wilt verbinden. 6.5
Beperken van toegang tot de webserver
Onder normale omstandigheden krijgen alle computers die dat willen toegang tot de bestanden die door de webserver worden aangeboden. Je kunt hier echter wat tegen doen door toegang voor bepaalde gebruikers tegen te houden. Dit kan op basis van IP-adres, het kan ook op basis van namen van gebruikers die je gedefinieerd hebt. 6.5.1 Allow en Deny Een zeer elementaire wijze om te bepalen of wij toegang krijgen tot een bepaalde directory, is door middel van de Allow- en Denydirectives. Deze directives kunnen gebruikt worden om de toegang aan computers toe te staan of juist te ontzeggen. Order deny,allow Deny from all Allow from mijnwebserver.nl
Door middel van de directive Order bepaal je om te beginnen in welke volgorde de toegangsregels bekeken moeten worden. Je hebt hiervoor de volgende opties:
6 Apache
Deny,Allow
Allow,Deny
Mutual-failure
241
Eerst wordt naar de Deny-directives gekeken, dan pas naar de Allow-directives. De standaardinstelling is dat geen toegang verleend wordt. Alleen gebruikers voor wie een Allowdirective gedefinieerd is, krijgen toegang tot de server. Er wordt eerst gekeken naar Allow-directives en dan pas naar Deny-directives. De standaardinstelling is dat toegang verleend wordt. Alleen gebruikers waarvoor een Deny-directive gedefinieerd is, wordt toegang tot de server ontzegd. Deze werkwijze is een stuk minder veilig als de werkwijze waarbij Order Deny,Allow gebruikt wordt, maar wel handig als je niet van plan bent met toegangsbeperkingen te werken. Alleen hosts die voorkomen in de Allow-lijst en niet voorkomen in de Deny-lijst krijgen toegang. Dit heeft hetzelfde effect als Order Allow,Deny. Er wordt voorkeur gegeven aan het gebruik van Order Allow,Deny in plaats van deze optie.
Je kunt deze statements op verschillende manieren definiëren: met behulp van gedeeltelijke of volledige computernamen of op basis van volledige of gedeeltelijke IP-adressen. Daarnaast is het ook mogelijk een verwijzing naar ‘all’ op te nemen om toegang uit te sluiten voor iedereen. Hierna zie je een voorbeeld hoe deze regels in de praktijk toegepast kunnen worden: Order deny,allow Deny from all Allow from somedomain.com Allow from 192.168.0.0/255.255.0.0
6.5.2 Toegang beperken op basis van gebruikersnamen Naast authenticatie op basis van IP-adressen is het ook mogelijk te authenticeren op basis van gebruikersnamen. Als je gebruikmaakt van deze mogelijkheid, moeten gebruikers zichzelf met hun gebruikersnaam bekend maken voordat ze toegang tot een directory
242
Linux 4
krijgen waarop deze vorm van authenticatie van toepassing is. Voordat je echter gebruik kunt maken van authenticatie op basis van gebruikersnamen, moet je ervoor zorgen dat er gebruikersaccounts worden gemaakt voor de webserver. Op Fedora gebruik je hiervoor de opdracht htpasswd en op SUSE Linux gebruik je htpasswd2. De werking van de opdracht is verder voor beide systemen gelijk. In het volgende voorbeeld wordt een gebruikersaccount gemaakt voor gebruiker Betty. In dit voorbeeld is Betty de eerste gebruiker in de wachtwoordendatabase, daarom wordt met de optie –c /etc/apache2/htpasswd aangegeven met welke naam en op welke locatie het bestand gemaakt moet worden. Houd er rekening mee dat de locatie die hier vermeld is, specifiek is voor SUSE Linux. Op andere distributies zal gebruikgemaakt worden van een andere locatie zoals /etc/httpd.: htpasswd2 –c /etc/apache2/htpasswd Betty.
Direct nadat op deze wijze een gebruikeraccount voor Betty is gemaakt, verschijnt een prompt waarop een wachtwoord voor deze gebruiker ingevoerd moet worden. Dit wachtwoord wordt opgeslagen in het bestand htpasswd. Nadat de database met wachtwoorden eenmaal is gemaakt met behulp van de parameter –c, hoeft deze parameter volgende keren niet meer gebruikt te worden. Om een volgende keer een gebruiker Franck toe te voegen aan het bestand, gebruik je dus gewoon: htpasswd2 /etc/apache2/htpasswd Franck
Het is ook mogelijk gebruikers vanuit deze database te verwijderen: maak in dat geval gebruik van de optie –D: gebruik bijvoorbeeld: htpasswd2 –D /etc/apache2/htpasswd bas
om gebruiker bas uit de database te halen, zodat hij niet langer kan inloggen op beveiligde directory’s. Nadat je een database hebt gemaakt waarin gebruikersaccounts worden opgeslagen, kun je daar vervolgens gebruik van maken wanneer je toegang verleent tot bepaalde directory’s. Hierna zie je een voorbeeld waarin dat gebeurt:
6 Apache
243
AuthType Basic AuthName “Boekhouders” AuthUserFile /etc/apache2/htpasswd Require user Betty Alex
In dit voorbeeld wordt gewerkt met de authenticatiemethode ‘Basic. Bij deze authenticatiemethode worden wachtwoorden over het netwerk verstuurd. Dit is niet veilig, maar daar staat tegenover dat het AuthType Basic wel heel eenvoudig te installeren is. Er is ook nog een geavanceerde methode genaamd Digest’, maar die laten we hier buiten beschouwing. Vervolgens wordt met AuthName “Boekhouders” een naam gegeven aan de directory waartoe de toegang beperkt moet worden. Daarna wordt aangegeven welk bestand gebruikt wordt als gebruikersdatabase en tot slot wordt aangegeven welke gebruikers specifiek toegang krijgen tot de directory in kwestie. In dit geval geldt dat dus voor gebruikers Betty en Alex. Let even op de wijze waarop gebruikersnamen in deze lijst van elkaar onderscheiden worden: je zet alleen een spatie en verder helemaal niets tussen de namen van de gebruikers. Als alternatief is het overigens ook mogelijk om alle gebruikers die een account hebben in het bestand htpasswd, toegang te geven. Neem in dat geval de regel Require user valid-user op. 6.5.3 Toepassing gebruikersauthenticatie Er zijn globaal twee methoden waarop je gebruikersauthenticatie kunt toepassen. Als eerste is het mogelijk om de authenticatie in het configuratiebestand zelf op te nemen. Daarnaast kun je een bestand met de naam .htaccess plaatsen in de te beveiligen directory. Vervolgens plaats je in dit bestand de regels waarmee je de beveiliging wilt toepassen. In beide gevallen moet je oppassen voor de directive AllowOverride. Deze staat namelijk standaard op none en dat zorgt ervoor dat het niet mogelijk is om instellingen die op serverniveau gedaan zijn op een lager niveau te overschrijven. Mocht het niet lukken om beveiligingsinstellingen toe te passen, controleer dan de wijze waarop AllowOverride op dat moment is ingesteld.
244
Linux 4
6.6
Apache beveiligen met OpenSSL
Standaardcommunicatie tussen een webserver en een browser is niet beveiligd. Dit betekent dat het verkeer onderschept kan worden door iemand die gebruikmaakt van een sniffer en dat uit de onderschepte pakketjes de verzonden data gereconstrueerd kunnen worden. Als het gaat om onschuldige data, is dat geen probleem. Zodra echter gegevens verzonden worden waarvoor het van belang is dat ze goed beveiligd zijn, is het van belang dat deze gegevens tijdens het transport versleuteld worden. Hiervoor kan gebruikgemaakt worden van SSL. De meest voor de hand liggende keuze voor het Linux-platform is OpenSSL. 6.6.1 De werking van Secure Sockets Layer Bij communicatie op een netwerk wordt vaak gebruikgemaakt van een public/private key-paar. Deze sleutels kunnen voor verschillende doelen worden ingezet: encryptie; bewijzen van identiteit; bewijzen dat een bericht tijdens transport niet gewijzigd is. Basis voor al deze drie vormen van encryptie zijn een publieke sleutel en een privésleutel. We zullen het verder hebben over de public key en de private key. Beide sleutels zijn wiskundig aan elkaar gerelateerd: ze hebben elkaar nodig om gebruikt te kunnen worden. De private key is alleen bekend bij de eigenaar van het sleutelpaar: deze sleutel wordt gebruikt om de vertrouwelijkheid van verschillende soorten boodschappen te kunnen garanderen, dus het is van het grootste belang dat deze sleutel ook geheim blijft. De public key daarentegen wordt aan de hele wereld beschikbaar gesteld. De voornaamste toepassing van public keys en private keys is encryptie. Als Franck bijvoorbeeld een bericht wil sturen aan Audrey en dat wil versleutelen, heeft Franck de publieke sleutel van Audrey nodig. Het bericht wordt vervolgens versleuteld met deze public key en naar Audrey gestuurd. Zij kan het bericht op haar beurt lezen door het te ontcijferen met haar private key. Het mooie van het systeem is dat iedereen kan beschikken over de public key van Audrey en haar zo versleutelde berichten kan sturen, maar dat
6 Apache
245
om het bericht te ontcijferen de private key nodig is: Audrey kan dat alleen zelf doen. Een andere belangrijke toepassing van public keys en private keys is het bewijzen van identiteit. Hierbij gebruikt een gebruiker zijn private key om te bewijzen dat een bericht ook echt van hem afkomstig is. Dit doet de gebruiker door een signature aan een bericht toe te voegen en deze te versleutelen met zijn private key. Als deze signature op basis van de public key van diezelfde gebruiker ontcijferd kan worden, wordt daarmee bewezen dat het bericht inderdaad van die gebruiker afkomstig is. Nu is er met beide hiervoor genoemde technieken een probleem: hoe weet iemand zeker dat hij inderdaad communiceert met de partij waarmee hij denkt te communiceren? Om daar een garantie voor te kunnen geven wordt in netwerken gebruikgemaakt van de Certificate Authority. Een gebruiker stelt zijn public key beschikbaar in een PKI-certificaat. Op dit PKI-certificaat wordt vervolgens door de Certificate Authority (CA) een bewijs van echtheid geplaatst: de CA doet dit door het bewijs van echtheid te versleutelen met zijn private key. Wanneer een gebruiker die de public key van de CA heeft deze ondertekening kan ontcijferen, is daarmee bewezen dat het PKI-certificaat door de CA ondertekend is en is het in hoge mate aannemelijk dat het bericht ook inderdaad van de beoogde gebruiker afkomstig is. In de meeste gevallen wordt gebruikgemaakt van PKI-certificaten die ondertekend zijn door een CA die algemeen bekend is, zoals Verisign. Deze techniek wordt onder andere ook ingezet wanneer de communicatie met een webserver beveiligd wordt door middel van SSL. Dit gaat als volgt: 1. De browser maakt contact met de webserver op de HTTPS-poort 443 in plaats van de standaardpoort 80. 2. De browser vraagt aan de server om zijn public key en deze wordt direct daarop door de server verzonden. 3. De browser controleert of het PKI-certificaat dat van de server ontvangen is, ondertekend is door een geldige CA. Voor dit doel zijn browsers geconfigureerd met een lijst van CA’s die wereldwijd algemeen bekend zijn. 4. Als de sleutel geldig is, wordt een veilige verbinding tussen de browser en de server tot stand gebracht. Is de sleutel die van de server ontvangen is niet geldig, dan ziet de gebruiker een waar-
246
Linux 4
schuwing waarin gemeld wordt dat er problemen waren met de public key van de server. De gebruiker mag vervolgens zelf bepalen of hij de server in kwestie voldoende vertrouwt om ermee verder te gaan of niet. 6.6.2 Een PKI-certificaat maken Om veilig te kunnen communiceren met een webserver is dus een PKI-certificaat nodig. Als tweede stap moet je aan de Apache-server duidelijk maken dat hij dit certificaat ook moet gaan gebruiken. Er zijn verschillende mogelijkheden om zo’n certificaat aan te maken: Je neemt contact op met een commerciële Certificate Authority en dient een verzoek in om een PKI-certificaat te maken. Hieraan zijn de nodige kosten verbonden. Je installeert in het netwerk een CA en gebruikt deze om PKI-certificaten te ondertekenen. Je maakt een testcertificaat om een en ander te configureren. Houd er rekening mee dat er voor een werkelijk veilige oplossing maar één echte mogelijkheid is en dat is gebruik te maken van de eerste optie. Je klanten zullen immers snel afhaken wanneer ze op de website vertrouwelijke gegevens achter moeten laten terwijl het PKI-certificaat dat door de server wordt gebruikt niet valide is. Als je daarentegen alleen te maken hebt met internetklanten en je de gelegenheid hebt ervoor te zorgen dat de interne CA op elk werkstation bekend is, is er niets op tegen gebruik te maken van een CA die in het eigen netwerk geïnstalleerd is. Omdat het voor dit hoofdstuk te ver gaat om zelf een CA in het leven te roepen, lees je nu hoe je zelf een testcertificaat kunt maken. Voor commerciële toepassingen wordt deze werkwijze niet aanbevolen, maar je kunt hem uitstekend gebruiken om te testen dat het systeem werkt. 1. Om een sleutelpaar te kunnen maken heb je eerst een bestand nodig waarin zo veel mogelijk willekeurige getallen staan. Om zo’n bestand te genereren maak je gebruik van de randomgetalgenerator in /dev/random. Gebruik de opdracht cat /dev/randmom > /tmp/ random om een bestand te maken dat gevuld is met willekeurige getallen. Als je niets doet, gaat het maken van dit bestand door tot in het oneindige: gebruik na een paar seconden de toetsencombinatie Ctrl-C om te stoppen met het maken van het bestand. Langer
6 Apache
247
is niet nodig, want in de volgende opdracht worden toch maar 1024 bits uit dit bestand met randomgetallen gebruikt. 2. Op basis van het bestand met de willekeurige getallen, kun je nu een server key maken. Gebruik hiervoor de opdracht openssl genrsa –des3 –out server.key –rand /tmp/random 1024. Het duurt enige momenten voordat deze opdracht voltooid is. Er zijn verschillende parameters die gebruikt kunnen worden om dit bestand te maken. Raadpleeg eventueel de man-pagina van OpenSSL voor meer details. Tijdens het maken van de sleutels word je om een passphrase (wachtwoord) gevraagd. Dit wachtwoord wordt gebruikt om de private key van dit bestand te beveiligen. Houd er rekening mee dat deze passphrase elke keer wanneer de Apacheserver gestart wordt ook ingevoerd moet worden! Beide sleutels worden vervolgens opgeslagen in het bestand server.key. Dit bestand wordt gemaakt in de huidige directory. Figuur 6.2 Het is uitstekend mogelijk om vanaf de console zelf een public/ private key-paar voor gebruik met SSL aan te maken
3. Nu moet een certificaat worden gemaakt. Omdat er geen CA voorhanden is om de ondertekening van het certificaat te regelen, wordt in deze procedure een zogenoemd self-signed certificaat gemaakt. Om de signing van het certificaat te regelen moet een behoorlijk aantal vragen beantwoord worden. Deze vragen worden gesteld zodat de identiteit van degene die het PKI-certificaat ondertekent, achterhaald kan worden. Dit is belangrijk voor gebruikers van het certificaat die meer informatie willen over de echtheid ervan. Als je dit certificaat voor de webserver wilt gaan gebruiken, is het aan te raden in deze vragen dusdanige antwoorden te gebruiken dat het mogelijk wordt voor gebruikers om je te traceren. Gebruik de op-
248
Linux 4
dracht openssl req –new –x509 –key server.key –out server.crt om het certificaat te genereren. Figuur 6.3 Om met succes een certificaat aan te kunnen maken moet antwoord gegeven worden op een behoorlijk aantal vragen
4. Als gevolg van de voorgaande procedure zijn er nu twee bestanden gemaakt: het bestand server.crt waarin het certificaat van de server is opgeslagen en het bestand server.key met daarin de private key van de server. Om beide bestanden bruikbaar te maken voor de Apache-webserver, moet je ze nu kopiëren naar de directory waarin de configuratiebestanden van de Apache-server zijn opgeslagen: /etc/apache2 op SUSE Linux en /etc/httpd op Fedora Linux. Eigenlijk maakt de exacte locatie waar je deze bestanden naartoe kopieert niet bijzonder veel uit. Je verwijst namelijk in het Apache-configuratiebestand toch naar de exacte locatie van deze bestanden. 6.6.3 Apache configureren voor gebruik van SSL De procedure die nu gevolgd moet worden, hangt af van de Linuxdistributie waarvan je gebruikmaakt. We bespreken eerst welke werkwijze voor SUSE Linux gevolgd moet worden en vervolgens hoe je te werk moet gaan op Fedora Linux. Apache 2 op SUSE configureren voor gebruik van SSL Om te beginnen moet je op SUSE Linux het algemene instellin-
6 Apache
249
genbestand /etc/sysconfig/apache2 bewerken. Hierin regel je als eerste dat het opstarten van de Apache-server vertraagd wordt, zodat je in de gelegenheid bent de passphrase in te voeren tijdens het opstarten. Dit doe je door ervoor te zorgen dat de volgende regel in het configuratiebestand is opgenomen: APACHE _ START _ TIMEOUT=”15”. Vervolgens zorg je ervoor dat een aantal variabelen in de overige configuratiebestanden automatisch goed gezet worden met behulp van de parameter APACHE _ SERVER _ FLAGS=”SSL”. Als dit gebeurd is, zorg je er in het hoofdconfiguratiebestand voor dat de Apache-server gebruikmaakt van de juiste parameters. Op SUSE Linux bewerk je hiervoor het bestand /etc/apache2/defaultserver.conf. Zorg dat in elk geval de volgende parameters in dit bestand zijn opgenomen. Deze regels zorgen ervoor dat de server weet dat van SSL-encryptie gebruikgemaakt moet worden en waar de encryptiesleutels teruggevonden kunnen worden: SSLEngine on SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL SSLCertificateFile /etc/apache2/server.crt SSLCertificateKeyFile /etc/apache2/server.key
Tip! Als je werkt met virtual hosts, heb je ook de bovenstaande regels nodig. Neem ze dan op in de definitie van de virtual host en zorg ervoor dat de virtual host gedefinieerd wordt met een directive als . Nadat je deze wijzigingen hebt aangebracht, moet je de Apacheserver opnieuw starten. Tijdens het opstarten wordt gevraagd de passphrase voor het bestand server key in te voeren. Als de Apache-server automatisch geactiveerd wordt tijdens het opstarten van de server, wordt ook dan om de passphrase gevraagd. Dit betekent dat je altijd paraat moet staan wanneer de server opnieuw gestart wordt (eigenlijk mag dat natuurlijk geen probleem zijn: Linux-servers worden namelijk helemaal niet vaak opnieuw gestart!). Als je dit een probleem vindt, kun je overwegen ervoor te zorgen dat de Apache-server niet langer automatisch gestart wordt door hem uit de runlevelconfiguratie te verwijderen.
250
Linux 4
Apache 2 configureren voor gebruik van SSL op andere Linux-distributies Als je geen gebruikmaakt van SUSE, maar van een andere Linuxdistributie, volg je een werkwijze die in grote mate lijkt op de werkwijze die in de hiervoor genoemde procedure beschreven is. Toch zijn er enkele afwijkingen. De belangrijkste zit hem natuurlijk in de locatie en naam van de configuratiebestanden: op de meeste distributies zorg je ervoor dat de volgende directives opgenomen worden in het bestand /etc/httpd/httpd.conf: Listen 443 SSLEngine on SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL SSLCertificateFile /etc/apache2/server.crt SSLCertificateKeyFile /etc/apache2/server.key
Let op de eerste regel uit deze voorbeeldconfiguratie: hierin wordt aangegeven dat de Apache-webserver ook op poort 443 moet luisteren. Op SUSE Linux is het niet nodig deze regel op te nemen, hier wordt dit namelijk geregeld vanuit het Apache-configuratiebestand in de directory /etc/sysconfig. 6.7
Werken met Apache-modules
Na installatie van een Apache-webserver heb je aardig wat functionaliteit standaard al voorhanden. Heel veel mogelijkheden zijn echter ook niet standaard aanwezig. Denk bijvoorbeeld aan de mogelijkheid gebruik te maken van geavanceerde scripttalen als Perl en PHP. Daarnaast zijn er nog veel meer optionele zaken die voor de Apache-server geregeld kunnen worden. Al deze functionaliteit is niet standaard aanwezig in de Apache-webserver, maar wordt geregeld door bepaalde modules aan te zetten. Het spreekt voor zich dat hiervoor wel de juiste module geïnstalleerd moet zijn, maar dat gebeurt in veel gevallen automatisch. Als je bijvoorbeeld PHP installeert vanuit SUSE’s YaST, heb je daarbij gelegenheid om gelijk ook de bijbehorende Apache-module weg te schrijven. Als dit gebeurd is, moet je er vervolgens zelf nog voor zorgen dat de module in kwestie ook wordt aangeroepen vanuit de Apache-configuratiebestanden.
6 Apache
251
Figuur 6.4 Modules waarmee de functionaliteit van Apache uitgebreid kan worden, kunnen gewoon als RPM op de server geïnstalleerd worden
Wanneer je ervan verzekerd bent dat een module op het systeem geïnstalleerd is, kun je hem vanuit het Apache-configuratiebestand aanroepen. Maak hiervoor gebruik van het statement LoadModule. Gebruik bijvoorbeeld LoadModule php5 om tijdens het laden van de Apache-webserver de betreffende module ook te activeren. Je kunt ook testen of PHP-functionaliteit nu daadwerkelijk beschikbaar is. Voer hiervoor de volgende procedure uit: 1. Zorg ervoor dat zowel PHP5 als de apache-mod_php5 geïnstalleerd zijn op het systeem. 2. Gebruik de opdracht service apache2 restart (SUSE) of service httpd restart (Fedora) om de Apache-server opnieuw te starten. 3. Ga naar de documentroot van de webserver en maak hier een document met de naam php_info.php en de volgende inhoud:
4. Open nu een browser en activeer de pagina http://uwserver/php_ info.php. De PHP-informatiepagina wordt nu getoond. De Apacheserver kan van nu af aan ook PHP-code interpreteren.
252
Linux 4
Als voorbeeld heb je in het voorgaande gespeeld met de PHP-module. Er zijn echter nog veel meer modules waarmee je de werking van de Apache-server kunt uitbreiden. Je vindt een compleet overzicht van de meer dan 400 modules die beschikbaar zijn op http:// modules.apache.org. Hieronder vind je een korte lijst met namen van modules die naar onze mening in het bijzonder de moeite waard zijn. bw_mod
Gebruik deze module om het bandbreedtegebruik van de Apache-server in te stellen. Het is in het bijzonder erg nuttig dat je per virtuele server of directory kunt opgeven hoeveel bandbreedte gebruikt mag worden. mod_auth_mysql Met behulp van deze module handel je authenticatie af via een MySQL-database. mod_clamav Gebruik ClamAV als virusscanner op alle documenten voordat ze aan een eindgebruiker gegeven worden. mod_ftpd Zorgt ervoor dat Apache ook FTP-requests kan afhandelen. mod_mono Gebruik deze module om Mono in te zetten. Met behulp van Mono kan in een nietWindows-omgeving toch met ASP.NET-clienttoepassingen gewerkt worden. mod_rewrite Zorgt ervoor dat URL’s herschreven worden voordat ze aan de eindgebruiker worden aangeboden. 6.8
Samenvatting
In dit hoofdstuk heb je geleerd hoe je een Apache-webserver configureert. Er is aandacht besteed aan de wijze waarop een HTMLdocument wordt opgebouwd. Daarnaast heb je geleerd te werken met virtuele hosts, elementaire gebruikersbeveiliging en SSL-beveiligde sessies. Tot slot heb je in het laatste deel van dit hoofdstuk geleerd hoe je modules configureert om de Apache-server extra dingen te laten doen.
7
Linux als mailserver
7.1
Inleiding
Naast webservices kan ook e-mail met recht beschouwd worden als een van de fundamenten van moderne bedrijfsvoering. En je raadt het al, een behoorlijk aantal mailservers maakt gebruik van Linux. Twee Linux-pakketten voor afhandeling van mail zijn met name populair: Sendmail en Postfix. In dit hoofdstuk leer je hoe je een Postfix-mailserver inricht om berichten op het netwerk te verzenden en ontvangen. Voordat je begint met de configuratie en installatie van een Linux-mailserver, is inzicht in de werking van de verschillende componenten waaruit een mailserver bestaat onontbeerlijk. In dit hoofdstuk kun je lezen uit welke componenten elke mailoplossing bestaat, ongeacht of deze nu geïnstalleerd is op een Linux- of op een Windows-server. 7.2
Architectuur van een mailoplossing
Het eerste onderdeel dat nodig is in een mailserver, is het onderdeel dat ervoor zorgt dat de mailberichten verstuurd kunnen worden. Hiervoor wordt in de meeste gevallen gebruikgemaakt van het Simple Message Transfer Protocol (SMTP). Een SMTP-server is een server die het mailadres van de geadresseerde leest en op basis van dit mailadres het bericht bij de beoogde ontvanger aflevert. SMTP is echter niet de enige oplossing die ingezet kan worden om mailberichten te versturen. Daarom spreken we liever in meer algemene bewoordingen over een Message Transfer Agent (MTA).
254
Linux 4
Een voorbeeld van een andere MTA is uucp, een oud protocol dat ingezet werd om mailberichten tussen verschillende Linux-servers te kopiëren. Om ervoor te zorgen dat een mailbericht bij de ontvanger kan worden afgeleverd, moet de mailserver in staat zijn de naam van de mailserver van de geadresseerde te achterhalen. Als je bijvoorbeeld een bericht wilt versturen naar [email protected], moet de MTA weten waar hij dit bericht moet afleveren. Hierbij komt DNS om de hoek kijken. Om wat preciezer te zijn: in het geval dat een bericht verstuurd moet worden naar een gebruiker in het domein sandervanvugt.nl, moet het MX-record voor het betreffende domein achterhaald worden. Op basis van dit MX-record wordt bekend wat de verantwoordelijke mailserver van het domein in kwestie is en hierdoor kan het bericht worden afgeleverd bij die verantwoordelijke mailserver. Wanneer je een mailbericht stuurt naar een gebruiker in een bepaalde organisatie, wordt dit bericht ontvangen door de mailserver van die organisatie. Die kan er in principe twee dingen mee doen. Om te beginnen kan hij het direct doorsturen naar de computer waarop de eindgebruiker in kwestie op dat moment is aangemeld. Hiervoor moet echter wel aan een belangrijke voorwaarde worden voldaan: de gebruiker in kwestie moet op dat moment ook echt zijn aangemeld. Aangezien dit in veel gevallen niet zo zal zijn, is het fenomeen van de ontvangende mailserver verzonnen. Dit is een mailserver die alle berichten voor zijn gebruikers ontvangt en bewaart. In dit model is het niet de mailserver zelf die het initiatief neemt een bericht af te leveren, maar komt de gebruiker zelf langs om zijn mail op te halen. Dit laatste kan algemeen gesproken op twee manieren: door middel van het Post Office Protocol (POP) of door middel van IMAP. Het POP-protocol is ervoor ontworpen om mail te downloaden van een mailserver en vervolgens op de clientcomputer er iets mee te doen. Het IMAP-protocol daarentegen veronderstelt dat de gebruiker een blijvende verbinding heeft met de mailserver en online met zijn mail werkt. Omdat dat niet altijd handig is, voorzien sommige IMAP-mailservers in caching functionaliteit.
7 Linux als mailserver
7.3
255
De Linux-opdracht mail
Bij de configuratie van een mailserver is het erg handig als je ook kunt testen of de mailserver het naar behoren doet. Omdat je een server draait, heb je waarschijnlijk niet direct een grafische interface ter beschikking om een en ander uit te proberen. Dat hoeft ook helemaal niet, want op elke Linux-distributie kan de opdracht mail gebruikt worden om even een berichtje te versturen. Hoe het werk? Heel eenvoudig. In zijn meest eenvoudige vorm wordt de opdracht mail gevolgd door de naam van een gebruiker. Bijvoorbeeld mail linda. Vervolgens verschijnt een prompt waarin gevraagd wordt het onderwerp (subject) in te voeren. Als dat gebeurd is, kan het bericht zelf getypt worden. Klaar met typen van het bericht? Voer dan een punt in op een lege regel en druk op Enter. Het bericht wordt nu afgeleverd aan de geadresseerde. Als je alleen een gebruikersnaam – dus zonder domeinnaam – gegeven hebt, wordt deze lokaal op het systeem gezocht. Als de SMTPservice al actief is en de server met internet verbonden is, zal de gebruiker in het gespecificeerde domein gelokaliseerd worden. Mail vanuit scripts Leuk dat je vanaf de opdrachtregel een bericht kunt versturen, veel leuker is het om rechtstreeks vanuit een script mail te versturen. Zo verstuur je bijvoorbeeld een alert naar een gebruiker als zich een kritische situatie voordoet. Voor dergelijke berichten is een subject-regel vaak al genoeg. Om een dergelijk mailbericht te versturen gebruik je de volgende opdracht: mail -s “iets” root < .
Let even op de redirection van de punt aan het einde van de regel. Dit is nodig om aan de mail-opdracht te vertellen dat het eind van de opdracht bereikt is. Met de opdracht mail kun je ook kijken of er berichten zijn. Het resultaat van deze opdracht kan er als volgt uitzien:
256
Linux 4
BTN:~ # mail Heirloom mailx version 12.1 6/15/06.
Type ? for help.
“/var/spool/mail/root”: 8 messages 8 unread >U
1 [email protected] Thu Mar 29 16:09
19/634
CPU load is
19/649
CPU load of
19/649
CPU load of
19/649
CPU load of
19/649
CPU load of
high U
2 [email protected] Thu Mar 29 20:15
stres U
3 [email protected] Thu Mar 29 20:27
stres U
4 [email protected] Thu Mar 29 20:28
stres U
5 [email protected] Thu Mar 29 20:29
stres U
6 [email protected] Wed Apr 18 11:18
19/631
ca marche pas
U
7 [email protected] Wed Apr 18 11:18
19/631
ca marche pas
U
8 [email protected] Wed Apr 18 11:20
19/622
blah
?
Op basis van het nummer dat aan elk mailbericht is toegekend, kun je de inhoud van het bericht lezen. Hoe dat werkt? Eenvoudig, voer het nummer van het betreffende bericht in en je kunt het lezen. Klaar met lezen? Druk dan nu op q om het bericht te sluiten en indien gewenst het volgende bericht te lezen. 7.4
Postfix-componenten
Een Postfix-mailserver bestaat uit verschillende componenten. We beginnen met een kort overzicht hiervan: De mailserver zelf: eigenlijk is er onder Postfix geen sprake van dé mailserver. Postfix is namelijk niet één programmabestand, maar een complete verzameling van programmabestanden die met elkaar samenwerken. Deze programmabestanden worden doorgaans wel allemaal geactiveerd door één service die vanuit de runlevelscripts gestart wordt. We hebben het om die reden in dit hoofdstuk niet over de afzonderlijke onderdelen, maar over het geheel. De configuratiebestanden: Postfix kent twee belangrijke configuratiebestanden. In het configuratiebestand main.cf (doorgaans in /etc/postfix) wordt de werking van de mailserver gedefinieerd. Als beheerder heb je het meeste te maken met de instellingen in dit
7 Linux als mailserver
257
bestand. Het configuratiebestand master.cf bepaalt hoe de verschillende componenten van het Postfix-programma ingezet worden. Hier heb je als beheerder veel minder vaak mee te maken. De lookup tables: door middel van verschillende lookup tables kan de werking van de mailserver verder aangepast worden. De lookup tables hebben zonder uitzondering betrekking op de wijze waarop mailberichten afgehandeld worden. Een belangrijke taak die is weggelegd voor deze lookup tables, is bijvoorbeeld het opnieuw routeren van inkomende mailberichten naar een bepaalde gebruiker. Verderop in dit hoofdstuk zul je hier wat voorbeelden van zien. 7.4.1 Configuratie van master.cf Zoals gezegd, als beheerder heb je niet bijzonder vaak te maken met de instellingen in het bestand master.cf. Een uitzondering hierop is als je bijvoorbeeld de aflevering van lokale mail op de server wilt sturen. Standaard wordt lokale mail geplaatst in de mailbox van een gebruiker die deze dan met een POP-client leeg kan halen. Als alternatief kan deze lokale gebruiker overigens ook gebruikmaken van de lokale Linux-opdracht mail. Maar het kan ook anders. Wellicht wil je dat de mail eerst door het mailfilter procmail onder handen genomen wordt of dat de mailberichten naar de Cyrus IMAPd-server gaan. Dit zijn typische zaken die je regelt in master.cf. Hieronder zie je een overzicht van een deel van de instellingen in dit configuratiebestand. web:/etc/postfix # cat master.cf # # Postfix master process configuration file.
For details on the
format # of the file, see the Postfix master(5) manual page. # # ============================================================= ===== # service type
private unpriv
chroot
(yes)
(yes)
wakeup
maxproc command
+ args #
(yes)
(never) (100)
# ============================================================= ===== smtp
inet
n
#submission inet n
-
n
-
-
smtpd
-
n
-
-
smtpd
258
Linux 4
#
-o smtpd _ etrn _ restrictions=reject
#
-o smtpd _ client _ restrictions=permit _ sasl _
authenticated,reject #smtps
inet
n
-
n
-
-
smtpd -o
smtpd _ tls _ wrappermode=yes #
-o smtpd _ tls _ wrappermode=yes -o smtpd _ sasl _ auth _
enable=yes #submission
inet
n
-
n
-
-
smtpd #
-o smtpd _ etrn _ restrictions=reject
#
-o smtpd _ enforce _ tls=yes -o smtpd _ sasl _ auth _ enable=yes
#628
inet
pickup
fifo
cleanup
unix
n
-
n
n
-
-
n
n
-
60
-
n
qmqpd
1
pickup
-
0
cleanup
qmgr
fifo
n
-
n
300
1
qmgr
#qmgr
fifo
n
-
n
300
1
oqmgr
#tlsmgr
unix
rewrite
unix
-
-
n n
1000?
1
-
-
tlsmgr trivial-
rewrite bounce
unix
-
-
n
-
0
bounce
defer
unix
-
-
n
-
0
bounce
trace
unix
-
-
n
-
0
bounce
verify
unix
flush
unix
n
-
n n
1000?
1 0
verify flush
proxymap
unix
-
-
n
-
-
proxymap
smtp
unix
-
-
n
-
-
smtp
# When relaying mail as backup MX, disable fallback _ relay to avoid MX loops relay
unix
-
-
n
-
-
smtp
-o fallback _ relay= #
-o smtp _ helo _ timeout=5 -o smtp _ connect _ timeout=5
showq
unix
n
-
n
-
-
showq
error
unix
-
-
n
-
-
error
discard
unix
-
-
n
-
-
discard
local
unix
-
n
n
-
-
local
virtual
unix
-
n
n
-
-
virtual
lmtp
unix
-
-
n
-
-
lmtp
anvil
unix
-
-
n
-
1
anvil
#localhost:10025 inet
n
-
n
-
-
smtpd -o content _ filter= scache
unix
-
-
n
-
1
scache
7 Linux als mailserver
259
# # ============================================================= ==== # Interfaces to non-Postfix software. Be sure to examine the manual # pages of the non-Postfix software to find out what options it wants. # # Many of the following services use the Postfix pipe(8) delivery # agent.
See the pipe(8) man page for information about
${recipient} # and other message envelope options. # ============================================================= ===== # # maildrop. See the Postfix MAILDROP _ README file for details. # Also specify in main.cf: maildrop _ destination _ recipient _ limit=1 # maildrop
unix
-
n
n
-
-
pipe
flags=DRhu user=vmail argv=/usr/local/bin/maildrop -d ${recipient} cyrus
unix
-
n
n
-
-
pipe
user=cyrus argv=/usr/lib/cyrus/bin/deliver -e -r ${sender} -m ${extension} ${user} uucp
unix
-
n
n
-
-
pipe
flags=Fqhu user=uucp argv=uux -r -n -z -a$sender $nexthop!rmail ($recipient) ifmail
unix
-
n
n
-
-
pipe
flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient) bsmtp
unix
-
n
n
-
-
pipe
flags=Fq. user=foo argv=/usr/local/sbin/bsmtp -f $sender $nexthop $recipient procmail
unix
-
n
n
-
-
pipe
flags=R user=nobody argv=/usr/bin/procmail -t -m /etc/procmailrc ${sender} ${recipient}
In het voorgaande voorbeeldbestand zie je als eerste een specificatie van alle services die deel uitmaken van de Postfix-mailserver. Daarna wordt een aantal opties voor Postfix gedefinieerd. Elk van
260
Linux 4
deze regels is verdeeld in een aantal kolommen. De volgende kolommen zijn beschikbaar: Kolom
Betekenis
Service
Dit is de naam van de betreffende service. Doorgaans wordt hier verwezen naar Linux-programmabestanden die je ook ergens op
Type
schijf terug kunt vinden. Hiermee wordt aangegeven welk type service het betreft. Het type inet is een internet socket die dus via een poortnummer bereikbaar is om gegevens van internet te ontvangen. Het type unix is een lokale socket die gebruikt wordt voor communicatie binnen het mailsysteem. Het type fifo tot slot is een zogenoemde named pipe. Dit is een datastroom die voortdurend open staat. Het voordeel hiervan is dat het een zeer snelle werking garandeert, maar als nadeel brengen named pipes ook een behoorlijke werkbelasting
Kolom
met zich mee. Betekenis
Unpriv
Standaard worden alle onderdelen van Postfix gestart met de permissies van de gebruiker Postfix. Als dit voor een bepaald onderdeel onvoldoende is, plaats je hier een n om aan te geven dat
Chroot
de betreffende service als root gestart moet worden. Het standaardgedrag van de Postfix-mailserver is om in een chroot-omgeving te draaien. SUSE gebruikt bijvoorbeeld de directory /var/spool/postfix voor dit doel. Als je Postfix niet in een
Wakeup
chroot-omgeving wilt gebruiken, zet je hier een n neer. Sommige services moeten automatisch periodiek gestart worden. Als dit voor een service het geval is, specificeert je hier het aantal seconden dat als interval gebruikt moet worden om de betreffende
Maxproc
service te starten. Standaard kan elke service 100 keer gelijktijdig gestart zijn. Als dit voor een bepaalde service niet het geval is, geef je hier aan wat dan wel het maximum is. Specificeer 0 als je geen begrenzing in wilt stellen voor het maximumaantal gelijktijdig te starten
command +
processen. Hier geef je aan welk programmabestand gestart moet worden om
args
de betreffende service te starten.
Zoals aangegeven is er in de meeste gevallen geen reden om de instellingen in master.cf aan te passen. Als je echter als gevorderd gebruiker de Postfix-mailserver wilt tunen, doe je dat hier. Vergeet niet na de aanpassingen de opdracht service postfix restart te
7 Linux als mailserver
261
gebruiken om de Postfix-mailserver met de nieuwe instellingen te laten werken. 7.4.2 Configuratie van main.cf Het belangrijkste configuratiebestand voor de Postfix-mailserver is main.cf. Om duidelijk te maken wat belangrijk is en wat minder belangrijk is, bespreken we een werkend voorbeeld van dit configuratiebestand. Dit voorbeeld is in gebruik op de server van de auteur van dit boek en zorgt ervoor dat mail voor verschillende maildomeinen op een veilige wijze ontvangen en verzonden kan worden. Hieronder zie je hoe de main.cf er op deze mailserver uitziet. DNS
Een MTA kan alleen werken als de DNS-configuratie in orde is. Verzeker je ervan dat de mailserver als mailserver voor de betreffende DNS-domeinen is aangewezen door een MX-resource record in de DNS-database.
########################### # Config starts here ###### ########################### mynetworks = 127.0.0.0/8 readme _ directory = /usr/share/doc/packages/postfix/README _ FILES inet _ protocols = all biff = no mail _ spool _ directory = /var/mail canonical _ maps = hash:/etc/postfix/canonical virtual _ alias _ maps = hash:/etc/postfix/virtual virtual _ alias _ domains = hash:/etc/postfix/virtual relocated _ maps = hash:/etc/postfix/relocated transport _ maps = hash:/etc/postfix/transport sender _ canonical _ maps = hash:/etc/postfix/sender _ canonical masquerade _ exceptions = root masquerade _ classes = envelope _ sender, header _ sender, header _ recipient myhostname = web.sandervanvugt.nl mydomain = sandervanvugt.nl program _ directory = /usr/lib/postfix inet _ interfaces = 127.0.0.1 ::1 80.69.93.216 masquerade _ domains = sandervanvugt.nl
262
Linux 4
mydestination = $myhostname, localhost.$mydomain, $mydomain, clptrainer.com, cletrainer.com, fransvoorkids.nl, sandervanvugt. nl, sandervanvugt.com, novellcourses.com, creaflo.nl, sandervanvugt.org defer _ transports = mynetworks _ style = subnet disable _ dns _ lookups = no relayhost = mailbox _ command = /usr/bin/procmail mailbox _ transport = strict _ 8bitmime = no disable _ mime _ output _ conversion = no smtpd _ sender _ restrictions = hash:/etc/postfix/access smtpd _ client _ restrictions = smtpd _ helo _ required = no smtpd _ helo _ restrictions = strict _ rfc821 _ envelopes = no smtpd _ recipient _ restrictions = permit _ sasl _ authenticated, reject _ unauth _ destination smtpd _ use _ tls = no smtp _ use _ tls = no alias _ maps = hash:/etc/aliases mailbox _ size _ limit = 0 message _ size _ limit = 102400000 smtpd _ recipient _ limit = 50 # SASL SUPPORT FOR CLIENTS # # Added by Sander to support SMTP user authentication smtpd _ sasl _ auth _ enable = yes smtpd _ sasl _ security _ options = noanonymous broken _ sasl _ auth _ clients = yes
Dit voorbeeld bevat alle parameters die nodig zijn om een werkende mailserver te configureren. Er zijn uiteraard ook nog andere parameters, deze zijn echter optioneel en daarom in dit voorbeeldbestand niet opgenomen. Hieronder vind je een overzicht van gebruikte parameters: Dit is een lijst van netwerkadressen die de mailserver als relay-host mogen gebruiken. Zoals je ziet, kan deze mynetworks
7 Linux als mailserver
263
mailserver niet voor dit doel misbruikt worden; alleen het lokale netwerk is toegestaan. readme _ directory Dit is een specificatie van de directory waarin de documentatie van de Postfix-mailserver voorkomt. inet _ protocols Geeft aan welke IP-versies gebruikt mogen worden. In de meeste gevallen kan het geen kwaad hier de optie all te gebruiken al is strikt genomen IPv4 natuurlijk voldoende. biff biff is een systeem waarmee een gebruiker een melding kan krijgen op het moment dat er een nieuw mailbericht binnenkomt. Op een lokale werkplek waar Postfix rechtstreeks van internet andere berichten ontvangt, heeft het zin deze optie aan te zetten. Op een mailserver waar berichten alleen maar via POP opgehaald worden, heeft dit totaal geen zin. De mailserver is dan namelijk niet in staat de opdracht biff op de computer van de gebruiker uit te voeren. mail _ spool _ directory Dit is de naam van de standaarddirectory waar de Postfix-mailserver binnenkomende berichten neerzet. Zorg er op een drukke mailserver voor dat je ruim voldoende ruimte in deze directory hebt, deze kan namelijk snel vollopen! masquerade _ exceptions Door middel van masquerading zorg je ervoor dat de namen van afzenders van mailberichten herschreven kunnen worden. Masquerading wordt bijvoorbeeld gebruikt om de naam van een host uit een mailadres weg te laten. In de meeste gevallen is het zinnig om een uitzondering te definiëren voor de gebruiker root. Op het moment namelijk dat root mailberichten gaat versturen, is het juist wel zinnig om te zien waar het bericht precies vandaan komt. masquerade _ classes Er zijn verschillende elementen waarom masquerading plaats kan vinden. De standaardopties zorgen ervoor dat de masquerading zowel op het mailadres van de afzender (sender) als het mailadres van de ontvanger (recipient) toegepast kan worden. myhostname De naam van de computer waarop de Postfix-mailserver draait. Zorg ervoor dat hier de volledige naam van de computer komt te staan, inclusief het DNS-domein waarin de computer gebruikt wordt. mydomain Het standaarddomein van de mailserver. Zorg ervoor dat deze parameter altijd een waarde heeft, anders weet de mailserver namelijk niet voor welk domein hij verantwoordelijk is en zal hij niet in staat zijn mailberichten te ontvangen. program _ directory De naam van de directory waarin de Postfix-programmabestanden staan.
264
Linux 4
Dit is een lijst met IP-adressen waarop de mailserver moet werken. Let erop dat hier in veel gevallen alleen het loopback-adres staat. Zet hier dus ook het adres neer waarop de server contact heeft met de buitenwereld. masquerade _ domains Als je wilt dat namen van afzenders en geadresseerden van mailberichten automatisch herschreven kunnen worden door middel van Masquerading, zorg je er hier voor dat een lijst gegeven wordt van alle domeinen waarvoor dat het geval is. mydestination Dit is een zeer belangrijke parameter. Hier geef je namelijk aan voor welke domeinen de mailserver berichten wil ontvangen. Als je maar één domein gebruikt, wordt het ontvangen van mail automatisch geregeld door middel van de parameters $myhostname, localhost.$mydomain en $mydomain. defer _ transports Hiermee geef je aan dat bepaalde services niet gebruikt mogen worden voor het afleveren van mailberichten. In de meeste gevallen heeft deze optie geen waarde, hetgeen prima in orde is. mynetworks _ style Door middel van de parameter mynetworks wordt aangegeven welke computers Postfix moet vertrouwen. Er zijn echter verschillende manieren waarop een netwerk geïnterpreteerd kan worden. Door middel van deze optie geef je aan wat Postfix precies moet verstaan onder ‘mynetwork’. Als je de optie host gebruikt, zal Postfix alleen de lokale computer vertrouwen. Bij gebruik van de optie subnet zal Postfix alle computers vertrouwen die voorkomen in het zelfde lokale netwerk. Als de optie class gebruikt wordt, vertrouwt Postfix alle computers in hetzelfde netwerk. Met de laatste optie kun je er onbedoeld voor zorgen dat veel te veel computers vertrouwd worden! disable _ dns _ lookups Met deze parameter geef je aan of wel of niet de bijbehorende DNS-naam voor inkomende berichten opgezocht moet worden. Als je deze optie op no hebt staan, zorgt dat voor duidelijk leesbare logbestanden, maar het maakt de mailserver wel wat langzamer. Als performance een issue is, geef deze optie dan de waarde yes. relayhost Gebruik deze optie om de naam van de mailserver van de provider op te geven als je niet rechtstreeks berichten af wilt leveren op internet. mailbox _ command Als een opdracht gebruikt moet worden om mail af te leveren in de mailbox van gebruikers, specificeer je deze opdracht hier. Het is bijvoorbeeld redelijk gebruikelijk hier te inet _ interfaces
7 Linux als mailserver
265
verwijzen naar de opdracht procmail die ingezet kan worden als mailfilter. mailbox _ transport Met deze optie kan een parameter opgenomen worden om te verwijzen naar een opdracht die ingezet moet worden om mailberichten af te leveren bij een gebruiker. In de meeste gevallen heeft deze optie geen waarde. strict _ 8bitmime Deze optie heeft alleen in uitzonderlijke gevallen de waarde yes. Als je in staat wilt zijn mailberichten te ontvangen van internetmailservers, moet deze optie altijd de waarde no hebben. smtpd _ sender _ restrictions Met behulp van deze optie kan verwezen worden naar een lijst van legitieme afzenders. Deze afzenders worden doorgaans opgenomen in de table /etc/postfix/access waarover je later in dit hoofdstuk meer leest. smtpd _ client _ restrictions Deze optie kan ingezet worden om te bepalen wie er mailberichten mogen versturen. Standaard heeft deze optie geen waarde, wat betekent dat iedereen toestemming heeft mailberichten via deze server te verzenden. Als dat niet gewenst is, kunnen restricties opgenomen worden als sasl_authenticated om aan te geven dat alleen gebruikers toegang krijgen die eerst door middel van SASL zijn aangemeld (zie verderop in deze paragraaf voor meer informatie). smtpd _ helo _ required Bij het initialiseren van een mailsessie hoort een client zichzelf bekend te maken door middel van een zogenoemde HELO or EHLO. Met deze optie geef je aan of dit een vereiste is of dat je het ook accepteert als een client de helo achterwege laat. Standaard is het niet nodig dat een client zich op deze wijze bekendmaakt. smtpd _ helo _ restrictions Als een eindgebruiker zich dan zelf bekend moet maken door middel van een HELO, kan hier aangegeven worden welke eisen daaraan gesteld moeten worden. Zo kan bijvoorbeeld opgegeven worden dat de connectie geweigerd moet worden als de HELO niet aan de syntaxiseisen voldoet, bijvoorbeeld omdat een ongeldige hostnaam gebruikt is. strict _ rfc821 _ envelopes Als je geen mail meer wilt ontvangen van Windows-gebruikers, zet je deze optie aan. Dit betekent dat alleen mailclients die zich strikt houden aan de specificaties in RFC821 berichten mogen versturen. smtpd _ recipient _ restrictions Gebruik deze optie om aan te geven wie via de mailserver berichten mogen versturen. In het hiervoor genoemde voorbeeld is het niet iedereen toegestaan
266
Linux 4
om deze mailserver te misbruiken. Door middel van de parameter permit _ sasl _ authenticated, reject _ unauth _ destination is ervoor gezorgd dat alleen gebruikers die aangemeld zijn
via het SASL-mechanisme mailberichten mogen versturen. smtpd _ use _ tls Geeft aan of TLS-encryptie gebruikt moet worden voor gebruikers die de SMTP-service willen gebruiken. smtp _ use _ tls Zie bovenstaande. alias _ maps Verwijst naar het bestand waarin aliases bijgehouden moeten worden. Zie de paragraaf Aanpassen van de Postfixlookup tables verderop in dit hoofdstuk voor meer informatie. mailbox _ size _ limit Geeft een maximale grootte in bytes aan mailboxen. In het voorbeeldbestand is geen maximale grootte ingesteld. Het is niet aan te raden dit ook te doen voor mailservers waarop veel gebruikers actief zijn. message _ size _ limit Bepaalt de maximale grootte in bytes voor een mailbericht. smtpd _ recipient _ limit Dit is een basale instelling om ervoor te zorgen dat de mailserver niet door spammers misbruikt kan worden. Met deze instelling zorg je er namelijk voor dat nooit meer dan vijftig geadresseerden gelijktijdig in één bericht gebruikt worden. 7.4.3 Beveiliging door middel van SASL Standaard kan een mailserver door iedereen gebruikt worden om mailberichten te versturen. Dit is echter niet wenselijk. Een mailserver zou gebruikt moeten kunnen worden door gebruikers die een bericht hebben voor een gebruiker in een van de domeinen die door de mailserver beheerd worden. Dit wordt door Postfix afgehandeld met de parameter mydestination. Daarnaast mogen alleen legitieme gebruikers de mailserver gebruiken om berichten naar anderen te sturen. Standaard is voor dit laatste geen voorziening getroffen. Wij raden je aan dit wel te doen, anders loop je het risico dat de server misbruikt wordt door spammers. In de main.cf van Postfix zorgen de volgende regels ervoor dat alleen geauthenticeerde gebruikers toegestaan zijn: smtpd _ recipient _ restrictions = permit _ sasl _ authenticated, reject _ unauth _ destination smtpd _ sasl _ auth _ enable = yes smtpd _ sasl _ security _ options = noanonymous broken _ sasl _ auth _ clients = yes
7 Linux als mailserver
267
Om de authenticatie af te handelen wordt gebruikgemaakt van een additioneel proces, de Secure Authentication Sockets Layer (SASL). Om SMTP-authenticatie af te handelen maakt SASL gebruik van twee componenten: Het configuratiebestand /usr/lib/sasl2/smtpd.conf. Dit bestand heeft een vrij eenvoudige inhoud waarmee gespecificeerd wordt dat SMTP-authenticatie over SASL plaats moet vinden. Om in te loggen op basis van de gegevens in het passwd-bestand moet dit bestand de volgende inhoud hebben: pwcheck _ method: saslauthd mech _ list: plain login
Het servicescript salsauthd. Deze service moet gestart zijn om ervoor te zorgen dat SMTP-authenticatie over SASL mogelijk is. 7.4.4 Aanpassen van de Postfix-lookup tables Op basis van de voorgaande informatie heb je een Postfix-mailserver kunnen configureren. We hebben echter nog niet alle opties besproken. Een aantal opties wordt toegepast door gebruik te maken van de zogenoemde lookup tables. In deze tables neem je regels op die bepalen hoe mailberichten verwerkt worden. De lookup tables zelf zijn tekstbestanden. Nadat je deze tekstbestanden op de gewenste wijze gemaakt hebt, moeten ze omgezet worden naar binaire bestanden die door de Postfix-mailserver verwerkt kunnen worden. Hiervoor wordt gebruikgemaakt van de opdracht postmap. Dit betekent bijvoorbeeld dat nadat je wijzigingen aangebracht hebt in het bestand /etc/postfix/canonical, je deze wijzigingen moet compileren. Dit doe je met de volgende opdracht: postmap hash:/etc/postfix/canonical
Vergeet niet dat je dit elke keer moet doen nadat wijzigingen zijn aangebracht in de Postfix-lookup tables! Uiteraard moet je de precieze opdracht wel zo aanpassen dat er naar de juiste table verwezen wordt. We bespreken nu de meest belangrijke tables.
268
Linux 4
De access lookup table Met behulp van deze lookup table regel je dat berichten van bepaalde afzenders en geadresseerden wel of niet geaccepteerd worden. In /etc/postfix/main.cf staat de volgende regel die ervoor zorgt dat deze table ook gebruikt wordt: smtpd _ sender _ restrictions = hash:/etc/postfix/access
In de access lookup table vind je regels die uit twee kolommen bestaan. In de eerste kolom vind je een verwijzing naar de geadresseerde, in de tweede kolom een aanduiding van wat er moet gebeuren als een match optreedt voor een van deze geadresseerden. Hieronder zie je een voorbeeld hoe deze lookup table eruit kan zien: [email protected]
OK
193.173.100.0
REJECT
De canonical lookup table De canonical lookup table heeft betrekking op zowel de mailadressen van afzenders van mailberichten als op de mailadressen van ontvangers van berichten. Als je regels wilt schrijven die alleen betrekking hebben op afzenders, gebruik je de sender_canonical table en als je regels wilt schrijven die alleen betrekking hebben op ontvangers, gebruik je de recipient_canonical table. In de canonical lookup tables kun je ervoor zorgen dat berichten die gericht zijn aan een bepaald adres, automatisch doorgestuurd worden naar een bepaalde gebruiker. In het voorbeeld zie je de canonical lookup table die gebruikt wordt op de mailserver van de auteur van dit boek. Zoals je ziet, is dit een server die verschillende domeinen host. Er zijn echter maar twee gebruikers die aan deze domeinen verbonden zijn en door het opnemen van deze regels, worden berichten die naar de betreffende domeinen verstuurd worden evenredig verdeeld tussen deze twee gebruikers. @clptrainer.com
sander
@cletrainer.com
sander
@sandervanvugt.com
[email protected]
@fransvoorkids.nl @creaflo.nl
florence florence
7 Linux als mailserver
269
De relocated lookup table De relocated lookup table kan ingezet worden om informatie te geven over gebruikers waarvan het mailadres veranderd is. Je kunt bijvoorbeeld een mailbericht terug laten sturen naar de afzender van mail aan deze gebruikers, maar ook is het mogelijk mail automatisch door te sturen. In het volgende voorbeeld zie je hoe het werkt: [email protected]
[email protected]
[email protected]
Dit adres bestaat niet
Wij raden je aan voorzichtig te zijn met de relocated lookup table. Te vaak blijkt namelijk dat je met het gebruik van deze lookup table spammers juist van dienst bent. Door middel van deze table wordt immers nauwkeurige informatie verschaft die spammers van dienst kan zijn. De transport lookup table De transport lookup table is wel heel belangrijk. Hiermee specificeer je namelijk door welk mechanisme berichten uit een bepaalde reeks afgehandeld moeten worden. Niet alleen kun je een bepaald mechanisme specificeren, bijvoorbeeld om ervoor te zorgen dat de mailberichten door het Cyrus IMAPd-proces afgehandeld worden, maar ook is het mogelijk om mailberichten door te sturen naar een andere server die voor verdere afhandeling zorgt. Dit laatste staat bekend als de Nexthop-specificatie. Hier zie je hoe deze table gebruikt kan worden. root@
local:
novellcourses.com smtp:mail.novellcourses.com sandervanvugt.com cyrus:
In dit voorbeeld wordt ervoor gezorgd dat alle mailberichten aan de gebruiker root lokaal afgeleverd worden. Door een @ achter de naam van de gebruiker root te zetten, zorg je er overigens voor dat het niet uitmaakt aan welk domein het bericht gericht is; root is root en daarmee uit. Vervolgens wordt alles dat bestemd is voor het domein novellcourses.com doorgestuurd over SMTP naar de mailserver van het betreffende domein. Tot slot wordt mail die binnenkomt voor sandervanvugt.com opgevangen door de Cyrus-server waarover je later in dit hoofdstuk meer leest.
270
Linux 4
De virtual lookup table Er bestaat enige overlapping tussen de canonical lookup table en de virtual lookup table. Beide zorgen er namelijk voor dat mail die binnenkomt voor een bepaald domein doorgestuurd wordt. In het voorbeeld zie je hoe deze table gebruikt kan worden: lpitrainer.com
sander,alex
[email protected] root [email protected]
sanne
[email protected]
linda
De alias lookup table Eigenlijk is het geen echte lookup table zoals je ze gewend bent in een Postfix-omgeving, maar het kan toch wel gebruikt worden: het bestand /etc/aliases. We hebben het hier over exact hetzelfde bestand als dat gebruikt wordt in een Sendmail-omgeving om aliasen te definiëren. Om wijzigingen in dit bestand ook daadwerkelijk door te voeren, gebruik je de opdracht newaliases. 7.5
Configuratie van inkomende mail met procmail
Wanneer je intensief gebruikmaakt van een of ander mailsysteem, kan het de moeite waard zijn de binnenkomende mailberichten automatisch te sorteren. Zo zorg je er bijvoorbeeld voor dat berichten van een bepaalde afzender automatisch in een speciaal voor deze afzender gemaakt mapje geplaatst worden. Ook kun je ervoor zorgen dat spamberichten linea recta doorgestuurd worden naar /dev/ null, zodat je ze in de inbox nooit zult aantreffen. Het antwoord op deze vragen is procmail. Procmail is een aparte service die geen deel uitmaakt van de Postfix-mailserver. Met behulp van procmail kun je zonder al te veel problemen een eenvoudig mailfilter definiëren. De werking van procmail is eenvoudig: het programma kijkt of er een bestand met de naam .procmailrc bestaat in de homedirectory van de betreffende gebruiker. In dit bestand kunnen namelijk regels gedefinieerd worden op basis waarvan inkomende mail verwerkt wordt. Aan de hand van het volgende voorbeeld kun je kennismaken met de werking van procmail-filters:
7 Linux als mailserver
271
:0 * ^TO news@sandervanvugt\.nl InteressanteBerichten :0 * ^From:.*@bloodynerds\.nl /dev/null
In dit voorbeeld worden twee regels gedefinieerd voor binnenkomende mail. Elk van deze regels begint met de constructie :0; hieraan kan het procmail-proces herkennen dat er een nieuwe definitie begint. In de eerste regel wordt gekeken naar berichten die verzonden zijn aan het mailadres [email protected]. Let overigens op de manier waarop de punt in de DNS-naam voorafgegaan wordt door een Escape-teken, ook dat is een kwestie van syntaxis. Deze eerste regel is typisch voor lidmaatschap van een mailinglist. Hierbij worden berichten verstuurd naar het adres van de mailinglist. Wanneer je een van deze berichten binnenkrijgt, wordt het automatisch doorgestuurd naar de mail ‘InteressanteBerichten’ in de mailbox. De tweede regel in ons voorbeeld .procmailrc vervolgens is typisch voor de afhandeling van ongewenste mailberichten. Deze regel gaat ervan uit dat alle ongewenste berichten altijd afkomstig zijn vanuit het DNS-domein bloodynerds.nl. De oplossing is erg resoluut: al deze berichten worden regelrecht doorgestuurd naar de NULL-device. Dit zorgt ervoor dat de eindgebruiker er nooit meer iets van te zien krijgt. Uiteraard is een dergelijke configuratie alleen zinnig wanneer je echt zeker weet dat uit dit domein alleen maar ongewenste berichten komen, je ziet er namelijk nooit meer iets van terug. 7.6
Herdistributie van mail met qpopper
De POP-daemon qpopper wordt op de meeste Linux-distributies standaard beschikbaar gesteld. Daar is dan ook een goede reden voor, het is namelijk de meest gebruikte Linux POP-server. Ook de werking van een POP-server is relatief eenvoudig. Om gebruik te kunnen maken van een POP-server op het systeem heb je om te beginnen voor elke POP-gebruiker een valide gebruikersaccount
272
Linux 4
nodig. In principe is dat een Shell-account die ook door gebruikers gebruikt kan worden om in te loggen op de mailserver. Als je dit een onprettig idee vindt, kun je in /etc/passwd de standaard-shell /bin/bash vervangen door bijvoorbeeld de opdracht /bin/passwd. Gebruikers kunnen dan niet langer inloggen, maar zijn wel in staat hun wachtwoord te wijzigen. Wanneer je ervoor gezorgd hebt dat de gebruikersconfiguratie op de juiste wijze geregeld is, moet je regelen dat de POP-server automatisch gestart wordt. Dit kan door de server als daemon te starten met de opdracht /usr/sbin/popper. Het is echter aan te raden in plaats daarvan gebruik te maken van het xinetd-mechanisme. In de meeste gevallen vind je hier een kant-en-klaar qpopper-configuratiebestand waarin je alleen nog maar hoeft aan te geven dat de server qpopper gestart moet worden. Doe dit door het bestand als in het volgende voorbeeld te wijzigen: # # qpopper – pop3 mail daemon # service pop3 { disable
= no
socket _ type
= stream
protocol
= tcp
wait
= no
user
= root
server
= /usr/sbin/popper
server _ args
= -s
flags
= IPv4
}
Het laatste onderdeel van de qpopper-configuratie bestaat er tot slot uit ervoor te zorgen dat xinetd actief is. Controleer dit met de opdracht ps aux | grep xinetd. Als het niet actief is, kun je het starten vanuit het System-V-opstartmechanisme van de server. Op SUSE Linux kun je er bijvoorbeeld met de opdracht chkconfig xinetd 2345 voor zorgen dat xinetd voortaan automatisch gestart wordt. Wanneer dit geregeld is, luistert qpopper voortaan naar binnenkomende connecties op de standaard-POP3-poort 110. Je kunt nu vanaf elke computer die verbinding kan maken met de mailserver de berichten binnenhalen.
7 Linux als mailserver
7.7
273
Cyrus IMAPd
Er zijn twee manieren om mail te ontvangen: offline en online. In het eerste geval is het typisch gebruik te maken van een POP-mailserver, in het tweede geval is IMAP het voor de hand liggende protocol. In de voorgaande paragraaf heb je geleerd hoe je een POPserver inricht. We besteden nu aandacht aan de Cyrus IMAPdmailserver, de meest gebruikte IMAP-server voor Linux. Het werken met een IMAP-service biedt een aantal belangrijke voordelen. Het grootste voordeel is dat de mail op de server bewaard blijft. Je kunt dus altijd bij het mailarchief komen en als er eens iets gebeurt met je eigen computer, ben je daarmee niet gelijk ook al je mail kwijt. Het nadeel –voor zover dat een nadeel mag heten – is dat je de server er wel op in moet richten. Dit betekent vooral dat de server flink wat extra ruimte nodig heeft; zeker omdat een IMAP-gebruiker geneigd is om alles te bewaren wat ook maar enigszins relevant is. 7.7.1 De mailserver configureren voor IMAP Cyrus IMAPd biedt de mogelijkheid mail zowel via IMAP als POP3 te benaderen. Om dit zo efficiënt mogelijk te laten gebeuren maakt Cyrus IMAPd gebruik van mailboxen die opgeslagen worden in een speciaal formaat. Dit speciale formaat maakt het proces waarmee mail afgehandeld wordt zo snel mogelijk. Om berichten uit deze database op te kunnen halen heeft elke gebruiker een mailaccount nodig op de IMAP-server. Dit betekent niet dat het nodig is dat de gebruiker ook op de server in kan loggen, integendeel – die optie kun je beter uit laten staan. Het betekent echter wel dat de betreffende gebruikersnaam moet bestaan. Verderop lees je hoe je dit bewerkstelligt. Om te beginnen verzeker je je ervan dat de Cyrus IMAPd-software geïnstalleerd is. Als je gebruikmaakt van RPM, heb je daarvoor de package cyrus-imapd nodig. Als deze software geïnstalleerd is, moet je als eerste aan de Postfix-mailserver vertellen dat hij gebruik moet maken van Cyrus IMAPd. Om te beginnen moet er in de /etc/postfix/master.cf een regel staan die ervoor zorgt dat Cyrus IMAPd gebruikt wordt. Deze regel staat er vaak standaard al en ziet er als volgt uit:
274
Linux 4
cyrus
unix
-
n
n
-
-
pipe
user=cyrus argv=/usr/lib/cyrus/bin/deliver -e -r ${sender} -m ${extension} ${user}
Verander deze regel niet, het is namelijk de regel die ervoor zorgt dat het programma local, dat deel uitmaakt van de Cyrus-server, niet langer gebruikt wordt, maar in plaats daarvan het programma deliver wordt aangeroepen. Vervolgens moet je de transport lookup table van Postfix aanpassen. In dit bestand geef je immers aan welke type mail door welke mailhandler afgehandeld moet worden. Je regelt dit per domein. Als je dus twee domeinen hebt met de namen mijndomein.nl en mydomain.com en je wilt beide via Cyrus IMAPd laten afhandelen, plaats je in /etc/postfix/transport de volgende twee regels: mijndomein.nl
cyrus:
mydomain.com
cyrus:
Daarbij is het handig ervoor te zorgen dat een lokale gebruiker als root uitgesloten wordt van dit mechanisme. Dit regel je door een uitzonderingsregel te definiëren en die in het begin van de transport table neer te zetten. Deze regel komt er dan als volgt uit te zien: root@
local:
Vergeet niet dat alle lookup tables in /etc/postfix nog apart gegenereerd moeten worden. Dit regel je met de volgende opdracht: postmap hash:/etc/postfix/transport
Het resultaat is dat Postfix vanaf dat moment alle mail door zal sturen naar het deliver-programma dat deel uitmaakt van Cyrus IMAPd. Migratie Als je een POP3-server migreert naar een IMAP-server, wil je waarschijnlijk dat de downtijd zo klein mogelijk is. Dit regel je door eerst de volledige configuratie van Cyrus IMAPd in orde te maken, zoals beschreven wordt in de rest van deze paragraaf. Pas als alles naar behoren geconfigureerd is, voer je de opdracht postmap uit om Postfix van de wijzigingen op de hoogte te stellen.
7 Linux als mailserver
275
7.7.2 De Cyrus-server configureren Het belangrijkste deel van de configuratie van de Cyrus IMAPdserver regel je in het configuratiebestand /etc/imapd.conf. In dit bestand vind je per regel een optie. Achter de naam van de optie staat een dubbelepunt en daarachter staat de waarde die aan de optie is toegekend. Het betreffende configuratiebestand is niet bijzonder omvangrijk. Hieronder vind je de inhoud zoals deze standaard voorkomt op een SUSE Linux 10-server: web:/etc/postfix # cat /etc/imapd.conf configdirectory: /var/lib/imap partition-default: /var/spool/imap sievedir: /var/lib/sieve admins: cyrus allowanonymouslogin: no autocreatequota: 10000 reject8bit: no quotawarn: 90 timeout: 30 poptimeout: 10 dracinterval: 0 drachost: localhost sasl _ pwcheck _ method: saslauthd lmtp _ overquota _ perm _ failure: no lmtp _ downcase _ rcpt: yes # # if you want TLS, you have to generate certificates and keys # #tls _ cert _ file: /usr/ssl/certs/cert.pem #tls _ key _ file: /usr/ssl/certs/skey.pem #tls _ ca _ file: /usr/ssl/CA/CAcert.pem #tls _ ca _ path: /usr/ssl/CA
De belangrijkste opties die je in het configuratiebestand vindt, zijn de volgende: Hiermee wordt verwezen naar de standaarddirectory waarin de accountconfiguraties voorkomen. Gewoonlijk is dit de directory /var/lib/imap. Er is weinig reden deze optie aan te passen. partition-default Dit is de naam van de directory waarin de configdirectory
276
Linux 4
mailboxen opgeslagen worden. Zorg ervoor dat je hier meer dan voldoende ruimte in beschikbaar hebt! admins Dit is een lijst van de gebruikers die beheerderspermissies hebben op de Cyrus-server. Standaard heeft alleen de gebruiker cyrus beheerpermissies, je kunt deze lijst uitbreiden met andere gebruikers als dat nodig is. allowanonymouslogin Deze optie moet altijd de waarde no hebben. De optie bewerkstelligt namelijk dat inloggen zonder gebruikersnaam en wachtwoord mogelijk is; iets wat altijd voorkomen moet worden! autocreatequota Met deze optie stel je in hoe groot een mailbox maximaal mag worden. De grootte is in kilobyte, dus de standaardwaarde zorgt ervoor dat gebruikers maximaal 10 MB in hun mailbox mogen opslaan. Als je geen gebruik wilt maken van quota, geef deze parameter dan de waarde -1. quotawarn Met deze parameter geef je het percentage aan waarbij de gebruiker een waarschuwing moet krijgen dat zijn quota bijna bereikt zijn. Standaard staat deze parameter ingesteld op 90%. timeout Gewoonlijk houdt de client verbinding met de Cyrusmailserver. Als de verbinding echter gedurende langere tijd niet actief is, bepaal je met deze parameter dat de verbinding automatisch verbroken moet worden. Volgens de standaardinstelling gebeurt dit na 30 minuten. sasl _ pwcheck _ method Er zijn verschillende manieren om wachtwoorden te controleren. Simple Authentication and Security (SASL) is de standaardmethode, omdat deze methode een stuk veiliger is dan normale Linux-wachtwoorden. 7.7.3 De server starten Nadat je in /etc/imapd.conf de basisparameters opgegeven hebt, wordt het tijd de Cyrus-server te starten. Om dit te doen start je eerst de SASL-server (als deze nog niet gestart is) en dan pas de Cyrus-server zelf. Voer hiervoor de volgende opdrachten uit: rcsaslauthd start rccyrus start
Om ervoor te zorgen dat beide services in het vervolg automatisch gestart worden, kun je de volgende twee opdrachten gebruiken: insserv saslauthd insserv cyrus
7 Linux als mailserver
277
Vervolgens is het handig om met telnet op poort 143 te kijken of de service inderdaad aanwezig is. Zie je de banner van de IMAP-server? Geef dan in telnet de opdracht . logout om de verbinding te verbreken. Je bent nu klaar voor de volgende fase. 7.7.4 Gebruikersbeheer Als de Cyrus-server eenmaal actief is, kun je overgaan tot de volgende fase: het toevoegen van gebruikers. Dit doe je door gewone UNIX-gebruikersaccounts aan te maken. Om ervoor te zorgen dat deze gebruikers geen lokale toegang krijgen, maar alleen maar hun wachtwoord mogen wijzigen, gebruik je de volgende twee opdrachten: useradd -s /usr/bin/passwd gebruiker passwd gebruiker
De volgende fase in het beheer van gebruikers is dat de administratieve gebruiker een wachtwoord moet krijgen. Als je dit vergeet, kan de gebruiker cyrus namelijk helemaal niets op de server. Gebruik daarom de opdracht passwd cyrus en voer een wachtwoord in voor deze gebruiker, als je tenminste de gebruiker cyrus wilt gebruiken voor het beheer van de mailserver. Nog handiger is het om /etc/imapd.conf aan te passen en een andere gebruikersnaam op te nemen. Zo voorkom je dat een eventuele hacker al te eenvoudig de informatie achterhaalt die nodig is om op de server in te breken. Nadat je de administratieve account ingesteld hebt, gebruik je de opdracht cyradm om op de Cyrus-server in te loggen en de overige beheertaken uit te voeren: cyradm -user cyrus -auth login localhost
Je ziet nu de Cyrus-shellprompt voor je waarin je alle beheertaken uitvoert. Vanuit deze shellprompt ga je aan het werk met de speciale Cyrus-opdrachten die beschikbaar zijn. Hier volgt een overzicht van de meest belangrijke opdrachten: help / ? Geeft een overzicht van beschikbare opdrachten. listmailbox / lm Toont de namen van alle mailboxen. createmailbox / create / cm Hiermee maak je een mailbox
aan. Je moet dit doen voor iedere gebruiker die je in staat wilt stellen via Cyrus IMAPd zijn mail te ontvangen. Dit doe je door mid-
278
Linux 4
del van de opdracht createmailbox user.usernaam. Let erop dat de aanduiding user. voorafgaand aan de naam van de gebruiker verplicht is. Hiermee zorg je er namelijk voor dat de juiste permissies ingesteld worden. deletemailbox / delete / dm Gebruik deze opdracht om een mailbox te verwijderen. Houd er rekening mee dat je eerst rechten moet instellen op de betreffende mailbox voordat deze opdracht gebruikt kan worden! setquota / sq Met behulp van deze opdracht stel je quota in op mailboxen. listquota / lq Toont de quota die op dit moment zijn ingesteld. setaclmailbox / setacl / sam Stelt een ACL in op een mailbox. Houd er rekening mee dat ook een beheerder standaard geen permissies heeft om mailboxen te verwijderen. Dit regel je door eerst de opdracht setaclmailbox te gebruiken. Om bijvoorbeeld beheerder sander alle rechten te geven op de mailbox van gebruiker linda, gebruik je de opdracht setaclmailbox linda sander all. deleteaclmailbox / deleteacl / dam Verwijdert een ACL die op dit moment staat ingesteld. listaclmailbox / listacl / lam Toont een overzicht van alle ACL’s die op dit moment bestaan. Om via de Cyrus-mailserver te kunnen mailen moet je er minimaal voor zorgen dat elke gebruiker een mailbox heeft. Zoals je in het hiervoor genoemde hebt kunnen lezen, wordt daarvoor de opdracht createmailbox gebruikt. Nadat je de mailbox hebt gemaakt, is het ook handig als je permissies op de mailboxen zet, zodat je er in elk geval als beheerder beheertaken op uit kunt voeren. Gebruik hiervoor de opdracht setaclmailbox, zoals hiervoor beschreven. Als dat gebeurd is, is de mailbox klaar voor gebruik. Je hoeft nu alleen nog maar de mailclient in te stellen zodat deze er zijn berichten vandaan gaat halen. Omdat elke mailclient zijn eigen configuratieopties heeft, behandelen we hier niet hoe je hiervoor te werk moet gaan. Raadpleeg de documentatie van de mailclient hiervoor.
7 Linux als mailserver
7.8
279
Samenvatting
In dit hoofdstuk heb je geleerd hoe je Linux inricht als mailserver. Je hebt gelezen dat dit niet bepaald eenvoudig is. Een mailoplossing bestaat namelijk uit verschillende onderdelen. Om te beginnen is er het onderdeel dat communiceert met mailservers op internet om mailberichten te kunnen versturen en ontvangen. Dit is de zogenoemde MTA. Je hebt gelezen hoe je Postfix als MTA kunt inzetten. Het tweede belangrijke onderdeel is het deel dat ervoor zorgt dat berichten bij de gebruiker afgeleverd worden. Hiervoor wordt gebruikgemaakt van een POP-server of een IMAP-server. In dit hoofdstuk heb je geleerd hoe beide voor dit doel ingezet worden.
8
Bestanden delen met Linux
8.1
Inleiding
Naast het gebruik van Linux als web- of mailserver, wordt Linux ook nog steeds regelmatig ingezet als fileserver. Hiervoor worden twee protocollen gebruikt: Network File System (NFS) om bestanden te kunnen delen in een pure Linux-omgeving en Samba voor het delen van bestanden met Windows-gebruikers. In dit hoofdstuk leer je hoe je op basis van beide protocollen een bestandsserver opzet. 8.2
Linux als NFS-server
NFS (Network File System) is de traditionele manier waarop UNIX-computers bestanden met elkaar delen. NFS wordt nog steeds regelmatig gebruikt, want het is een heel snel protocol om bestanden te delen met andere gebruikers. De NFS-server moet ervoor zorgen dat directory’s geëxporteerd worden. Op de client kan de geëxporteerde directory vervolgens worden binnengehaald met behulp van de opdracht mount –t nfs. Zowel voor gebruik van NFS op een server als op een client moet ondersteuning voor NFS in de kernel gecompileerd worden. Of dit op het systeem al gebeurd is, kun je nagaan door het bestand /proc/filesystems te raadplegen. NFS is echter zo algemeen, dat deze functionaliteit vrijwel altijd in de kernel aanwezig is.
282
Linux 4
/proc In het /proc-bestandssysteem vind je heel veel informatie over de huidige status van de kernel en de randapparaten die herkend worden. Niet alleen om te achterhalen welke bestandssystemen ondersteund worden, maar ook voor menig ander doel vind je hier zeer nuttige informatie over het systeem. Het is daarom van harte aan te raden om er eens een kijkje te nemen om te achterhalen wat er precies gebeurt. Om een computer in te zetten als NFS-server heb je een aantal ingrediënten nodig. Om te beginnen is dat een aantal daemons dat ervoor zorgt dat de NFS-service op de computer beschikbaar gesteld wordt. Daarnaast moet je het configuratiebestand /etc/export maken en daarin de namen opnemen van de directory’s die je met NFS aan anderen beschikbaar wilt stellen. In de volgende paragrafen leer je hoe je te werk gaat om dit te regelen. 8.2.1 De NFS-daemons Om NFS-services aan andere computers beschikbaar te stellen zijn de daemons rpc.nfsd en rpc.mountd nodig. Deze services registreren zich vervolgens bij de rpc-portmapper. Dit is een service die de speciale RPC-adressen die door NFS gebruikt worden omzet in poortadressen. Op de meeste distributies wordt de RPC-portmapper gestart met behulp van een eigen runlevelscript. Vaak is het niet nodig om dit proces apart te starten, maar wordt het automatisch gestart wanneer je de NFS-server op de computer activeert. Op Fedora doe je dit met het script /etc/init.d/nfs, op SUSE Linux wordt hiervoor het script /etc/init.d/nfsserver gebruikt. 8.2.2 Definitie van de shares Tijdens het opstarten en daarna niet meer, kijkt de NFS-daemon in het configuratiebestand /etc/exports welke directory’s op de NFSserver voor anderen beschikbaar gesteld worden. Dat het NFSproces dit alleen tijdens het opstarten doet, betekent dus ook dat je de NFS-service opnieuw moet starten nadat je wijzigingen in dit bestand hebt aangebracht. Dit is handig te doen door de opdracht killall –SIGHUP nfsd te gebruiken, maar je kunt natuurlijk ook het init-script voor NFS gebruiken hiervoor.
8 Bestanden delen met Linux
283
De structuur van het bestand /etc/exports is vrij eenvoudig. Je geeft op welke directory’s toegankelijk gemaakt worden, vervolgens geef je eventueel aan voor wie ze toegankelijk zijn en daarbij specificeer je door middel van opties op welke manier ze gebruikt mogen worden. De inhoud van dit bestand kan er bijvoorbeeld als volgt uitzien: /share
192.168.0.0/255.255.0.0(rw,no _ root _ squash,insecure)
In dit voorbeeld wordt een directory met de naam /share geëxporteerd. Om ervoor te zorgen dat alle computers op alle lokale netwerken bestanden in deze directory mogen benaderen, wordt gebruikgemaakt van de aanduiding 192.168.0.0/255.255.0.0. Hiermee wordt verwezen naar alle computers waarvan het IP-adres begint met 192.168. In plaats van een IP-adres en bijbehorend subnetmasker, kun je hier trouwens ook computernamen of gedeeltelijke domeinnamen opgeven. Ook is het mogelijk om de server gewoon helemaal open te zetten door hier een * te specificeren. Tussen haakjes staan vervolgens de opties die bepalen hoe de computers toegang hebben tot deze directory. De opties die in dit voorbeeld gebruikt worden, zorgen ervoor dat er met weinig restricties contact gezocht kan worden met deze server. De volgende opties zijn onder andere beschikbaar. secure
insecure ro
rw noaccess
Deze standaardinstelling bepaalt dat aanvragen afkomstig moeten zijn van poorten waarvan het nummer lager is dan 1024. Dit zijn gereserveerde (well-known) poortadressen. Deze optie is met name bedoeld om misbruik door crackers te voorkomen. Het contact met deze directory mag vanaf elk poortadres opgebouwd worden. De directory wordt read-only gemount. Gebruikers kunnen dus wel bestanden lezen, maar niet schrijven. De directory wordt read/write gemount. Hiermee wordt alles beneden de gespecificeerde directory ontoegankelijk gemaakt voor de client. Door gebruik van deze parameter kun je toegang tot subdirectory’s van een geëxporteerde directory ontzeggen.
284
Linux 4
link _ relative
Symbolic links waarvan de verwijzing absoluut is ingesteld, worden ingesteld op een relatieve verwijzing. Een verwijzing naar bijvoorbeeld /etc/hosts wordt dan zoiets als ../hosts. Deze optie heeft alleen zin als het volledige bestandssysteem van een server geëxporteerd wordt, anders loop je namelijk het risico dat de verwijzingen van de links niet meer kloppen. link _ absolute Symbolic links blijven zoals ze zijn. Dit is het standaardgedrag. root _ squash De gebruiker met het UID 0 en de groep met het GID 0 (de gebruiker en de groep root) komen er niet in als deze optie aan staat. Alle verzoeken die van hen afkomstig zijn, worden uitgevoerd met het UID 65534 op de server. Deze UID wordt standaard gebruikt door de gebruiker ‘nobody’. Als root via een andere machine over een NFS-mount binnenkomt, heeft hij dus minimale rechten als deze optie gebruikt is. no _ root _ squash Deze standaardoptie zorgt ervoor dat ook de gebruiker root gewoon toegang heeft tot de server. Dit is de standaardinstelling. squash _ uids, Met deze opties kunnen UID’s en GID’s squash _ gids opgegeven worden waarvan aanvragen ook doorgestuurd moeten worden naar de gebruiker anonymous. De syntaxis hiervoor is squash_uids=0-10,13,18,100-1000. Indien van deze optie geen gebruikgemaakt wordt, worden alle client-UID’s doorgestuurd naar gebruikers met dezelfde UID op de NFSserver. all _ squash Deze optie zorgt ervoor dat alle aanvragen geïnterpreteerd worden als afkomstig van de gebruiker anonymous. map _ daemon Hiermee wordt ervoor gezorgd dat elke gebruikers en groups-ID op de client vertaald wordt in een valide naam die voorkomt op de server. Om deze optie te kunnen gebruiken moet op de client de daemon rpc.ugidd
8 Bestanden delen met Linux
map _ identity
map _ static
# uid
285
actief zijn. De standaardinstelling is ‘map_ identity’ die alle ID’s met rust laat. Deze optie specificeert dat een UID van een gebruiker op een clientcomputer geïnterpreteerd wordt als dezelfde UID op de server en vice versa. Dit is het standaardgedrag. Om dit systeem goed te laten werken is het handig gebruik te maken van een onderliggend mechanisme waardoor alle gebruikersnamen gedeeld worden. Hiervoor zou gebruikgemaakt kunnen worden van bijvoorbeeld NIS of OpenLDAP. Met deze optie kan verwezen worden naar een tekstbestand waarin statische mappings tussen users voorkomen. Je specificeert de optie als bijvoorbeeld ‘map_static=/etc/nfs/ guid.map’. De inhoud van dit bestand ziet eruit als: remote
0-99
local
-
#deze ID’s worden gemapt
naar anonymous uid
100-500
gid
0-49
1000 #deze ID’s worden gemapt naar 1000-1400 -
#ook deze ID’s worden
gemapt naar anonymous gid
50-100
700
#GID 50-100 worden gemapt naar
700-750
map _ nis
De mappings worden overgelaten aan de NIS-server. Het NIS-domein van de client moet hierbij als argument gegeven worden. anonuid, anongid Met deze opties kan worden ingesteld welke UID en GID gebruikt moeten worden voor de account anonymous. In het volgende zie je een voorbeeld van hoe een NFS-configuratie waarin deze opties gebruikt worden eruit kan zien: #Voorbeeld van /etc/exports / laksmi(rw) laetitia(rw,no _ root _ squash) /pub
(ro,insecure,all _ squash)
286
Linux 4
/pub/private /home
(noaccess)
@local(ro,all _ squash,anonuid=0,anongid=100)
Wellicht is dit bestand niet echt een voorbeeld van een slimme configuratie (hopelijk zie je zelf ook waarom), maar de betekenis is als volgt. Op de eerste regel wordt read/write-toegang gegeven aan de computers laksmi en laetitia. Hierbij wordt gebruiker root van computer laetitia niet automatisch gemapt naar de gebruiker anonymous. Dit betekent dat de gebruiker root gewoon als root toegang heeft tot het andere systeem. Lekker gemakkelijk, maar ook redelijk onveilig. Vervolgens krijgt iedereen toegang tot de directory pub. Er staat hier geen naam van een server gespecificeerd, dus de regel heeft betrekking op iedereen. Mensen die binnenkomen, mogen vanaf elke poort een aanvraag sturen en ze krijgen de privileges die de gebruiker anonymous op de server heeft. De subdirectory private echter is geheim, vandaar dat niemand daar toegang in heeft. Tot slot mogen alle gebruikers uit de netgroup local de bestanden onder /home benaderen. Dit gebeurt echter wel met read-only-toegang en alle UIDs en GIDs worden vertaald, respectievelijk in UID 0 en GID 100. 8.2.3 Client-authenticatie Wanneer het gaat om de rechten die je als NFS-gebruiker hebt op een NFS-server, gaat NFS uit van een erg eenvoudig principe. Bij het aanmelden op de NFS-server neem je je UID mee naar deze server. Dit betekent dat de server je probeert aan te melden op basis van hetzelfde UID. In het voorgaande overzicht heb je echter gelezen dat er een aantal opties is dat je kunt opnemen in /etc/exports en waarmee je dit gedrag kunt beïnvloeden. Wanneer je in de NFS-omgeving uitgaat van een gebruikersconfiguratie die geheel wordt bijgehouden in de lokale wachtwoordbestanden, kan dat tot verwarrende resultaten leiden. Het systeem functioneert echter het best wanneer gebruikgemaakt wordt van een centraal mechanisme waarin gebruikersnamen worden bijgehouden. Denk daarbij aan NIS, LDAP of eventueel een directoryservice van een derde partij, zoals eDirectory van Novell. Ook bij gebruik van dergelijke oplossingen is het nog steeds mogelijk uitzonderingen te definiëren. Hierover heb je in het voorgaande kunnen lezen.
8 Bestanden delen met Linux
287
8.2.4 Locking In het oorspronkelijke ontwerp wist de NFS-server niets van locken van bestanden. Dit betekent dat het kon voorkomen dat twee gebruikers gelijktijdig hetzelfde bestand geopend hadden en daar wijzigingen in aanbrachten die niet met elkaar in overeenstemming waren. Omdat dit onvoorspelbare en ongewenste gevolgen kan hebben, wordt tegenwoordig automatisch met het starten van een NFS-server de locking op bestanden geregeld. Dit zorgt ervoor dat slechts één gebruiker tegelijk een bepaald bestand geopend mag hebben. Een volgende gebruiker die probeert toegang te krijgen tot hetzelfde bestand, zal er niet inkomen. Hiermee kan op voorhand veel ellende worden voorkomen. 8.2.5 Linux als NFS-client Als de NFS-server eenmaal goed geconfigureerd is, is het een koud kunstje om vervolgens vanaf een andere computer een mount uit te voeren. Je gebruikt hiervoor de opdracht mount en specificeert daarbij het juiste type van de mount, de naam van de server en te mounten directory, en tot slot de naam van het punt waarop de directory gemount moet worden. Een voorbeeld hiervan zie je in de opdracht mount -t nfs damayanti:/home /home. Hiermee wordt de directory /home vanaf de computer damayanti gekoppeld aan de directory /home op het lokale systeem. Deze werkwijze heeft echter wel één nadeel: je moet root zijn om de mount uit te kunnen voeren. Alleen de gebruiker root heeft namelijk permissies om op een systeem een mount uit te voeren. Dit zorgt ervoor dat het er in de praktijk meestal op neerkomt dat NFS-mounts automatisch worden uitgevoerd vanuit /etc/fstab. Als alternatief zou je ervoor kunnen kiezen een sudoconfiguratie aan te maken, zodat ook normale gebruikers directory’s mogen mounten. Om deze mount vanuit fstab uit te voeren zou je de volgende regel in dit bestand moeten opnemen: damayanti:/home
/home
nfs
_ netdev 0 0
Bij het mounten van een met NFS geëxporteerde directory kun je een aantal opties specificeren. Met name de volgende opties zijn interessant: rsize=n, wsize=n
Hiermee geef je op hoe groot de NFS-pakketjes zijn die verstuurd worden. De stan-
288
Linux 4
timeo=n
hard
soft
intr
daardwaarde is 1024 bytes, voor betere prestaties kun je beide instellen op 8192. Alleen wanneer je contact maakt met een versie NFS-server die ouder is dan versie 2, moet je ervoor zorgen dat beide opties staan ingesteld op de waarde 1024. Dit bereik je door de parameters rsize en wsize gewoon niet te gebruiken. Met deze optie wordt gespecificeerd welke timeout er aan een NFS-request verbonden is. De waarde hiervan wordt opgegeven in tienden van seconden; de standaardwaarde is 7. Wat er gebeurt wanneer deze waarde overschreden wordt, hangt ervan af of je de parameter hard of soft hebt opgegeven. Deze standaardoptie zorgt ervoor dat een server een melding geeft als er een timeout optreedt en vervolgens oneindig doorgaat met proberen de mount uit te voeren. Dit kan erg vervelend zijn, want het betekent dat je in het ergste geval ook oneindig staat te wachten totdat de mount voltooid is. Dit kun je echter voorkomen door gebruik te maken van de optie bg (background) waarmee het verzoek de mount uit te voeren op de achtergrond wordt uitgevoerd. Deze optie zorgt ervoor dat niet oneindig geprobeerd wordt een mount uit te voeren, maar dat een I/O-error gegenereerd wordt wanneer er na 60 seconden nog steeds geen contact gemaakt is. Als deze optie aan staat, is het toegestaan een NFS-request te onderbreken met bijvoorbeeld de toetsencombinatie Ctrl-C.
De opties kunnen zowel direct bij de opdracht mount gebruikt worden als in /etc/fstab. In beide gevallen worden verschillende opties met een komma van elkaar onderscheiden. Zo kan bijvoorbeeld een mount worden uitgevoerd met de opdracht mount –t nfs -o rsize=8192,wsize=8192,intr laetitia:/home /home. Een dergelijke oplossing leent zich er goed voor om de homedirectory die op een andere server voorkomt lokaal te mounten.
8 Bestanden delen met Linux
289
Als je snel een overzicht wilt hebben van mounts die door een NFS-server zijn uitgevoerd, kun je hiervoor op die server de opdracht showmount gebruiken. Als de opdracht zonder argumenten gegeven wordt, wordt een lijst gegeven van alle computers die een directory op de NFS-server in gebruik hebben. Je kunt het ook gebruiken vanaf een client om aan een server op te vragen wie wat in gebruik heeft. Zo kun je met de opdracht showmount -a laetitia een lijst opvragen van alle computers die een directory van NFSserver laetitia in gebruik hebben. Ook heel handig is de opdracht showmount –e. Hiermee vraag je namelijk een overzicht op van de shares die een andere host in de aanbieding heeft. 8.3
Linux als Samba-server
Server Message Blocks (SMB) is het protocol dat in een Microsoftomgeving gebruikt wordt om bestanden te delen tussen clients onderling en tussen servers en werkstations. De gestandaardiseerde versie van dit protocol staat bekend als CIFS (Common Internet File System). Al een behoorlijke tijd is er een open source-implementatie van dit protocol: de Samba-server. Je leert nu hoe je deze server kunt configureren om de Linux-server in te zetten als fileserver in een Windows-omgeving. De belangrijkste aspecten van deze server worden uiteengezet. Zo lees je hoe je deze server kunt inzetten als normale bestandsserver, maar ook hoe je hem kunt inzetten op een soortgelijke wijze als de Windows NT Primary Domain Controller (PDC). Tevens lees je hoe je een Samba-server kunt integreren in Active Directory. We gaan hier uit van de 3.xversies van de Samba-server. Er wordt inmiddels al gewerkt aan versie 4, maar deze was op het moment dat dit geschreven werd nog in een heel pril stadium. 8.3.1 Componenten van de Samba-server Voordat we in detail kunnen bekijken op welke wijze een Sambaserver in een netwerk ingezet kan worden, zetten we eerst uiteen uit welke componenten de Samba-server bestaat. Om de Sambaserver naar behoren te kunnen beheren moet je immers wel weten welke processen en configuratiebestanden daarvoor beheerd moeten worden. Om deze vraag te kunnen beantwoorden is het overigens van belang te weten met welke versie van de Samba-server je
290
Linux 4
werkt. In de meeste gevallen zal dit versie 3.x zijn. Oudere distributies maken gebruik van versie 2.2.x. In dit boek echter besteden we geen aandacht aan de configuratie van 2.2.x-servers. Om te achterhalen welke versie je gebruikt geef je in een terminalvenster de opdracht smbd -V. Samba-processen Om gebruik te kunnen maken van de Samba-server wordt een drietal processen gebruikt. Ten eerste is er smbd. Dit is het proces dat ervoor zorgt dat bestanden gedeeld kunnen worden met behulp van het protocol CIFS (Common Internet File System). Smbd is dus het meest belangrijke proces dat je nodig hebt om te kunnen werken met de Samba-server. Naast smbd is er ook nog het proces nmbd. Dit is de NetBIOS-naamserver die nodig is om door middel van NetBIOS over TCP/IP (NBT) de Samba-service bekend te maken. Deze service is niet echt noodzakelijk, maar vervult toch een heel handige rol: dankzij nmbd wordt de Samba-server namelijk ook zichtbaar in de netwerkomgeving op andere computers. Als derde is er winbdinbdd. Deze service is nieuw in versie 3.x van Samba en zorgt ervoor dat de Samba-server kan communiceren met een Active Directory-omgeving. Later in dit hoofdstuk leer je meer over dit proces. Om Samba te starten wordt gebruikgemaakt van scripts in /etc/ init.d. Op Fedora gebeurt het eenvoudig en zijn er twee scripts die alles regelen: smb zorgt ervoor dat de Samba-server en alle noodzakelijke componenten (denk bijvoorbeeld aan nmbd) geladen worden, daarnaast is er op Fedora het script winbind dat de communicatie met Active Directory regelt als dat nodig is. SUSE daarentegen maakt gebruik van meerdere scripts: smb zorgt ervoor dat de Samba-server gestart wordt. nmb wordt gebruikt om nmbd te activeren. smbfs kan tijdens het booten van de computer worden aangeroepen om mounts naar een Samba-server uit te voeren. Het configuratiebestand smb.conf De daemon-processen van de Samba-server maken gebruik van één configuratiebestand. Dit bestand heeft de naam smb.conf en komt doorgaans op de standaardlocatie /etc/samba voor. In dit configuratiebestand wordt de volledige Samba-server gedefinieerd. Je
8 Bestanden delen met Linux
291
kunt er in totaal een kleine vierhonderd verschillende parameters in opnemen. Deze parameters zijn op uitstekende wijze gedocumenteerd in de man-pagina van smb.conf. Smb.conf is opgedeeld in twee hoofdonderdelen. Deze worden ‘secties’ genoemd. Om te beginnen is er de sectie [global]. Hierin vind je algemene parameters die ervoor zorgen dat de Samba-server zijn werk kan doen. Denk hierbij aan algemene zaken zoals de naam van de server die gedefinieerd moet worden. In principe is er niet zo veel nodig in deze sectie om een werkende server te krijgen. Aangezien alle opties een standaardwaarde hebben die standaard goed staat, is het voldoende om hier alleen de naamgeving van de server te regelen. Naast de sectie [global] zijn er secties waarin de shares gedefinieerd kunnen worden. Dit zijn de namen van de gedeelde netwerkbronnen. Je kunt hier zowel printers als bestanden mee delen. Om je gelijk maar kennis te laten maken met de mogelijkheden van de Samba-server, zie je in het onderstaande een klein voorbeeld waarmee een werkende Sambaserver gedefinieerd kan worden. Op basis van dit voorbeeld kun je een werkende Samba-server maken. Probeer het maar eens uit op de computer, je zult zien dat je gelijk kunt beginnen met delen van bestanden door gebruik te maken van de directory /tmp. Op een operationele server is het overigens niet verstandig om een share te maken op /tmp, maar om snel een Samba-server uit te proberen is het een handig voorbeeld: je hoeft namelijk niets aan rechten te doen op het lokale bestandssysteem. Verderop in dit hoofdstuk kun je lezen waar de verschillende opties in dit voorbeeld precies voor gebruikt worden. [global] workgroup = workgroup printing = cups printcap name = cups security = user encrypt passwords = yes server string = Samba-server [share] comment = Algemene datashare path = /tmp writeable = Yes inherit permissions = Yes
292
Linux 4
browseable = yes guest ok = no printable = no
Andere configuratiebestanden Naast de drie componenten die in hiervoor genoemd zijn, kan ook gebruikgemaakt worden van extra configuratiebestanden. Of dit ook inderdaad in deze situatie het geval is, hangt af van de specifieke configuratie die gebruikt wordt. We zullen kort de overige mogelijke configuratiebestanden bespreken. lmhosts
Dit bestand kan door de Samba-server gebruikt worden om NetBIOS-namen in IP-adressen te vertalen. De opbouw van dit bestand heeft veel weg van de opbouw van het bestand /etc/hosts. Door gebruik te maken van een lmhosts-bestand kun je ervoor zorgen dat er geen netwerkverkeer gegenereerd wordt om te achterhalen welk IP-adres bij een bepaalde computernaam hoort. Gebruik van dit bestand is optioneel. Hieronder zie je een voorbeeld van hoe de inhoud van dit bestand eruit kan zien.
127.0.0.1 localhost 192.168.0.50
xtina
192.168.0.51
laetitia
smbfstab
In sommige gevallen wil je ervoor zorgen dat tijdens het opstarten van de Linux-computer automatisch een aantal Samba-shares gemount worden. Als je gebruikmaakt van het bestand /etc/fstab, heeft dit tot gevolg dat gewone gebruikers de definities van deze shares kunnen uitlezen. Dit is vervelend, aangezien hier ook gebruikersnamen en wachtwoorden in voor kunnen komen. Om die reden kan voor dit doel gebruikgemaakt worden van een afzonderlijk configuratiebestand. Houd er overigens rekening mee dat dit bestand niet automatisch ook afdoende beveiligd is. In veel gevallen wordt namelijk gewoon nog gebruikgemaakt van de permissiemodus 644. Het is dus aan te raden
8 Bestanden delen met Linux
smbpasswd
smbusers
293
voor gebruik wel ook de permissiemodus aan te passen. Dit bestand wordt onder bepaalde omstandigheden gebruikt om de namen van Samba-gebruikers en de bijbehorende versleutelde wachtwoorden bij te houden. In versie 3 van de Samba-server is de functionaliteit van dit bestand overgenomen door de zogenoemde Trivial Database (TDB). Het configuratiebestand smbpasswd kan echter nog steeds gebruikt worden. Soms is het nodig dat de naam van een gebruiker op het werkstation vertaald wordt in de naam van een gebruiker op de Linux-server. Denk bijvoorbeeld aan een mapping van de gebruiker administrator naar de Linux-gebruiker root. Om dit soort mappings automatisch plaats te laten vinden kun je gebruikmaken van het bestand smbusers.
8.3.2 Samba als fileserver We zullen nu een aantal mogelijkheden bespreken om de Sambaserver te configureren. Voordat we bespreken wat er moet gebeuren om met succes een Samba-server te installeren, zullen we eerst duidelijk maken welke verschillende componenten met elkaar moeten communiceren om een werkende Samba-server te krijgen. Er moet namelijk op Linux het een en andere geconfigureerd worden en daarnaast ook op Windows. Vervolgens moet je ervoor zorgen dat beide werelden elkaar ook kunnen begrijpen. Een Samba-server is een Linux-server die aan Windows-gebruikers toegang geeft tot Linux-bestanden. Dit betekent dat er ergens een vertaalslag plaats moet vinden. De toegang tot de Linux-bestanden wordt namelijk geregeld door middel van Linux-permissies die uitgedeeld worden aan Linux-gebruikers. Dit zit hem in het Linux-bestandssysteem en ook al benader je dat met Samba, het is en blijft een Linux-bestandssysteem. Je kunt dit vergelijken met de configuratie van een Windows 2003-netwerkomgeving. Als je daar immers alleen de share definieert maar de NTFS-permissies niet regelt, hebben gebruikers namelijk ook geen toegang. Om de hele procedure compleet te maken beginnen we bij de configuratie van de Linux-permissies.
294
Linux 4
Permissies, owners en andere Linux-eigenaardigheden Onder Linux zijn er drie belangrijke permissies: Read, Write en Execute. Deze permissies worden uitgedeeld op bestanden en op directory’s. In de volgende tabel kun je lezen wat de betekenissen zijn van de permissies. Permissie Bestanden Read Bekijken van de inhoud Write Wijzigen van de inhoud Verwijderen van het bestand Execute Opstarten van programma’s
Directory’s Zien van bestanden in de directory Maken van bestanden Verplaatsen van bestanden Verwijderen van bestanden Subdirectory’s activeren
Waar op netwerkbesturingssystemen als Netware of Windows op een uitgebreide manier met groepen gewerkt wordt, ligt de situatie onder Linux anders. Om te beginnen heeft elk bestand onder Linux een eigenaar. De eigenaar van het bestand is in principe de gebruiker die dit bestand heeft gemaakt, maar dit kan gewijzigd worden. Wanneer je de opdracht ls -l geeft, krijg je in de tweede kolom een overzicht te zien van gebruikers die eigenaar zijn van bestanden in de directory die op dat moment actief is. Figuur 8.1 Met de opdracht ls -l kun je precies zien wie er eigenaar is van de bestanden in de huidige directory
8 Bestanden delen met Linux
295
Naast het feit dat elk bestand een eigenaar heeft, is ook aan elk bestand een groep als eigenaar verbonden. Ook deze groep is relevant voor de permissies. Nu ben je van andere netwerk besturingssystemen misschien gewend dat een gebruiker lid kan zijn van meerdere groepen tegelijk. Onder Linux ligt dit een stuk lastiger. Elke gebruiker heeft één primaire groep waar hij lid van is. Je kunt gebruikers wel lid maken van meerdere groepen, maar dit is zo omslachtig dat vrijwel iedereen het probeert te vermijden. We gaan er hier dan ook niet verder op in hoe je dit zou moeten regelen. Naast de gebruiker en groep die eigenaar zijn van een bestand, is er de rest van de wereld, lees: alle andere gebruikers die op het systeem gedefinieerd zijn. Ook aan de rest van de wereld worden permissies gegeven. De standaardinstelling is in de meeste gevallen dat de rest van de wereld hooguit de bestanden mag lezen. Je zou je echter moeten afvragen of zelfs zo’n minimale instelling al wenselijk is. Wanneer een gebruiker een bestand benadert op een Linux-computer, moet er altijd bepaald worden welke permissies deze gebruiker op het betreffende bestand heeft. Hiervoor worden achtereenvolgens de volgende vragen gesteld: Is de gebruiker eigenaar van het bestand? Is de gebruiker lid van de groep die eigenaar is van het bestand? Zo niet: dan behoort de gebruiker dus bij de rest van de wereld. Overeenkomstig deze drie entiteiten worden permissies op Linuxbestanden uitgedeeld. Wanneer je de opdracht ls -l geeft in een willekeurige directory, wordt als resultaat een aantal kolommen getoond. De permissies worden weergegeven aan het begin van elke regel. Dit ziet eruit als -rwx-r-xr-x. Het eerste liggende streepje wordt gebruikt om aan te geven wat voor type bestand het is. Als hier bijvoorbeeld de letter d staat, is het een directory. Daarna worden de volgende drie posities gereserveerd voor de permissies van de eigenaar van het bestand. In dit voorbeeld is dat rwx Het tweede groepje van drie wordt gebruikt om aan te duiden wat de permissies zijn van de groep. Als laatste worden de permissies van alle andere gebruikers getoond.
296
Linux 4
Groepslidmaatschap van Linux-gebruikers Zoals eerder gezegd, op een Windows- of Netware-systeem is het gebruikelijk dat een gebruiker lid is van meerdere groepen tegelijk. Op Linux is dit niet gebruikelijk. Een gebruiker is meestal slechts lid van één groep en deze groepslidmaatschap is geregeld in de gebruikersdatabase /etc/passwd. We noemen dit overigens de primaire groep. Figuur 8.2 In /etc/passwd wordt gedefinieerd van welke groep een gebruiker lid is
In figuur 8.2 zie je een voorbeeld van de gebruikersdatabase /etc/ passwd. Op de laatste regel wordt gebruiker pleunie gedefinieerd. Het tweede veld bevat alleen een kruisje dat aangeeft dat het wachtwoord van pleunie in /etc/shadow versleuteld is opgeslagen. In het derde veld treffen we de gebruikers-ID (UID) van pleunie. Dat is het unieke nummer waarmee pleunie intern bij het systeem bekend is. Vervolgens is in het vierde veld de Group-ID (GID) vermeld. Het is handig wanneer dit voor alle gebruikers gelijk is. Houd er echter rekening mee dat Fedora niet uitgaat van dit principe en voor elke gebruiker een groep maakt met de naam van de gebruiker. Alleen de gebruiker zelf is lid van die groep. Vaak wordt voor dit doel gebruikgemaakt van de groep met GID 100. Welke groep dat precies is, wordt geregeld in het groepsbestand /etc/group.
8 Bestanden delen met Linux
297
Figuur 8.3 In /etc/group wordt gedefinieerd welke groepen er op een systeem voorkomen
Om te kijken van welke groep alle gebruikers lid zijn, moet dus het bestand /etc/group geopend worden. Hierin lezen we in dit voorbeeld dat het om de groep users gaat. Alle gebruikers zijn dus lid van dezelfde groep. Van Linux naar Samba Wanneer je aan de hand van het hiervoor genoemde ervoor gezorgd hebt dat de Linux-server op het gebied van rechten goed is afgeschermd, kun je de Samba-server inrichten. Hiervoor moeten twee dingen gebeuren. Als eerste moeten de gebruikers van de Samba-server gedefinieerd worden. De Windows-gebruikers die binnenkomen met hun Windows-gebruikersnaam, kunnen namelijk niet rechtstreeks authenticeren op de Linux-gebruikersdatabase. Dit komt omdat Windows van een totaal ander authenticatiemechanisme gebruikmaakt dan Linux. Om die reden moet met de opdracht smbpasswd een database gemaakt worden waarin de Samba-gebruikers gedefinieerd zijn. Op een Samba-server bestaat elke gebruiker dus twee keer: eerst een keer als Linux-gebruiker, daarna een keer als Samba-gebruiker. Dit kan overigens ook op andere manieren geregeld worden, daarover lees je verderop in dit hoofdstuk meer. Wanneer ervoor gezorgd is dat de Samba-gebruikers gedefinieerd zijn, moeten vervolgens de Samba-shares gemaakt worden. Dit zijn
298
Linux 4
de gedeelde bronnen die de gebruikers in hun netwerkomgeving te zien krijgen. Je regelt dit in het configuratiebestand smb.conf. Je kunt dit bestand op de meeste distributies terugvinden in de directory /etc/samba. Wanneer je dit configuratiebestand hebt gemaakt, moet ervoor gezorgd worden dat de Samba-processen gestart worden. 8.3.3 Configuratie van de Samba-server: een praktijkvoorbeeld Nu je op de hoogte bent van wat er allemaal moet gebeuren om een Samba-server aan het werk te krijgen, zullen we een praktisch scenario uitwerken waarin een Samba-server wordt ingericht. Alle noodzakelijke stappen worden op een rij gezet, zodat je direct aan het werk kunt. Verderop in dit hoofdstuk lees je in meer detail hoe de Samba-server geconfigureerd kan worden. In dit scenario wordt uitgegaan van een klein bedrijf waarin twee gebruikers op de administratie zitten en er drie mensen op de werkvloer staan. Beide groepen hebben een privédirectory die niet toegankelijk is voor mensen uit de andere groepen. Gebruikers Linda en Frans zijn lid van de groep Administratie, Kees, Eric en Sander zijn lid van de groep Delivery. Leden van de beide groepen moeten vanaf hun Windows-werkplek toegang krijgen tot hun homedirectory en daarnaast ook tot hun gedeelde groepsdirectory. Zorg ervoor dat je ingelogd bent als root om de volgende procedure uit te kunnen werken. 1. Maken van groepen Het is handig om als eerste de benodigde Linux-groepen te maken. Je kunt er dan namelijk bij het maken van de gebruikers voor zorgen dat deze direct aan de juiste groep toegevoegd kunnen worden. Maak hiervoor gebruik van de opdracht groupadd. groupadd delivery groupadd administratie
2. Maken van gebruikers Nu de groepen zijn gemaakt, kunnen als tweede stap de gebruikers gemaakt worden. Hiervoor maken we gebruik van de opdracht useradd. Door bij deze opdracht de optie -g te gebruiken kan direct aangegeven worden van welke groepen de gebruikers lid
8 Bestanden delen met Linux
299
gemaakt moeten worden. Op sommige distributies moet je ook de optie -m gebruiken om ervoor te zorgen dat de homedirectory’s gemaakt worden. Nadat de gebruikers zijn gemaakt, kun je ze met de opdracht passwd van een wachtwoord voorzien. useradd -g administratie –m linda passwd linda useradd -g administratie –m frans passwd frans useradd -g delivery –m kees passwd kees useradd -g delivery –m eric passwd eric useradd -g delivery –m sander passwd sander
3. Maken van de groepsdirectory’s Nu de gebruikers en groepen gecreëerd zijn, moet je ervoor zorgen dat de gedeelde groepsdirectory’s waarvan deze gebruikers gebruik gaan maken ook gemaakt worden. Dit doe je met de opdracht mkdir. De optie –p in het volgende voorbeeld zorgt er trouwens voor dat bij het maken van de directory /data/administratie ook gelijk de directory /data wordt gemaakt als deze nog niet bestaat. mkdir –p /data/administratie mkdir –p /data/delivery
4. Aanpassen van permissies Alle directory’s zijn op dit moment gemaakt, alleen zijn nog niet de juiste gebruikers en groepen lid van deze directory’s. Om hier verandering in aan te brengen maak je gebruik van de opdracht chown wat staat voor Change Owner. Met deze opdracht kun je zowel de gebruiker als de groep die eigenaar moet worden aanpassen. De namen van de gebruiker en de groep die lid moeten worden, worden in dat geval met een punt (een dubbelepunt mag ook) van elkaar gescheiden. chown root.administratie /data/administratie chown root.delivery /data/delivery
300
Linux 4
5. Samba-gebruikers maken Alle Linux-permissies staan nu goed ingesteld. In de volgende stap maken we de Samba-gebruikers. De Windows-gebruiker meldt zich immers vanaf zijn pc aan op de share door middel van zijn Windows-credentials. Deze Windows-credentials moeten vervolgens via de Samba-gebruiker doorgegeven worden aan het Linux-systeem. Om de Samba-gebruikers te maken gebruik je de opdracht smbpasswd. Direct na het maken van de Samba-gebruiker vraagt het systeem om een wachtwoord. Het is handig maar niet verplicht hier gebruik te maken van hetzelfde wachtwoord als dat de Linux-gebruiker in gebruik heeft. smbpasswd -a linda smbpasswd -a frans smbpasswd -a kees smbpasswd -a eric smbpasswd -a sander
6. Aanpassen van de shares in smb.conf Tot nu toe hebben we ons alleen nog maar beziggehouden met het voorbereidende werk. De werkelijke configuratie van de Sambaserver bestaat eruit dat het configuratiebestand smb.conf wordt aangepast. We laten je hier een redelijk klein voorbeeld van dit bestand zien. Verderop in dit hoofdstuk kun je kennismaken met uitgebreidere voorbeelden. [global]
workgroup=Samba
netbios name = samba
time server = yes
encrypt passwords = yes
socket options = SO _ KEEPALIVE IPTOS _ LOWDELAY TCP _ NODELAY
wins support = no
veto files = /*.eml/*.nws/riched20.dll/*.{*}/
security = user
[homes]
comment = Home Directories
valid users = %S
browseable = no
writeable = yes
8 Bestanden delen met Linux
create mask = 0640
directory mask = 0750
301
[administratie]
comment = administratie
valid users = linda frans
browseable = no
writeable = yes
create mask = 0660
directory mask = 0770
[delivery]
comment = delivery
valid users = kees eric sander
browseable = no
writeable = yes
create mask = 0660
directory mask = 0770
We zetten kort de betekenis van de verschillende opties uit dit voorbeeld naast elkaar. workgroup=samba
Hiermee wordt de naam van de werkgroep aangegeven zoals deze in de netwerkomgeving zichtbaar zal zijn. netbios name = samba
Met behulp van deze instelling bepaal je hoe de Samba-server zichzelf op het netwerk bekend gaat maken. time server = yes
Deze waarde bepaalt dat de Samba-server zich als tijdbron adverteert voor de Windows clients in het netwerk. Dat is handig omdat dan de klokken van de werkstations in het netwerk gelijk staan met de klok van de server. encrypt passwords = yes
Deze parameter zorgt ervoor dat de Samba-server in staat is versleutelde wachtwoorden van Windows te ontcijferen. Je moet deze parameter op yes hebben staan wanneer je gebruikmaakt van Windows 95b, Windows NT 4.0 SP 3 of hoger. socket options = SO _ KEEPALIVE IPTOS _ LOWDELAY TCP _ NODELAY
302
Linux 4
Deze parameter zorgt ervoor dat de Samba-server zo efficiënt mogelijk op het netwerk communiceert. wins support = no
Hiermee wordt aangegeven dat de Samba-server op het netwerk niet de rol van WINS-server vervult. veto files = /*.eml/*.nws/riched20.dll/*.{*}/
Dit is een lijst met bestanden die nooit in een Samba-share zichtbaar zullen worden. Deze bestanden kunnen dus ook niet gebruikt worden. De verschillende bestandsnamen worden met behulp van een / van elkaar onderscheiden. security = user
Er zijn verschillende manieren waarop je de authenticatie op de Samba-server kunt regelen. Al deze manieren worden gedefinieerd met de regel security =. Het meest gebruikelijk is dat er gebruikgemaakt wordt van de regel security = user. Hiermee wordt bepaald dat op de Samba-server een aparte gebruikersdatabase moet worden gemaakt waarop de Windows-gebruikers kunnen authenticeren. Als alternatief kan ook gebruikgemaakt worden van andere instellingen. Hierover lees je verderop in dit hoofdstuk meer. [homes]
Door een willekeurige naam tussen blokhaken te zetten en volledig links uit te lijnen wordt een nieuwe share gedefinieerd. Vergelijk dit bijvoorbeeld ook met de shares [administratie] en [delivery]. comment = Home Directories
Dit is de aanduiding voor de share die in de netwerkomgeving zichtbaar wordt. valid users = %S Met de parameter valid users
kan aangegeven worden welke gebruikers toegang hebben tot een share. De waarde %S staat voor alle gebruikers die een account hebben. Als alternatief kunnen hier ook namen van gebruikers gespecificeerd worden. Wanneer de permissies op Linux-niveau goed geregeld zijn, is gebruik van deze parameter in feite overbodig.
8 Bestanden delen met Linux
303
browseable = no
Door in de share de optie browseable op no te zetten wordt bepaald dat de share niet getoond wordt in het overzicht van beschikbare shares. Dit is vooral nuttig wanneer het gaat om de share die toegang geeft tot de homedirectory’s. Zo voorkom je namelijk dat gebruikers naar elkaars homedirectory gaan browsen. De gebruikers zullen overigens wel hun eigen gedeelde homedirectory terugvinden in hun netwerkomgeving. writeable = yes
Hiermee wordt bepaald dat gebruikers gewoon read/write-toegang hebben tot de bestanden als hun Linux-permissies dat ook toestaan. Ze mogen dus bestanden in de share maken en bestanden die in de share voorkomen kunnen gelezen worden. create mask = 0660
Met deze parameter worden de standaardpermissies voor nieuw aan te maken bestanden ingesteld. Hierbij wordt de permissie read vertegenwoordigd door de waarde 4, write is 2 en execute is 1. Het eerste getal kan verwaarloosd worden. Het tweede getal verwijst naar de permissies van de owner, het derde getal naar de permissies van de groep en het laatste getal naar de permissies van de rest van de wereld. Let vooral even op het gebruik van deze instelling bij de gedeelde directory’s: door hier 0660 te specificeren wordt bepaald dat iedereen die lid is van de betreffende groep alles mag met de bestanden in de directory. Voor gedeelde groepsdirectory’s is dat waarschijnlijk ook de bedoeling. Wanneer je echter deze instelling gebruikt op de homedirectory’s van de gebruikers, loop je het risico dat deze daar iets minder blij mee zijn. directory mask = 0750 Zelfde functie als het create mask,
maar dan toegepast op direc-
tory’s die worden gemaakt. Wanneer je handmatig met behulp van een editor een Samba-configuratiebestand maakt, loop je natuurlijk het risico dat dit bestand door een typefout niet gebruikt kan worden. Het is daarom handig om even een controle uit te voeren op het bestand voordat je de Samba-server start. Gebruik hiervoor de opdracht testparm. Deze opdracht voert een controle uit of de syntaxis van het bestand in orde is.
304
Linux 4
Figuur 8.4 Met behulp van de opdracht testparm kun je controleren of er geen syntaxisfouten voorkomen in het Sambaconfiguratiebestand
7. Opstarten van de daemons Wanneer je de hiervoor genoemde stappen succesvol hebt uitgevoerd, hoeven alleen nog de daemons opgestart te worden. Gebruik hiervoor de scripts in de directory /etc/init.d van de server. 8.3.4 Samba als PDC Tot nu toe heb je kunnen lezen over de Samba-server in een omgeving met werkgroepen. Het werkgroepmodel is echter voor professionele omgevingen niet de meest ideale oplossing. In dat soort omgevingen is het aan te raden de Samba-server te installeren als Domain Controller. Dit biedt onder andere het voordeel dat je de werkomgeving van de gebruiker veel beter kunt vormgeven. Door middel van loginscripts zorg je ervoor dat bepaalde zaken automatisch geregeld worden wanneer de gebruiker zich aanmeldt. Daarnaast kun je gebruikmaken van roaming profiles die ervoor zorgen dat de voorkeursinstellingen van de gebruiker altijd beschikbaar zijn, waar op het netwerk hij zich ook aanmeldt. Je kunt hier lezen hoe je de Samba-server aan kunt maken als Windows NT 4-stijl Domain Controller. Voor integratie van de Samba-server in een omgeving waarin Active Directory gebruikt wordt, kun je de volgende paragraaf lezen. Je kunt er overigens meteen alvast rekening mee houden dat het met Samba versie 3 niet mogelijk is een Samba-server in te zetten als Domain Controller in een Active Directory-omgeving.
8 Bestanden delen met Linux
305
De rol van de Domain Controller Wanneer je Samba inzet als Domain Controller, maak je gebruik van een configuratiemethode die door Microsoft werd toegepast in Windows NT 4.0. Hierbij is de Domain Controller de server waarop alle gegevens worden bijgehouden die nodig zijn om aan te kunnen melden op een netwerk. Windows NT 4.0 maakt hiervoor gebruik van twee verschillende soorten servers: de PDC en de BDC. De Primary Domain Controller (PDC) is de server in het netwerk die de hoofdrol speelt. Wanneer je gegevens van gebruikers wilt kunnen aanpassen, heb je altijd deze PDC nodig. Vanuit de optiek van fouttolerantie wordt naast de PDC ook gebruikgemaakt van een Backup Domain Controller (BDC). Deze vervult twee taken. Als eerste maakt de BDC het mogelijk om gegevens over het netwerk te verspreiden. Hierdoor kan het voor een gebruiker eenvoudiger gemaakt worden om te authenticeren, omdat de netwerkgegevens zich dichter bij hem bevinden. Daarnaast functioneert de BDC als reservekopie van de PDC. Dit betekent dat de BDC in staat is het werk van de PDC over te nemen. Dit gaat echter niet zondermeer. Om een BDC te verheffen tot PDC moet je hem ‘promoveren’. In een Windows-omgeving maak je hiervoor gebruik van de opdracht dcpromo. Deze opdracht bestaat echter niet onder Linux. Wanneer je Samba als Domain Controller inricht, moet je er rekening mee houden dat de Samba-server niet opgenomen kan worden in een bestaand Windows NT 4-netwerk waarin al Domain Controllers voorkomen. Samba kan namelijk niet communiceren met Windows NT Domain Controllers. Wel is het mogelijk voor een Samba PDC om te communiceren met Samba BDC’s. Voor meer informatie hierover verwijzen we naar de Samba-BDCHOWTO die je onder andere op www.tldp.org kunt raadplegen. De configuratie van de Samba-PDC Uiteraard moet je om een Samba-PDC te maken het configuratiebestand smb.conf bewerken. Houd er rekening mee dat de wijze waarop je de PDC configureert afhankelijk is van het type werkstation dat je gebruikt. In een omgeving met alleen Windows 9x heb je een andere configuratie nodig dan in een omgeving met Windows NT-, 2000- en XP-werkstations. In het volgende voor-
306
Linux 4
beeld vind je een configuratie die geoptimaliseerd is voor een omgeving waarin gebruikgemaakt wordt van Windows 2000/XPwerkstations. [global] netbios name = samba workgroup = MYDOMAIN os level = 99 encrypt passwords = yes log file = /var/log/samba/%m debug level = 1 socket options = SO _ KEEPALIVE IPTOS _ LOWDELAY TCP _ NODELAY wins support = yes character set = ISO8859-15 client code page = 850 veto files = /*.eml/*.nws/riched20.dll/*.{*}/ time server = yes domain master = yes local master = yes preferred master = yes domain admin group = root domain logons = yes security = user logon script = %U.bat logon path = \\%L\profiles\%u\%m logon home = \\%L\%u\.win _ profile\%m logon script = logon.bat logon drive = H: add user script = /usr/sbin/useradd –d /dev/null –g 100 –s /bin/ false %u
[netlogon] comment = Network Logon Service path = /usr/local/netlogon writable = no browsable = no
8 Bestanden delen met Linux
307
[profiles] path = /home/sambaprofiles browsable = no writable = yes create mask = 0600 directory mask = 0700 [homes] read only = no browsable = no guest ok = no map archive = yes
Deze configuratie zorgt ervoor dat je een volledig werkende Samba-server kunt instellen als PDC. We zullen niet alle parameters bespreken, maar ons vooral richten op die instellingen die relevant zijn voor een Samba-PDC. Veel van deze instellingen heb je al eerder in dit hoofdstuk gezien. De configuratie bestaat in dit geval naast de sectie [global] uit drie andere secties. Ten eerste is dat [netlogon] waarin geregeld wordt dat gebruikers toegang krijgen tot hun logonscript. Met dit script kun je ervoor zorgen dat bepaalde instellingen automatisch worden uitgevoerd wanneer de gebruiker zich aanmeldt. Vervolgens wordt in [profiles] de toegang tot de profielen van de gebruikers geregeld en tot slot is er de sectie [homes] waarin geregeld wordt dat gebruikers ook toegang krijgen tot hun homedirectory’s. Afhankelijk van de werkwijze die je wilt gebruiken, zou je ook zonder deze laatste drie secties kunnen werken. Pas dit dus aan naar eigen behoefte. De eerste parameter die opvalt in de sectie global is netbios name = samba. Hiermee wordt de naam ingesteld waarmee je de Samba-server in de netwerkomgeving van de clientcomputers zult terugvinden. Vervolgens is er een aantal instellingen waarmee bepaald wordt dat de Samba-server ‘de baas’ is in het netwerk. Om te beginnen moet de Samba-server onder alle omstandigheden de verkiezing van de master browser winnen. De parameter os level = 99 zorgt hiervoor. Het effect hiervan is dat de Samba-server het browseproces in het netwerk beheert en er dus voor zorgt dat an-
308
Linux 4
dere computers zichtbaar kunnen worden in de netwerkomgeving. Het is belangrijk deze taak over te laten aan de Samba-server. Als namelijk een normale Windows-computer de verkiezing van Master Browser zou winnen, bestaat het risico dat je de Sambaserver nooit in de netwerkomgeving van de computers terugvindt. Een volgende parameter die opvalt is time server = yes. Je raadt het waarschijnlijk al: met behulp van deze instelling zorg je ervoor dat de Samba-server de tijd op het netwerk bepaalt. De werkstations halen de tijd op bij de Samba-server en wanneer de Samba-server vervolgens door middel van NTP de tijd ophaalt bij een internettijdserver, zorgt dit ervoor dat overal op het netwerk dezelfde tijd gebruikt wordt. Dit is zeer aan te raden. Op deze manier kunnen ook toepassingen die op een of andere manier afhankelijk zijn van de juiste netwerktijd hun werk goed doen. Dan komen er weer enkele instellingen die ermee te maken hebben dat de Samba-server de browserverkiezingen op het netwerk wint. De parameter domain master = yes zorgt ervoor dat de Sambaserver Domain Master Browser wordt. Dit betekent dat de Sambaserver ook in een domein dat uit verschillende fysieke netwerken bestaat, de browserservices kan verschaffen. Met de parameter local master = yes wordt aangegeven dat de Samba-server meedoet in de browserverkiezingen en ook in staat is deze te winnen. De regel set preferred master zorgt er in combinatie met het os-level voor dat de Samba-server de verkiezing van de masterbrowser ook wint. Interessant om te weten: door middel van set preferred master = yes wordt ervoor gezorgd dat er direct na het starten van de Samba-server een browserverkiezing geforceerd wordt die de Samba-server vervolgens ook gaat winnen. Vervolgens zijn er twee regels die ervoor zorgen dat de Samba-server zijn werk als PDC kan doen: security = user domain logons = yes
De regel security = user komt misschien als een verrassing aangezien er ook een optie is om de security in te stellen op domain. Er is echter een belangrijk verschil tussen beide. Met de regel security = domain zorg je ervoor dat een andere PDC gebruikt wordt als domain controller. Deze instelling is dus uitstekend wan-
8 Bestanden delen met Linux
309
neer je de authenticatie van gebruikers wilt laten afhandelen door een andere Samba-server of een Windows-PDC. Als je er echter voor wilt zorgen dat de Samba-server zich als PDC gaat gedragen, gebruik je altijd de instelling security = user. Met de regel domain logons = yes vervolgens vertel je aan deze Samba-server dat hij het werkstations mogelijk moet maken in te loggen op het domain. Vervolgens komt er een aantal instellingen waarin geregeld wordt dat de gebruikersomgeving op de juiste wijze gedefinieerd wordt: logon script = logon.bat logon path = \\%L\profiles\%u\%m logon home = \\%L\%u\.win _ profile\%m logon drive = H:
Om te beginnen wordt het logonscript logon.bat aangeroepen. Dit is een MS-DOS-batchfile waarin opdrachten staan die ervoor zorgen dat de gebruikersomgeving wordt vormgegeven. Hierbij kun je onder andere denken aan een aantal netwerkverbindingen die automatisch worden gemaakt. De regels waarin het logon path en de logon home gedefinieerd worden, zorgen er vervolgens voor dat op de juiste wijze verwezen wordt naar de locatie waar de roaming profiles met daarin de instellingen van de gebruiker bewaard worden. De regel komt in twee varianten voor: dit is nodig om zowel aan Windows 9x-gebruikers (logon home) als aan Windows NTen latere gebruikers (logon path) de juiste ondersteuning te geven. Door middel van variabelen wordt verwezen naar de precieze directory’s die verderop in het configuratiebestand gedefinieerd worden. Bovendien zorgt de variabele %u ervoor dat voor iedere gebruiker naar een aparte directory verwezen wordt. In deze directory wordt vervolgens het profile van de gebruiker neergezet. Dit profile heeft voor Windows NT en later standaard de naam NTprofile.dat en moet beschrijfbaar zijn voor gebruikers. Mocht het nodig zijn om de gebruikers iedere keer met vaste instellingen te confronteren, dan kun je als beheerder de naam van dit bestand wijzigen naar NTprofile.man. Je maakt er zo een mandatory profile van dat door gebruikers niet gewijzigd kan worden. Tot slot is er in deze verzameling instellingen de aanduiding waarmee de logon-drive voor gebruikers geregeld wordt. Hiermee zorg
310
Linux 4
je ervoor dat de gebruiker vanuit de Windows Verkenner automatisch een driveletter H: ziet die verwijst naar de homedirectory van de gebruiker. Deze parameter is optioneel, maar voor een gebruiker is het wel erg prettig als hij bestaat. Als laatste in de sectie [global] is er de parameter add user script. Hiermee zorg je ervoor dat op het lokale Linux-systeem automatisch een gebruiker gemaakt wordt wanneer deze nog niet bestaat. Wanneer je gebruikmaakt van deze parameter, moet je er zeker van zijn dat de authenticatie op de Samba-server betrouwbaar is. Wanneer het voorkomt dat een gebruiker wél op de Samba-server kan authenticeren, maar niet bestaat in de lokale gebruikersconfiguratiebestanden op de Linux-machine, treedt dit script in werking. In het voorbeeld add user script = /usr/ bin/useradd –d /dev/null –g 100 –s /bin/false %u wordt op de Linux-server een lokale gebruiker gemaakt die daar verder ook helemaal niets kan. Met de optie –d /dev/null wordt zijn homedirectory doorgelust naar het null-device, hij krijgt als shell de niet-shell /bin/false toegewezen. Dit laatste zorgt ervoor dat de gebruiker niet in staat is lokaal in te loggen op de Linux-machine. Het enige wat wel geregeld wordt, is dat de gebruiker automatisch lid gemaakt wordt van de groep met GID 100. In de meeste gevallen wordt deze GID gebruikt voor een algemene groep waarvan alle gebruikers lid zijn. Uiteraard kun je de opdracht waarmee een gebruiker wordt gemaakt ook zo instellen dat de gebruiker op de lokale Linux-computer ook wat kan. Je moet je echter afvragen of dit wenselijk is. Wij denken dat het nuttig kan zijn een gebruiker een eigen homedirectory te geven, maar dat er voor de meeste Windows-gebruikers geen enkele reden is in te kunnen loggen met een shellaccount op de Linux-server. Als tweede onderdeel moet een aantal shares gemaakt worden. Om te beginnen is dat de share [netlogon]. De gebruiker doet hier verder praktisch weinig mee, maar de share moet bestaan om een succesvolle domain-logon te kunnen doen. Daarnaast kan deze share gebruikt worden om logonscripts en systeempolicybestanden te plaatsen. Let er wel op dat de share niet toegankelijk en zeker niet beschrijfbaar hoeft te zijn voor gebruikers. Om die reden hebben zowel de parameter writable als browsable de waarde no.
8 Bestanden delen met Linux
311
De tweede share die wordt gemaakt, is de locatie waar de profielen van de gebruikers geplaatst kunnen worden. Dit zijn de zogenoemde roaming profiles die ervoor zorgen dat de gebruiker op elke pc waarop hij zich aanmeldt, gebruik kan maken van dezelfde desktopinstellingen. Deze share is nodig voor gebruikers die vanaf een Windows NT, 2000- of XP-werkstation binnenkomen. De share hoeft niet browsable te zijn, maar hij moet wel beschrijfbaar zijn voor de gebruikers. Anders zouden gebruikers immers niet in staat zijn om wijzigingen in hun profiel op te slaan. De instellingen voor het create mask en het directory mask zorgen ervoor dat de gebruiker als enige toegang heeft tot zijn profiel. Als laatste wordt er een share gedefinieerd voor de homedirectory van de gebruiker. Deze share is nodig voor de verwijzingen die gedaan worden door de parameters logon drive en logon path. Houd er rekening mee dat gebruikers ook daadwerkelijk op het lokale Linux-bestandssysteem een homedirectory moeten hebben, anders werkt het nog niet. Dat betekent dat het voorbeeld dat eerder gegeven is voor de parameter add user script in dit geval niet handig is. De optie –d /dev/null zorgde er immers voor dat het null-device als homedirectory gebruikt werd. Om te kunnen werken met profielen is het om die reden aan te raden gebruik te maken van een add user script dat wel een homedirectory maakt, bijvoorbeeld add user script = /usr/sbin/useradd –m –g 100 –s /bin/false %u. Hierbij zorgt de optie –m ervoor dat op de standaardlocatie een homedirectory wordt gemaakt die dezelfde naam heeft als de gebruiker zelf. Wanneer je alle hierboven beschreven wijzigingen hebt aangebracht, kun je met de opdracht testparm controleren of er geen fouten voorkomen in smb.conf. Als dit het geval is, kun je de server opnieuw starten. Gebruik hiervoor als root de opdracht /etc/ rc.d/init.d/smb restart. Tip! Wanneer je de opdracht /etc/init.d/smb restart uitvoert, weet je zeker dat de nieuwe configuratie meteen wordt geactiveerd. Het kan ook eenvoudiger: gewoon een minuutje wachten, dan zorgt Samba er in versie 3 voor dat de wijzigingen vanzelf geactiveerd worden.
312
Linux 4
Aanpassen van de configuratie van de werkstations Op basis van het voorgaande heb je ervoor gezorgd dat de Sambaserver zich als PDC gedraagt. Je bent er echter nog niet helemaal. Om gebruik te maken van de Samba-PDC moet namelijk voor elke computer een computeraccount worden gemaakt. Hiervoor zijn drie stappen nodig. Als eerste moet je in /etc/passwd een account maken voor elke computer die in het netwerk voorkomt. Vervolgens moeten deze computeraccount met de opdracht smbclient worden toegevoegd aan de database waarvan de Sambaserver gebruikmaakt. Als dat gedaan is, moet tot slot op de Windows-computer een aantal instellingen gewijzigd worden om ervoor te zorgen dat deze aanmeldt op het domein dat je op de Samba-PDC gedefinieerd hebt. 1. De computeraccounts maken Om computeraccounts aan te kunnen maken heb je een domain administrator nodig. Het is niet voldoende dat je op het lokale Linux-systeem al een gebruiker hebt met de naam root, je moet op de Samba-server een soortgelijke gebruiker hebben. Voordat je computers kunt maken, moet je eerst deze gebruiker definiëren. Dit doet je met de opdracht smbpasswd –a root. Als dit gebeurd is, kun je de computeraccounts maken in de lokale gebruikersdatabase op de Linux-server. Hiervoor maak je gebruik van de NetBIOS-namen zoals deze bekend zijn op de Windows-werkstations. Je kunt deze naam als volgt achterhalen: 1. Klik met de rechtermuisknop op Deze Computer. 2. Selecteer de optie Eigenschappen. 3. Activeer nu het tabblad Computernaam. Deze naam heb je nodig. Nu moet je deze computernaam toevoegen aan de gebruikersdatabase op de Samba-server. Houd daarbij rekening met de volgende zaken: Elke computer moet een unieke UID hebben. Je kunt dit bereiken door de computeraccounts toe te voegen met een opdracht als useradd. Deze opdracht zorgt er namelijk voor dat UID’s automatisch gegenereerd worden. Ook computers moeten lid zijn van een groep. Het is aan te raden voor dit doel een aparte groep aan te maken in /etc/group. Zorg ervoor dat de computers geen wachtwoord, homedirectory of
8 Bestanden delen met Linux
313
shell hebben. Als dit wel het geval is, zou een hacker er namelijk misbruik van kunnen maken. De naam van elke computer moet eindigen op een dollarteken. Als dit niet het geval is, kan de account niet als computeraccount herkend worden. Om bijvoorbeeld de computer x-tina een computeraccount te geven op de Samba-server, zou je de opdracht useradd –d /dev/null –g 400 –s /bin/false x-tina$ kunnen gebruiken. Hierbij wordt er overigens wel van uitgegaan dat op dat moment reeds een groep met GID 400 op het systeem aanwezig is. Gebruik hiervoor eventueel de opdracht groupadd. 2. Voeg de computeraccounts toe aan de Samba-gebruikersdatabase Je herinnert je wellicht dat het niet voldoende is om een lokale gebruiker te maken op een Linux-systeem als je met de Samba-server wilt werken. Windows-computers en gebruikers melden zich namelijk aan op een manier die door het Linux-loginmechanisme niet begrepen wordt. In jargon heet het dat Windows gebruikmaakt van andere credentials. Om die reden moet er wanneer op de Sambaserver de parameter security=user gebruikt wordt, een aparte gebruikersdatabase gedefinieerd worden op de Samba-server. In deze gebruikersdatabase moeten ook de Windows-computeraccounts voorkomen. Hiervoor gebruik je de opdracht smbclient. Met de opdracht smbclient –m –s x-tina kun je de computer uit het voorgaande voorbeeld toevoegen aan deze database. In deze opdracht geeft de optie –m aan dat het om een computeraccount gaat, de optie –s zorgt ervoor dat eventuele wachtwoorden vanaf de console ingevoerd kunnen worden. Let erop dat in dit geval de naam van de computeraccount niet beëindigd hoeft te worden met een dollarteken, je hebt immers –m gebruikt om aan te geven dat je een computeraccount wilt maken. 3. Windows aanpassen voor aanmelden op het domein De laatste stap is Windows aanpassen om aan te laten melden op het domein. Let even op: het is hierbij belangrijk welke Windowsversie je gebruikt. De werkwijze is namelijk per Windows-versie verschillend. Ook moet je er rekening mee houden dat Windows XP Home Editie geen mogelijkheid heeft aan te melden op een domein. Alle andere Windows-versies sinds Windows 98 hebben deze mogelijkheid wel. Als op een of meerdere computers in het
314
Linux 4
netwerk gebruikgemaakt wordt van Windows XP Home Editie, zou je dus kunnen overwegen hier een ander besturingssysteem te installeren. Gebruik bijvoorbeeld een Linux-desktopbesturingssysteem want Linux kan uitstekend als Samba-client geconfigureerd worden. Je kunt hier lezen hoe je Windows XP Professional aan kunt laten loggen op een domein. Windows XP Professional 1. Klik op Start en selecteer vervolgens het Configuratiescherm. Zorg ervoor dat hier de klassieke weergave actief is. 2. Dubbelklik op Systeem om de eigenschappen van de computer te openen. 3. Activeer nu het tabblad Computernaam en klik hier op Network ID. De Network Identification Wizard wordt nu gestart. Klik op Volgende om te beginnen. 4. Selecteer nu de optie Deze computer maakt deel uit van een zakelijk netwerk en klik op Volgende. 5. Nu kies je de optie Mijn computer gebruikt een netwerk met een domein. Lees het overzichtsscherm en klik op Volgende. 6. Er verschijnt nu een scherm waarin je zichzelf als gebruiker bekend kunt maken. Hier moet je eenmalig inloggen als domain administrator. Dit is de gebruiker root die je in het begin van de procedure hebt opgegeven. Voer het wachtwoord van deze gebruiker in en de naam van het domein waarop je aan wilt melden. 7. Start nu de computer opnieuw op. Er verschijnt een domeinloginprompt waarmee je je kunt aanmelden op het domein. 8.3.5 Een Samba-server integreren in Active Directory Samba kan ingericht worden als PDC of BDC. Over die eerste mogelijkheid heb je in de voorgaande paragrafen kunnen lezen. Sinds versie 3.0 van de Samba-server kan een Samba-server ook als Member-server opgenomen worden in een Windows-netwerk waarin Active Directory gebruikt wordt. Let wel even goed op voordat je overenthousiast aan het werk gaat: je hebt nog steeds Windows 2000-servers nodig die de rol van Domain Controller vervullen. Het enige wat je met Samba kunt doen, is de Sambaserver lid maken van Active Directory. Dit betekent dat gebruikers kunnen authenticeren op Active Directory en vervolgens toegang kunnen krijgen tot gedeelde resources op de Samba-server. Dit is vooral handig wanneer Samba in een netwerk naast Windowsservers gebruikt wordt. Om een Samba-server in te haken op een
8 Bestanden delen met Linux
315
Active Directory-omgeving moet je hem eerst lid maken van het domein. Samba lid maken van een Active Directory Domain Om Samba te integreren met Active Directory moet je de Sambaserver lid maken van het domein. In feite is dit een simpele procedure die slechts uit vier stappen bestaat. Aangezien heel veel al besproken is, kun je in het volgende beknopt lezen hoe je te werk moet gaan. 1. Maak een Active Directory-gebruiker op de Windows 2000-server. Wat we uiteindelijk willen, is immers als Active Directorygebruiker toegang krijgen tot een share die op een Samba-server gedefinieerd is. Dit betekent dat je alle Samba-gebruikers in Active Directory moet maken. AD is het primaire mechanisme waarop gevalideerd wordt. 2. Zorg ervoor dat de Samba-gebruiker als Linux-gebruiker bestaat en regel de permissies. Zoals onder alle omstandigheden geldt, moet je er ook in dit scenario voor zorgen dat op de Samba-server een gebruiker bestaat die permissies heeft op de share die je wilt delen. Dit betekent dat je hem in /etc/passwd moet maken en dat hij ook permissies moet krijgen. Je kunt als alternatief ook gebruikmaken van een van de opties om deze account automatisch te laten maken, maar in kleine omgevingen echter is het zinnig dit handmatig te doen omdat je er dan meer controle over hebt. 3. Pas smb.conf aan. Uiteraard moeten ook in dit geval enkele regels toegevoegd worden aan smb.conf. Dit bestand is immers de enige locatie waar je de totale configuratie van de Samba-server regelt. Het gaat hier om de volgende regels: [global] workgroup = NWTRADERS password server = IPadres van je 2000 server security = ADS
Met de eerste regel maak je de Samba-server lid van het active Directory Domain dat in dit geval NWTRADERS heet. Vervolgens verwijs je met de regel password server naar de server waarop de authenticatie moet worden afgehandeld. Gebruik hiervoor het IP-adres van de Windows 2000 Domain Controller. Tot slot geef je aan dat nu eens voor de verandering gebruik moet
316
Linux 4
worden gemaakt van ADS (Active Directory Services) om de beveiliging af te handelen. 4. Voeg de Samba-server toe aan Active Directory. Net als in het geval waar je Samba als PDC configureert, heb je ook bij het gebruik van Active Directory een computeraccount nodig. Deze computeraccount moet vanaf de Samba-server worden gemaakt in Active Directory. Hiervoor maak je gebruik van de zeer veelzijdige opdracht net. Met deze opdracht kun je toveren vanaf een Sambaserver en het is absoluut de moeite waard hier eens de man-pagina van door te bladeren. In dit geval gebruik je de opdracht net ads join -U Administrator%password. Zoals te raden valt, maak je hiermee een computeraccount voor de server in AD. Let erop dat achter de optie –U naam en wachtwoord gebruikt worden van een beheerdersaccount in Active Directory die voldoende permissies heeft om daar een computeraccount te maken. Het resultaat van dit alles is dat je in Active Directory een computeraccount voor de Samba-server ziet verschijnen. De Samba-server is nu lid van Active Directory. Het resultaat hiervan is dat je met de credentials uit de Windows-omgeving shares kunt benaderen die door de Samba-server worden aangeboden. Samba met Kerberos authenticeren op het domein In het voorgaande heb je gebruikgemaakt van normale wachtwoordauthenticatie om de Samba-server toe te voegen aan het Active Directory-domain. Het kan ook beter: met Kerberos vindt de authenticatie op een veel slimmere manier plaats, omdat gebruikgemaakt wordt van encryptie en Kerberos-tickets ter identificatie. Het voordeel hiervan is dat er geen wachtwoorden uitgelezen kunnen worden wanneer deze over het netwerk verstuurd worden. Kerberos-authenticatie zorgt er namelijk voor dat er helemaal geen wachtwoorden verstuurd hoeven worden. Om dit voor elkaar te krijgen voer je drie stappen uit. 1. Pas smb.conf aan. Deze keer gaat het om de volgende regels. Het belangrijke verschil met het voorgaande is dat er een Kerberosrealm toegevoegd wordt die nodig is voor het uitwisselen van Kerberos-tickets. [global] workgroup = NWTRADERS
8 Bestanden delen met Linux
317
realm = NWTRADERS.MSFT ads server = IPadres van je 2000 server security = ads
2. Haal de initiële Kerberos-tickets op. Wanneer smb.conf op de juiste wijze is gemaakt, moet je ervoor zorgen dat de benodigde Kerberos-tickets op de Samba-server bekend zijn. Dit doe je met behulp van de opdracht kinit [email protected]. 3. Voeg de Samba-server toe aan Active Directory. Hiervoor gebruik je de opdracht net ads join. Dit zorgt ervoor dat de server wordt toegevoegd aan AD. Het voordeel van dit alles? Op de achtergrond kan nu het geavanceerde protocol Kerberos gebruikt worden en het is niet meer nodig dat voortdurend wachtwoorden heen en weer gestuurd worden. Op deze wijze wordt er veel veiliger geauthenticeerd. De wereld op zijn kop: Linux-gebruikers loggen in op Active Directory Het gaat er in dit hoofdstuk om dat Windows-gebruikers gebruik kunnen maken van gedeelde bronnen op een Samba-server. Dit betekent dat je op de Linux-server een voorziening moet treffen die het voor de Windows-gebruikers mogelijk maakt daarop in te loggen. Dit scenario leent zich vooral in een omgeving waar op de servers voornamelijk gebruikgemaakt wordt van Linux als besturingssysteem. Soms echter is het tegenovergestelde het geval en komt er binnen een omgeving die vooral uit Windows-servers bestaat een Linux-server voor. In zo’n omgeving zullen alle gebruikersaccounts bijgehouden worden in Active Directory. In principe moet je voor gebruikers die ook iets moeten doen op de Linux-computer een aparte account maken op deze computer. Niet echt handig, want dat geeft je als beheerder dubbel werk. Gelukkig is het met behulp van winbind mogelijk om dit dubbele werk te voorkomen. Je maakt dus in Active Directory een gebruiker en zorgt ervoor dat je vanaf een Linux-machine als deze gebruiker kunt aanmelden zonder dat de gebruiker ook daadwerkelijk op de Linux-server bestaat. Voer hiervoor de volgende stappen uit. 1. Maak de gebruiker in Active Directory 2. Pas nsswitch.conf aan. In het configuratiebestand /etc/nsswitch. conf wordt bepaald in welke volgorde belangrijke configuratiebestanden gebruikt moeten worden. Dit configuratiebestand stamt uit het tijdperk dat nog niet zo intensief gebruikgemaakt werd van
318
Linux 4
PAM. Voor services die niet met PAM overweg kunnen, moet je er in dit bestand voor zorgen dat tijdens de authenticatie eerst gekeken wordt naar het winbind-mechanisme en pas daarna naar de traditionele UNIX-gebruikersbestanden. Je kunt dit aangeven door de volgende regels op te nemen in nsswitch.conf Passwd:
winbind compat
Group:
winbind compat
3. Wijzig de PAM-configuratie. De meeste moderne services maken niet langer gebruik van nsswitch.conf, maar van het PAM-mechanisme. Om ervoor te zorgen dat gebruikers die met PAM inloggen zich kunnen aanmelden op Active Directory, neem je in het begin van het configuratiebestand een regel op die ervoor zorgt dat iedereen die zich aanmeldt op Active Directory ook welkom is op het Linux-systeem. Gebruik hiervoor de volgende regel: auth
sufficient
pam _ winbind.so
Deze regel moet als allereerste regel worden opgenomen in het bestand /etc/pam.d/login. Vergeet ook niet te controleren of de PAMmodule pam_winbind.so wel op het systeem voorkomt. 4. Pas smb.conf aan. Je maakt straks gebruik van de Winbind-service. Deze service is gerelateerde aan de Samba-server. Dit betekent dat de totale configuratie van deze service ook geregeld wordt in het Samba-configuratiebestand smb.conf. Je regelt dit met de volgende parameters. Deze parameters zorgen ervoor dat voor elke gebruiker die via het Winbind-mechanisme binnenkomt, automatisch de juiste credentials op het systeem worden gemaakt. Je kunt de regels uit het voorbeeld hieronder gewoon letterlijk overnemen. Voor meer uitleg over de exacte betekenis van deze regels kun je de man-pagina van smb.conf raadplegen. [global] winbind separator = + winbind cache time = 15 template shell = /bin/bash idmap uid = 10000-20000 idmap gid = 10000-20000 template homedir = /home/%U winbind uid = 1000-20000
8 Bestanden delen met Linux
319
winbind gid = 1000-20000 workgroup = NWTRADERS
5. Start winbindd. Wanneer alle noodzakelijke voorzieningen getroffen zijn, moet je ervoor zorgen dat Winbind actief wordt op de Linux-server. Hiervoor maak je gebruik van de Winbind-daemon (winbindd). Je kunt deze service starten vanuit /usr/sbin, maar je kunt hem ook activeren met behulp van het script dat voorkomt in de directory /etc/init.d. Wanneer dit gebeurd is, voldoe je aan alle voorwaarden en kun je op de Linux-prompt inloggen op Active Directory. 6. Controleer de werking. Als je alle bovenstaande stappen doorlopen hebt, kun je uitproberen of het werkt. Dit doe je door op de Linuxloginprompt in te loggen als een Active Directory-gebruiker. Let even op de syntaxis die daarvoor nodig is: je geeft als eerste de naam van het domein waarop je inlogt, vervolgens een + en tot slot de naam van de gebruiker als wie je wilt inloggen. Dat betekent dat gebruiker melissa uit het domein NWTRADERS zich aanmeldt als NWTRADERS+melissa. Vind je het +-teken niet elegant? Geen nood: dit is heel eenvoudig te wijzigen. In smb.conf wordt met behulp van de parameter winbind separator bepaald welk teken gebruikt moet worden om de domeinnaam en gebruikersnaam van elkaar te scheiden. Wil je hiervoor een uitroepteken, &-teken of ander teken gebruiken, dan regel je dat in een handomdraai met deze parameter. 7. Problemen? Lukt het niet op de manier die hiervoor beschreven is? Verzeker je er dan van dat de Linux-server waarop je inlogt wel een computeraccount heeft in Active Directory. Is dit niet het geval? Geef dan op de Linux-server de opdracht net ads join om hem alsnog lid te maken van AD. 8.3.6 Authenticatie op een andere server In het voorgaande heb je gelezen over de werkwijzen die je kunt volgen om te authenticeren op iets anders dan de lokale Samba-gebruikersdatabase. Deze authenticatiemethode wordt geregeld met behulp van de parameter security = in de sectie [global] van smb.conf. Er is nog een werkwijze die we niet besproken hebben. Het is namelijk ook mogelijk te authenticeren op een andere server. Hiervoor wordt gebruikgemaakt van de parameter security = server. Met behulp van deze instelling kun je je bijvoorbeeld aanmelden bij een andere Samba-server of bij een Windows NT-
320
Linux 4
server. Het nut daarvan ligt voor de hand. Wanneer in het netwerk gebruikgemaakt wordt van meerdere Samba-servers, voorkom je met deze parameter dat je op elke Samba-server een aparte Sambagebruikersdatabase moet maken. Naast de parameter security = server, moet je natuurlijk ook aangeven op welke server er dan geauthenticeerd moet worden. Gebruik hiervoor de optie password server =. In het volgende voorbeeld zie je twee regels die voor dit doel opgenomen kunnen worden in smb.conf. [global] security = server password server = laksmi damayanti
Houd er rekening mee dat je met behulp van deze instelling voor Samba-gebruikersnamen gaat informeren op een andere server. Het is echter nog steeds noodzakelijk dat op elk van die servers wel een Linux-gebruiker bestaat met de benodigde permissies op het Linux-bestandssysteem. Als je geen zin hebt deze Linux-gebruikers overal handmatig te maken, zou je gebruik kunnen maken van een service als NIS of LDAP. 8.3.7 Grafische hulpprogramma’s voor configuratie In het voorgaande heb je kunnen lezen over de manier waarop Samba geconfigureerd kan worden. Hierbij hebben we vrijwel uitsluitend gekeken naar de beheermogelijkheden die geboden worden door het configuratiebestand smb.conf direct aan te passen. Dit is echter niet de enige mogelijkheid. Als onderdeel van de Samba-server wordt standaard ook de component SWAT (Samba Web Administration Tool) meegeleverd. Daarnaast worden door de verschillende distributies ook de nodige mogelijkheden geboden. Deze tools staan echter in geen verhouding tot de mogelijkheden die SWAT biedt. Waar je met SWAT gewoon alle instellingen vanuit een grafische interface kunt regelen, beperken zowel Fedora als SUSE zich tot grafische hulpprogramma’s waarmee alleen het hoognodige kan. Voordat je SWAT kunt gebruiken, zul je het eerst aan moeten zetten. De mogelijkheid de Samba-server met behulp van SWAT te beheren, wordt geleverd vanuit inetd of xinetd. Dit betekent dat je ervoor moet zorgen dat de service vanuit dit mechanisme ook beschikbaar is. Je moet in elk geval het bestand /etc/services aanpas-
8 Bestanden delen met Linux
321
sen om de SWAT-service bekend te maken. De volgende stap is afhankelijk van de configuratie die je gebruikt: ofwel je definieert in inetd.conf een regel om de service te starten of je zorgt ervoor dat er een SWAT-configuratiescript aanwezig is voor xinetd. Wanneer dit gebeurd is, moet je inetd of xinetd opnieuw starten. Vervolgens is SWAT klaar voor gebruik. 1. /etc/services aanpassen Om SWAT te kunnen starten moet de service bekend zijn. Pas hiervoor het configuratiebestand /etc/services aan en neem er de volgende regel in op: swat
901/tcp
2a. Pas inetd.conf aan Wanneer je gebruikmaakt van inetd, moet je het configuratiebestand /etc/inetd.conf aanpassen om ervoor te zorgen dat SWAT benaderd kan worden. Neem hiervoor de volgende regel op in dit bestand: swat
stream tcp
nowait root
/usr/sbin/swat swat
In de meeste gevallen zal deze regel uitstekend zijn werk doen, maar het kan soms nodig zijn om de locatie van het SWAP-programmabestand aan te passen. Nadat je inetd.conf aangepast hebt, moet de service inetd opnieuw gestart worden. Gebruik hiervoor de opdracht killall –HUP inetd. SWAT is nu beschikbaar. 2b. Pas xinetd aan Het verschil tussen inetd en xinetd is dat bij xinetd elke service zijn eigen configuratiebestand krijgt. Dit bestand wordt geplaatst in de directory /etc/xinetd.d. Op SUSE Linux ziet het configuratiebestand voor SWAT er standaard als volgt uit: service swat { socket _ type
=
stream
protocol
=
wait
no
=
tcp
322
Linux 4
user
=
root
server
=
/usr/sbin/swat
only _ from
=
127.0.0.1
log _ on _ failure
+=
disable
yes
=
USERID
}
Let in dit voorbeeld vooral even op de laatste regel: deze zorgt ervoor dat SWAT standaard uit staat. Je moet er op zijn minst voor zorgen dat deze regel gewijzigd wordt in disable = no. Ook de regel only _ from is interessant. Deze zorgt er standaard voor dat SWAT alleen vanaf de lokale computer gebruikt mag worden. Wil je SWAT ook vanaf andere locaties op het netwerk kunnen gebruiken, wijzig deze regel dan bijvoorbeeld in only _ from = 0.0.0.0. Hiermee maak je toegang vanaf elke andere computer mogelijk. Nadat je het SWAT-configuratiebestand voor xinetd gemaakt of aangepast hebt, moet ook xinetd opnieuw gestart worden. Gebruik hiervoor de opdracht killall –HUP xinetd, dit forceert het proces xinetd om zijn configuratie opnieuw in te lezen. Als deze stappen met succes zijn uitgevoerd, kun je SWAT gebruiken. Voordat je toegang krijgt, zie je eerst een loginscherm waarin je je bekend moet maken. Je kunt hier inloggen als Linuxgebruiker root. Nadat dit gebeurd is, kom je in de SWAT-interface terecht. Je ziet hier in één grafisch programma alles wat je voor de Samba-server kunt instellen. Veel van de informatie die je hier kunt regelen, zal je op basis van de informatie in dit hoofdstuk bekend voorkomen, er zijn echter ook nog heel veel opties die in dit hoofdstuk niet besproken zijn. Wij raden je aan vooral uitgebreid rond te kijken in de mogelijkheden die geboden worden. SWAT is overzichtelijk en biedt veel informatie over alles wat mogelijk is. Houd er overigens rekening mee dat SWAT werkt met twee verschillende weergaven. Je komt standaard in de basisweergave waarin je niet alle opties ziet. Om wel alle mogelijkheden met SWAT aan te kunnen passen maak je gebruik van de geavanceerde weergave.
8 Bestanden delen met Linux
323
Figuur 8.5 Met behulp van SWAT kun je alle instellingen van de Samba-server vanuit een overzichtelijke webinterface aanpassen
8.4
Samenvatting
In dit hoofdstuk heb je gelezen over de wijze waarop je bestanden op de Linux-server beschikbaar kunt stellen aan andere gebruikers. Hierbij is aandacht besteed aan twee belangrijke systemen. Allereerst heb je gelezen over de wijze waarop met NFS bestanden gedeeld kunnen worden. Vervolgens heb je gelezen hoe je een Samba-server kunt inzetten om bestanden toegankelijk te maken voor Windows-, Linux- en Apple-gebruikers. Je hebt kennisgemaakt met de belangrijkste methoden die gebruikt kunnen worden om met Samba bestanden te delen: Samba als standalone-server, Samba als PDC en Samba als deel van Active Directory.
9
Beheer op afstand
9.1
Inleiding
Er zijn verschillende oplossingen om contact te maken met een server. Vroeger zat aan elke server een monitor en toetsenbord vast en ging je er direct op aan het werk. Tegenwoordig doen we dat niet meer. Servers staan vaak zonder beeldscherm en toetsenbord in een serverhok waar überhaupt vrijwel nooit een beheerder te bekennen is (het is daar namelijk doorgaans veel te koud). Beheer op afstand is dus voor het moderne serverbeheer van groot belang en onder Linux wordt voor dit doel gebruikgemaakt van Secure Shell (SSH). Naast SSH zijn er ook andere mogelijkheden. Zo is het bijvoorbeeld een optie om de console van de server over te nemen in een VNC-sessie. Het belangrijkste nadeel van VNC echter is dat er op geen enkele wijze beveiliging wordt toegepast en daarom is dit zeker voor onveilige internetverbindingen niet aan te raden. Om die reden richten we ons in dit hoofdstuk op de mogelijkheden van SSH. 9.2
Veilig contact maken met andere computers
SSH is de belangrijkste methode om contact te maken met andere computers. Het doel van secure shell is inloggen op een andere computer om daar opdrachten op uit te voeren. SSH is daarom een essentiële tool voor de systeembeheerder; je zult het vaak gebruiken om de server van afstand te onderhouden. De meerwaarde van secure shell bestaat eruit dat de communicatie versleuteld wordt
326
Linux 4
door gebruik van encryptietechnieken. Omdat SSH gebruikmaakt van versleuteling, wordt van oude technieken waarin dat niet gebeurt (denk aan telnet en de oeroude r-services) tegenwoordig geen gebruik meer gemaakt. Naast de opdracht ssh zijn er gerelateerde opdrachten die je kunt gebruiken om een veilige verbinding met een andere computer te initialiseren. Dit zijn de opdrachten sftp en scp. De opdracht sftp wordt op een clientcomputer gebruikt om een beveiligde FTP-sessie te maken met een andere server. Daar is overigens niets speciaals voor nodig, op de andere server moet alleen de SSH-deamon sshd actief zijn. Voor sftp heb je dus geen aparte FTP-server meer nodig. De opdracht scp wordt gebruikt om op veilige wijze bestanden te kopiëren naar een andere computer. Windows SSH is ontwikkeld voor gebruik op Linux, maar je kunt het op Windows echter ook gebruiken. Hiervoor heb je het gratis programma PuTTY nodig. Je kunt PuTTY downloaden van www.PuTTY.nl/download.html. Op deze site vind je eveneens de tools pscsp en psftp. Dit zijn opdrachten die je op Windows op de opdrachtprompt gebruikt om bijvoorbeeld vanaf de Windows machine op veilige wijze een bestand te kopiëren naar de Linux-server. Let er bij het werken met SSH op dat er twee versies van het protocol in omloop zijn. De parameters van beide versies zijn verschillend. De meeste hedendaagse Linux-distributies maken gebruik van versie 2. Om die reden zullen we in dit hoofdstuk dan ook de nadruk leggen op deze versie. Het gebruik van versie 1 wordt met nadruk afgeraden; verkeer dat over SSH versie 1 verstuurd wordt, kan namelijk afgeluisterd worden en is daarom onveilig. Beveiliging De mate van beveiliging die met SSH bereikt wordt, hangt direct samen met de encryptietechniek die gebruikt wordt. Nu hebben de meeste encryptiealgoritmes de eigenschap dat ze hooguit een jaar of vijf houdbaar zijn. Na vijf jaar is de processorkracht dusdanig gegroeid dat algoritmes die ooit als veilig beschouwd werden binnen korte tijd gekraakt kunnen worden.
9 Beheer op afstand
9.3
327
Authenticatiemethoden
Een van de meest krachtige features van SSH is de authenticatie. Naast authenticatie op basis van wachtwoorden biedt SSH een aantal andere mogelijkheden die zeer de moeite waard zijn. De meest gebruikte mogelijkheid is de optie waarbij gebruikgemaakt wordt van keys. De echte kracht van SSH-encryptie schuilt echter in het gebruik van PAM op de achtergrond. Hierdoor komt feitelijk elke manier van aanmelden die het doet onder Linux in aanmerking. Het enige wat nodig is, is een PAM-module. Neem deze PAM-module op in het PAM-configuratiebestand /etc/pam.d/ssh en je kunt op de alternatieve wijze authenticeren. 9.3.1 De werking van SSH-authenticatie In de eerste fase van de authenticatieprocedure maakt de client contact met een server. Hierbij is het belangrijk dat de client zeker weet dat hij ook inderdaad met de betreffende server contact heeft en niet met een andere host. In deze fase wordt gebruikgemaakt van de host-key van de server. Elke host heeft een eigen host-key. Deze wordt gebruikt ter identificatie van de betreffende host. Op het moment dat een gebruiker contact maakt met een host, wordt de host-key aan de gebruiker aangeboden. De gebruiker kan vervolgens de host-key vergelijken met een lijst van bekende hosts die de gebruiker bijhoudt in het bestand known_hosts. Dit bestand komt voor in de directory .ssh in de homedirectory van de gebruiker. Komt de host-key nog niet voor in de known_hosts op de computer van de gebruiker, dan ontvangt deze een waarschuwing en wordt gevraagd of hij wel zeker weet dat hij de authenticatieprocedure voort wil zetten. Wanneer je er zeker van bent dat je inderdaad met de beoogde host verbinding hebt, kun je deze vraag positief beantwoorden. Dit heeft als gevolg dat de betreffende host permanent wordt toegevoegd aan de lijst van bekende hosts in known_hosts. Vervolgens kan overgegaan worden naar de tweede fase van de authenticatie waarbij de gebruiker in kwestie zich aanmeldt op de andere computer.
328
Linux 4
Figuur 9.1 Als een gebruiker voor het eerst contact maakt met een onbekende host, krijgt hij een waarschuwing te zien
Naast de host-key heeft elke host een server RSA-key. Deze RSAkey wordt gebruikt als de zogenoemde sessie-key. Deze key dient niet voor het vaststellen van de identiteit van een host, maar zorgt ervoor dat op veilige wijze gecommuniceerd kan worden. Wanneer de client verbinding heeft gemaakt, genereert deze een willekeurig getal van 256 bits. Dit getal wordt door de client versleuteld met zowel de host-key als de sessie-key die de client van de server ontvangen heeft en teruggestuurd naar de SSH-server. Wanneer dit versleutelde getal op de server bekend is, kan het door beide partijen gebruikt worden als session-key waarmee alle gegevens die over en weer verstuurd worden versleuteld worden. Wanneer dit initiële contact tot stand gebracht is, wordt de authenticatie voortgezet. Op dit moment is er namelijk weliswaar een veilige communicatie mogelijk tussen client en server, maar de identiteit van de client is nog op geen enkele wijze vastgesteld. Hiervoor kan gebruikgemaakt worden van verschillende mechanismen: Authenticatie op basis van een wachtwoord (standaard). Authenticatie op basis van public/private-keys. Andere methoden op basis van PAM. De server bepaalt in het configuratiebestand /etc/ssh/sshd_config welke vorm van authenticatie is toegestaan. De standaardvoorzieningen op een moderne Linux-distributie zijn veilig genoeg en
9 Beheer op afstand
329
zorgen ervoor dat gebruikers op basis van hun wachtwoord kunnen aanmelden. Nadat de authenticatie succesvol is uitgevoerd, bestaat er een beveiligd kanaal. Dit beveiligde kanaal kan door beide partijen gebruikt worden om gegevens heen en weer te sturen. De client kan op dit moment een remote terminal op de server starten, TCP/IPverbindingen doorsturen of gewoon een opdracht uitvoeren op de andere machine. SSH maakt het vrijwel allemaal mogelijk. 9.3.2 Authenticatie-instellingen op de server vastleggen Om te bepalen welke wijze van authenticatie gebruikt moet worden voor clients die zich willen aanmelden met behulp van SSH, moet je zoals gezegd op de server het configuratiebestand /etc/ssh/ sshd_config bewerken. In dit bestand wordt gebruikgemaakt van een aantal standaardwaarden. Wanneer je niets aanpast in sshd_ config, worden alle standaardwaarden gebruikt zoals je ze in de regels kunt lezen die in het voorbeeldbestand gebruikt worden. Wil je daarentegen andere dan de standaardwaarden gebruiken, dan moet je dit bestand bewerken. De volgende regels in dit bestand hebben betrekking op de wijze waarop aangemeld wordt. ChallengeResponseAuthentication Met behulp van deze instelling bepaal je of authenticatie door middel van challenge-response is toegestaan. Je zou het misschien niet zeggen, maar deze optie bepaalt of je al dan niet mag inloggen op basis van een gebruikerswachtwoord. Standaard staat deze mogelijkheid aan. Je dient je echter te realiseren dat er een belangrijk nadeel verbonden is aan deze optie: de machine is kwetsbaar voor een brute-force attack op het wachtwoord, waarbij een ongeautoriseerde gebruiker kan proberen in te loggen op de server door willekeurig gebruikersnamen en wachtwoorden uit te proberen. Voor een optimale beveiliging zou je dan ook moeten overwegen deze optie uit te zetten. De standaardwaarde staat op yes. Verander dit naar no om ervoor te zorgen dat authenticatie op basis van wachtwoorden niet langer toegestaan is. HostbasedAuthentication Hiermee kun je aangeven of authenticatie op basis van het rhostsmechanisme is toegestaan. Hieronder wordt ook inbegrepen de authenticatie die plaatsvindt op basis van een lijstje met computers
330
Linux 4
dat gedefinieerd is in het configuratiebestand /etc/hosts.equiv. Aangezien dit een zeer onveilige werkwijze is, wordt het gebruik van deze optie sterk afgeraden. Gebruik deze optie niet, tenzij je echt niet anders kunt. IgnoreUserKnownHosts Met behulp van deze parameter kun je aangeven of eindgebruikers zelf in staat zijn een bestand aan te maken in hun homedirectory met de naam .ssh/known_hosts. Het nut van een dergelijk bestand is dat het hiermee mogelijk gemaakt kan worden dat de gebruiker zelf lijsten bijhoudt van hosts die vertrouwd worden. De standaardinstelling voor deze parameter is yes en het is handig om dat ook maar zo te laten. Alleen als je vanuit de optiek van een strikt beveiligingsbeleid zelf wilt kunnen bepalen met welke veilige hosts contact gemaakt kan worden, is het aan te raden deze optie uit te zetten. Dit brengt echter veel werk met zich mee voor de beheerder. KerberosAuthentication en KerberosOrLocalPasswd Met de parameter KerberosAuthentication wordt aangegeven of authenticatie met behulp van Kerberos-tickets is toegestaan. De standaardwaarde voor deze parameter is no en deze optie wordt zelden gebruikt. Niet omdat Kerberos-authenticatie niet goed werkt, maar omdat de setup van een omgeving die dit mogelijk maakt erg complex is. De optie KerberosOrLocalPassword wordt gebruikt om aan te geven dat ofwel gebruikgemaakt wordt van Kerberos, ofwel van het lokale passwd-mechanisme waarbij gebruikers aanmelden op de traditionele UNIX-manier waarbij gebruikgemaakt wordt van de lokale gebruikersdatabase. Deze waarde staat standaard op yes, wat het mogelijk maakt altijd in te loggen met het passwd-mechanisme, zelfs als staat KerberosAuthentication aan. PasswordAuthentication Met deze optie bepaal je niet of een gebruiker al dan niet in mag loggen met zijn gebruikerswachtwoord. Deze optie daarentegen bepaalt of het gebruik van wachtwoorden in clear-text toegestaan is. Dit zijn wachtwoorden die in leesbare vorm verstuurd worden zoals het geval is bij wachtwoorden in een telnetsessie. Verbied dit altijd, clear-text wachtwoorden zijn namelijk bijzonder onveilig. Daarom staat deze parameter op moderne Linux-distributies tegenwoordig vaak op no.
9 Beheer op afstand
331
PubKeyAuthentication Deze parameter staat standaard aan en zorgt er in protocol versie 2 voor dat authenticatie kan plaatsvinden op basis van public keys. Zorg ervoor dat deze optie aan staat. Realiseer je echter wel dat deze methode alleen werkt als je met een opdracht als ssh-keygen of PuTTYgen op Windows ook de public/private key-paren gegenereerd hebt. Authenticatie-instellingen op de client Waar je er in /etc/ssh/sshd_config voor zorgt dat bepaalde mogelijkheden op de server aan of uit gezet worden, moet je ook op de client regelen op welke wijze de authenticatie plaats moet vinden. Om die reden kunnen ook hier de nodige instellingen geregeld worden. Om instellingen te specificeren die elke keer gebruikt moeten worden, neem je deze op in het client-configuratiebestand /etc/ssh/ssh_config. Dit bestand is geldig voor iedere gebruiker, tenzij een gebruiker in zijn eigen homedirectory een bestand heeft met de naam .ssh/config waarin instellingen in het algemene configuratiebestand overschreven worden. Tot slot kunnen de opties in dit bestand nog overschreven worden door gebruik te maken van opties die gespecificeerd worden met de opdracht ssh. Voor normaal gebruik is het niet nodig instellingen in ssh_config aan te passen; de standaardconfiguratie werkt voor de meeste omstandigheden prima. 9.4
Snel aan het werk
Wanneer je de authenticatie-instellingen geregeld hebt, kun je in principe direct aan het werk met SSH en aanverwante programma’s. Hierna laten we zien hoe je de secure remote-opdrachten kunt gebruiken. 9.4.1 ssh De meest populaire opdracht uit het SSH-pakket is ssh. Je gebruikt het om contact op te bouwen met een server waarop het sshd-proces actief is. Gebruik de opdracht service sshd status om te kijken of de SSH-daemon al actief is en als dat niet het geval is, gebruik dan service sshd start om SSH te starten. Wanneer dit gebeurd is, kunnen clients met behulp van de opdracht ssh hostnaam contact maken met een remote-computer. Uiteraard kan
332
Linux 4
in plaats van de hostnaam ook gebruikgemaakt worden van een IP-adres. Wanneer de opdracht ssh vanaf de prompt wordt gestart, kunnen hierbij ook de nodige parameters gegeven worden. Om te beginnen is dat natuurlijk de naam van de computer waarmee contact gemaakt moet worden. Daarnaast kun je in de vorm user@hostnaam ook de gebruikersnaam op de betreffende host meegeven. Een voorbeeld hiervan zie je in de volgende opdracht: ssh [email protected]
Tot slot is het mogelijk een opdracht te specificeren die direct uitgevoerd moet worden. Zo zorgt de opdracht ssh melissa@server kill -9 sshd
ervoor dat op de remote host wordt ingelogd en vervolgens na succesvolle authenticatie automatisch een niet zo heel erg zinnige opdracht wordt uitgevoerd (al is het zeer aannemelijk dat Melissa als ze een gewone gebruiker is deze opdracht toch niet kan uitvoeren). Wanneer er niets anders geregeld is, wordt als eerste geprobeerd in te loggen door gebruik te maken van public/private-keys. Alleen als dit niet lukt, wordt gevraagd om een wachtwoord. Dit betekent dat op een nieuw systeem je op basis van wachtwoorden aanmeldt; om namelijk met sleutels aan te kunnen melden, moeten die sleutels wel eerst gegenereerd zijn. Dit doe je door bij de opdracht sshkeygen gebruik te maken van de optie –t. Geef bijvoorbeeld de opdracht ssh-keygen –t dsa om een DSA-key te genereren. Dit doe je op de computer waarop je als gebruiker werkt. De sleutel die op deze wijze gegenereerd wordt, moet vervolgens gekopieerd worden naar het bestand authorized_keys dat voorkomt in de directory .ssh in de homedirectory van de gebruiker. Je kunt dit handmatig doen (verderop in dit hoofdstuk leer je hoe), maar als handig alternatief is het ook mogelijk gebruik te maken van de opdracht ssh-copyid om de sleutels geautomatiseerd naar de andere server te kopiëren. Dit doe je bijvoorbeeld door middel van de volgende opdracht: ssh-copy-id -i ~/.ssh/id _ dsa.pub [email protected]
9 Beheer op afstand
333
Wanneer bij gebruik van de opdracht ssh wordt ingelogd op een remote server, wordt overigens ook een PAM-configuratieproces in de aanmeldingsprocedure betrokken. Je kunt dus PAM gebruiken om verder te specificeren wat er tijdens het inloggen met SSH precies moet gebeuren. Hieronder zie je hoe het standaardconfiguratiebestand van PAM voor SSH er op OpenSUSE uit ziet: #%PAM-1.0 auth
requisite
pam _ nologin.so
auth
include
common-auth
account
include
common-account
password include
common-password
session
required
pam _ loginuid.so
session
include
common-session
# Enable the following line to get resmgr support for # ssh sessions (see /usr/share/doc/packages/resmgr/README) #session
optional
pam _ resmgr.so fake _ ttyname
Wanneer je door middel van SSH gebruikmaakt van een andere computer, kun je er ook voor zorgen dat alle uitvoer van X-programma’s wordt doorgestuurd naar de eigen computer. Hiervoor moet gebruikgemaakt worden van de optie ForwardX11. Je kunt deze optie aanzetten in het clientconfiguratiebestand, maar als alternatief is het ook mogelijk om X-forwarding mogelijk te maken door de optie -X te gebruiken bij de opdracht ssh. Houd er echter rekening mee dat je wel moet voldoen aan de meest elementaire voorwaarde om X-forwarding te kunnen gebruiken: de client moet voorzien zijn van een X-server. Als je een Linux-systeem gebruikt in grafische modus, zal dat het probleem niet zijn. Als je echter door middel van PuTTY op een Windows-computer grafische schermen door wilt sturen vanaf de Linux-server, zul je er wel eerst voor moeten zorgen dat op Windows een X-server beschikbaar is. Een uitstekende en niet al te dure X-server voor Windows is X-win32. Je kunt deze server aanschaffen via www.starnet.com. Tot besluit geven we enkele voorbeelden van de manier waarop een client met de opdracht ssh contact kan maken met de server. alex@x-tina:~> ssh –l [email protected]
334
Linux 4
Met deze regel logt gebruiker alex, die lokaal is aangemeld, in op linux.sandervanvugt.nl. De optie –l zorgt ervoor dat hij gebruik kan maken van een andere loginnaam op de andere computer: franck in dit geval. De optie -l mag overigens gebruikt worden, maar is niet strikt noodzakelijk. Ook zonder -l kun je uitstekend als een andere gebruiker aanmelden op een andere computer. Een andere mogelijkheid is dat een gebruiker van een afstandje inlogt op een computer en een opdracht op die computer uitvoert. De volgende opdracht toont hoe gebruiker alex computer Linux. sandervanvugt.nl uitschakelt: alex@x-tina:~> ssh [email protected] shutdown –h now
Het vervelende van dit voorbeeld is dat alex waarschijnlijk wel eerst een wachtwoord moet invoeren om dit als root te kunnen doen. Dit kan echter voorkomen worden door te werken met keys. Ook erg handig is wanneer de weergave van grafische toepassingen meteen geregeld wordt. De volgende opdracht zorgt ervoor dat alle grafische toepassingen die door alex gestart worden op Linux. sander.nl, kunnen worden weergegeven op x-tina: alex@x-tina:~> ssh –X Linux.sandervanvugt.nl
Voor alle duidelijkheid: deze opdracht zorgt ervoor dat een prompt voor alex geopend wordt op Linux.sandervanvugt.nl. Vanuit die remote prompt mag alex vervolgens opdrachten invoeren. Deze opdrachten worden uitgevoerd op de server (ze belasten dus daar de processor en andere resources). Je zult echter het venster dat door de opdrachten gegenereerd wordt op je eigen computer zien. Tot slot is het met SSH ook mogelijk om connecties die binnenkomen op bepaalde poorten door te sturen. Dit fenomeen staat bekend als SSH tunneling of port forwarding en dat is een zeer handige methode om ervoor te zorgen dat je een beveiligde connectie maakt voor een protocol dat in principe niet beveiligd is. Daarnaast is SSH tunneling ook erg nuttig om firewalls en proxy’s te omzeilen. Geen enkele beheerder kan namelijk zien wat er in een SSH-tunnel plaatsvindt. In het volgende zie je een voorbeeld waarmee de auteur van dit boek ervoor zorgt dat hij door een
9 Beheer op afstand
335
proxy heen over poort 443 contact maakt met zijn SSH-server, om vervolgens via die SSH-server contact te maken met zijn mailserver bij internetprovider xs4all: ssh -p 443 -f [email protected] -L 4000:pop.xs4all.nl:110 sleep 60000 ssh -p 443 -f [email protected] -L 4001:smtp.xs4all.nl:25 sleep 60000
Wij kunnen ons voorstellen dat dit voorbeeld wel enige uitleg nodig heeft. We bespreken de eerste regel en als je deze begrijpt, is het niet moeilijk de tweede regel ook te begrijpen. Om te beginnen maakt ssh contact met uitgaande poort 443. Het handige daarvan, is dat poort 443 op vrijwel elke proxy open staat, de proxy zal namelijk denken dat het HTTPS-verkeer is en je geen enkele belemmering opleggen. Connect Als de beheerder van de proxyserver zijn werk goed gedaan heeft, kijkt de proxy in het pakketje om te zien of het wel HTTP-verkeer is. Als dat het geval is, werkt de hiervoor genoemde truc niet. Je hebt dan additionele software nodig zoals transconnect. Hiermee tunnel je het SSH-pakketje eerst in een HTTP-header, zodat het vervolgens als legitiem HTTP-verkeer beoordeeld wordt. Het verkeer gaat naar de server sandervanvugt.org en op die server wordt aangemeld als root. Met de optie -L 4000 wordt aan dit verkeer een lokale poort 4000 toegekend. Hiermee zijn we er echter nog niet; alles wat verbonden is aan lokale poort 4000, wordt direct doorgestuurd naar de mailserver pop.xs4all.nl:110. Dit betekent dat de gebruiker die deze opdracht uitvoert, vervolgens aan zijn mailclient de instructie kan geven dat deze zijn berichten moet ophalen op lokale poort 4000, in plaats van poort 110 op de mailserver. We zijn er met deze uitleg nog niet helemaal. Bij het tot stand brengen van de tunnel wordt namelijk ook de optie -f gebruikt. Deze optie zorgt ervoor dat ssh samen met een andere opdracht op de achtergrond uitgevoerd wordt. Hiervoor is echter wel een andere
336
Linux 4
opdracht nodig en deze vind je helemaal aan het einde van de regel: sleep 60000. Deze opdracht zorgt ervoor dat de verbinding ongeveer 18 uur (60.000 seconden) in stand gehouden wordt. Na afloop van die 60.000 seconden wordt de tunnel afgebroken en zul je deze opdracht opnieuw moeten uitvoeren. Wellicht dat je je afvraagt waarom deze ingewikkelde constructie met -f nodig is? Welnu, deze zorgt ervoor dat er geen loginscherm getoond wordt, maar dat de verbinding netjes op de achtergrond gestart wordt. Je hebt er dan geen last van en kunt gewoon nog je normale werk doen; wel zo handig. Mocht het overigens nodig zijn dat deze SSH-tunnels permanent worden toegepast op een machine, dan kun je ze opnemen in het clientconfiguratiebestand /etc/ssh/ssh_config. Met de optie RemoteForward zorg je ervoor dat een remote host doorgestuurd wordt naar een lokale poort. Zo zorgt bijvoorbeeld de volgende regel ervoor dat remote poort 15000 op host iets.ergens.nl doorgestuurd wordt naar lokale poort 4000 die verbonden is aan IP-adres 192.168.1.10: RemoteForward 129.168.1.10:80 mijn.server.nl:15000
Met de volgende optie zorg je ervoor dat een lokale poort doorgestuurd wordt naar een remote host: LocalForward 192.168.1.10:4000 pop.xs4all.nl:110
In dit laatste voorbeeld herken je de port forwarding die we zojuist vanaf de opdrachtregel gedaan hebben. Het verschil tussen local port forwarding en remote port forwarding is de initiator van het verkeer. In de meeste gevallen zul je local port forwarding nodig hebben, dit is namelijk het scenario waar een clienttoepassing contact moet maken met een server die ergens op internet draait. Denk daarbij aan het ophalen van mailberichten. Remote port forwarding is handig als je een service die op je eigen machine draait, beschikbaar wilt stellen via een server op internet. De server op internet stuurt dan alle verkeer die op de gedefinieerde poort binnenkomt door naar de gespecificeerde poort op de client. Dit laatste zal in de praktijk minder vaak nodig zijn. Houd er ook rekening mee dat in beide gevallen bij port forwarding een SSH-proces moet draaien op de server waarmee je communiceert.
9 Beheer op afstand
337
9.4.2 scp Een ander handige opdracht uit de SSH-suite is scp. Je gebruikt deze opdracht om bestanden over te sturen tussen twee computers op basis van SSH-functionaliteit. Gebruik van scp is eenvoudig: je geeft als eerste argument een volledige verwijzing naar het bronbestand en als tweede argument een verwijzing naar het doelbestand. Daarbij kan ook gelijk de gebruikersnaam meegegeven worden van de gebruiker wiens credentials op beide servers gebruikt moeten worden. Zo kun je bijvoorbeeld de volgende opdracht gebruiken om het bestand /etc/hosts van een computer naar een andere computer te kopiëren: scp sander@x-tina:/etc/hosts root@laetitia:/etc/hosts
Wellicht dat je je afvraagt of het noodzakelijk is om in beide gevallen te verwijzen naar de betreffende host, welnu, dat is niet het geval. Het voorgaande voorbeeld echter stelt je in staat om vanaf een derde host (het werkstation bijvoorbeeld) een bestand van de ene server naar de andere server te versturen. Als je wilt verwijzen naar een lokaal bestand, volstaat het een eenduidige verwijzing naar dit bestand te gebruiken. Let overigens even goed op als je een afwijkend poortadres moet gebruiken: scp gebruikt hiervoor niet de optie -p (kleine letter) maar -P (hoofdletter). Windows Op Windows is standaard geen scp-opdracht beschikbaar. Het alternatief maakt deel uit van PuTTY en heet pscp. Je kunt dit hulpmiddel downloaden van internet, installeer het vervolgens in de directory \Program Files op de Windows-computer en je kunt voortaan bestanden kopiëren tussen een Windows-computer en de Linux-server. 9.4.3 sftp Naast de klassieke r-opdrachten en telnet is er nog een gouwe ouwe die standaard behoorlijk onveilig is: de opdracht ftp die gebruikt kan worden als FTP-client. Net als vrijwel alle andere opdrachten die al lang in gebruik zijn, verstuurt ook deze opdracht zijn gegevens zonder dat er op enige wijze iets versleuteld wordt. Dit betekent dat gevoelige gegevens, zoals wachtwoorden en gebruikersnamen, uitgelezen kunnen worden wanneer iemand
338
Linux 4
ze met een sniffer probeert te onderscheppen. Gebruik de Secure FTP-functionaliteit die je er bij SSH gratis en voor niets bij krijgt. Bewerk hiervoor de parameter Subsystem in het configuratiebestand /etc/ssh/sshd_config en gebruik daarna de opdracht service sshd restart om SSH opnieuw te starten. Met behulp van de optie Subsystem kunnen andere systemen op SSH ‘aangehaakt’ worden. Je gebruikt deze optie in algemene zin om de functionaliteit van SSH uit te breiden. In de volgende voorbeeldregel zie je hoe op OpenSUSE op deze manier als subsystem een sftp-server gestart wordt: Subsystem sftp
/usr/lib/ssh/sftp-server
Wanneer de SSH-service zo geconfigureerd is dat de sftp-server automatisch gestart wordt, is de rest kinderspel. Je kunt de opdracht sftp gebruiken om bestanden op de FTP-server te plaatsen of te downloaden. Deze opdracht werkt precies hetzelfde als de normale ftp-client, met als enige verschil dat je kunt profiteren van alle voordelen die SSH te bieden heeft, zoals op sleutels gebaseerde authenticatie. 9.5
Configuratie van key-based authenticatie
In de voorgaande paragrafen is vooral gebruikgemaakt van authenticatie op basis van wachtwoorden. Deze vorm van authenticatie werkt op zich goed, maar is niet optimaal. Om voor een betere beveiliging te zorgen is het beter public en private keys te gebruiken. De server moet dit echter wel toestaan. Of dit het geval is, achterhaal je door in het configuratiebestand /etc/ssh/sshd_config op de server te zoeken naar de volgende regel: PubkeyAuthentication yes
Staat deze regel er niet in? Voeg hem dan toe en start het sshd-proces opnieuw op met behulp van de opdracht service sshd restart. Op de client is gewoonlijk geen extra configuratie nodig; de client verbindt automatisch op basis van keys als dat mogelijk is. Wel moet je de sleutels eerst genereren. Volg hiervoor de volgende procedure:
9 Beheer op afstand
339
1. Log op de client in als de gebruiker waarvoor je sleutels wilt genereren. Geef nu de volgende opdracht: ssh-keygen -t dsa
Deze opdracht zorgt ervoor dat een public/private-key-paar gegenereerd wordt. Daarbij wordt een aantal vragen gesteld, je ziet een samenvatting hiervan in de volgende listing: SFO:~/.ssh # ssh-keygen -t dsa Generating public/private dsa key pair. Enter file in which to save the key (/root/.ssh/id_dsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /root/.ssh/id _ dsa. Your public key has been saved in /root/.ssh/id _ dsa.pub. The key fingerprint is: 84:44:ce:ac:66:fb:1b:4c:2f:76:6e:47:e8:27:5d:5b root@SFO
In de vetgedrukte regels zie je dat de opdracht om invoer van de gebruiker vraagt. Om te beginnen is dat de naam van het bestand waarin de sleutels opgeslagen worden. Gebruik hiervoor de standaardsuggestie, dit zorgt ervoor dat de private key opgeslagen wordt in ~/.ssh/id_dsa en de public key in ~/.ssh/id_dsa. pub. Vervolgens vraagt de opdracht om een passphrase. Dit is een wachtwoord (eigenlijk wachtzin) dat de private key beschermt; je zult het elke keer moeten invoeren voordat je op basis van sleutels kunt aanmelden. Dit lijkt misschien onhandig; feitelijk vervang je immers de noodzaak een wachtwoord in te voeren door de noodzaak een wachtzin in te voeren, maar wij bevelen aan altijd gebruik te maken van een wachtzin. Je voorkomt zo namelijk dat iemand die je key steelt, er met je identiteit vandoor gaat. Stel je maar eens voor wat de gevolgen zouden zijn als je je laptop verliest waarop de key staat waarmee je toegang krijgt tot al de servers. De persoon die je laptop vindt, zou dan ook alle servers kunnen beheren! 2. Nadat de sleutels zijn gemaakt, moet je ervoor zorgen dat de public key op de server aan het bestand .ssh/authorized_keys in de homedirectory van de account aldaar gemaakt wordt. Dit doe je door de twee volgende stappen uit te voeren:
340
Linux 4
2a. Kopieer ~/.ssh/id_dsa.pub naar een tijdelijk bestand op de server, bijvoorbeeld met de volgende opdracht: scp ~/.ssh/id _ dsa.pun LHR:~/pubkey
2b. Zorg nu dat op de server de public key toegevoegd wordt aan het eind van het bestand ~/.ssh/authorized_keys. Controleer voordat je dit doet wel eerst even of de directory .ssh bestaat. Geef dan de volgende opdracht om de public key toe te voegen: cat ~/pubkey >> ~/.ssh/authorized _ keys
3. Meer hoeft er niet te gebeuren, je kunt nu meteen aanmelden op de remote server. Je zult zien dat er niet langer om een wachtwoord gevraagd wordt. Wel moet je nu een passphrase invoeren. Als het je erom ging eenvoudiger in te loggen, is er dus feitelijk nog niets veranderd. Je moet namelijk nog steeds iets invoeren. 9.5.1 Werken met passphrases vereenvoudigen met ssh-agent Je hebt nu op het werkstation een private key en op de server een public key, maar daarmee ben je er echter nog niet. Als je de key met een wachtwoord hebt beveiligd, zul je namelijk merken dat je wel elke keer dat van de private key gebruikgemaakt wordt de passphrase moet invoeren. Dat is natuurlijk niet echt handig. Gelukkig kun je dit probleem oplossen door gebruik te maken van ssh-add en ssh-agent. Door deze twee hulpmiddelen te gebruiken wordt de passphrase gecached in het werkgeheugen. Zolang je vanuit een bepaalde shell werkt, hoef je de passphrase niet opnieuw in te voeren. De volgende procedure beschrijft hoe je dit configureert: 1. Open een terminalvenster. Geef in dit terminalvenster de volgende opdracht: ssh-agent /bin/bash
Dit zorgt ervoor dat ssh-agent actief wordt voor de /bin/bash shell vanaf dat moment. 2. Gebruik nu de opdracht ssh-add. Deze opdracht zal je vragen om de passphrase in te voeren die bij de private key hoort. Nadat je dit gedaan hebt, zie je de volgende melding:
9 Beheer op afstand
341
Identity added: /root/.ssh/id _ dsa (/root/.ssh/id _ dsa)
Je hebt nu de ssh-agent geconfigureerd. Tot op het moment dat je uitlogt, hoef je de passphrase nooit meer in te voeren. Je hoeft je echter geen zorgen te maken dat iemand de passphrase kan uitlezen, want deze wordt door encryptie beschermd bewaard in het werkgeheugen van de computer. Niemand kan er dus bij komen, zelfs de gebruiker root niet. 9.5.2 Key-configuratie in PuTTY Ook als je vanaf Windows met PuTTY contact maakt met de SSHserver, kan er de behoefte zijn aan werken met public/private-keys. Je zult in dat geval op de Windows-machine met het PuTTY-onderdeel PuTTYgen een sleutelpaar moeten genereren. Dit sleutelpaar vervolgens installeert je eerst in PuTTY en vervolgens op de server. In de volgende procedure lees je wat hier voor nodig is. 1. De opdracht PuTTYgen wordt niet automatisch geïnstalleerd op de computer wanneer je alleen het PuTTY-programmabestand binnengehaald hebt. Controleer daarom eerst of het op de computer aanwezig is. 2. Start PuTTYgen. Dit opent het venster van de PuTTY Key generator (zie figuur 9.2). Figuur 9.2 Als je in PuTTY public/ private-keys wilt gebruiken, moet je ze eerst met PuTTYGen maken
342
Linux 4
3. Geef onder in het venster aan wat voor type sleutels je wilt genereren. Wij raden je aan gebruik te maken van een 2048-bits DSA-key. Vul deze waarden in en klik dan op Generate. Je moet nu de muiscursor heen en weer bewegen over het lege deel van het PuTTYGen-venster. Dit zorgt ervoor dat willekeurige data gegenereerd wordt die in je sleutelpaar gebruikt wordt. 4. Als het sleutelpaar is gemaakt, zie je het venster dat je in de figuur 9.3 ziet. In dit venster geef je de eigenschappen van de key aan. Er zijn twee belangrijke taken die je hier moet uitvoeren. Om te beginnen moet je de public-key die boven in beeld getoond wordt kopiëren en opslaan in een bestand. Maak niet gebruik van de knop Save public key die je onder in het venster ziet, want hiermee wordt de sleutel opgeslagen in een formaat dat op Linux niet werkt. Kopieer daarom nu eerst de public key, open Notepad en plak daar de sleutel in. Sla dit bestand vervolgens op op de computer. Figuur 9.3 Door middel van kopiëren en plakken moet je de public key opslaan in een bestand
5. Bepaal nu of je een passphrase wilt gebruiken om je private key te beschermen. Als dit het geval is, voer je in de velden Key passhprase en Confirm passphrase tweemaal dezelfde passphrase in. Klik dan op Save private key om de passphrase op te slaan in een bestand.
9 Beheer op afstand
343
Figuur 9.4 In PuTTY moet je aangeven welke private key je wilt gebruiken
6. Open nu het PuTTY-scherm en laad indien van toepassing de sessie waarin je de passphrase wilt gebruiken. Open dan links onder in beeld de optie Connection > SSH > Auth. Je ziet nu het venster uit figuur 9.4. Klik hier op de knop Browse om te bladeren naar de locatie waar je private key is opgeslagen en voeg de private key toe aan je sessie. 7. Ga nu links in beeld terug naar de optie Session en klik op Save. Dit zorgt ervoor dat de private key ook daadwerkelijk voor de sessie beschikbaar is. 8. Verlaat nu tijdelijk het PuTTY-venster en open een Windowsopdrachtvenster. Gebruik hierin de opdracht pscp om de public key te kopiëren naar een tijdelijk bestand op de Linux-server. Dit tijdelijke bestand moet gemaakt worden in de homedirectory van de gebruiker die de sleutel moet gaan gebruiken. Als de public key is opgeslagen in een bestand met de naam pubkey in de huidige directory en je wilt deze kopiëren naar de homedirectory van gebruiker root op server sandervanvugt.nl, gebruik je hiervoor de volgende opdracht: pscp pubkey [email protected]:/root
9. Nu is het tijd naar de server zelf te gaan. Op de server gebruik je vanuit de homedirectory van de gebruiker root (of de andere gebruiker waarvoor je de sleutel gemaakt hebt) de volgende opdracht
344
Linux 4
om de public key toe te voegen aan het bestand .ssh/authorized keys. 10. Je bent nu klaar. Vanaf dit moment kun je ook vanuit PuTTY inloggen op basis van een public/private-key-paar. 9.5.3 X Forwarding op Windows Eerder in dit hoofdstuk heb je gelezen hoe je grafische sessies kunt doorsturen naar een Linux-werkstation. Wellicht dat je dit ook op Windows wilt kunnen doen. Er is echter wel een probleem: om een grafische sessie door te sturen naar Windows heb je een X-server voor Windows nodig. Dit is een softwareproduct dat ervoor zorgt dat je grafische vensters uit een X-omgeving kunt weergeven op Windows; Windows zelf kan namelijk niet overweg met X-applicaties. Helaas zijn er geen goede open source X-servers voor Windows, dus je kunt gebruikmaken van een betaalbare oplossing. Een zo’n oplossing is X-win32; je vindt een gratis evaluatieversie op www.starnet.com. Deze is 45 dagen bruikbaar. Wil je er gebruik van blijven maken, dan moet je de zeer redelijk geprijsde betaalde versie aanschaffen. Nadat je X-win32 geïnstalleerd hebt, moet je een aantal stappen doorlopen om de Windows-machine te configureren: 1. Sla in PuTTY de server waarvan je grafische sessies wilt doorsturen op onder een profiel. Open dan in PuTTY Connection > SSH > X11 en selecteer de optie Enable X11 forwarding. Voer nu bij X11 display location de tekst localhost:0 in. Je geeft hiermee aan dat alle vensters die vanaf een andere locatie doorgestuurd worden naar het werkstation, weergegeven moeten worden op de standaardmonitor. Kies nu nog steeds vanuit het hoofdvenster van het PuTTY-configuratiescherm de optie Session en klik op Save. Dit zorgt ervoor dat het profiel voor deze server opgeslagen wordt. 2. Start nu vanuit het menu Start het programma X-Config waarmee je X-Win32 kunt instellen en klik daar op het tabblad Beveiliging. Klik vervolgens op Add en typ de tekst localhost. je hoeft dus niet de naam of het adres van de server op te geven, maar verwijst juist naar je eigen werkstation. Klik nu op OK om deze instelling op te slaan.
9 Beheer op afstand
345
Figuur 9.5 In het X-win32configuratieprogramma geef je aan dat localhost toestemming heeft Xvensters af te beelden op basis van X-win32
3. Zorg er nu voor dat eerst X-Win32 en dan PuTTY gestart is. Dubbelklik vervolgens op de sessie die je opgeslagen hebt en voer de gebruikersnaam en het wachtwoord in om een sessie tot stand te brengen naar de andere machine. Je kunt nu elk grafisch programma op de server starten, de schermen zullen keurig doorgegeven worden op het werkstation. 9.6
Samenvatting
In dit hoofdstuk heb je kennisgemaakt met SSH. Je hebt geleerd hoe je op basis van SSH verbinding maakt met een Linux-computer op afstand. Hierbij is aandacht besteed aan Linux als SSH-client, maar ook aan de wijze waarop je Windows met Putty als SSHclient kunt gebruiken. Je hebt geleerd hoe je deze client gebruikt om met een wachtwoord in te loggen op de remote machine, maar ook hoe je voor dit doel gebruikmaakt van public/private-keys. Daarnaast heb je geleerd hoe je grafische toepassingen in een SSHomgeving gebruikt en hoe je SSH als eenvoudige VPN-oplossing inzet door middel van SSH-tunneling.
10
De Netfilter-firewall
10.1
Inleiding
Als het goed is, wordt in een netwerkomgeving de bescherming tegen indringers op twee locaties geregeld. Als eerste is er het punt waarop het netwerk met de buitenwereld verbonden wordt. Hier staat in de meeste omstandigheden een goed geconfigureerde firewall die ervoor zorgt dat geen ongeoorloofd verkeer van de buitenwereld je netwerk op kan en dat het ook onmogelijk is dat bepaalde soorten verkeer vanaf je eigen netwerk naar buiten gestuurd worden. Dit type beveiliging wordt in de meeste netwerken afgehandeld door een hardwarefirewall die voor dit doel geoptimaliseerd is. Wist je overigens dat aardig wat gerenommeerde merken van firewallleveranciers voor dit doel gebruikmaken van Linux als besturingssysteem dat op de firewall draait? De tweede laag van beveiliging gebeurt binnen het netwerk zelf. Je mag helemaal zelf weten hoe je dit inricht. In veel situaties worden er binnen het LAN extra services ingezet die voor extra beveiliging zorgen. Denk bijvoorbeeld aan de firewall die er op het netwerk van een school voor zorgt dat het netwerk van de studenten gescheiden wordt van het netwerk van de docenten. Soms echter komen dergelijke interne firewalls niet voor. Wat wel altijd gebruikt zou moeten worden, is een firewall op de servers zelf. Deze firewall wordt ingezet als tweede laag van defensie en zorgt dat misbruikers binnen het eigen netwerk tegengehouden worden. Vergelijk deze laag maar met die van de personal firewall op een pc. De meeste Linux-distributies zorgen ervoor dat standaard al tijdens de installatie zo’n firewall wordt aangezet. Voor deze firewalls wordt gebruikgemaakt van de Linux firewallfunctionaliteit
Linux 4
348
die in de kernel is meegeleverd door Netfilter. Dit firewallsysteem wordt beheerd met behulp van de opdracht iptables. Tip! Netfilter is de naam van de firewalloplossing die door Linux geboden wordt. Om deze firewalloplossing te beheren maak je gebruik van de opdracht iptables.
10.2
Tables en chains
Het uitgangspunt van de iptables is dat de regels waaruit een firewall bestaat, zijn ingedeeld in drie tabellen (tables). Standaard zijn het er drie, maar je mag er als je dat wilt zelf meer maken. Standaard zijn de volgende tables beschikbaar: filter nat mangle In elk van deze tabellen vind je een aantal chains. Deze chains zijn de verzamelingen regels waaruit de firewall is opgebouwd. De regel is de meest elementaire bouwsteen in een netfilter firewall. Een aantal chains wordt standaard meegeleverd, maar het is mogelijk hier eigen chains aan toe te voegen. Welke chains je kunt gebruiken, is afhankelijk van het type table dat je gebruikt. Verderop in dit hoofdstuk vind je hier meer informatie over. Naast de hoofdverdeling in drie verschillende tabellen biedt Netfilter nog verschillende soorten ‘kleinere’ features. Dit zijn onderdelen die vaak in de afzonderlijke rules verwerkt zijn:
stateful packetfiltering; port forwarding; packetfiltering op basis van TCP-flags; filtering op basis van inkomend MAC-adres; filtering van uitgaande pakketjes op basis van user-ID; anti-DoS-features; logging.
1 0 D e n e t f i l t e r- f i r e w a l l
349
Tip! Er is in de laatste Linux-kernelversies nogal gesleuteld aan het firewallmechanisme. In 2.0 kernels werd gebruikgemaakt van ipfwdadmin. Met behulp van deze opdracht kon een heel behoorlijke firewall worden gemaakt. Vervolgens werd in 2.2 kernels ipchains geïntroduceerd. Als je ooit met dit systeem in aanmerking komt, zul je merken dat het grote overeenkomsten vertoont met iptables dat in kernel versie 2.4 geïntroduceerd werd. Tussen de 2.4 kernels en de 2.6 kernels is geen belangrijke wijziging opgetreden in het mechanisme dat voor firewalling gebruikt wordt.
10.2.1 De table filter De table filter bestaat uit drie ingebouwde chains. Let overigens op de manier waarop de namen van de chains geschreven worden, die is altijd in hoofdletters: INPUT OUTPUT FORWARD De INPUT-chain wordt gebruikt om binnenkomende pakketjes te filteren. De OUTPUT-chain wordt gebruikt voor het verwerken van pakketjes die op de lokale machine gedefinieerd zijn en naar buiten verstuurd moeten worden. De FORWARD-chain verwerkt alle pakketjes die door de firewall gerouteerd worden. 10.2.2 De table nat Ook de table nat bestaat uit drie chains: PREROUTING OUTPUT POSTROUTING Door middel van de table nat worden twee soorten NAT (Network Address Translation) ondersteund. Om te beginnen is dit het veelgebruikte masquerading. Dit is de vorm van NAT waarin hosts op het privénetwerk internet op kunnen door gebruik te maken van het IP-adres van de firewall. Computers op internet zien in dat geval niets anders als de firewall en zijn zich er niet van bewust dat er achter die firewall een volledig netwerk voorkomt. Daarnaast is
350
Linux 4
het ook mogelijk het omgekeerde te doen. Dit betekent dat je nodes op het interne netwerk met behulp van de table nat bereikbaar kunt maken voor de buitenwereld door er een geregistreerd IP-adres aan toe te wijzen. Dit verschijnsel wordt ook aangeduid als statisch NAT. Dit betekent dat je aan de interface van de router een tweede IP-adres toekent en er door middel van de table nat voor zorgt dat alles wat op dat secundaire IP-adres binnenkomt, wordt doorgestuurd naar de betreffende host op het privénetwerk. Van de drie regels wordt de PREROUTING-chain gebruikt om pakketjes te behandelen zodra ze binnenkomen; dat wil zeggen nog voordat het routingproces ermee aan de slag kan. De OUTPUT-chain wordt gebruikt om pakketjes te behandelen die door het lokale systeem gegenereerd worden, maar nog voordat het routingproces ermee aan de slag gaat en de POSTROUTINGchain tot slot wordt gebruikt om pakketjes te behandelen voordat ze het systeem verlaten, maar nadat het routingproces ermee aan het werk is geweest. Figuur 10.1 SUSE Linux biedt vanuit YaST2 een mogelijkheid op een eenvoudige maar weinig gedetailleerde wijze een firewall in elkaar te klikken
1 0 D e n e t f i l t e r- f i r e w a l l
351
10.2.3 De table mangle De table mangle tot slot bestaat uit twee ingebouwde chains: PREROUTING OUTPUT De PREROUTING-chain behandelt alle inkomende pakketjes voordat ze gerouteerd worden. De OUTPUT-chain behandelt uitgaande pakketjes voordat ze gerouteerd worden. De table mangle wordt alleen in speciale gevallen gebruikt, bijvoorbeeld wanneer speciale services zoals Quality of Service (QoS) gebruikt worden om pakketjes een hogere prioriteit te geven. Om een eenvoudige firewall te maken mag je deze tabel gewoon vergeten. 10.3
Werken met tables en chains
De opdracht iptables biedt alles wat nodig is om chains te definiëren. Wanneer je dit doet, moet je als eerste aangeven in welke table een chain thuishoort. Als je dit niet doet, wordt een nieuw gedefinieerde table automatisch toegewezen aan de default table filter. Om een chain wel aan een specifieke table toe te wijzen maak je gebruik van de optie -t. 10.3.1 Rules Bij het definiëren van een chain wordt gebruikgemaakt van verschillende rules. Het is belangrijk dat in deze rules de juiste volgorde gebruikt wordt. In normale gevallen gaat een pakketje door alle regels in de chain. Dit is niet het geval als er een DENY of REJECT in de rule voorkomt. In dat geval wordt het pakketje direct tegengehouden. In alle andere gevallen worden dus alle regels verwerkt. Als geen enkele regel een match oplevert met het betreffende pakketje, wordt de laatste regel in het verhaal toegepast. Deze regel staat ook bekend als de policy. In het Nederlands mag je dit gerust vertalen in standaardbeleid. Dit is dus de standaardregel die wordt toegepast voor alle pakketjes waarvoor geen specifieke rule gevonden kon worden. 10.3.2 Flags, options, extensions en actions Wanneer je voor het eerst kennismaakt met Netfilter, komt het systeem behoorlijk ingewikkeld over. Als je echter eenmaal door
352
Linux 4
hebt hoe de opdracht iptables waarmee je Netfilter instelt in elkaar zit, valt het best mee. De opdracht iptables kent enkele standaardsoorten parameters die altijd terugkomen: Om te beginnen zijn er de flags. Hiermee vertel je wat voor soort actie er uitgevoerd moet worden. Vervolgens moet verwezen worden naar de chain waarin je aan het werk wilt. Als tweede zijn er de opties. Deze worden gebruikt om verdere specificatie aan te brengen. Een veelgebruikte optie die bijvoorbeeld toegepast kan worden, is die waarin je de source- en destination-adressen aangeeft. Bij deze opties kunnen vervolgens extensions aangegeven worden. Hiermee kan het gedrag van een optie verder gespecificeerd worden. Denk bijvoorbeeld aan source- en destination-poortadressen die gebruikt moeten worden. Tot slot zijn er de actions. Deze worden altijd voorafgegaan door de schakeloptie -j en bepalen wat er met een pakketje moet gebeuren. De algemene syntaxis van iptables komt er dus samengevat als volgt uit te zien: Iptables [-flags] [chain] [options [extensions] ] [ACTION]
Op de volgende pagina’s krijg je een overzicht van wat er aan flags, options, extensions en actions gebruikt kan worden. We beperken ons tot de meest belangrijke opties. Voor een volledig overzicht kun je de man-pagina van iptables raadplegen. Flag
Beschrijving
-t table
Specificeert in welke table een rule toegepast moet worden. Als deze flag niet
-A , --append
gebruikt wordt, wordt de standaard table filter gebruikt. Voegt een of meer rules toe aan de gespecificeerde table. Als argument moet aangegeven worden op welke chain deze opdracht uitgevoerd moet worden en
-D, --delete
welke regel eraan toegevoegd moet worden. Verwijdert een of meer rules uit de aangegeven table. Als argument moet aangegeven worden in welke chain gewerkt wordt en welke regel uit de chain bewerkt moet worden. Je kunt verwijzen naar de betreffende regel door middel van een regelnummer (gebruik de optie -L voor een overzicht van alle
-F, --flush
regelnummers). Verwijdert alle regels uit een chain.
-I, --insert
Voeg een regel toe in een chain. De syntaxis hiervoor is iptables -I chain regelnum mer regel.
1 0 D e n e t f i l t e r- f i r e w a l l
353
Flag
Beschrijving
-L, --list
Toont alle regels. Bij deze optie kan aangegeven worden dat alleen regels uit één bepaalde chain getoond moeten worden. Als dit niet gebeurt, worden alle
-N, --new-chain
regels uit alle chains getoond. Definieer een nieuwe chain. Je mag zelf bepalen welke naam die chain moet
-P, --policy
krijgen. Uiteraard moet deze naam wel uniek zijn. Wordt gebruikt om de policy te definiëren. De policy is de standaardregel die in een van de standaard-chains gebruikt wordt. Er kunnen geen policy’s ingesteld worden voor custom chains. Een policy heeft altijd ofwel de action DROP ofwel de ACCEPT. Gebruik deze optie om een regel te vervangen. De syntaxis van deze optie is -R
-R , --replace
chain regelnum mer regelspecificatie.
-X, --delete-chain
Verwijdert een custom chain. Dit kan alleen wanneer er geen regels meer in de
-Z, --zero
chain voorkomen. Zet alle counters waarin bijgehouden wordt hoeveel pakketjes/bytes door een
-E, --rename-chain
bepaalde regel verwerkt zijn op nul. Geeft een andere naam aan een van de custom chains. Kan niet worden toegepast op een standaard-chain.
In deze tabel heb je een overzicht gevonden van de flags die gebruikt kunnen worden. Deze flags definiëren alleen nog maar op welke positie in de chain iets moet gebeuren. De werkelijke actie wordt uitgevoerd door de options. Hier wordt namelijk heel concreet aangegeven aan welke eigenschappen een pakketje moet voldoen om voor verwerking door een regel in aanmerking te komen. In de volgende tabel vind je een overzicht van alle opties die gebruikt kunnen worden. Option
Beschrijving
-d [!] adres[/mask], --destination
Hiermee wordt aangegeven wat het adres is waar een pakketje naartoe gestuurd moet worden. Als adres mag een IP-adres van een node gegeven worden. Het is ook mogelijk een IP-netwerkadres te gebruiken, maar in dat geval moet ook het subnetmasker ingevoerd worden; bijvoorbeeld 193.173.100.0/24 om te verwijzen naar het netwerk 193.173.100.0. Het is ook mogelijk te verwijzen naar namen, maar die moeten dan wel via het standaard name resolving mechanisme achterhaald kunnen worden. Als je een regel wilt maken waarin verwezen wordt naar alle IP-adressen, gebruik je de aanduiding 0/0 of 0.0.0.0/0. Door gebruik te maken van het uitroepteken is het mogelijk te verwijzen naar adressen die juist niet behandeld moeten worden.
354
Linux 4
Option
Beschrijving
[!] -f, --fragment
Soms worden pakketjes in meerdere delen, de zogenoemde fragments verstuurd. Als dit het geval is, komt in deze fragments geen adresinformatie meer voor. Als je in een regel wilt verwijzen naar deze fragments, gebruik je de optie –f, zo weet je zeker dat alle fragmenten waaruit een pakketje bestaan
-h -i [!] interface, -in-interface
worden meegenomen. Geeft hulp over het gebruik. Specificeert de interface waarop de pakketjes binnenkomen. Deze optie is alleen nuttig voor de INPUT-, PREROUTING- en FORWARD-chains aangezien alleen deze chains betrekking hebben op de inkomende interface. Als argument moet de naam van de interface gegeven worden: eth0, ppp0, lo, enzovoort. In deze naamgeving kan gebruikgemaakt worden van een + als wildcard; eth+ verwijst dus naar alle eth-interfaces. Let er vooral goed op dat het weglaten van deze interface betekent dat de regel van toepassing is op elke interface; dit
-o [!] interfaces --out-interface -j target, --jump
zou gemakkelijk tot ongewenst gedrag kunnen leiden. Met deze optie wordt verwezen naar de naam van de interface waarop de pakketjes naar buiten gestuurd worden. Vanwege de aard van de chains heeft deze optie alleen nut in de chains OUTPUT, POSTROUTING en FORWARD. Met deze zeer belangrijke optie wordt aangegeven wat er moet gebeuren op het moment dat een rule een treffer oplevert. Je verwijst hiermee naar een van de targets (ACCEPT, DROP, REJECT, enzovoort) die later in dit hoofdstuk beschreven worden. Als je deze optie vergeet, gebeurt er niets met een pakketje dat voldoet aan de voorwaarden van een regel, alleen de teller dat er
-n, --numeric
een treffer is geweest wordt opgehoogd. Vergeet deze optie dus niet! Zorgt ervoor dat iptables niet probeert IP-adressen in namen te vertalen wanneer het een overzicht geeft van alle aanwezige regels. Dit komt de
-p [!] protocol, -protocol
snelheid aanzienlijk ten goede. Wordt gebruikt om te verwijzen naar het protocol waarop de regel betrekking heeft. Elke naam of elk protocolnummer dat gespecificeerd is in /etc/protocols kan hier gebruikt worden. Als deze optie niet gebruikt wordt, geldt de regel voor
-s [1] address[/ mask], --source -v, --verbose
alle protocollen op het systeem. Deze optie wordt gebruikt om te verwijzen naar het source address dat in een pakketje gebruikt wordt. Bij het tonen van een lijst van alle regels zorgt deze optie ervoor dat er wat
-x, --exact
extra informatie over de regels getoond wordt. Toont het precieze en niet het afgeronde aantal pakketjes en bytes wanneer
--line-numbers
getoond wordt hoeveel pakketjes door een bepaalde regel afgehandeld zijn. Wordt in combinatie met de optie -L gebruikt om nummers voor elke regel te
-m, match _ exten-
tonen. Deze optie wordt gebruikt om te verwijzen naar een match extension. In de
sion
volgende paragraaf kun je lezen wanneer je hier gebruik van wilt maken.
1 0 D e n e t f i l t e r- f i r e w a l l
355
Iptables extensions In het voorgaande heb je gelezen hoe je op een algemene wijze een regel kunt definiëren. Om ervoor te zorgen dat de regel verder verfijnd wordt, maak je gebruik van match extensions. Match extensions zijn uitbreidingen op de bestaande functionaliteit van iptables. Elk van deze extensies wordt aangeroepen door een bepaalde kernelmodule. Dit heeft een enorm stuk flexibiliteit tot gevolg. Door een nieuwe kernelmodule te schrijven zou je er dus voor kunnen zorgen dat er nog meer match extensions beschikbaar komen. Dat is gelijk ook de reden waarom de match extensions gescheiden zijn van de options. Er zijn twee soorten match extensions. Om te beginnen zijn er de match extensions die gerelateerd zijn aan een protocol. Deze worden altijd aangeroepen met een protocolspecificatie zoals -p tcp. Daarnaast zijn er de overige meer algemene match extensions. Deze worden aangeroepen met de speciale optie -m. In de volgende tabel vind je een overzicht van alle soorten match extensions. In de eerste kolom zie je de protocolspecificatie en het type match extension. Deze kolom toont je hoe je de betreffende match extension moet aanroepen. In de tweede kolom zie je de exacte match extension waar het om gaat en in de derde kolom wordt de betekenis verder uitgewerkt. Specificatie
Match extension
Beschrijving
-p tcp
--sport [!] [port[:port] ], --source-port --dport [!] [port[:port]], -destination-port --tcp-flags [!] mask comp
Wordt gebruikt om de source-poort of reeks source-poorten te specificeren. Om een reeks op te geven gebruik je bijvoorbeeld 1234:1240. Wordt gebruikt om de destination-poort of reeks destination poorten op te geven. Hiermee kun je opgeven welke TCP/IP-flags bekeken moeten worden. Als mask specificeer je alle flags die bekeken moeten worden, als comp specificeer je die flags waarop
[!] –syn
gefilterd moet worden. Staat gelijk aan --tcp-flags SYN,RST,ACK SYN waar gekeken wordt naar pakketjes waarin SYN aan staat en RST en ACK niet. Dergelijke pakketjes worden gebruikt om een TCP-connectie op te bouwen, ze kunnen echter ook misbruikt worden in een SYN-attack.
356
Specificatie
-p udp
-p icmp
Linux 4
Match extension
Beschrijving
--tcp-option [!] nummer --sport [!] [port[!port]], -source-port --dport [!] [port[:port]], -destination port --icmp-type [!] type[/code]
Kijkt naar een specifieke TCP-optie. Gelijk aan de overeenkomende optie bij -p tcp.
Gelijk aan de overeenkomende optie bij -p tcp.
Kan gebruikt worden om te filteren op een specifiek type ICMP-pakketje. Gebruik de opdracht iptables p icmp -h om een overzicht te krijgen van alle typen
-m mac
--mac-source [!] adres
ICMP-pakketjes waarop gefilterd kan worden. Hiermee kun je filteren op inkomende MAC-pakketjes. Aangezien deze optie alleen werkt op inkomende pakketjes, heeft het dus alleen zin er gebruik van te maken in de chains PREROUTING en de INPUT. Deze match extension kan gebruikt worden om het aantal
-m limit
van een bepaald soort pakketje te beperken. Deze optie is bijvoorbeeld nuttig om ervoor te zorgen dat DoS-attacks voorkomen worden. Hiermee wordt een server immers bestookt met constant hetzelfde pakketje. Zonder verdere specificatie wordt het aantal pakketjes van een bepaalde
--limit aantal
soort met deze optie beperkt tot drie per uur. Hiermee kun je de match extension -m limit verder specificeren. De opties zijn n/s, n/m , n/h en n/d waarin n een getal is en /s, /m , /h en /d bepalen of het gaat om
--limit-burst aantal -m multiport
-m mark
--source-port port[,port[,…]] --destination-port port[,port[,…]] --mark waarde[/ masker]
een aantal pakketjes per seconde, minuut, uur of dag. Stelt een maximaal aantal pakketjes in dat in een burst voor mag komen waarna de limit wordt toegepast. De standaardwaarde is 5. Deze extensiemodule wordt gebruikt om tot een maximum van vijftien source-poorten op te kunnen geven. Zie voorgaande, maar dan voor destination-poorten.
Kan alleen gebruikt worden in de table MANGLE en heeft betrekking op iproute2. Deze optie heeft een beperkte toepasbaarheid.
1 0 D e n e t f i l t e r- f i r e w a l l
357
Specificatie
Match extension
Beschrijving
-m state
--state state
Wordt gebruikt om de status van een pakketje te bekijken. Deze kan ingesteld staan op INVALID (het pakketje maakt geen deel uit van een connectie), ESTABLISHED (pakketje maakt deel uit van een connectie, NEW (pakketje poogt een nieuwe connectie op te bouwen) en RELATED (pakketje bouwt een nieuwe connectie op die gerelateerd is aan een reeds bestaande connectie). Dit is een experimentele module waarin gekeken wordt
-m unclean
naar ongebruikelijke pakketjes. Denk bijvoorbeeld aan TCP-pakketjes met een ongebruikelijke optie zoals FIN.
-m tos
--tos tos
Ook wordt gekeken naar andere ongeldige pakketjes. Wordt gebruikt om te kijken naar een waarde die in het TOS-veld is ingesteld. Gebruik de opdracht iptables m tos -h voor een volledig overzicht van deze waarden.
-m owner
--uid-owner UID
Deze match extension zoekt naar de eigenaar van een pakketje. Deze eigenaar wordt bepaald op basis van de eigenaar van het proces dat het pakketje gegenereerd heeft en kan dientengevolge alleen gebruikt worden voor pakketjes die op de lokale machine gegenereerd zijn en via de chain
--gid-owner gid --pid-owner pid --sid-owner sessionid
OUTPUT naar buiten gaan. Zoekt naar de overeenkomstige GID van de owner. Zoekt naar het process-ID van het proces dat het pakketje gegenereerd heeft. Zoekt naar de overeenkomstige session-ID die aan een pakketje verbonden is.
Iptables actions Tot nu toe hebben we alleen nog gekeken naar de criteria waar in een pakketje naar gekeken moet worden. Waar het bij een firewall natuurlijk allemaal om gaat, is dat er bij een match ook een bepaalde actie wordt uitgevoerd. Iptables biedt hiervoor een behoorlijk aantal opties. In de volgende tabel vind je hier een volledig overzicht van.
358
Linux 4
Action
Beschrijving
ACCEPT DROP
Laat het pakketje door.
REJECT [--rejectwith option]
Laat het pakketje vallen zonder dat er een bericht teruggestuurd wordt naar de afzender van het pakketje. Laat het pakketje vallen, maar zorgt ervoor dat er wel een ICMP-bericht teruggestuurd wordt naar de afzender van het pakketje. Standaard wordt het ICMPbericht icmp-port-unreachable teruggestuurd. Wanneer je gebruikmaakt van --reject-with , is het ook mogelijk zelf op te geven welke ICMP-foutmelding
gegenereerd moet worden. Hiervoor kun je kiezen uit: – icmp-net-unreachable – icmp-host-unreachable – icmp-port-unreachable – icmp-proto-unreachable – icmp-net-prohibited – tcp-reset
MASQUERADE [--toports port [-port]]
– icmp-host_prohibited Deze action kan alleen gebruikt worden in de chain nat/POSTROUTING. Daarnaast moet deze optie alleen gebruikt worden wanneer het masqueradeadres dynamisch door middel van DHCP uitgedeeld wordt. Bij gebruik van statische adressen moet je gebruikmaken van SNAT. Deze optie zorgt ervoor dat iptables zich als klassieke NAT-router gaat gedragen: alle pakketjes die naar buiten verstuurd worden, worden verstuurd met als afzender het geregistreerde
REDIRECT [[to-ports port[-port]]
IP-adres van de NAT-router. Ook deze action kan alleen gebruikt worden in de table nat en wel in de chains PREROUTING en OUTPUT. Met deze action wordt ervoor gezorgd dat de betreffende pakketjes doorgestuurd worden naar de lokale machine. Eventueel kan hierbij opgegeven worden dat de redirection plaats moet vinden naar gespecifi-
RETURN
ceerde poorten. Als deze actie voorkomt in een door jezelf gemaakte custom chain, is het resultaat dat het pakketje doorgestuurd wordt naar de volgende regel in de betreffende chain. Wanneer de actie in een van de standaard chains voorkomt, zorgt
QUEUE
deze actie ervoor dat de default policy wordt uitgevoerd. Deze geavanceerde optie zorgt ervoor dat pakketjes doorgestuurd kunnen worden naar een specifieke toepassing. Om dit te kunnen doen moet gebruikgemaakt worden van de module ip_queue.
1 0 D e n e t f i l t e r- f i r e w a l l
Action
Beschrijving
LOG [--log-level level] [--log-prefix string] --log-tcpsequence --logtcp-options --logip-options
Deze optie zorgt ervoor dat het betreffende pakketje gelogd wordt naar de
359
standaardlogfunctie, in de meeste gevallen syslogd. Met behulp van de optie --log-level wordt ingesteld welk loglevel hiervoor gebruikt moet worden.
Dit verwijst naar standaardloglevels zoals die in het syslogd-mechanisme gebruikt moeten worden. Om ervoor te zorgen dat voorafgaand aan een gelogde regel een bepaalde string getoond wordt, kan gebruikgemaakt worden van de optie --log-prefix. De overige drie specificaties kunnen gebruikt worden om
TOS [--set-tos tos]
respectievelijk tcp-sequencenummers, tcp-opties en ip-opties te loggen. Deze actie kan alleen gebruikt worden in de table mangle. Met behulp van deze actie kun je het TOS-veld in de IP-header instellen op een bepaalde waarde. Zie
DNAT --todestination ipaddr[ipaddr][: port:port]
voor meer informatie de opdracht iptables -j TOS –h. Deze actie kan alleen gebruikt worden in de chains nat/PREROUTING en nat/ OUTPUT-. Deze actie zorgt ervoor dat het destination IP-adres in een pakketje vertaald moet worden in een ander IP-adres, eventueel in een reeks IP-adressen. Ook is het mogelijk te vertalen naar een specifiek poortadres. Om dit laatste te bewerkstelligen moet in de regel echter wel gebruikgemaakt worden van de optie -p tcp of de optie -p udp om een match op een bepaalde poort te
SNAT --to-source ipaddr[-ipaddr][: port:port] MIRROR MARK [--set-mark mark] Custom-chain
definiëren. De hier gebruikte techniek staat ook bekend als port forwarding. Deze regel kan alleen worden toegepast in nat/POSTROUTING. De actie specificeert dat het source IP-adres vertaald moet worden in een ander IP-adres. Eventueel kunnen hier ook poortadressen bij gebruikt worden. Dit is een experimentele actie waarbij source en destination IP-adressen omgedraaid worden. Hiermee kan in de table mangle de markwaarde van een pakket worden ingesteld. Zorgt ervoor dat een zelfgemaakte chain met de gespecificeerde naam wordt aangeroepen.
10.4
Iptables in de praktijk
In het voorgaande heb je kennisgemaakt met de bouwstenen waaruit een iptables-firewall is opgebouwd. Omdat wij ons kunnen voorstellen dat je door de bomen even het bos niet meer ziet, zullen we nu bespreken hoe je een en ander het beste in de praktijk kunt toepassen. Om te beginnen moet je ervoor zorgen dat er een policy wordt ingesteld voor een aantal chains. De policy is de standaardregel die het standaardgedrag voor iptables bepaalt. Alleen wanneer er
360
Linux 4
in een eerdere regel een uitzondering gedefinieerd is, wordt er van deze standaard-policy afgeweken, zo niet dan is altijd de policy op pakketjes van toepassing. Vooral wanneer je iptables gebruikt om te bepalen welke pakketjes wel en welke pakketjes niet doorgestuurd mogen worden, is het aan te raden de policy zo in te stellen dat alle verkeer wordt tegengehouden. De volgende regels zorgen ervoor dat in de table filter het standaardgedrag voor elke chain wordt ingesteld op DROP. Hiermee maak je een veilig systeem, namelijk een systeem dat volledig dicht zit. De kunst is hier vervolgens uitzonderingen op te definiëren. Je kunt naar hartenlust experimenteren met iptables. Alle opdrachten die je geeft, zijn na een herstart van je computer toch weer vergeten; je krijgt tijdens het opstarten gewoon de standaardinstellingen weer terug. Als je op een systeem met een bestaande configuratie met iptables wilt experimenteren, geef dan eerst de opdracht iptables –L om een overzicht te geven van alle chains die op dit moment gedefinieerd zijn en de inhoud van die chains. Geef vervolgens de opdracht iptables --flush om alle bestaande regels weg te gooien en met een schone lei te beginnen. Vervolgens kun je verdergaan met het instellen van de standaard-policy’s. Figuur 10.2 Geef voordat je begint met bouwen van een firewall altijd eerst de opdracht iptables -L om te kijken of er misschien standaard al het een en ander geactiveerd is
iptables -P FORWARD DROP iptables -P INPUT DROP iptables –P OUTPUT DROP
1 0 D e n e t f i l t e r- f i r e w a l l
361
Met de standaard-policy ingesteld op DROP, weet je in elk geval zeker dat je veilig bent, maar daarnaast weet je ook dat er helemaal niets is dat werkt als het op IP gebaseerd is. Het is echter wel een goede basis om verder te bouwen aan de iptables-firewall. In het volgende voorbeeld zullen we bespreken hoe je iptables zo kunt instellen dat een router op basis van iptables alleen ftp-pakketjes van het interne netwerk doorlaat naar buiten. Voor de rest gebeurt er niets anders. Dit is misschien niet het meest realistische scenario, maar toont wel heel aardig hoe je een iptables-firewall moet opzetten. Daarnaast is het aardig dat voor het gebruik van FTP twee poorten opengezet moeten worden, er is immers een ftp-opdracht en een ftp-datapoort. Om dit voor elkaar te krijgen zijn de volgende regels nodig. iptables -P FORWARD DROP iptables -P INPUT DROP iptables -P OUTPUT DROP iptables -A FORWARD -s 192.168.1.0/24 -d 0/0 -m multiport -p tcp -dport ftp,ftp-data
-j ACCEPT
iptables -A FORWARD -s 0/0 -d 192.168.1.0/24 -p tcp --sport ftpdata –j ACCEPT iptables -A FORWARD -s 0/0 -d 192.168.1.0/24 -p tcp --sport ftp ! --syn -j ACCEPT iptables -A FORWARD –j LOG --log-prefix “iptables FORWARD:
“
De regels beginnen ermee dat de policy voor elke chain wordt ingesteld op DROP, zodat een veilige situatie als uitgangspunt genomen wordt. Hierop wordt vervolgens een uitzondering gedefinieerd in de chain FORWARD. In de eerste regel in de chain FORWARD wordt bepaald dat alle ftp en ftp-datapakketjes die uit het sourcenetwerk 192.168.1.0 komen, mogen worden doorgelaten. De volgende twee regels definiëren dat zowel ftp-data als ftp-pakketjes teruggestuurd mogen worden. Type machine In het voorgaande voorbeeld wordt gebruikgemaakt van een FORWARD-chain. Kun je daaruit afleiden wat voor soort machine dit is? Een standaloneserver of een router? Op de normale ftp-pakketjes die vanaf het externe netwerk terugkomen, wordt echter nog wel een uitzondering gemaakt: wanneer
362
Linux 4
de TCP SYN-flag aan staat, wordt het pakketje niet doorgelaten. In dat geval is het namelijk een pakketje dat probeert een sessie te initiëren en dat is niet toegestaan. Het gaat er immers niet om dat buitenstaanders de FTP-servers kunnen gebruiken, maar dat je gebruikers FTP-servers op internet kunnen gebruiken. Vanaf het externe netwerk mogen alleen pakketjes teruggestuurd worden als antwoord op verzoeken die vanaf het lokale netwerk afkomstig zijn. Tot slot wordt voor alle overige pakketjes in de chain FORWARD een entry weggeschreven in het logbestand. De reden waarom deze laatste regel alleen geldt voor alle overige pakketjes ligt voor de hand: wanneer een pakketje immers een regel tegenkomt waaraan voldaan wordt, wordt er niet verder gekeken of er nog meer regels zijn waaraan voldaan wordt. Dit betekent dat alle ftp-pakketjes al afgehandeld zijn op het moment dat een pakketje bij de laatste regel komt. Houd er rekening mee dat deze laatste regel er waarschijnlijk voor zorgt dat gigantisch veel informatie weggeschreven wordt naar de logbestanden! (Voor een hacker zou dit een leuke uitdaging zijn om dit als DoS-attack te gebruiken.) De hiervoor genoemde regels zorgen ervoor dat iptables alle ftp-pakketjes van het interne netwerk doorlaat naar het externe netwerk en dat het ook mogelijk is dat er antwoord komt op deze pakketjes. Deze regels hebben zin wanneer de machine waarop je ze gebruikt een router is. Maar hoe zit het nu met ftp-pakketjes die gegenereerd worden vanaf de lokale machine? Welnu, deze worden niet doorgelaten. Het verkeer op de lokale machine wordt immers bepaald door de chains INPUT en OUTPUT in de table filter; de FORWARD-chain die in het hiervoor genoemde gebruikt is definieert de werking van een router. Om ervoor te zorgen dat ook de lokale machine ftp-pakketjes mag versturen, moeten de regels nog wat uitgebreid worden. De nu volgende regels dienen als uitbreiding op het voorgaande voorbeeld. We gaan er daarbij overigens van uit dat de lokale machine op de externe interface gebruikmaakt van IP-adres 10.0.0.1 iptables -A OUTPUT -o eth0 -s 10.0.0.1 -d 0/0 -m multiport -p tcp --dport ftp,ftp-data -j ACCEPT iptables -A OUTPUT -j LOG --log-prefix “iptables OUTPUT:
“
iptables -A INPUT -i eth0 -s 0/0 -d 10.0.0.1 -p tcp --sport ftpdata -j ACCEPT iptables -A INPUT -I eth0 -s 0/0 -d 10.0.0.1 -p tcp --sport ftp !
1 0 D e n e t f i l t e r- f i r e w a l l
363
--syn -j ACCEPT iptables -A INPUT -j LOG --log-prefix “iptables INPUT:
“
Je ziet dat deze regels eigenlijk grotendeels gelijk zijn aan de regels in de FORWARD-chain. Het enige verschil is dat het nu om een intern proces gaat. Dat betekent dat er niet gewerkt wordt met de FORWARD-chain, maar met OUTPUT voor uitgaande pakketjes en met INPUT voor alles wat binnenkomt. Alles bij elkaar zijn deze regels efficiënt om ervoor te zorgen dat er geen pakketjes verstuurd kunnen worden met uitzondering van ftp-pakketjes. Het kan echter veel eenvoudiger: vooral voor wat betreft de pakketjes die als antwoord weer terugkomen. Wanneer gebruikgemaakt wordt van connection tracking door de twee hiervoor noodzakelijke kernelmodules te laden, kun je gewoon kijken naar pakketjes met een status (--state) van ESTABLISHED of RELATED. Hoe dat er dan uit komt te zien, kun je in de volgende regels zien. Let vooral op de eerste twee regels waarin de kernelmodules geladen worden die noodzakelijk zijn voor connection tracking: modprobe ip _ conntrack modprobe ip _ conntrack _ ftp iptables -P FORWARD DROP iptables -P INPUT DROP iptables -P OUTPUT DROP iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A FORWARD -m state --state NEW -s 192.168.1.0/24 -d 0/0 -p tcp --dport ftp -j ACCEPT iptables -A FORWARD -m limit -j LOG --log-prefix “iptables FORWARD: “ iptables -A OUTPUT -o eth0 -s 10.0.0.1 -d 0/0 -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A OUTPUT -m state --state NEW -o eth0 -s 10.0.0.1 -d 0/0 -p tcp --dport ftp -j ACCEPT iptables -A OUTPUT -m limit -j LOG --log-prefix “iptables OUTPUT: “ iptables -A INPUT -I eth0 -s 0/0 -d 10.0.0.1 -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A INPUT -m limit -j LOG --log-prefix “iptables INPUT:
“
364
Linux 4
Let erop dat naast de nieuwe functie van connection tracking hier ook een limiet gesteld wordt aan het maximale aantal regels dat in de logbestanden zal verschijnen. Hiervoor wordt gebruikgemaakt van de match extension -m limit. Deze match extension zorgt ervoor dat er van elke pakketsoort maximaal drie logs per uur plaatsvinden. Zo heb je gelijk actie ondernomen tegen de hacker die er misbruik van wil maken dat hij anders je logbestanden razendsnel vol kan schrijven (maar daar had je natuurlijk met behulp van logrotate al maatregelen tegen getroffen). 10.5
Iptables als Network Address Translator
Je hebt tot nu toe gelezen over de wijze waarop je een eenvoudige router met iptables kunt beveiligen. In het dagelijks leven zul je echter vooral routers tegenkomen waarop gebruikgemaakt wordt van NAT. Dit zorgt ervoor dat op het privénetwerk gebruikgemaakt wordt van adressen uit de private address range. Deze privéadressen worden door de NAT-router vertaald, zodat elke node uit het lokale netwerk internet op kan door gebruik te maken van het IP-adres van de NAT-router. NAT is echter meer dan dat. Wanneer je de beschikking hebt over meerdere geregistreerde IP-adressen, is het ook mogelijk om nodes die op het lokale netwerk voorkomen bereikbaar te maken op een van deze geregistreerde IP-adressen. Tip! Adressen uit de private address range worden op internet niet gerouteerd. De volgende adressen kunnen voor dit doel gebruikt worden:
Alle adressen uit het netwerk 10.0.0.0. Alle adressen van 172.16.0.0 tot en met 172.31.255.255. Alle adressen die beginnen met 192.168. In figuur 10.3 zie je het voorbeeldnetwerk dat we gaan configureren met behulp van iptables. Wat hier opvalt, is dat het netwerk uit twee componenten bestaat. Om te beginnen is er een aantal nodes dat alleen maar contact op hoeft te kunnen nemen met nodes op internet, maar niet vanaf internet bereikbaar hoeft te zijn. Daarnaast zijn er twee servers op het interne netwerk die wel vanaf internet bereikt moeten kunnen worden. Om dit laatste voor elkaar te
1 0 D e n e t f i l t e r- f i r e w a l l
365
krijgen is het absoluut noodzakelijk dat je beschikt over meerdere geregistreerde IP-adressen. Je kunt een dergelijk netwerk configureren met behulp van de volgende configuratie. Figuur 10.3 Dit netwerk moet geconfigureerd worden met iptables
modprobe iptable _ nat modprobe ip _ nat _ ftp modprobe ip _ conntrack modprobe ip _ conntrack _ ftp iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT DROP iptables -t nat -A PREROUTING -d 193.173.97.2 -j DNAT --todestination 192.168.1.2 iptables -t nat -A PREROUTING -d 193.173.97.3 -j DNAT --todestination 192.168.1.3 iptables -t nat -A POSTROUTING -s 192.168.1.2 -j SNAT --to-source 193.173.97.2 iptables -t nat -A POSTROUTING -s 192.168.1.3 -j SNAT --to-source 193.173.97.3 iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -j SNAT iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A FORWARD -s 192.168.1.0/24 -d 0/0 -m state --state NEW -j ACCEPT iptables -A FORWARD -s 0/0 -d 192.168.1.2 -m state --state NEW,ESTABLISHED,RELATED -p tcp --dport www -j ACCEPT iptables -A FORWARD -s 0/0 -d 192.168.1.3 -m state --state NEW,ESTABLISHED,RELATED -p tcp --dport ftp -j ACCEPT iptables -A OUTPUT -m state --state NEW,ESTABLISHED,RELATED -j
366
Linux 4
ACCEPT iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A INPUT -I eth0 -s 192.168.1.0/24 -d 192.168.1.1 -m state --state NEW -j ACCEPT
Veel van de regels in dit voorbeeld zul je herkennen. Nieuw zijn de regels waar gewerkt wordt in de nat-table (-t nat). De eerste twee regels zorgen ervoor dat alle pakketjes die binnenkomen op IP-adres 193.173.97.2 en 3 vertaald worden naar de overeenkomstige private IP-adressen. Vervolgens zijn er twee regels (POSTROUTING) waarin het omgekeerde gebeurt. Dit is noodzakelijk om ervoor te zorgen dat pakketjes die afkomstig zijn van de WWW- en FTP server op het private netwerk door de iptablesrouter verstuurd worden met de juiste source-adressen. Als dit niet zou gebeuren, zouden ze immers met de source-adressen uit het netwerk 192.168.1.0 het internet op gaan en dientengevolge onbereikbaar zijn. Vervolgens is er als derde POSTROUTING-regel in de nat-table de regel die ervoor zorgt dat alle pakketjes die afkomstig zijn van alle andere nodes op het private netwerk naar buiten gaan met het IP-adres van de iptables-router. Aangezien hier gebruikgemaakt wordt van een statisch IP-adres (het adres 193.173.97.1), wordt gebruikgemaakt van de action SNAT. Als er nu geen gebruikgemaakt zou zijn van een statisch IP-adres op de iptables-router, maar een dynamisch adres dat verkregen is van een DHCP-server, zou hier in plaats van SNAT gebruikgemaakt moeten worden van de action MASQUERADE. Doordat naar de status van een pakketje gekeken wordt, is het niet nodig om nog aparte regels te definiëren die ervoor zorgen dat de antwoorden vanaf internet ook weer teruggestuurd mogen worden naar deze nodes. Dit gebeurt automatisch door te kijken naar de status ESTABLISHED en RELATED. Misschien denk je dat je er nu bent: dat is niet helemaal het geval. De iptables-router is op dit moment namelijk nog niet geconfigureerd om te luisteren naar de IP-adressen 193.173.97.2 en 193.173.97.3. Dit is eenvoudig op te lossen door gebruik te maken van IP-aliasen. Dit betekent dat een tweede IP-adres aan een interface wordt toegewezen. Je verwijst dan alleen niet naar eth1, maar naar eth1:0 en eth1:1, enzovoort. Om het hiervoor genoemde voorbeeld compleet te maken moet je hiervoor nog de volgende opdrachten uitvoeren: ifconfig eth1:0 193.173.97.2
1 0 D e n e t f i l t e r- f i r e w a l l
367
ifconfig eth1:1 193.173.97.3
Deze opdrachten zorgen ervoor dat eth1 niet langer naar slechts één IP-adres luistert, maar naar drie verschillende IP-adressen. Tip! Zoals je waarschijnlijk gemerkt zult hebben, komen er in een beetje serieuze firewall al snel heel veel regels voor. Je moet er natuurlijk niet aan denken na een vergissing al deze regels opnieuw in te moeten voeren! Dit is eenvoudig te voorkomen door een back-up van alle regels te maken met de opdracht iptables-save. Als je op deze wijze een back-up hebt weggeschreven naar een bestand, kun je de regels uit dit bestand weer terugzetten met de opdracht iptables-restore. Gebruik daarbij de redirector om te verwijzen naar het bestand waarin de back-up opgeslagen is: iptables-save > firewallrules iptables-restore < firewallrules
10.6
Samenvatting
In dit hoofdstuk heb je kennisgemaakt met het laatste ingrediënt dat nodig is om een goed functionerende Linux-server te bouwen: de firewall. We hebben besproken hoe je handmatig met behulp van iptables zelf een firewall kunt bouwen. Het is absoluut de moeite waard je te bekwamen in de werking van iptables. Het verschil tussen een goed functionerende firewall en een firewall die net niet helemaal doet wat je ervan verwacht, zit hem namelijk in de details en nu net deze details kunnen niet ingesteld worden vanuit een grafische interface.
11
Shellscripting
11.1
Inleiding
Je hebt nu kennisgemaakt met de belangrijkste netwerk gerelateerde services die gebruikt worden op Linux-systemen. Daarmee zijn we er echter nog niet. Om een server werkelijk te kunnen beheren, is het noodzakelijk dat je overweg kunt met shellscripts. In dit hoofdstuk vind je een gedegen introductie in dit onderwerp. 11.2
Shellscripts
Er zijn twee belangrijke redenen om je te verdiepen in shellscripting. De eerste reden is dat vrijwel alles wat gebeurt tijdens het opstarten van de computer, gebeurt in de vorm van shellscripts. Mocht er ooit eens wat mis gaan tijdens het opstarten, of mocht je ooit eens de behoefte hebben om de opstartprocedure van het systeem aan te passen, dan is het om die reden belangrijk dat je de scripts uit de opstartprocedure kunt lezen en zelf kunt inschatten wat er mis gaat. Daarnaast is het van belang dat je zelf eenvoudige shellscripts kunt schrijven. Je zult merken, je eerste shellscript zal waarschijnlijk niet heel veel meer zijn dan enkele opdrachten die door middel van een pipe aan elkaar verbonden zijn. Als je echter de smaak te pakken krijgt en de basiselementen van een shellscript onder de knie hebt, zul je al snel kleine intelligente scripts kunnen schrijven. Ben je weer wat verder, dan worden de scripts steeds groter, tot op het moment dat je een aan het ziekelijk grenzende behoefte krijgt om shellscripts te schrijven voor vrijwel alle regelmatig terugkerende taken.
370
Linux 4
11.2.1 Een script of iets anders? Voordat je begint met scripten, is het zaak je af te vragen of een shellscript de meest geëigende oplossing is voor het probleem dat je wilt tackelen. Vaak zijn er namelijk ook andere mogelijkheden, zoals het schrijven van een Perl-script of zelfs een volledig programma geschreven in de programmeertaal C. Elk van deze oplossingen heeft zo zijn voor- en nadelen. Het belangrijkste voordeel van een shellscript is dat het relatief eenvoudig te maken is. Ook hoeven shellscripts niet gecompileerd te worden voordat je ermee aan het werk kunt. Het enige wat je nodig hebt op de doelcomputer, is namelijk dat de shell waarin het script geschreven is aanwezig is. Het nadeel echter is dat het langzaam is. Dit komt omdat de shell er altijd voor moet zorgen dat het script geïnterpreteerd wordt en de opdrachten die in het script voorkomen op de juiste wijze worden geïnterpreteerd. Ook bevindt de shell zich tussen de opdrachten en de hardware die uiteindelijk gebruikt worden om de opdrachten uit te voeren. Dit is niet het geval als je bijvoorbeeld gebruikmaakt van een C-programma. Een dergelijk programma hoeft niet eerst geïnterpreteerd te worden, maar kan direct aan het werk op de hardware nadat het voor gebruik op die hardware gecompileerd is. Voor veel voorkomende taken op de server is een C-programma toch vaak minder geschikt, ondanks dat het sneller is. Een C-programma moet namelijk eerst gecompileerd worden voordat het gebruikt kan worden. Heb je ooit de behoefte om een wijziging in het programma toe te passen? Dan is dat gezien de lastige taal waarin C geschreven is ook een stuk moeilijker. Daarnaast zijn de taken waarvoor shellscripts ingezet worden relatief eenvoudig. De winst die je zou halen door deze taken uit te laten voeren door een C-programma, is daarom vaak te verwaarlozen. Time Als je complexe shellscripts gaat schrijven, is snelheid een serieus issue. Het gebruik van een ietwat afwijkende constructie kan ervoor zorgen dat het shellscript een heel stuk sneller wordt. Om die reden is het belangrijk precies te weten hoe snel een script nu eigenlijk is. Dit doe je met behulp van de opdracht time. Gebruik bijvoorbeeld time mijnscript en je zult precies zien hoeveel tijd in beslag genomen werd voor het uitvoeren van het script.
11 Shellscripting
371
11.2.2 Verschillende shells? Er zijn op Linux zeer verschillende shells die gebruikt kunnen worden. Bij het schrijven van een shellscript moet je daar rekening mee houden. Een script dat voor een bepaalde shell geschreven is, doet het namelijk niet altijd ook automatisch op een andere shell. Gelukkig wordt de keuze relatief eenvoudig gemaakt door het feit dat de Bash-shell (/bin/bash) de meest gebruikte shell is op Linux. Elke Linux-distributie maakt er standaard gebruik van. Qua features is het ook een heel rijke shell en daarom is er weinig reden om iets anders te gebruiken als Bash. Bash is een afgeleide van de oeroude Bourne-shell (/bin/sh) die al in de jaren zeventig op UNIX-systemen gebruikt werd (de afkorting staat dan ook voor Bourne Again Shell). Het leuke daarvan is dat elk script dat geschreven is voor deze Bourne-shell het ook altijd onder Bash zal doen. Omgekeerd is dat niet het geval omdat Bash features heeft die in de Bourne-shell nog niet voorkwamen. Als je dus absoluut zeker wilt zijn dat je script het ook gaat doen, maak je gebruik van de Bourne-shell /bin/sh. Ben je zeker dat Bash voorkomt op het systeem waarop het script gebruikt wordt, zorg er dan voor dat het script altijd begint met de zogenoemde shebang. Dit is de aanduiding #!/bin/bash aan het begin van een script waardoor de shell weet welk programma gebruikt moet worden voor de uitvoering van het betreffende programma. Naast Bash zijn er nog veel andere shells die gebruikt kunnen worden. De drie meest bekende daarvan zijn de Korne-shell (/bin/ ksh) die onder Linux bekend staat als /bin/pdksh en de C-shell (/bin/csh) die onder Linux bekend staat als /bin/tcsh. Daarnaast heeft ook de zeer uitgebreide Z-shell (zsh) de laatste jaren wat terrein gewonnen. De Korne-shell zul je op Linux niet bijzonder vaak tegenkomen. Dit is echter op sommige UNIX-varianten een veelgebruikte shell en om die reden vinden sommige Linux-gebruikers die vroeger met Korne gewerkt hebben het prettig deze shell ook op Linux te gebruiken. De C-shell is vooral populair onder programmeurs die ook gebruikmaken van de programmeertaal C. Beide shells kenmerken zich doordat ze niet compatible zijn met de Bash-shell. Een script dat dus voor Korne- of C-shell geschreven is, zal het onder Bash niet doen en omgekeerd zal een Bash-script het niet doen onder de C-shell. Dit probleem kan echter opgelost worden
372
Linux 4
als de shell waarin het script geschreven is aanwezig is op het systeem waar het wordt uitgevoerd. Het is namelijk gebruikelijk elk shellscript te beginnen met de zogenoemde ‘shebang’. Dit is een regel die begint met een commentaarteken gevolgd door een uitroepteken en de naam van de shell die gebruikt moet worden om het script uit te voeren. Als de Bash-shell op het moment dat het script wordt aangeroepen niet actief is, maar wel ergens op de vaste schijf van de computer voorkomt, zorgt deze regel ervoor dat de shell alsnog geactiveerd wordt om het script uit te voeren. #!/bin/bash # # mijnscript [bestandsnaam] # # Dit script kan gebruikt worden om.... ....
11.2.3 Basiselementen van een script Elk goed shellscript bestaat altijd uit een aantal basiselementen. Als eerste begint het script met de regel met de shebang die aangeeft door welke shell het geïnterpreteerd moet worden. Daarna is het gebruikelijk enkele regels commentaar op te nemen. Deze commentaarregels beginnen met een #. Dit teken zorgt ervoor dat alles wat volgt niet door de shell geïnterpreteerd wordt. In dit commentaar is het aardig als je kort aangeeft hoe het script gebruikt moet worden door als eerste een syntaxisregel te definiëren. Deze syntaxisregel is in abstracte notatie een voorbeeld van het gebruik van het script. Ook misstaat het niet kort aan te geven wat het doel is van het script. Op het moment namelijk dat je begint met schrijven van een script, is het script altijd overzichtelijk en weet je precies wat het doet. Veel scripts echter gaan in de loop der tijd een eigen leven leiden. Er wordt meer en meer code aan toegevoegd totdat uiteindelijk de maker van het script zelf niet eens meer weet wat nu precies de bedoeling was. Om te voorkomen dat je dat ook overkomt is het goed om veel commentaar op te nemen. Niet alleen aan het begin van het script, maar bijvoorbeeld ook later in het script als je begint met het programmeren van een nieuw onderdeel. Zo verdeel je het script in hapklare brokken waarbij elke brok zijn eigen commentaar toegevoegd heeft. Het gevolg is dat je altijd het overzicht behoudt.
11 Shellscripting
373
Naast het commentaar bevat het script opdrachten die uitgevoerd moeten worden. Elke opdracht komt hiervoor in aanmerking: je mag in een script verwijzen naar interne shell-opdrachten (heel snel), maar ook naar opdrachten die ergens op de vaste schijf van de computer voorkomen. Zolang het maar een opdracht is die de shell kan terugvinden en kan uitvoeren, dan moet het goed komen. Hieronder volgt een eenvoudig voorbeeld van een script dat aan al deze voorwaarden voldoet: #!/bin/bash # # Klassiek voorbeeld van een shellscript # # gebruik: hallo # echo “Hallo wereld!” exit 0
In dit script zie je twee dingen die opvallen. Als eerste is dat de opdracht die uitgevoerd moet worden: “Hallo wereld”. Deze opdracht komt in het script voor om de eenvoudige reden dat nu eenmaal elke cursus programmeren begint met het begroeten van de wereld, dus dat hoeft voor een shellscript niet anders te zijn. Vervolgens wordt het script besloten met de opdracht exit 0. Deze opdracht zorgt ervoor dat het script wordt afgesloten en dat daarbij aan de shell verteld wordt of dat met succes is gebeurd. We noemen dit de zogeheten exit-status. Het gebruik van een exit-status is in een eenvoudig script als dit natuurlijk niet nodig, maar naar mate het script meer complex wordt en je ook de situatie wilt afvangen dat het script met een foutmelding beëindigd wordt, wordt het werken met een exit-status belangrijker. Op basis van de exit-status van een script kan de shell van waaruit het script werd uitgevoerd namelijk besluiten dat een bepaalde actie uitgevoerd moet worden. Uiteindelijk betekent dit dat je de exit-status kunt gaan gebruiken als foutcodes, zodat je altijd precies weet wat er misgegaan is op basis van de exit-status. Wil je overigens weten wat de exit-status was van de laatste opdracht of het laatste script dat je hebt uitgevoerd? Typ dan de opdracht echo $? in de shell. Je ziet nu hoe de laatste opdracht is afgesloten.
374
Linux 4
11.2.4 Uitvoerbaar maken Nu je het script geprogrammeerd hebt, wordt het tijd er ook wat mee te doen. Je wilt het resultaat van je programmeerkunsten tot zover natuurlijk wel eens uit proberen! Hiervoor bestaan verschillende manieren: 1. Aanroepen als argument van de Shell. 2. Het script ‘sourcen’. 3. Uitvoerbaar maken en aanroepen. Als je zonder al te veel handelingen te verrichten wilt kijken of het script bruikbaar is, kun je het aanroepen als argument van de shell. Concreet betekent dit dat je vanuit de huidige shell een nieuwe shell start en ervoor zorgt dat deze shell het script uitvoert. Als het script de naam “hallo” heeft, ziet de opdracht er als volgt uit: bash hallo
Er wordt op dat moment een subshell gestart en het script in kwestie wordt vanuit deze subshell geactiveerd. Deze manier van werken heeft een belangrijk gevolg: als er bijvoorbeeld een bepaalde variabele in het script wordt ingesteld, betekent dit dat de variabele in kwestie alleen in het script zelf beschikbaar is en niet meer in de shell van waaruit het script is aangeroepen nadat het script beëindigd is. De tweede manier om een script uit te voeren is door gebruik te maken van de opdracht source. Deze opdracht bestaat uit een enkele punt en daarna wordt de naam gegeven van het script dat je wilt voeren. In dit voorbeeld wordt dat dus: . hallo
Als je op deze manier een script uitvoert, wordt er géén subshell gestart, maar wordt het script vanuit de huidige shell gestart. Dit heeft een belangrijk gevolg: alle variabelen die je tijdens het script instelt, zijn ook na afsluiten van het script gewoon nog beschikbaar in de shell. Dit kan onverwachte gevolgen hebben, maar aan de andere kant kan het ook juist heel handig zijn. Zo wordt in heel veel van de scripts die aangeroepen worden tijdens het opstarten van de computer van deze techniek gebruikgemaakt om algemene varia-
11 Shellscripting
375
belen uit andere scripts aan te roepen. Omdat het ook verwarring kan veroorzaken, raden wij je aan voorzichtig te zijn met sourcen. Als je daarentegen precies weet wat je doet, is sourcen een handig middel om bijvoorbeeld variabelen centraal op te slaan. De laatste en meest gebruikelijke werkwijze om een script uit te voeren, is dat het script eerst uitvoerbaar gemaakt wordt. Onder Linux doe je dit door de Execute-permissie aan het script toe te kennen. De volgende opdracht laat zien hoe je dit regelt: chmod +x hallo
Als het script hallo in de huidige directory stond, zorgt deze opdracht ervoor dat je het script voortaan als een gewone opdracht kunt uitvoeren. Om dit vanuit de huidige directory te doen geef je de volgende opdracht: ./hallo
Let even op het gebruik van de constructie waarbij het script wordt aangeroepen met eerst ./ en dan de naam van het script. Hiermee geef je aan dat het script aangeroepen moet worden vanuit de huidige directory. Onder Linux komt de huidige directory namelijk om veiligheidsredenen niet voor in het zoekpad. Naamgeving Denk altijd na hoe je het script noemt. Zorg ervoor dat het nooit de naam heeft van een opdracht die ook bestaat in de vorm van een interne of externe opdracht. Dit kan gezien de grote hoeveelheid opdrachten die onder Linux bestaan best lastig zijn. Zo is er bijvoorbeeld een Linux-opdracht test. Als je het script test noemt, kan dat dus leiden tot onverwacht resultaat. Kijk daarom voor alle zekerheid eerst met bijvoorbeeld whereis gevolgd door de naam die je wilt gebruiken of er al iets bestaat met die naam. 11.2.5 Het script interactief maken Het aardige van een script is dat je aan gebruikers de mogelijkheid kunt geven invoer te geven voor het script. De gebruiker bepaalt zo zelf wat hij wil dat het script doet en je maakt het script inter-
376
Linux 4
actief. Om een script interactief te maken maak je gebruik van de opdracht read. Achter read zet je de naam van een variabele. De invoer van de gebruiker wordt tijdelijk opgeslagen in deze variabele met als doel er later weer iets mee te doen als de variabele wordt aangeroepen. Het volgende voorbeeld geeft aan hoe je een script interactief kunt maken. Ook zie je in dit voorbeeld een nieuwe methode om tekst weer te geven. #!/bin/bash # # Groet de wereld # Gebruik: ./hallo cat << EOF Vertel eens, welke boodschap wil jij vandaag aan de wereld geven? Houd je niet in, alles mag en niets is verboden want je bent toch de enige die het leest: EOF read boodschap echo “$boodschap wereld”
Dit fragment wordt na de shebang en het gebruikelijke commentaar geopend met een zogenoemd ‘here-document’. Dit is een alternatieve methode om tekst weer te geven op het scherm van de gebruiker. Zoals je ziet, bestaat de tekst die hier gebruikt wordt uit meerdere regels. Als je dit precies goed uitgelijnd op het scherm van de gebruiker wilt tonen, moet je erg goed de woorden tellen en ervoor zorgen dat elke regel netjes met de opdracht echo begint. Moet je later een woord in de tekst invoegen? Dan loop je het risico dat alles verspringt en je weer helemaal opnieuw mag beginnen: niet handig dus. Het here-document lost dit probleem voor je op. Een here-document begint altijd met de opdracht cat, gevolgd door de constructie << EOF. De tekenreeks die je achter de <<-constructie geeft, geeft aan waar het here-document ophoudt. Je mag hier alles voor gebruiken wat je maar wilt, het hoeft dus niet beslist EOF te zijn. Op het moment dat de shell dezelfde tekenreeks op een aparte regel in het script tegenkomt, weet de shell dat op dat punt het here-document eindigt. Alle tekst tussen het begin en het einde van het here-document wordt op het scherm van de gebruiker getoond.
11 Shellscripting
377
Na het here-document volgt het deel van het script waar het echt om gaat. De opdracht read boodschap regelt namelijk dat wat de gebruiker invoert, geplaatst wordt in een variabele met de naam boodschap. Een regel later wordt deze variabele weer gebruikt om een boodschap weer te geven. Let erop dat elke keer dat een variabele wordt aangeroepen, je voor de naam van de variabele een dollarteken zet. Bij het definiëren van een variabele heb je dus geen dollar nodig, maar als je later iets wilt doen met die variabele, heb je de dollar juist wel nodig. Variabele Een variabele is letterlijk een labeltje dat je aan een stukje geheugenruimte geeft. In dat stukje geheugenruimte stop je dan een bepaalde tekst. Door te verwijzen naar de naam van de variabele kun je later iets met deze informatie doen. Variabelen zijn bijvoorbeeld een heel handige manier om invoer van gebruikers te verwerken. 11.2.6 Werken met argumenten Nu kan het aardig zijn om het script interactief te maken, zodat het onderbroken wordt en de gebruiker om invoer vraagt. Dit gebeurt bijvoorbeeld vaak in installatiescripts om te vragen hoe je de installatie wilt uitvoeren. Als je echter het script gewoon wilt aanzetten op basis van de invoer die een gebruiker gegeven heeft en er verder niet meer naar om wilt kijken, is dit niet de meest handige methode. Veel handiger is het dan om de invoer als argument van het script mee te geven op de opdrachtregel tijdens het opstarten van het script. Dit is ook de manier waarop de meeste normale Linux-opdrachten werken. Als het hiervoor genoemde script herschreven wordt zodat het op deze wijze te werk gaat, kan het bijvoorbeeld worden aangeroepen als ./hallo hoi. Om te werken met argumenten die gegeven worden tijdens het aanroepen van het script, maakt de shell intern gebruik van een speciale variabele: $1. Het eerste argument is $1, het tweede argument is $2, het derde argument is $3 en ga zo maar door. De naam van het script zelf wordt weergegeven door middel van de constructie $0. Het gebruik van argumenten wordt gedemonstreerd in het volgende script:
378
Linux 4
#!/bin/bash # # Wie wil je groeten? # Gebruik: ./hallo [naam] echo “hallo $1”
De gebruiker roept dit script bijvoorbeeld aan als ./hallo linda. Bij het aanroepen van het script krijgt $1 (het eerste argument) dus de waarde linda. Dit zorgt ervoor dat de echo-regel “hallo linda” op het scherm van de gebruiker zet. Waar je bij het werken met argumenten wel even op moet letten, is dat elk woord dat je bij het aanroepen van het script meegeeft, als een apart argument gegeven wordt. Als je bijvoorbeeld het hiervoor genoemde script aanroept met ./hallo president van de republiek en in het script zelf alleen maar een $1 gedefinieerd is, wordt als resultaat “hallo president” getoond en wordt de rest van de invoer niet weergegeven. Wil je dat dit wel gebeurt? Dan moet je ervoor zorgen dat voor elk van deze woorden een aparte variabele in het script wordt gegeven. Dat is natuurlijk niet handig en daarom bestaat er ook een goede oplossing om dit probleem af te vangen. Als je van tevoren niet weet hoeveel argumenten bij het aanroepen van een script meegegeven worden maar alle mogelijkheden open wilt laten, verwijs je in het script naar deze onbekende hoeveelheid argumenten door gebruik te maken van $*. $* zal er namelijk voor zorgen dat alle argumenten gewoon weergegeven worden. Ons voorbeeldscript komt er dan dus uit te zien als: #!/bin/bash # # Wie wil je groeten? # Gebruik: ./hallo [naam1] [naam2] ... [naam n] echo “hallo $*”
Nu zijn er in een script verschillende constructies die gebruikt kunnen worden om te verwijzen naar een onbekende hoeveelheid argumenten. Bekijk bijvoorbeeld eens het volgende script, of nog beter: voer het uit en analyseer wat het script doet:
11 Shellscripting
379
#!/bin/bash # # Script that allows you to greet someone # Usage: ./hello [name] echo “Hello $1, how are you today” echo “\$* geeft $*” echo “\$# geeft $#” echo “\$@ geeft $@” echo “\$0 is $0” # Toon elk argument op een regel echo toon de interpretatie van \$* for i in “$*” do echo $i done echo toon de interpretatie van \$@ for i in “$@” do echo $i done
Voor het geval je zelf niet in staat bent het script uit te voeren, hebben wij dat maar even voor je gedaan. In het volgende zie je dat het script in kwestie is uitgevoerd met drie argumenten: web:~/scripts # ./hello linda lori leona Hello linda, how are you today $* geeft linda lori leona $# geeft 3 $@ geeft linda lori leona $0 is ./hello toon de interpretatie van $* linda lori leona toon de interpretatie van $@ linda lori leona
380
Linux 4
Je ziet dat dit script gestart wordt met drie argumenten. Om het verschil tussen $* en $@ duidelijk te maken, wordt in het script zelf gebruikgemaakt van de constructie for i in. Met behulp van deze constructie is het mogelijk om te kijken of er verschillende afzonderlijke elementen in een variabele voorkomen. Zoals je ziet, geeft for i in $* gewoon één tekenreeks. Alle argumenten worden hier dus als één string behandeld. De constructie for i in $@ echter zorgt ervoor dat elk argument als een aparte variabele behandeld wordt. Dit laatste is veel handiger, want het zorgt ervoor dat je met elke afzonderlijke variabele later weer iets kunt doen. Het gebrik van de constructie for i in komt later nog apart aan de orde. Op dit moment moet je echter onthouden dat deze constructie het mogelijk maakt om een aantal argumenten af te handelen, ook als op voorhand niet bekend is hoeveel argumenten dat dan zijn. Handige hulpmiddelen Bij het schrijven van een shellscript maak je gebruik van twee soorten opdrachten. Om te beginnen zijn er de interne opdrachten bash: deze zijn standaard in het werkgeheugen aanwezig en hoeven dus niet apart geladen te worden. Daarnaast zijn er tal van externe opdrachten die je in het script kunt aanroepen. Het nadeel van gebruik van deze externe opdrachten is dat ze langzamer zijn dan interne opdrachten, ze moeten immers eerst vanaf de vaste schijf ingelezen worden voordat je ze kunt gebruiken. Het voordeel echter is dat je met de combinatie van de scripttaal en deze externe opdrachten een zeer flexibel geheel krijgt. Een opdracht die goede diensten bewijst in scripts is cut. Met cut haal je informatie uit tekstregels. De opdracht cut werkt met velden die in een tekstregel voorkomen. In principe probeert cut deze van elkaar te onderscheiden door te kijken naar een spatie tussen de velden; een ideale manier dus om woorden uit tekstregels te halen. Ook is het mogelijk aan te geven dat gekeken moet worden naar speciale tekens die gebruikt worden om velden van elkaar te scheiden. Als zo’n speciaal teken als field separator gebruikt wordt, kan dat aangegeven worden met de optie -d (delimiter). Vooral in combinatie met de opdracht cat levert cut interessante mogelijkheden. Zo toon je bijvoorbeeld een lijst van alle gebruikers op de computer door cat en cut te combineren in een opdracht als cat /etc/passwd | cut -d : -f 1; hiermee geef
11 Shellscripting
381
je aan dat uit het resultaat van cat /etc/passwd het eerste veld (-f 1) gehaald moet worden en dat velden door middel van een dubbelepunt van elkaar onderscheiden kunnen worden.
11.3
Variabelen bewerken
In het begin van dit hoofdstuk hebben we gekeken naar de basiselementen waaruit een Linux-shellscript moet bestaan. Je weet nu dus welke onderdelen altijd in een goed shellscript moeten voorkomen. In deze paragraaf leer je hoe je variabelen in een shellscript kunt bewerken en daar bestaan nogal wat manieren voor! Een van deze manieren is command substitution. 11.3.1 Command substitution Met command substitution zorg je ervoor dat het resultaat van een opdracht in een script gebruikt wordt. In scripts wordt deze techniek vaak gebruikt om het resultaat van een opdracht toe te kennen aan een variabele. Dit is vooral handig als je werkt met waarden in een script die nogal eens wijzigen. Denk bijvoorbeeld aan een opstartscript waarin verwezen wordt naar de directory waarin de juiste modules staan voor de kernel die je gebruikt. De naam van deze directory verandert met elke nieuwe kernelversie die je installeert en daarbij gaat het ook nog eens om namen die niet echt lekker zijn om te onthouden. Denk bijvoorbeeld aan een naam als /lib/modules/2.6.16-308a. Het aardige van deze namen is echter dat de naam van de huidige kernel altijd overeenkomt met het resultaat van de opdracht uname -r. Dit betekent dat je in een script dus niet moet verwijzen naar de harde naam van de directory, maar het resultaat van uname -r moet gebruiken, zodat je altijd naar de juiste directory verwijst. En dat doel bereik je heel goed door gebruik te maken van command substitution. Zoals met heel veel zaken zijn er verschillende manieren om dat doel te bereiken. Een van de beschikbare opties is om de opdracht waarvan je het resultaat wilt gebruiken tussen backquotes te plaatsen. Het volgende script geeft hier een voorbeeld van. #!/bin/bash # # Kopieer een kernel module naar de juiste directory
382
Linux 4
# Gebruik: ./modkop echo Geef naam en locatie van het bestand dat je wilt kopiëren read file cp $file /lib/modules/`uname -r`
De eerste twee coderegels van dit script zorgen ervoor dat interactief gevraagd wordt de naam van een bestand in te voeren. Deze naam wordt met de opdracht read file bewaard in een variabele met de naam file. Tot slot wordt dit bestand gekopieerd naar een subdirectory van /lib/modules. De exacte naam van deze subdirectory wordt bepaald door de uitvoer van de opdracht uname -r. Naast het plaatsen van de uit te voeren opdracht tussen backquotes, is er nog een mogelijkheid. Je kunt de opdracht in kwestie tussen haakjes plaatsen met een $ -teken ervoor. De regel cp $file /lib/ modules/`uname -r` kan dus ook herschreven worden naar cp $file /lib/modules/$(uname -r).
11.3.2 Bewerken van variabelen Nu kan het een keer voorkomen dat een variabele in een script een waarde heeft die je niet bevalt. In dat geval is het goed te weten dat er tal van bewerkingen op de variabele uitgevoerd kunnen worden. De tactiek die hiervoor wordt toegepast, is de tactiek van de substitution-operators. Voordat we het hier echter over kunnen hebben, behandelen we eerst hoe een nieuwe variabele gemaakt kan worden op basis van een oude variabele. Dit kan soms grote voordelen hebben: bijvoorbeeld om de waarde te bewerken die als argument gegeven is bij het aanroepen van een script. Argumenten mogen namelijk niet bewerkt worden in scripts. Als je iets met een argument wilt doen, moet je het dus altijd in een andere variabele onderbrengen. Het volgende script laat zien hoe twee argumenten ondergebracht worden in een nieuwe variabele. Het script gaat ervan uit dat als eerste argument de voornaam van de gebruiker gegeven wordt en als laatste argument de achternaam: #!/bin/bash # # Groet de gebruiker op een vriendelijke manier # Gebruik: ./hallo
11 Shellscripting
383
naam=”$1 $2” echo “hallo $naam”
Op het moment dat er een gebruiker is die Kees Bres heet en zijn naam invoert, wordt Kees toegekend aan $1 en Bres aan $2 en wordt dus vriendelijk “hallo Kees Bres” op het scherm gezet. De truc waar het hier om gaat, is dat beide argumenten ondergebracht worden in één nieuwe variabele. In dit script is dat vrij zinloos, maar je zult in latere scripts leren dat het heel handig kan zijn op deze wijze te werk te gaan. 11.3.3 Substitution-operators Op het moment dat het voor een script van cruciaal belang wordt dat een bepaalde variabele ook een waarde heeft, is het de moeite waard daar in het script een controle voor in te bouwen. In Bash maak je daarvoor gebruik van substitution-operators. Deze zorgen er bijvoorbeeld voor dat een standaardwaarde wordt toegekend als de gebruiker vergeten is deze in te voeren. Een speciaal geval van substitution-operators zijn de pattern matching-operators. Hiermee kun je namelijk de waarde van een variabele bewerken. Om te beginnen bespreken we het gebruik van substitution-operators. Hieronder volgt een lijst van de mogelijkheden. ${parameter:-waarde} Toont
waarde als parameter niet gedefinieerd is. ${parameter=waarde} Kent waarde toe aan parameter als parameter niet bestaat, maar niet als parameter de waarde nul heeft. ${parameter:=waarde} Kent waarde toe aan parameter als parameter niet gedefinieerd is of de waarde nul heeft. ${parameter:?waarde} Toont waarde als foutmelding wanneer parameter niet gedefinieerd is of de waarde nul heeft. Het gevolg hiervan is dat de shell ook direct wordt afgebroken. ${parameter:+waarde} Als parameter wel een waarde heeft, wordt waarde gegeven. Heeft parameter geen waarde, dan gebeurt er juist niets.
384
Linux 4
Substitution-operators zijn lastig te begrijpen, dus volgen hierna enkele voorbeelden. Hierbij worden achtereenvolgens enkele opdrachten op de opdrachtregel gegeven waarmee iets gedaan wordt met de variabele BLAH. Je ziet dat het resultaat elke keer anders is, afhankelijk van de substitution-operator die gebruikt is. Om het eenvoudiger te maken de regels uit te leggen hebben wij er regelnummers voor gezet. Houd er rekening mee dat je deze in je eigen script niet mee hoeft te nemen: 1. sander@linux %> echo $BLAH 2. 3. sander@linux %> echo ${BLAH:-variable is leeg} 4. variabele is leeg 5. sander@linux %> echo $BLAH 6. 7. sander@linux %> echo ${BLAH=waarde} 8. waarde 9. sander@linux %> echo $BLAH 10.
waarde
11.
sander@linux %> BLAH=
12.
sander@linux %> echo ${BLAH=waarde}
13. 14.
sander@linux %> echo ${BLAH:=waarde}
15.
waarde
16.
sander@linux %> echo $BLAH
17.
waarde
18.
sander@linux %> echo ${BLAH:+leukhoor}
19.
leukhoor
In de eerste regel van deze listing wordt de opdracht echo $BLAH gegeven. Hiermee wordt de variabele BLAH uitgelezen. Deze is echter nog niet gedefinieerd, dus als resultaat wordt in regel 2 een lege regel gegeven. Vervolgens wordt in regel 3 een boodschap gedefinieerd die getoond moet worden als de variabele leeg is. In regel 4 gebeurt dat ook. Dat hiermee de variabele BLAH geen waarde krijgt, wordt aangetoond in regel 5 en 6. In regel 7 vervolgens wordt aan BLAH een waarde toegekend. BLAH bestond op dat moment niet, dus de waarde wordt ook echt toegekend wat blijkt in regel 9 en 10 wanneer de waarde van BLAH opnieuw wordt uitgelezen. In regel 11 vervolgens wordt een nulwaarde aan BLAH toegekend. De variabele bestaat nadrukkelijk wel, maar heeft
11 Shellscripting
385
geen waarde wat blijkt als de constructie echo ${BLAH=waarde} gebruikt wordt. Omdat BLAH de nulwaarde heeft, wordt er geen nieuwe waarde aan toegekend. Vervolgens wordt in regel 14 de waarde weer opnieuw ingesteld door gebruik te maken van de constructie :=, wat zich inderdaad een nuance anders gedraagt als =. Tot slot wordt in regel 18 de waarde leukhoor gegeven, puur om de reden dat BLAH op dat moment wel een waarde heeft; leukhoor is immers de tekst die weergegeven moet worden als de variabele wel een waarde heeft. Neem er notie van dat :+ dus eigenlijk het omgekeerde gedrag heeft als :-, wat juist iets doet als de variabele geen waarde heeft. Bovenstaande is redelijk abstract en kan gebruikt worden om bijvoorbeeld eenvoudige foutmeldingen te genereren. In ingewikkelder scripts kom je dit tegen. Dit is echter niet de meest elegante manier om foutmeldingen te genereren, omdat de wijze waarop ze opgemaakt worden niet echt fraai is. Later in dit hoofdstuk leer je hoe je dit op een fraaiere manier doet. 11.3.4 Pattern matching-operators De substitution-operators worden gebruikt om het geval af te vangen waarin een variabele geen waarde heeft. Met een pattern matching-operator kan gezocht worden naar een bepaald patroon in een variabele en kan de variabele overeenkomstig dat patroon bewerkt worden. Dit is erg handig omdat je er een string op maat mee kunt maken. Denk bijvoorbeeld aan het geval waar de gebruiker een volledige bestandsnaam (inclusief directory-aanduiding) geeft en het script alleen de bestandsnaam moet overhouden. De pattern matching-operator is de gewezen methode om dit voor elkaar te krijgen. Hieronder zie je een voorbeeld waarbij gebruikgemaakt wordt van pattern matching-operators: #!/bin/bash # # Script om een bestandsnaam uit een directorynaam te halen # stripit bestandsnaam=${1##*/} echo “de bestandsnaam is $bestandsnaam”
386
Linux 4
Hieronder zie je hoe dit script zich gedraagt wanneer het wordt uitgevoerd: sander@linux %> ./stripit /bin/bash de bestandsnaam is bash
Pattern matching-operators zoeken altijd naar een string. In dit geval was dat de string */. Met andere woorden: de pattern matching-operator zoekt naar een / die voorafgegaan wordt door iets. De aanduiding ## geeft aan dat gezocht wordt naar de longest match. Dit zoeken begint aan de voorkant van de string. Met andere woorden: de pattern matching-operator zoekt naar de laatste / die voorkomt in de string, verwijdert die slash en alles wat ervoor staat. Dit gedrag wordt bewezen wanneer je het script uitvoert met het argument /bin/bash/; in dat geval zorgt de pattern matchingoperator er namelijk voor dat alles verwijderd wordt. Een variant op deze pattern matching-operator is ${variabele#patroon}. In dat geval wordt gezocht naar de kortste match. Als in het hiervoor genoemde script bijvoorbeeld gebruikgemaakt zou worden van de constructie bestandsnaam=${1#*/}, zou in het eerste argument van het script gezocht worden naar de eerste slash die voorkomt, al dan niet met iets ervoor en deze zou verwijderd worden. Je kunt pattern matching-operators gebruiken om te zoeken vanaf het begin van een tekenreeks. Je kunt ze ook vanaf het einde laten zoeken. De structuur wordt dan ${variabele%patroon} en ${variabele%%patroon}. Het eerste geval zoekt vanaf de achterkant naar de eerste keer dat patroon voorkomt en de tweede zoekt vanaf de achterkant naar de laatste keer dat het patroon voorkomt. Het volgende script toont aan hoe dit werkt: #!/bin/bash # # Script om een directorynaam uit een volledige bestandsnaam te halen # stripdir dirnaam=${1%%/*} echo “de directorynaam is $dirnaam”
11 Shellscripting
387
Je zult echter merken dat dit script een probleem geeft wanneer het met het verkeerde argument wordt aangeroepen. Dit blijkt uit de volgende listing: sander@linux %> ./stripdir /bin/bash de directorynaam is
Je ziet dat het script hier iets te enthousiast zijn werk doet en er niets overblijft. Gelukkig kan dat opgelost worden door eerst een pattern matching-operator te gebruiken die alleen de slash aan het begin van de volledige bestandsnaam verwijdert, als die slash tenminste gegeven is. Het volgende script laat zien hoe dit werkt: #!/bin/bash # # Script om een directorynaam uit een volledige bestandsnaam te halen # stripdir dirnaam=${1#/} dirnaam=${dirnaam%%/*} echo “de directorynaam is $dirnaam”
De constructie ${1#/} biedt hier de oplossing. Deze constructie zoekt namelijk alleen vanaf het begin van het script naar een slash. Als deze slash gevonden wordt, wordt hij verwijderd. Het aardig is echter dat hij niet verwijderd wordt als hij niet gevonden wordt. Als een gebruiker dus per ongeluk usr/bin/passwd in plaats van /usr/bin/passwd als argument geeft, wordt er niets verwijderd. In de volgende regel wordt de variabele dirnaam nog een keer gedefinieerd. Er is namelijk niets op tegen een variabele tweemaal achter elkaar te definiëren. In die tweede definitie wordt het eigenlijke werk gedaan en wordt van achter af gezocht naar het patroon /*. Dit zorgt ervoor dat alles vanaf de eerste slash in de bestandsnaam verwijderd wordt en de gebruiker dus alleen de naam van de directory overhoudt. Uiteraard is dit script ook heel eenvoudig aan te passen, zodat het volledige pad uit een bestandsnaam bewaard wordt. Dit krijg je al voor elkaar als je de tweede definitie van de variabele dirnaam wijzigt naar dirnaam=${dirnaam%/*}. Het gevolg daarvan is immers dat gezocht wordt naar de laatste slash in de bestandsnaam en dat deze laatste slash en alles wat erachter staat wordt verwijderd.
388
Linux 4
Op basis van het voorgaande ben je nu ook in staat een iets ingewikkelder voorbeeld te interpreteren. Het is nog steeds een redelijk onzinnig voorbeeld, maar geeft wel aan welke essentiële bouwstenen er in een script gebruikt moeten worden. #!/bin/bash # # Kijk naar de datum van vandaag en geef aan de hand daarvan een boodschap waaruit # blijkt welke dag en welke maand het is. # Gebruik: ./vandaag vandaag=`date + %d-%m-%y` echo “vandaag is het ${vandaag%-*}
In dit voorbeeld wordt eerst gebruikgemaakt van command substitution om het resultaat van de opdracht date toe te kennen aan de variabele vandaag. Vervolgens wordt hierop een bewerking uitgevoerd door te zoeken naar de laatste - in de waarde van de variabele vandaag en alles vanaf die - te verwijderen. Zoals gezegd, het gaat hier om het principe hoe het werkt en niet zozeer om een nuttige toepassing te gebruiken, want de code van dit script had natuurlijk net zo goed vervangen kunnen worden door één definitie van een variabele, namelijk: vandaag=`date + %d-%m`
11.4
Rekenen in scripts
Bash biedt ook uitgebreide mogelijkheden om berekeningen uit te voeren in een shellscript. Misschien dat je je afvraagt waarom het überhaupt handig is te rekenen in een script. Want voor het maken van berekeningen zijn er zoveel handiger middelen. Niets is bijvoorbeeld zo handig als het maken van een spreadsheet om snel te weten wat er uit een bepaalde som komt. Toch kan het ook zeer handig zijn om berekeningen toe te passen in scripts. Met een eenvoudige berekening zorg je er bijvoorbeeld voor dat een bewerking een beperkt aantal keer wordt uitgevoerd, of dat er bij het uitvoeren van een bewerking een teller wordt bijgehouden, zodat je precies kunt zien hoe vaak een bewerking met succes uitgevoerd is. Van dit laatste vind je in het volgende script een eenvoudig voorbeeld:
11 Shellscripting
389
#!/bin/bash counter=1 while true do counter=$((counter + 1)) echo counter is $counter done
Voordat we op de rekenkundige bewerking die in dit script uitgevoerd wordt kunnen ingaan, moeten we een andere nieuwigheid introduceren. In dit script wordt namelijk gebruikgemaakt van de constructie while. Dit is een zeer handige constructie die wordt gebruikt om een aantal bewerkingen net zo lang uit te voeren als aan een bepaalde conditie voldaan wordt. De voorwaarde van de conditie is in dit geval zeer eenvoudig, de opdracht true moet met succes uitgevoerd kunnen worden. Nu is het aardige dat de opdracht true altijd succesvol uitgevoerd wordt. Dat wil zeggen: de opdracht levert altijd de exit status 0 op om aan te geven dat het goed gegaan is, net zoals de opdracht /bin/false altijd een exit status 1 oplevert. Houd er overigens rekening mee dat dit script een zeer hoge processorbelasting tot gevolg zal hebben. Er is immers geen enkele limiet ingesteld op het uitvoeren van de opdracht true. Wat er moet gebeuren als de conditie die gesteld wordt in een while-loop waar is, staat tussen de do en de done uitgelegd. In dit geval wordt er een variabele ingesteld met de naam counter. Zoals je ziet heeft deze variabele aan het begin van het script reeds de waarde 1 meegekregen. Bij deze waarde wordt nu 1 opgeteld. De waarde van de nieuwe variabele counter wordt vervolgens in de tweede opdrachtregel achter do weergegeven met de opdracht counter is $counter. Vervolgens wordt er opnieuw gekeken of aan de conditie in de while-loop nog steeds voldaan wordt. Dit is het geval en dat zorgt ervoor dat er weer 1 opgeteld wordt bij de waarde die de variabele counter op dat moment heeft. Het resultaat van dit alles is een zeer snel oplopende lijst met getallen; op een snelle computer kan deze bewerking zomaar tienduizend keer per seconde uitgevoerd worden.
390
Linux 4
Figuur 11.1 Een mogelijkheid van het gebruik van berekeningen in een script is om een teller te laten lopen
Het voorgaande voorbeeld is aardig, maar niet bijzonder nuttig. Toch zijn er ook wel nuttige voorbeelden te verzinnen. Zo is er bijvoorbeeld de mythe dat een USB-stick of andere typen flashgeheugen maar een beperkt aantal keren beschreven kunnen worden. Na ongeveer tienduizend schrijfacties zou het geheugen op de stick onherstelbaar beschadigd worden en kun je er dus niets meer mee. Deze stelling is met een script waarin een teller gecombineerd wordt met een while-loop eenvoudig aan te tonen (of te ontkrachten, probeer maar uit): #!/bin/bash # # killstick <mountpunt> # counter=1 while cp /129MBfile $1 do sync rm -rf $1/129MBfile sync counter=$((counter + 1)) echo de waarde van counter is $counter done echo Uw stick is nu gesloopt.
11 Shellscripting
391
Dit voorbeeld is iets ingewikkelder, maar moet op basis van wat eerder in deze serie behandeld is goed te begrijpen zijn. Als eerste de uitgangspunten. Dit script is geschreven om te testen of USBsticks wel of niet beperkt houdbaar zijn. Om deze test te doen moet de stick ergens gemount worden. Dit mountpunt moet als argument meegegeven worden wanneer het script gestart wordt. Daarnaast heb je een bestand nodig met een grootte van 129 MB. Dit om ervoor te zorgen dat hoe dan ook steeds op hetzelfde gedeelte van de stick gegevens weggeschreven worden. Je kunt dit bestand maken met de opdracht dd if=/dev/zero of=/129MBfile bs=1024 count=129000. Laten we dan nu eens kijken naar wat het script precies doet. Testmethoden Testen kan op veel verschillende manieren. Als alternatief voor het bovenstaande, zou je er bijvoorbeeld ook voor kunnen kiezen de stick 99% vol te schrijven en de herhaalde schrijfactie op de overgebleven 1% uit te voeren. Dat gaat tenminste wel zo snel. Om te beginnen zie je de gebruiksregel waarin wordt uitgelegd hoe het script werkt. Hiermee wordt aangegeven dat het script zelf killstick heet en dat het als verplicht argument het mountpunt van de USB-stick meekrijgt. Het zou overigens aardig zijn als hier een controle op plaatsvindt, zodat een foutmelding gegeven wordt als de gebruiker het mountpunt niet meegeeft, maar daar komen we later nog een keer op terug. Vervolgens wordt de while-loop weer geopend. Deze keer wordt een opdracht uitgevoerd waarmee het bestand /129MBfile gekopieerd wordt naar het mountpunt van de stick. Zolang dit succesvol gebeurt, worden de volgende opdrachten uitgevoerd. Als eerste wordt de opdracht sync aangeroepen, zodat het weggeschreven bestand ook daadwerkelijk naar het fysieke medium geschreven wordt en niet ergens in de cache blijft hangen. Dan wordt het bestand in kwestie weer verwijderd en ook die verwijdering wordt netjes gescynchroniseerd. Als laatste gedeelte van de conditionele loop die op while volgt, wordt de counter weer netjes opgehoogd en de waarde van die counter wordt ook aan de gebruiker getoond. Op het moment dat de opdracht cp /192MBfile $1 niet meer uitgevoerd kan worden, wordt er in dit script van uitgegaan dat de stick in kwestie gesloopt is. Voor het
392
Linux 4
gemak worden andere omstandigheden, bijvoorbeeld die waarin de stick door de gebruiker verwijderd is, maar even vergeten. De gebruiker ziet nu de melding ‘uw stick is nu gesloopt’ met daarboven de laatste waarde die was toegewezen aan de variabele counter. Op deze manier blijkt dus dat het gebruik van een counter in een script wel degelijk zijn nut kan hebben! Terug naar rekenen in scripts. Tot nu toe hebben we het nog maar gehad over een manier om te rekenen in een script (waarschijnlijk ook de enige manier die je zult gaan gebruiken). Er zijn echter veel meer mogelijkheden en die zullen we nu de revue laten passeren. Om te beginnen gebruiken we de opdracht expr om een berekening uit te voeren. Deze externe opdracht kan toegepast worden voor allerhande berekeningen. In de volgende regel zie je hoe expr gecombineerd kan worden met opdracht substitutie om een waarde aan een variabele toe te wijzen. vla=`expr 1 + 2`; echo $vla
Zoals je ziet, wordt hier een variabele gedefinieerd met de volkomen willekeurig gekozen naam vla. Deze variabele wordt gevuld met het resultaat van de berekening expr 1 + 2. Deze berekening kun je overigens ook gewoon op de opdrachtregel uitvoeren. Het gebruik van backquotes zorgt er hier voor dat gebruikgemaakt wordt van opdracht substitutie. Dan volgt een ;. Voor het geval het je even ontschoten is, de puntkomma wordt gebruikt om twee opdrachten van elkaar te scheiden. Achter de puntkomma komt de tweede opdracht waarmee de nieuwe waarde van de variabele vla wordt uitgelezen. Ondanks dat het hiervoor genoemde voorbeeld prima werkt, is van een deugdelijk script geen spraken. Als eerste is er het probleem dat in de opdrachtregel gewerkt wordt met vaste waarden. Veel handiger is het een script te schrijven waarbij deze waarden bijvoorbeeld op de opdrachtregel meegegeven worden. Daarnaast is ook de operator (+ in dit geval) als vaste waarde gegeven. Tot slot wordt gebruikgemaakt van de opdracht expr en dat is een externe opdracht. Dit betekent dat het script eerst de externe opdracht zal moeten inlezen van schijf en pas als dat gebeurd is aan het werk kan gaan. Veel handiger is het om gebruik te maken van interne opdrachten die altijd in het werkgeheugen aanwezig zijn, omdat ze
11 Shellscripting
393
met de shell zelf geladen worden. Aan alle overige bezwaren wordt in het volgende voorbeeldscript tegemoetgekomen: #!/bin/bash # #reken $1 $2 $3 #$1 is het eerste getal #$2 is de operator #$3 is het tweede getal x=`expr $1 $2 $3` echo $x
Als eerste moeten we ook hier weer aangeven dat het eigenlijk onzinnig is wat er gebeurt, het script voegt namelijk niets toe aan de mogelijkheden die sowieso al door expr geboden worden! Maar het gaat er hier om dat je begrijpt hoe expr ingezet kan worden, dus dit nadeel nemen we maar even voor lief. Afgezien daarvan is het script wel veel meer flexibel als wat er in de voorgaande voorbeeldregel werd gedaan. Het grote voordeel bestaat eruit dat de getallen waarmee gerekend en de operator op de opdrachtregel als argument bij het script meegegeven kunnen worden. Vervolgens geeft het script de waarde van de berekening die tijdelijk in de variabele x gegeven wordt weer. Bij een berekening zoals in het voorgaande gemaakt is, kan gebruikgemaakt worden van een aantal operatoren: + - / * %
optellen ( 1 + 1 = 2) aftrekken (10 - 2 = 8) delen (10 / 2 = 5) vermenigvuldigen (3 * 3 = 9) modulus; berekent dat wat overblijft na een deling als gebruikgemaakt wordt van gehele getallen: (11 % 3 = 2)
Het aardige is dat geen van deze operatoren echt problemen oplevert, behalve de operator *. Het gebruik van deze operator geeft de foutmelding syntax error: linux:> expr 1 * 1 expr: syntax error
394
Linux 4
Op het eerste gezicht lijkt dit wellicht merkwaardig, maar de reden voor deze foutmelding is dat de * een speciale betekenis heeft voor de shell. Een * is immers een jokerteken. Wanneer de shell in een eerste poging de volledige opdrachtregel inleest en interpreteert, zal het ook de * interpreteren. Dit is nu net niet de bedoeling. Om aan te geven dat de shell ervan af moet blijven, moet je daarom gebruikmaken van een escapeteken. De juiste berekening met een * erin wordt dus: expr 1 \* 1
Een tweede manier om te rekenen is door gebruik te maken van het interne Bash-opdracht let. Met behulp van deze opdracht wordt het resultaat van een berekening aan een variabele toegekend. Je ziet dit in de volgende regel: let x=”1 + 2”
Als resultaat van deze berekening heeft de variabele x een waarde gekregen. Het nadeel van deze werkwijze, is dat let geen mogelijkheid heeft het resultaat van de berekening direct weer te geven, maar dit altijd aan een tijdelijke variabele kan toekennen. Dit betekent dat als je gebruik wilt maken van let, het voorgaande script met een kleine aanpassing ineens wel heel handig kan zijn. #!/bin/bash # #reken $1 $2 $3 #$1 is het eerste getal #$2 is de operator #$3 is het tweede getal let x=”$1 $2 $3” echo $x
Het voordeel van de tweede variant van ons script? Je maakt nu gebruik van een interne opdracht en niet langer van een externe opdracht en daardoor wint het script aan snelheid. Zeker voor gevorderde gebruikers is het winnen van snelheid een belangrijk gegeven: een goed geoptimaliseerd shellscript kan meer dan twee keer zo snel zijn als een slecht geoptimaliseerd script.
11 Shellscripting
395
De volgende manier van rekenen heb je in de inleiding van deze paragraaf al gezien. Je kunt namelijk ook werken zonder expliciet interne opdracht en de berekening tussen haakjes zetten. Het voorgaande voorbeeldscript kan dus net zo goed geschreven worden als: #!/bin/bash # #reken $1 $2 $3 #$1 is het eerste getal #$2 is de operator #$3 is het tweede getal x=(($1 $2 $3)) echo $x
In plaats van de dubbele ronde haken mag je overigens ook gebruikmaken van blokhaken. De werking verandert in dat geval helemaal niets. Het voorbeeldscript komt er dan dus uit te zien als: #!/bin/bash # #reken $1 $2 $3 #$1 is het eerste getal #$2 is de operator #$3 is het tweede getal x=[$1 $2 $3] echo $x
Een laatste techniek die toegepast kan worden bij het werken met getallen in Bash-shellscripts, is het toewijzen (declare) van een bepaald type aan een variabele. Dit doet je met behulp van de interne opdracht declare. Het idee hierbij is dat je voordat je een variabele van een bepaald type gaat gebruiken, eerst aangeeft wat voor type variabele het is. Het voordeel van deze werkwijze is dat voor de evaluatie van de waarde van de variabele, er niet langer een $-teken voor hoeft te staan. Hoe dit in zijn werk gaat, blijkt uit het volgende voorbeeld: declare -i A declare -i B C=A+B
396
Linux 4
Als je gewend bent in C of een andere high-level-taal te programmeren, stemt de mogelijkheid gebruik te maken van declare je misschien hoopvol. Je moet er echter niet teveel van verwachten. De mogelijkheden die geboden worden in de programmeertaal C zijn veel uitgebreider. In C bijvoorbeeld kun je aangeven dat je wilt werken met een long integer, of een variabele van het type float om te werken met getallen achter de komma. Dat alles is met Bash niet mogelijk. Daarbij komt nog het nadeel dat het werken met declare de zaken niet overzichtelijker maakt. Juist omdat je werkt met declare en daardoor niet langer aan hoeft te geven dat iets als variabele gezien moet worden, kan verwarring ontstaan. Daarom hebben wij maar één advies over het werken met declare: niet doen, je maakt het er namelijk niet overzichtelijker mee. Stijlen Je kunt Bash-script schrijven in de traditionele Bash-stijl. Als alternatief is het ook mogelijk gebruik te maken van een stijl die lijkt op de programmeertaal C. Zoals zo vaak met Linux heb je ook hier als gebruiker de keuze. In dit boek echter richten wij ons op de Bash stijl, de C-stijl is naar onze mening vooral interessant voor mensen die al C-programmeerervaring hebben. Voor mensen die dat niet hebben, is de C-stijl onnodig complex. 11.4.1 Priemgetallen Altijd al willen weten door welke getallen een bepaald getal gegeven is? Ook daar heeft Linux een prima hulpmiddel voor in de vorm van de opdracht factor. Geef factor, gedeeld door een willekeurig getal en je ziet meteen door welke getallen het getal deelbaar is. bash$ factor 27417 27417: 3 13 19 37
11.4.2 Geavanceerde berekeningen met bc Het probleem van rekenen binnen Bash is dat welke methode je ook gebruikt, je alleen maar gehele getallen kunt gebruiken. Dat is leuk als je een bewerking een bepaald aantal keren uit wilt laten voeren, maar het is een heel stuk minder handig als je echt een nauwkeurige berekening wilt uitvoeren. In dat geval biedt de
11 Shellscripting
397
‘rekenmachine’ bc uitkomst. Toegegeven, het is geen Windows Calculator, maar die kun je dan ook niet binnen een shellscript gebruiken. De opdracht bc is typisch een geval van een handige externe opdracht die je vanuit een shellscript aanroept om berekeningen uit te voeren. Om te werken met bc is het handig om het programma eerst eens in interactieve modus te openen. Dit doe je door op een opdrachtregel de opdracht bc te typen. Vervolgens kom je in de interactieve bc-omgeving terecht waarin je sommen kunt uitvoeren. In de volgende listing zie je hoe dit werkt. user@linux:~> bc bc 1.06 Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc This is free software with ABSOLUTELY NO WARRANTY. For details type `warranty’. 10/3 3 quit
Dit voorbeeld geeft aan dat ook bc standaard niet aan nummers achter de komma doet. Gelukkig is het niet al te moeilijk dit wel aan bc te leren. Hiervoor geef je met de interne bc-opdracht scale aan hoeveel getallen je achter de komma wilt. Wil je dus werken met 9 getallen achter de komma, dan begin je de bc-cyclus met de opdracht scale=9: user@linux:~> bc bc 1.06 Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc This is free software with ABSOLUTELY NO WARRANTY. For details type `warranty’. scale=9 10/3 3.333333333 quit
Nu is het best aardig dat je met bc in een interactief scherm kunt rekenen, maar in een shellscript heb je daar helemaal niets aan. Gelukkig is ook dat eenvoudig op te lossen. Gebruik de opdracht
398
Linux 4
om eerst de waarden aan te geven die je wilt gebruiken en gebruik vervolgens een pipe om dat naar de opdracht bc te sturen. Het bovenstaande voorbeeld kan dus ook weergegeven worden als: echo
echo “scale=9; 10/3” | bc
Het resultaat wordt meteen op de prompt getoond. Heb je het liever in een variabele? Dat kan ook, in dat geval laat je er gewoon wat command substitution op los, zoals je ziet in de volgende regel waarin het gedeelte dat gesubstitueerd wordt in de constructie $(...) geplaatst wordt. var=$(echo “scale=0; 10/3” | bc)
11.5
Werken met flow control
Tot nu toe hebben we nog niet echt aandacht besteed aan de mogelijkheid opdrachten alleen uit te voeren als voldaan wordt aan een bepaalde voorwaarde. In deze paragraaf maken we hier een begin mee en lees je hoe je met if...then...fi ervoor zorgt dat een opdracht alleen uitgevoerd wordt als aan een bepaalde voorwaarde voldaan wordt. Een script dat alleen maar lineair alle bewerkingen uitvoert, is niet interessant. Het wordt pas echt de moeite waard als een script bewerkingen uitvoert wanneer voldaan wordt aan bepaalde voorwaarde. Denk daarbij aan constructies als ‘ga alleen verder als de gebruiker de optie ja gekozen heeft’, of ‘zolang een bestand van een bepaald type bestaat, voer dan een actie uit’. De Bash-scripttaal kent verschillende mogelijkheden om opdrachten uit te voeren als aan een bepaalde conditie voldaan wordt. Hieronder tref je een overzicht van alle mogelijkheden: if
case
Zoals de naam al zegt, met if (als) wordt gekeken of aan een conditie wordt voldaan. Daarbij bestaat de mogelijkheid te werken met else om gevallen af te vangen waarin juist niet aan die conditie voldaan wordt. Met case kunnen opties afgevangen worden. Dit is typisch een constructie om te kijken of een gebruiker een bepaalde optie heeft gekozen en alleen in dat geval een
11 Shellscripting
for
while
until
399
bewerking uit te voeren. Deze constructie wordt in de opstartscripts in zeer ruime mate gebruikt. Dit is de constructie waarmee je een bewerking uitvoert voor een aantal gegevens. Dit wordt bijvoorbeeld gebruikt om een bewerking uit te voeren voor een hele reeks bestanden, of voor een variabele die een bepaalde waarde heeft. Qua functionaliteit ligt for redelijk dicht bij while. for wordt echter vooral toegepast op reeksen, terwijl while meer een tijdsaspect heeft. Je gebruikt while om een opdracht uit te voeren zo lang aan een bepaalde voorwaarde voldaan wordt. Deze constructie wordt gebruikt om een bewerking uit te voeren zolang aan een voorwaarde wordt voldaan. Deze constructie kan bijvoorbeeld gebruikt worden om in de gaten te houden of een bepaalde host bereikbaar is, of om te monitoren of een bepaald proces nog wel actief is. Dit bewerkstelligt juist het tegenovergestelde van while. Met until voer je een bewerking uit totdat aan een bepaalde voorwaarde wordt voldaan.
11.5.1 if then else De voorwaardelijke lus op basis van if then else is misschien wel de meest klassieke die gebruikt wordt in een shellscript. Zeker in combinatie met de opdracht test biedt deze constructie uitgebreide mogelijkheden. Deze opdracht kun je namelijk gebruiken om te kijken of een variabele een waarde heeft, een bestand bestaat en als het bestaat aan bepaalde voorwaarden voldoet en nog veel meer. Omdat test zo enorm handig is in combinatie met if then else, volgen hier eerst enkele controles die je met behulp van deze opdracht kunt uitvoeren. Om te beginnen geven we een aantal mogelijkheden tests uit te voeren op bestanden. Realiseer je wel dat deze lijst niet compleet is. Je kunt met test testen op nagenoeg alle eigenschappen van bestanden. test -e $1
test -f $1
test -d $1 test -x $1
Kijkt of $1 een bestaand bestand is zonder dat precies gekeken wordt wat voor type bestand het dan is. Kijkt of $1 een normaal bestand is. Aan deze voorwaarde wordt niet voldaan als $1 bijvoorbeeld een uitvoerbaar bestand is of een directory. Kijkt of $1 een directory is. Controleert of $1 een uitvoerbaar bestand is.
400
Linux 4
Een tweede mogelijkheid die test biedt, is twee bestanden met elkaar te vergelijken. Hiervoor bestaan de volgende opties: test $1 -nt $2 test $1 -ot $2 test $1 -ef $2
Controleert of $1 nieuwer is dan $2. Kijkt juist of S1 ouder is dan $2. kijkt of $1 en $2 beide verwijzen naar dezelfde inode. Dit is het geval als de ene bestaat als hard link naar de andere.
Naast de mogelijkheden te kijken naar bestanden kan test ook ingezet worden om te kijken naar getallen. De volgende opties worden ingezet om twee getallen met elkaar te vergelijken: test $1 -eq $2 test $1 -ne $2 test $1 -gt $2 test $1 -lt $2 test $1 -ge $2 test $1 -le $2
Kijkt of de integers $1 en $2 gelijk zijn aan elkaar. Controleert juist of $1 en $2 niet gelijk zijn aan elkaar. Levert de waarde ‘waar’ op als $1 groter is dan $2. Geeft juist de waarde ‘waar’ als $1 kleiner is dan $2. Kijkt of $1 groter is dan $2 of juist gelijk is aan $2. Controleert of $1 kleiner is of gelijk is aan $2.
Tot slot bespreken we nog een aantal tests die je op strings (tekenreeksen dus) kunt uitvoeren. test -z $1
test $1
test $1=$2
test $1 != $2
Controleert of $1 leeg is. Dit is een heel handige constructie om te kijken of een variabele wel een waarde heeft. Dit doet juist het tegenovergestelde: test $1 geeft een exit-status 0 wanneer $1 wel een waarde heeft. Controleert of $1 en $2 gelijk zijn aan elkaar. Deze optie kan gebruikt worden om de waarde van een variabele te vergelijken met de waarde van een andere variabele. Kijkt of $1 en $2 niet gelijk zijn aan elkaar. Het uitroepteken kan overigens bij alle ove-
11 Shellscripting
401
rige tests ook gebruikt worden. Zo kijk je bijvoorbeeld met test !-g $1 of $1 een bestand is waarop het Set Group ID (SGID) bit niet aan staat. Er zijn overigens twee manieren waarop de opdracht test gebruikt kan worden. Om te beginnen is dat de lange manier: test -f $1. Dit kan ook geschreven worden als [ -f $1 ]. Je gebruikt dan in plaats van de opdracht test blokhaken. In de praktijk zul je met name de laatste methode tegenkomen, de manier waarop test voluit geschreven wordt, wordt nauwelijks gebruikt. Tot zover even genoeg over test. Nu wordt het tijd te kijken hoe test gebruik kan worden in een if...then...else-loop. Om te beginnen de algemene constructie van if...then...else. Met deze constructie kijk je of voldaan wordt aan een bepaalde voorwaarde. Een heel eenvoudig voorbeeld volgt hieronder: if [ -z $1 ] then echo Je moet een argument opgeven bij deze opdracht fi
In deze eenvoudige test wordt gekeken of er bij het opstarten van het script waarin deze code voorkomt, wel een argument gebruikt is. Als dit niet het geval is, wordt de code in de if-loop actief. Is wel een argument gebruikt, dan gebeurt er verder niets. Let even op een aantal eigenaardigheden van deze lus: op de eerste regel komt if, met daarachter de conditie die uitgevoerd moet worden. Vervolgens komt op een aparte regel then. Je zou dit overigens kunnen vermijden door de if en de then door middel van een puntkomma van elkaar te scheiden: if [ -z $1 ]; then echo ... fi
Heeft precies hetzelfde resultaat, zoals je weet is een puntkomma immers niets meer of minder dan een scheidingsteken voor opdrachten. Na de then volgt steeds op aparte regels een lijst van opdrachten die uitgevoerd moeten worden. In dit specifieke geval
402
Linux 4
is dat niet echt ingewikkeld, want er is maar één opdracht. Tot slot volgt de aanduiding fi waarmee de if wordt afgesloten. Let erop dat je deze fi niet vergeet, want zonder fi gaat het niet goed en krijg je bij je pogingen dit script uit te voeren alleen een foutmelding waaruit blijkt dat je iets vergeten bent. In het voorgaande voorbeeld heb je een eenvoudig voorbeeld gezien van het gebruik van if: er wordt namelijk op precies één conditie getest. We kunnen het echter nog mooier maken door in een if-statement meerdere tests te doen. Hiervoor kan bijvoorbeeld gebruikgemaakt worden van else of elif. Dit is een samenstelling van else en if en hiermee zorg je er inderdaad voor dat in het if-statement een tweede if-statement opgenomen wordt. Een oud en vertrouwd verschijnsel uit de programmeerwereld dat bekend staat als nesting. Een niet al te ingewikkeld voorbeeld hiermee vind je in het volgende script: if [ -f $1 ] then echo “$1 is een bestand” elif [ -d $1 ] echo “$1 is een directory” else echo “ik weet niet wat $1 is” fi
In dit voorbeeld wordt gekeken naar het argument dat gebruikt is bij het starten van het script in kwestie. Als dit een bestand is (if [ -f $1 ]), volgt de melding dat het een bestand is. Is dit niet het geval, dan wordt het gedeelte onder elif actief: in feite is dit een tweede loop die geopend wordt. In deze loop wordt eerst gekeken of $1 misschien een directory is. Let wel, dit gedeelte van de loop wordt alleen actief als $1 dus niet een bestand is. Is $1 niet een bestand en ook geen directory, dan wordt het gedeelte na else actief. Let er overigens ook op dat alleen if wordt afgesloten met een fi. Er is geen aparte fi waarmee de elif afgesloten wordt. Tot slot nog iets over een andere manier waarop if-loops geschreven kunnen worden. In plaats van het werken met if ...then ...else ...fi kom je ook heel vaak de verkorte notatie tegen waarbij gebruikgemaakt wordt van de separators && en ||. Deze separators
11 Shellscripting
403
worden gebruikt om twee opdrachten van elkaar te scheiden en een conditionele relatie tussen beide opdrachten aan te brengen. Als && gebruikt wordt, wordt de tweede opdracht alleen uitgevoerd als de eerste opdracht met succes is uitgevoerd (met andere woorden: als de andere opdracht waar is). Als || gebruikt wordt, wordt de tweede opdracht alleen gebruikt als de eerste opdracht niet waar was. Hieronder zie je een voorbeeld van de eerste: [ -f $1 ] && echo $1 is een bestand
Zoals je ziet, is dit inderdaad een verkorte notatie van het eerste deel van het voorgaande script. Wil je gebruikmaken van de separator ||, dan kan dat er als volgt uitzien: [ !-f $1 ] || echo $1 is een bestand
Ook is het mogelijk om complexe scripts op deze manier te herschrijven. Dat is echter niet aan te raden, omdat dit heel vaak ten koste gaat van de leesbaarheid van een script. Tot slot van dit onderwerp geeft de volgende regel een iets complexer voorbeeld: rsync -vaze ssh --delete /srv/ftp 10.0.0.20:/srv/ftp || echo “rsync failed” | mail [email protected]
In deze regel probeert de opdracht rsync de inhoud van de directory /srv/ftp te synchroniseren met een gelijknamige directory op een andere server. Als dat goed is, is de regel daarmee klaar en kijkt de shell niet naar wat er achter de || staat. Gaat echter de synchronisatie met rsync niet goed, dan moet er een bericht verstuurd worden naar de beheerder van het systeem. Dit gebeurt hier door de tekst echo failed te pipen naar de opdracht mail die dit bericht doorstuurt naar een opgegeven mailaccount. Tot slot nog een voorbeeld met if waarin gebruikgemaakt wordt van een iets ingewikkelder constructie met piping en de opdracht substitutie: if [ `df -m /var | tail -n1 | awk ‘{print $4}’` -lt 120 ] then logger running out of disk space fi
404
Linux 4
Deze opdracht zorgt ervoor dat je in de gaten kunt houden of je nog wel voldoende ruimte hebt in de partitie /var. Hiervoor wordt de opdracht df -m gebruikt om de ruimte in megabytes die beschikbaar is te tonen. Met tail -n1 wordt de laatste regel uit de opdracht alleen bekeken. Deze regel bestaat uit vier velden. Door middel van awk ‘{print $4}’ wordt de waarde van het vierde veld er uitgehaald (je had hiervoor overigens ook cut -f 4 kunnen gebruiken, maar awk is net iets flexibeler dan cut). De uitkomst van deze waarde wordt dan weer vergeleken met het getal 120 en als de waarde kleiner is dan 120 MB, wordt met behulp van de opdracht logger een bericht geschreven naar het syslog-mechanisme. Zeker als je een dergelijk script met while combineert om het periodiek te laten uitvoeren, kun je op deze wijze continu monitoren of er nog wel voldoende schijfruimte beschikbaar is. 11.5.2 Arrays Een van de zaken die wellicht het lastigst te begrijpen is in een shellscript, is de array. Bij gebruik van een array gaat het erom dat meerdere waarden in een item opgeslagen kunnen worden. Eigenlijk is het dus een variabele die meer dan een waarde kan bevatten. Het handige van het gebruik van een array is dat het mogelijk is een bewerking uit te voeren op alle elementen die voorkomen in de array. Laten we gelijk maar eens met de deur in huis vallen en een voorbeeld geven: # zooi=(een twee drie vier) # echo $zooi een #echo ${zooi[*]} een twee drie vier # for i in ${zooi[*]}; do echo $i; done een twee drie vier # echo ${zooi[2]} drie
Om een array te definiëren bestaan er verschillende manieren. De meest eenvoudige methode is te werk te gaan zoals je dat waarschijnlijk ook gewend bent bij de definitie van een variabele en
11 Shellscripting
405
elke waarde die je aan de array wilt toekennen tussen haakjes op te nemen. De volgende regel kan dus gebruikt worden om een array genaamd ‘plaatsen’ te definiëren: plaatsen=(Groningen Roosendaal Heerenveen)
Elke waarde in de array krijgt vervolgens zijn eigen volgnummer. Standaard begint Bash te nummeren bij 0 en loopt zo verder. Groningen krijgt dus waarde 0, Roosendaal waarde 1 en Heerenveen waarde 2. Het is ook mogelijk deze waarden zelf te bepalen op het moment dat je de waarden aan de array toekent. Zo kun je de voorgaande array ook definiëren als: plaatsen=(Groningen 8=Roosendaal Heerenveen)
Hierbij wordt Groningen nog steeds op de eerste waarde in de array opgeslagen, maar is Roosendaal nu ineens waarde 8 (wat dus inderdaad de tussenliggende waarden overslaat). Na Roosendaal gaat het wel weer netjes verder in chronologische volgorde. Heerenveen krijgt dus in dit geval de waarde 9 toegewezen. Om iets te doen met de waarden uit een array heb je twee mogelijkheden. De eerste mogelijkheid is om letterlijk naar een bepaalde waarde op een bepaalde positie te verwijzen. Let er daarbij wel op dat de naam van de array en de waarden waarnaar je verwijst tussen accolades moeten staan. Gebruik bijvoorbeeld echo ${plaatsen[1]}
Nu is het letterlijk verwijzen naar een waarde in een array niet echt handig, je moet dan immers exact de waarde weten waarnaar je verwijst. Daarom is het veel handiger dat er ook manieren zijn om de hele array in een keer uit te lezen. Hiervoor wordt gebruikgemaakt van de aanduidingen @ en * die het nummer tussen de blokhaken vervangt: sander@linux~> plaatsen=(Groningen Roosendaal Heerenveen) sander@linux~>echo ${plaatsen[@]} Groningen Roosendaal Heerenveen
406
Linux 4
Er bestaat overigens een subtiel nuanceverschil tussen de @ en de *. Indien ze tussen aanhalingstekens gezet worden, zorgt * ervoor dat alle waarden die aan de array zijn toegekend als een enkele tekenreeks gezien worden. @ daarentegen zorgt ervoor dat de verschillende waarden als aparte tekenreeksen gezien worden. Dat dit laatste veel handiger is, blijkt pas wanneer een array gebruikt wordt in een itteratie met for. Je hebt hier eerder in dit hoofdstuk ook al over gelezen toen we het hadden over argumenten die bij een script meegegeven kunnen worden. Deze eenvoudige itteratie voert een opdracht uit zolang aan een bepaalde voorwaarde wordt voldaan. In het volgende voorbeeld zorgt for ervoor dat $i geprint wordt met behulp van de opdracht echo, zolang als er nog een waarde is in de array plaatsen die niet afgehandeld is: for i in “${plaatsen[@]}”; do echo $i done
Dit is maar een eenvoudig voorbeeld van wat je met array’s kunt doen, ingewikkelder voorbeelden komen echter ook in veel shellscripts voor. Wat denk je bijvoorbeeld van de volgende code : for i in $(cut -f 1,3 -d: /etc/passwd); do array[${i#*:}]=${i%:*} done echo “User ID $1 is ${array[$1]}.” echo “Er zijn op dit moment ${array[@]} gebruikersaccounts op je computer gedefinieerd.”
11.5.3 case Ook al is de gemiddelde IT-er niet direct in voetbal geïnteresseerd, het kan geen kwaad ook met de rest van de Nederlandse bevolking mee te kunnen praten en het volgende script helpt je daarbij. Zelf doen We geven nu voor de verandering eens eerst het script zonder ook maar iets uit te leggen van wat we nu eigenlijk van plan zijn. Een prima methode om te leren hoe het werkt, is het script te lezen zonder te kijken naar de uitleg. Grote kans dat je er alleen ook wel uitkomt!
11 Shellscripting
407
#!/bin/bash # Your personal soccer expert # Usage: wm echo Enter the name of the country you think will be Worldchampion Soccer echo in 2010. echo Be aware that this is a stupid script: it needs the name of your country echo to start with an uppercase letter read LAND case $LAND in Nederland | Niederlande | Holland) echo “Yes, you are an expert on soccer” ;; Deutschland | Duitsland | Germany | Mannschaft) echo “Nein, nein, NEIN!! Warum verstehen sie das noch nicht?” ;; England | Engeland) echo “Hahahahahahah, you must be joking” ;; * ) echo “Huh? Do they play also?” ;; esac
Uiteraard begint dit script ook weer met de gebruikelijke shebang en het commentaar waaruit blijkt hoe het script gebruikt moet worden. Het betreft weer een eenvoudig script dat geen argumenten nodig heeft op de opdrachtregel wanneer het gestart wordt. Vervolgens komt de body van het script waarin we gebruikmaken van een eenvoudige echo, omdat we iets aan de eindgebruiker willen vertellen. Heb je het idee dat dit veel eenvoudiger kan? Dat klopt: het ligt hier meer voor de hand gebruik te maken van een here-document, zodat het later ook mogelijk is nog eens tekst in te voegen in de tekst die op het beeldscherm getoond moet worden. Na het commentaar stopt het script even om op invoer van de gebruiker te wachten. Deze invoer wordt met behulp van read
408
Linux 4
ingelezen en in de variabele LAND gestopt. Hierbij kan opgemerkt worden dat de naam van die variabele absoluut niet in hoofdletters geschreven hoeft te worden, maar het maakt het script wel een stuk meer leesbaar als je dat wel doet. Zeker als je in een lang script veel verschillende variabelen definieert, is het de moeite waard ervoor te zorgen dat ze duidelijk te onderscheiden zijn als dusdanig. Om die reden hebben we hier gekozen voor hoofdletters. Daarna begint de body van het script waar deze keer gebruikgemaakt wordt van het statement case. Dit kan gebruikt worden om de gebruiker een aantal alternatieven voor te houden. De structuur van deze verschillende alternatieven is in principe eenvoudig (zoals alles in de wetenschap van shellscripting in principe eenvoudig is): alternatief1 | alternatief2) commando ;;
Op de eerste regel wordt voor het haakje een aantal alternatieven gegeven. Ongeacht welk alternatief gekozen wordt, dezelfde opdracht moet uitgevoerd worden. Daarom worden de verschillende alternatieven in dit geval van elkaar gescheiden door een |-teken. Dan komt op een nieuwe regel de opdracht die uitgevoerd moet worden. Uiteraard mogen dat meerdere opdrachten zijn die opdracht voor opdracht verspreid staan over verschillende regels. Tot slot – en dat is een onderdeel dat nogal eens vergeten wordt – moet elk alternatief afgesloten worden met de constructie ;;. In dit script zie je dat een drietal alternatieven gegeven wordt. Daarbij is de kans natuurlijk aanzienlijk dat een gebruiker iets invoert dat niet letterlijk als alternatief genoemd staat. Om dit af te vangen, wordt als laatste de optie * gegeven wat natuurlijk verwijst naar al het andere dat hier mogelijkerwijs ingevoerd wordt. Dan volgt tot slot nog het formele eind van deze case-loop en dat is esac. Probeer het script gerust uit en modificeer het naar eigen behoefte. Je zult zien dat je er zeer nuttige dingen mee kunt doen. 11.5.4 Virtueel kindje: while Iedereen die kinderen heeft, weet waar deze wezens bijzonder goed in kunnen zijn: zeuren. We definiëren zeuren voor het gemak maar even als het aanhoudend vragen om steeds hetzelfde. Daarom speciaal voor de frequent afwezige vaders en moeders onder de lezers
11 Shellscripting
409
een script dat je kind kan vervangen tijdens eenzame reizen. Het principe van dit script is eenvoudig. Het wordt gestart met een willekeurig argument; dat is het ding waar het script in kwestie om gaat zeuren. Vervolgens duikt het script een while-loop in. Deze loop zorgt ervoor dat de opdracht in de loop wordt uitgevoerd, zolang aan de conditie voldaan wordt. De code is als volgt: #!/bin/bash # Virtual child # Usage: zeur <woord> while true do sleep 1 echo ik wil een $1 done
Wellicht dat de constructie while true enige toelichting nodig heeft: met deze controle wordt gekeken of de opdracht true het resultaat true oplevert. Nu heet de opdracht true juist zo, omdat deze altijd het resultaat true oplevert. Dit script duikt dus een eindeloze herhaling in totdat het wordt afgebroken. Nu kunnen wij ons voorstellen dat ook andere mensen dan de frequente zakenreiziger die hun kindjes missen iets nuttigs met while willen kunnen doen. Zo kun je bijvoorbeeld met het volgende script de performance van je I/O-systeem testen: #!/bin/bash # # Script waarmee je je server extreem kunt stressen. # Opgepast: de kans is heel groot dat de werklast dusdanig wordt dat de server # nergens meer op reageert COUNTER=0 while true do cat /dev/sda > /dev/null & COUNTER=$(( COUNTER + 1 ))
410
Linux 4
echo $COUNTER done
Het doel van dit script is zo vaak mogelijk de inhoud van de totale vaste schijf te kopiëren naar het null-device. Dit gebeurt door middel van een redirection op het sda-device. (Controleer of de vaste schijf inderdaad een sda is of wellicht een andere devicenaam heeft!). De ampersand aan het eind van de opdracht is essentieel. Hiermee voer je de opdracht namelijk op de achtergrond uit. Dit betekent dat direct na het opstarten van deze opdracht de shell zijn handen vrij heeft om opnieuw te beginnen. Het opstarten van de belastende opdracht is in dit geval gekoppeld aan een while-loop waarin de opdracht true gebruikt wordt. Zoals je weet, de opdracht true wordt altijd succesvol uitgevoerd en er is dus geen enkele belemmering op de uitvoering van deze opdracht. Dit betekent dat er heel snel een heel groot aantal processen gestart wordt. Daarbij wil je waarschijnlijk wel weten hoe actief het systeem is en hoeveel processen er gestart zijn. Hiervoor gebruiken we een counter. Voorafgaand aan de while-loop wordt de counter geïnitialiseerd op 0 en elke keer dat de opdracht cat met succes is uitgevoerd, wordt de counter met 1 opgehoogd. Op deze wijze zien we in een teller precies hoe vaak de opdracht met succes uitgevoerd is. We hebben er overigens voor gekozen de variabele in hoofdletters te schrijven. De reden? Zeker in grotere scripts is het veel overzichtelijker als je zo in één oogopslag kunt zien wat de variabelen zijn. 11.5.5 Speuren naar je lief: until Het tegengestelde van while wordt bewerkstelligd door until. Dit wordt gedemonstreerd in het volgende script: #!/bin/bash # # Script dat kijkt of je lief al is aangemeld # gebruik: ismijnlief until who | grep $1 >> /dev/null do echo $1 is er nog niet sleep 5 done
11 Shellscripting
411
echo $1 is zojuist ingelogd
In dit script is de opdracht die uitgevoerd wordt in de test who | grep $1. Hierbij is $1 de naam van je lief, bijvoorbeeld linda. De opdracht who | grep linda is waar als linda is aangemeld. De opdracht kan dan namelijk laten zien dat dit inderdaad het geval is. Zolang linda nog niet is aangemeld, is de opdracht niet waar (er is immers geen resultaat), dus duikt het de loop in. In de loop wordt eerst vriendelijk melding gedaan dat linda er nog niet is, waarna het script 5 seconden inactief wordt. Op het moment echter dat linda zich aanmeldt op het netwerk, wordt de loop doorbroken en toont het script de melding “linda is zojuist ingelogd” op het netwerk. Hier blijkt ook het nut van de redirector naar het nulldevice achter de test. Zonder deze redirector zou namelijk ook het resultaat van de opdracht who getoond worden en dat is natuurlijk niet fraai. We willen alleen maar weten dat linda is aangemeld en wat de opdracht daarom te melden heeft, is verder helemaal niet interessant. 11.5.6 Een bepaalde reeks opdrachten uitvoeren met for Soms is het nodig een aantal opdrachten achter elkaar uit te voeren waarbij het bij voorbaat vaststaat hoeveel opdrachten dat moeten zijn. Dan is for een uitstekende keuze. Een klassiek voorbeeld dat heel goed aangeeft waar het om gaat, is de for-loop waarbij een teller uitgevoerd wordt: #!/bin/bash # teller: telt van 1 tot 9 for (( teller=1; teller<10; teller++ )) ; do echo “De teller is nu $teller” done exit 0
De code van dit script is eenvoudig te doorgronden. In de conditionele loop wordt bepaald dat zolang de variabele teller een waarde heeft tussen 1 en 10, deze variabele automatisch met 1 verhoogd moet worden. Voor dit verhogen met 1, wordt gebruikgemaakt van de constructie teller++. Zolang aan de voorwaarde voldaan wordt dat de teller tussen deze twee waarden ligt, worden de opdrachten uitgevoerd die na de do komen. In dit geval is dit de opdracht echo die aangeeft wat de huidige waarde is van $teller. Op het mo-
412
Linux 4
ment dat alle werk verzet is, breekt de done aan en kan het script afgebroken worden. Hierbij wordt met exit 0 aan de shell doorgegeven dat er geen problemen waren met de uitvoering. Eerder in dit hoofdstuk heb je gelezen dat het gebruik van for ook heel handig kan zijn in combinatie met een array. Om te beginnen herhalen we even de betreffende code: # zooi=(een twee drie vier) # echo $zooi een #echo ${zooi[*]} een twee drie vier # for i in ${zooi[*]}; do echo $i; done een twee drie vier
In deze code zie je dat de operator for indien toegepast op een array een voor een alle waarden uit de array gaat behandelen. Dit kun je bijvoorbeeld ook toepassen op een tekstbestand om iets te doen met elke regel in het tekstbestand. Het volgende eenvoudige voorbeeld geeft aan hoe je met for ervoor zorgt dat een voor een elke regel uit het tekstbestand wordt weergegeven: for i in `cat /etc/passwd` do echo $i done
Je ziet dat nu elke regel uit /etc/passwd een voor een wordt weergegeven. Dit gaat overigens goed zolang er geen spatie in de regel voorkomt. Op het moment dat er een spatie voorkomt, wordt deze als internal field separator geïnterpreteerd en wordt for op dat deel van de regel toegepast. In een ander voorbeeld kan een input file gebruikt worden met daarin een lijst van bijvoorbeeld servers. Er van uitgaande dat zo’n input file bestaat, kun je met het volgende script eenvoudig testen of alle servers in het netwerk wel up zijn:
11 Shellscripting
413
#!/bin/bash # # check if hosts are replying to ping. This script requires the use of a file # named “ipad” which is in the same directory as the script and contains the # ip addresses of the hosts you want to check for i in `cat ipad` do ping -c 1 $i if [ “$?” -ne “0” ] then logger $i not responding to ping fi done echo showing failing nodes tail /var/log/messages | grep ping
In het voorgaande script wordt uitgegaan van een input-bestand met de naam “ipad”. Dit bestand bevat een lijst van alle IP-adressen of namen van computers die je wilt testen. De for-loop zorgt ervoor dat de hosts een voor een benaderd worden met één pingpakketje. Als de exit-status van de opdracht ping iets anders is dan 0 (met andere woorden, als het pingen niet goed ging), wordt er met logger een bericht geschreven naar syslog. In alle andere gevallen gebeurt er niets. In de laatste regel tot slot wordt er met tail voor gezorgd dat van de laatste tien regels in /var/log/messages alleen die regels getoond worden waarin de tekst ping voorkomt. 11.6
Werken met de stream editor
Een zeer handig hulpmiddel dat je kunt inzetten bij het werken met shellscripts, is de stream editor sed. Helaas is het niet alleen een handig, maar ook een moeilijk te doorgronden hulpmiddel. De stream editor sed heeft veel weg van de opdracht grep. Waar je grep gebruikt om tekenreeksen in tekstbestanden te vinden, gebruik je sed om niet alleen de tekenreeks te vinden, maar er ook iets mee te doen. Hiervoor bestaat de opdracht sed altijd uit
414
Linux 4
meerdere delen. In het eerste deel geef je aan wat de opdracht precies voor bewerking moet uitvoeren. Dan geef je aan waarnaar het moet zoeken. Dan geef je aan waardoor vervangen moet worden en tot slot geef je aan hoe de vervanging moet plaatsvinden. Bekijk bijvoorbeeld de volgende opdracht: sed “s/president/koning/g” staatshoofden.txt. In deze opdracht is de actie die uitgevoerd moet worden een substitutie (s). De tekst waarnaar gezocht moet worden, is president en de tekst waardoor dat vervangen moet worden is koning. Tot slot geeft de letter g aan dat deze opdracht uitgevoerd moet worden net zolang als dat er matches gevonden worden. Let erop dat je de eigenlijke opdracht sed altijd tussen aanhalingstekens moet zetten. Dit is om ervoor te zorgen dat niet de shell, maar sed het argument gaat interpreteren. Het laatste waar je rekening mee moet houden bij het werken met sed, is dat de opdracht nooit het originele bestand zal aanpassen. In plaats daarvan zal het de aanpassingen wegschrijven naar STDOUT. Om vervolgens dus ook iets met de aanpassingen te doen, zul je deze weg moeten schrijven naar een nieuw bestand. Je zult voor dit doel altijd moeten redirecten naar een tijdelijk bestand. Het is namelijk niet mogelijk het originele bestand te overschrijven. Stel je bijvoorbeeld de volgende bewerking voor waarbij je de inhoud van het bestand /etc/passwd wilt aanpassen, zodat de tekst home overal vervangen wordt door data: sed “s/home/data/ g” /etc/passwd. Het resultaat van deze opdracht wordt door sed op het beeldscherm geplaatst. Om daar iets mee te doen moet je het wegschrijven naar een tijdelijk bestand, bijvoorbeeld: sed “s/ home/data/g” /etc/passwd > /etc/passwd2. Dit tijdelijke bestand kun je vervolgens over het originele bestand heen kopiëren. Een andere handige taak die je met sed kunt uitvoeren, is dat je er tekst mee kunt verwijderen uit een bestand. Zorg er gewoon voor dat de nieuwe tekst leeg is. Een voorbeeld daarvan wordt gegeven in tail lijst.txt | sed “s/iets//g”. Hierbij wordt overal uit de lijst het woord iets verwijderd. Een andere handige taak die je met sed kunt uitvoeren, is het verwijderen van een regel die aan een bepaald patroon voldoet. De opdracht cat /etc/passwd | sed “/sander/d” zorgt er bijvoorbeeld voor dat uit /etc/passwd elke regel waarin de tekenreeks sander voorkomt, wordt verwijderd. Een alternatief is dat je met
11 Shellscripting
415
ook volledig lege regels kunt verwijderen. Hiervoor maak je gebruik van reguliere expressies en in dit geval wel de regulieren expressie waarmee je verwijst naar het begin en het einde van de regel. Dit komt er dan uit te zien als cat lijst.txt | sed “/^$/ d”. In deze opdracht wordt de constructie ^$ gebruikt om te verwijzen naar het begin van de regel (^) gevolgd door het einde van de regel ($) met niets er tussenin. sed
11.7
Werken met functies
Een aanvullend element waarmee je een shellscript kunt verrijken, is een functie. Dit is een subroutine, eigenlijk een script binnen het script, die gebruikt wordt om een naam te verbinden aan een aantal opdrachten die bij elkaar horen. Het voordeel van het gebruik van een functie is dat je de functie herhaaldelijk in hetzelfde script kunt aanroepen. Functies lenen zich dus heel goed voor situaties waarin bijvoorbeeld een foutmelding meerdere malen aangeroepen moet kunnen worden. Je verwijst op elke willekeurige positie in het script naar de naam van de functie om de bijbehorende opdrachten uit te voeren. Er zijn twee manieren om functies te definiëren: function functienaam { commando1 commando2 commandon }
en daarnaast kun je precies dezelfde functies definiëren met: functienaam () { commando1 commando2 commandon }
Wij raden je in verband met de overzichtelijkheid van je scripts aan altijd gebruik te maken van functies. Je maakt het script er name-
416
Linux 4
lijk veel beter leesbaar mee. Definieer de functies in het begin van het script, zodat je deze later opnieuw kunt aanroepen. In het volgende zie je een voorbeeld waarin gebruikgemaakt wordt van een foutmelding die als functie gedefinieerd is. #!/bin/bash # Laat het bestandstype zien # # gebruik: btype $1 function fout { echo “Je hebt een fout gemaakt” echo “Voer bij gebruik van dit script altijd de naam in van het bestand dat je wilt zien” exit 1 } if -z $1; then fout else file $1 fi exit 0
Dit voorbeeld is redelijk eenvoudig; de functie wordt bovendien maar één keer aangeroepen. Let overigens op het gebruik van exit 1 in het script om aan de shell aan te geven dat er iets niet helemaal goed gegaan is. De functie gedraagt zich als een onafhankelijk stuk code dat je keer op keer binnen je script kunt aanroepen. 11.8
Opties
In een shellscript wil je opties waarschijnlijk op een andere manier behandelen dan gewone argumenten. Het is dus belangrijk dat je opties van gewone argumenten kunt onderscheiden. Er zijn twee manieren om in een shellscript duidelijk te maken dat een argument een optie is. Als eerste kun je met de opdracht grep zoeken naar het koppelteken, waarmee een optie doorgaans begint. Daarnaast kun je gebruikmaken van de shell-opdracht getopts.
11 Shellscripting
417
11.8.1 Zoeken naar opties met grep De eerste manier om opties op een andere manier te behandelen dan gewone argumenten is te zoeken naar opties met de opdracht grep. Hierbij kun je zoeken naar alle tekens die voorafgegaan worden door een liggend streepje. Vervolgens moet je de shell-opdracht shift gebruiken om een voor een alle opties af te handelen. Deze opdracht zorgt er namelijk voor dat alle argumenten van een script een voor een afgehandeld kunnen worden. Pas als een argument is afgehandeld, komt het volgende argument aan de beurt. Als alle opties afgehandeld zijn, kun je verder gaan met de afhandeling van de gewone argumenten. De benodigde scriptcode moet de volgende vorm hebben: while het argument een optie is do case welke optie is het dan
-optie1)
-optie2)
commando’s;; commando’s;;
-optien)
commando’s;;
esac shift done verdere afhandeling van argumenten
De belangrijkste vernieuwing ten opzichte van de eerder in dit hoofdstuk besproken scripts zit in de eerste regel: while het argument een optie is. De vraag hierbij is dan natuurlijk: hoe wordt dan bepaald dat het eerste argument een optie is? Hiervoor dient de opdracht grep. Je moet de opdracht grep in de waarde van het eerste argument laten zoeken naar een koppelteken, waarmee elke optie dan ook beslist moet beginnen. Je zou dit op de volgende manier kunnen doen: while [ -n “$(echo $1 | grep ‘-’)” ]
De betekenis van deze regel is: terwijl het eerste argument minimaal één teken groot is en bovendien begint met een streepje,
418
Linux 4
moet er iets gebeuren. Dat wat moet gebeuren indien aan deze voorwaarde voldaan is, wordt op de volgende regels gespecificeerd met het statement case. Er moet immers gekeken worden wat de waarde is die voor de optie is gegeven. Na elke bekeken optie moet dan met de shell-opdracht shift het volgende argument op de positie van $1 worden geplaatst, zodat de test while ... herhaald kan worden. Op het moment dat de eerste parameter niet meer een koppelteken bevat, moet ten slotte verder gegaan worden met de afwerking van andere parameters. Dit script kan er als volgt uit zien: #optie [-a -b -c] parameters #script dat laat zien hoe gecheckt kan worden op opties. while [ -n “$(echo $1 | grep ‘-’)” ]; do case $1 in
-a) echo dit is de eerste optie
-b) echo dit is de tweede optie
-c) echo dit is de derde optie
*) fout
esac shift done echo parameter 1 is $1 echo parameter 2 is $2
Dit script is een aardige mogelijkheid om opties af te werken, mits aan een aantal voorwaarden is voldaan. De eerste voorwaarde is dat alle opties stuk voor stuk met een koppelteken beginnen. Dit script moet dus aangeroepen worden met de opdracht optie -a -b -c. Het onder Linux zo gebruikelijke optie -abc zal niet lukken. Hier zou ‘abc’ immers geïnterpreteerd worden als één optie. Daarnaast kunnen met dit script geen opties worden afgehandeld die zelf een argument hebben. Bij wijze van oplossing voor deze tekortkomingen kan gebruik worden gemaakt van de shell-opdracht getopts. 11.8.2 getopts De shell-opdracht getopts kan worden gebruikt in combinatie met de shell-opdracht while om te zoeken naar valide opties. Als eerste argument van getopts kan worden meegegeven welke opties geldig zijn. Daarbij kan gespecificeerd worden welke van deze opties een argument hebben. Als tweede argument heeft getopts de
11 Shellscripting
419
naam van een variabele die tijdens het werken van getopts wordt gebruikt om elke optie, terwijl deze verwerkt wordt, toe te kennen als waarde van de variabele. getopts blijft in een loop waarbij opties worden afgewerkt totdat het een exit-status 1 tegenkomt. De exit-status 1 wordt veroorzaakt doordat er geen opties meer zijn of doordat een fout is opgetreden. Hieronder volgt een eenvoudig voorbeeld: #gtpts [-a] [-b arg] [-c] args ... #Toont de werking van getopts while getopts “:ab:c” opt do case $opt in a ) echo Je hebt optie -a gekozen ;; b ) echo Je hebt optie -b gekozen echo het argument van -b is $OPTARG ;; c ) echo Je hebt optie -c gekozen ;; ? ) echo ‘optie [-a] [-b argument] [-c] args...’ exit 1 ;; esac done shift $(($OPTIND -1)) echo parameter 1 is $1 echo etcetera
In de eerste regel worden de opties gedefinieerd. Daarbij wordt met de dubbelepunt gespecificeerd dat optie -b een argument kan hebben. Het rijtje opties begint ook met een dubbelepunt, dit om te voorkomen dat een onduidelijke foutmelding wordt gegenereerd als een ongeldige optie wordt gegeven. Na de optie wordt de variabele opt gedefinieerd. Deze variabele wordt gebruikt tijdens de afhandeling van de opties. Vervolgens worden in het statement case stuk voor stuk alle opties afgewerkt. Daarbij is het niet nodig de opdracht shift te gebruiken. Het statement case kijkt naar de waarde van de variabele opt. Deze variabele is in de eerste regel gedefinieerd en wordt gebruikt om tijdelijk de waarde van de opties in te bewaren. Als de eerste gespecificeerde optie is afgehandeld, wordt de tweede optie in deze variabele geplaatst en dit gaat zo door totdat alle opties op zijn.
420
Linux 4
De regel waarin de optie -b wordt afgehandeld, is een bijzondere regel. Optie -b heeft immers een argument, dat door de opdracht getopts automatisch in een variabele OPTARG wordt geplaatst. De volgende regel waarin iets bijzonders gebeurt, is shift $(($OPTIND -1)). Hier wordt een shift uitgevoerd op basis van de waarde van de variabele OPTIND. De opdracht getopts houdt bij met welke optie hij bezig is door middel van de variabele OPTIND, de option index. Elke keer dat getopts een optie bewerkt heeft, wordt de waarde 1 opgeteld bij de huidige waarde van OPTIND. Daardoor kan verwezen worden naar de volgende optie die moet worden bewerkt. Dit betekent dat op het moment dat alle opties verwerkt zijn, OPTIND verwijst naar de eerste positionele parameter. Op de waarde van de variabele OPTIND wordt vervolgens een berekening uitgevoerd, namelijk OPTIND -1. Zoals elders in dit hoofdstuk besproken zal worden, is het mogelijk te rekenen met de waarde van een variabele. Nadat alle opties zijn behandeld, is de waarde van OPTIND gelijk aan alle opties +1. Door hier weer 1 vanaf te trekken blijft dus een waarde over die precies gelijk is aan het aantal opties. Deze waarde wordt weer doorgegeven aan de opdracht shift die ervoor zorgt dat het eerste argument dat geen optie is op de plaats van de eerste positionele parameter komt te staan. Samengevat doet de opdracht getopts dus het volgende: 1. Het eerste argument van getopts definieert alle opties die gebruikt kunnen worden. Elke optie die een argument kan hebben, wordt gevolgd door een dubbelepunt. De lijst opties begint met een dubbelepunt om onduidelijke foutmeldingen te voorkomen. 2. Het tweede argument is de naam van een variabele die tijdens de werking van getopts wordt gebruikt. 3. De opdracht getopts maakt gebruik van de eigen variabele OPTARG om het argument van een optie tijdelijk te bewaren. 4. De variabele OPTIND bevat het volgnummer van het eerste argument dat geen optie is. Nog een eenvoudig voorbeeld:
11 Shellscripting
421
#iets [-a string] [-b] [-c string] parameter while getopts “:a:bc:” opt; do case $opt in
a ) opta=$OPTARG ;;
b ) optb=$(echo blub) ;;
c ) optc=$OPTARG ;;
esac done shift $(($OPTIND – 1)) echo $opta $optb $optc $1
In dit script kunnen drie opties worden meegegeven, waarvan twee een argument kunnen hebben. De opdracht getopts zorgt ervoor dat alle opties worden afgehandeld. Elke optie is een verwijzing naar een aparte bewerking die aan de eigenlijke opdracht meegegeven kan worden. Het resultaat van deze bewerking wordt in een variabele gezet (in het voorbeeldscript zijn dit de variabelen opta, optb en optc). Naar deze variabele kan vervolgens weer worden verwezen nadat de opties afgewerkt zijn. Om nog eens te benadrukken waar het nu om gaat bij opties nog een voorbeeld. Uit dit voorbeeld wordt duidelijk dat een optie in feite gewoon een verwijzing naar een stuk programmacode is. Deze programmacode wordt gekoppeld aan een variabele, waarmee vervolgens weer dingen kunnen gebeuren. De regels in het volgende script zijn genummerd. De nummers maken geen deel uit van de daadwerkelijke code, maar worden hier alleen gegeven om de inhoud van het script beter te kunnen bespreken. 1.
#laatzien [-g] [-b bestanden]
2.
#-g toont gebruikers die ingelogd zijn
3.
#-b toont bestanden
4. 5.
function foutmelding
6.
{
7. echo ‘gebruik: laatzien [-g] [-b bestandsnaam]’ 8. exit 1 9.
}
10. 11. while getopts “:gb:” opt 12. do
422
Linux 4
13. case $opt in 14. 15. 16. 17. 18.
g ) users=$(who) echo $users ;; b ) bestanden=$(ls -l $OPTARG) echo $bestanden ;; * ) foutmelding ;;
19. esac 20. done 21. 22. shift $(($OPTIND -1))
Dit script toont een aantal constructies die in voorgaande paragrafen aan de orde zijn gekomen. Allereerst wordt in de eerste drie regels door middel van commentaar samengevat wat het script doet. Daarna wordt in regel 5 tot en met 9 een functie foutmelding gedefinieerd. Er is hier voor een functie gekozen, omdat de opdrachten die uitgevoerd moeten worden bij het optreden van een fout, meerdere malen in het script moeten worden aangeroepen. Het is in zulke gevallen raadzaam voor de overzichtelijkheid een functie te gebruiken. Naast de foutmelding zorgt de functie er door de opdracht exit 1 op regel 8 voor dat de uitvoering van het script wordt afgebroken als zich een foutsituatie voordoet. Dit is om te voorkomen dat bij een dubbele fout in het aanroepen van het script tweemaal dezelfde foutmelding zou worden gegenereerd. Vervolgens wordt in regel 11 tot en met 20 het statement while uitgevoerd. Hier wordt bepaald wat er moet gebeuren zolang er nog opties zijn. Hiervoor wordt de opdracht getopts gebruikt. De opties -g en -b worden gedefinieerd. Alleen de optie -b kan een argument hebben. De waarde van elke optie die aan de opdracht gegeven is, wordt doorgegeven aan de tijdelijke variabele opt. Dan wordt in regel 13 tot en met 19 elke optie afgehandeld. Als de optie -g gegeven is, wordt de reguliere Unix-opdracht who uitgevoerd. De output van deze opdracht wordt in een variabele geplaatst en de waarde van deze variabele wordt toegekend aan de variabele users. In regel 15 wordt de shell-opdracht echo $users gegeven. Samengevat houdt dit dus in dat de optie -g ervoor verantwoordelijk is dat de opdracht who wordt uitgevoerd.
11 Shellscripting
423
In regel 16 en 17 wordt de optie -b afgehandeld. Als -b gegeven is, wordt de opdracht ls -l uitgevoerd. Een eventueel argument dat aan -b is gegeven, wordt in de vorm van de systeemvariabele OPTARG doorgegeven aan de opdracht ls -l. Het resultaat daarvan wordt op regel 17 getoond. Regel 18 regelt ten slotte dat in elk ander geval de foutmelding die in de functie foutmelding is gedefinieerd, wordt getoond. Vervolgens moet nog afgehandeld worden wat er moet gebeuren als naast de opties nog andere argumenten aan de opdracht zijn gegeven. Allereerst zorgt regel 22 ervoor dat de shell-opdracht shift wordt uitgevoerd. Deze opdracht bewerkstelligt dat het eerste argument dat geen optie is op de plaats van de eerste positionele parameter komt te staan. Hiervoor wordt de systeemvariabele OPTIND gebruikt. Deze variabele heeft als waarde het volgnummer van het eerste argument dat geen optie is. Door hier een waarde 1 van af te trekken (dit wordt in de volgende paragraaf verder uitgewerkt) wordt precies het aantal opties als argument aan de shell-opdracht shift gegeven. Hierdoor wordt het eerste argument dat geen optie is de eerste positionele parameter. 11.9
Afvangen van ongeoorloofde toetsencombinaties
Een laatste toepassing in je scripts is het afvangen van ongeoorloofde toetsencombinaties, zoals Ctrl-C. Hiervoor kan de opdracht trap worden gebruikt. Hiermee kun je een opdracht koppelen aan een signaal dat naar een proces wordt gestuurd. Dit betekent dat een opdracht wordt uitgevoerd zodra een gespecificeerd signaal naar een proces wordt gestuurd; het signaal zelf wordt dan niet uitgevoerd. De drie meest voorkomende signalen die naar een proces worden gestuurd zijn: INT Veroorzaakt door Ctrl-C. TERM Veroorzaakt door kill. KILL Gelijk aan kill -9. Van deze en andere signalen die naar een proces kunnen worden gestuurd, mag alleen het KILL-signaal niet worden afgevangen. Er moet namelijk altijd een mogelijkheid zijn om een proces af te breken.
424
Linux 4
Om met de opdracht trap een signaal dat naar een proces wordt gestuurd af te vangen, moet de volgende syntaxis worden gebruikt: trap commando[‘s] signaal1 signaal2
De werking hiervan wordt geïllustreerd in het volgende (eenvoudige) voorbeeldscript: trap “echo ‘Foei toch!’” INT TERM echo “geef een getal” read getal echo “het getal dat je getypt hebt is $getal”
In dit script wordt op de eerste regel de trap gedefinieerd. Deze trap blijft gedurende de hele uitvoering van het script als een soort waakhond actief om te luisteren of er een ongeoorloofd signaal naar het proces wordt gestuurd. Als dit toch het geval is, wordt de aan het signaal gekoppelde opdracht uitgevoerd. 11.10
Geavanceerde scripts
Nu je kennis hebt gemaakt met alle ingrediënten van shellscripts, wordt het tijd om eens naar een wat ingewikkelder voorbeeld te kijken: while true do sleep 60 USAGE=`ps -eo pcpu,pid -o comm= | sort -k1 -n -r | head -1 |\
awk ‘{ print $1 } ‘`
USAGE=${USAGE%%.*} PID=`ps -eo pcpu,pid -o comm= | sort -k1 -n -r | head -1 |\
awk ‘{print $2 }’`
PNAME=`ps -eo pcpu,pid -o comm= | sort -k1 -n -r | head -1 |\
awk ‘{print $3 }’`
if [ $USAGE -gt 80 ] then USAGE1=$USAGE
11 Shellscripting
425
PID1=$PID PNAME1=$PNAME sleep 7 USAGE2=`ps -eo pcpu,pid -o comm= | sort -k1 -n -r | head -1 |\
awk ‘{ print $1 } ‘` USAGE2=${USAGE2%%.*} PID2=`ps -eo pcpu,pid -o comm= | sort -k1 -n -r | head -1 |\
awk ‘{print $2 }’` PNAME2=`ps -eo pcpu,pid -o comm= | sort -k1 -n -r | head -1 |\
awk ‘{print $3 }’` # Now we have variables with the old process information and # with the new information [ $USAGE2 -gt 80 ] && [ $PID1 = $PID2 ] && mail -s “CPU load\
of $PNAME is above 80%” root < . fi
done
Let om te beginnen even op de manier waarop dit script geschreven is. In het script komen enkele lange regels voor die niet op één regel van dit boek passen. Als je aan het eind van een regel een backslash (\) vindt, betekent dit dat de regel met code gewoon op de volgende regel doorgaat. Het doel van dit script is de server geautomatiseerd in de gaten te houden. Als beheerder wil je graag weten hoe zwaar de belasting van processen is. Het komt regelmatig voor dat een proces eventjes piekt, maar als een proces gedurende langere tijd piekt, dan moet de beheerder daarvan op de hoogte gesteld worden. Dat is precies wat er in dit script gebeurt. Het eerste stuk code dat daarvoor gebruikt wordt, is het volgende: while true do sleep 60 USAGE=`ps -eo pcpu,pid -o comm= | sort -k1 -n -r | head -1 |\
awk ‘{ print $1 } ‘`
USAGE=${USAGE%%.*} PID=`ps -eo pcpu,pid -o comm= | sort -k1 -n -r | head -1 |\
awk ‘{print $2 }’`
426
Linux 4
PNAME=`ps -eo pcpu,pid -o comm= | sort -k1 -n -r | head -1 |\
awk ‘{print $3 }’`
In deze code gebeuren twee dingen. Als eerste wordt een loop geopend op basis van while true. Deze loop zorgt ervoor dat de opdrachten in dit script eindeloos uitgevoerd worden. De opdracht sleep 60 op de derde regel zorgt ervoor dat het script elke minuut een keer geactiveerd wordt. Om verderop in het script een berekening te kunnen doen, worden er nu drie variabelen gedefinieerd: USAGE, PID en PNAME. In deze variabelen komt de CPU-belasting tijdens de laatste loop, de PID van het betreffende proces en de naam (PNAME) van het proces in kwestie. Om deze gegevens te kunnen krijgen wordt command substitution gedaan met de opdracht ps -eo, gevolgd door enkele pipes die ervoor zorgen dat precies die infomatie getoond wordt die nodig is. Let in het bijzonder op de variabele USAGE, deze wordt eerst gevuld door middel van command substitution. Als dat gebeurd is, wordt deze opnieuw gedefinieerd. De reden hiervoor is dat de CPU-belasting typisch een getal is als 18.09 en het probleem is dat Bash dat niet leuk vindt. Later in het script willen we de waarde van $USAGE met iets vergelijken en die vergelijking lukt alleen maar als het een heel getal is. Daarom zorgt USAGE=${USAGE%%.*} ervoor dat alles vanaf de punt verwijderd wordt en er dus een geheel getal overblijft. Op basis van de drie variabelen die we nu hebben, kan het tweede deel van het script uitgevoerd worden. We herhalen voor het gemak de code nog even die hierin aan de orde komt: if [ $USAGE -gt 80 ] then USAGE1=$USAGE PID1=$PID PNAME1=$PNAME sleep 7 USAGE2=`ps -eo pcpu,pid -o comm= | sort -k1 -n -r | head -1 |\
awk ‘{ print $1 } ‘` USAGE2=${USAGE2%%.*} PID2=`ps -eo pcpu,pid -o comm= | sort -k1 -n -r | head -1 |\
awk ‘{print $2 }’` PNAME2=`ps -eo pcpu,pid -o comm= | sort -k1 -n -r | head -1 |\
awk ‘{print $3 }’`
11 Shellscripting
427
# Now we have variables with the old process information and # with the new information [ $USAGE2 -gt 80 ] && [ $PID1 = $PID2 ] && mail -s “CPU load\
of $PNAME is above 80%” root < . fi
done
Om te beginnen kijken we of de waarde van $USAGE hoger is dan 80%. Als dat het geval is, hebben we een overactief proces en treedt de if-loop in werking. Nu moeten we kijken of deze hoge waarde structureel is. Daarom worden de oude waarden van USAGE, PID en PNAME opgeslagen in nieuwe variabelen en wordt zeven seconden (sleep 7) later opnieuw de test uitgevoerd die hiervoor ook al is uitgevoerd. In deze nieuwe test worden de variabelen USAGE2, PID2 en PNAME2 gevuld. Nu willen we weten of het proces dat we in eerste instantie gevonden hebben met een hoge belasting nog steeds een hoge belasting veroorzaakt. Dit gebeurt in de regel: [ $USAGE2 -gt 80 ] && [ $PID1 = $PID2 ] && mail -s “CPU load\
of $PNAME is above 80%” root < .
In deze regel wordt als eerste een test uitgevoerd om te kijken of $USAGE2 groter is dan 80. Als dat het geval is, zorgt de constructie met && ervoor dat gekeken wordt of de PID van het proces dat een belasting veroorzaakt hoger dan 80% , vergeleken wordt met het eerdere proces dat een hoge belasting veroorzaakte. Als dat ook het geval is, hebben we dus een proces dat te lang (zeven seconden in dit geval) een te hoge belasting veroorzaakt. In dat geval wordt de opdracht mail gebruikt om een bericht te versturen naar de gebruiker root, zodat deze daarvan op de hoogte is. 11.11
Samenvatting
In dit hoofdstuk heb je kennisgemaakt met de basiselementen die in shellscripts gebruikt worden. Op basis van deze kennis ben je nu in staat om shellscripts te lezen. Ook kun je nu zelf eenvoudige shellscripts schrijven. Wij raden je aan deze vaardigheid zo veel mogelijk in de praktijk te brengen, goede shellscripts zorgen ervoor dat je veel slimme dingen met je servers kunt doen terwijl je zelf lekker van de zon gaat genieten of een kop koffie drinkt.
428
Linux 4
Index Symbolen & 128 / 10 /boot 9 /etc/resolv.conf 204 /etc/sysconfig 193 /home 10 /proc 159 bestandssysteem 282 /srv 9 /usr 9 /var 9 A A-adres 175 Access Control Lists 105, 112 access lookup table 268 account 42 ACL 105, 113 beperkingen 117 standaard- 114 toepassen 116 action 352 Active Directory inloggen Linux-gebruikers 317 Samba-server integreren 314 Active Directory-omgeving. 304 adres directed broadcast 171 IP 167 klasse A 175 klasse B 175 klasse C 175 local broadcast 170 loopback 170 multicast 170 adresklasse 168 afsluiten 84
alias definiëren 119 alias lookup table 270 Allow 240 Apache beveiligen met OpenSSL 244 versie 1 228 versie 1.3 229 versie 2 228 werken met modules 250 Apache-webserver 223 configuratie 227 structuur configuratiebestanden 230 apache2 156 apropos 55 argument 377 array 404 at 135, 136 AT-opdrachtenset 201 atq 136 atrm 136 authenticatie afhandelen 267 challenge-response 329 client 286 instellingen op client 331 instellingen vastleggen op server 329 key-based 338 op andere server 319 op basis gebruikersnamen 241 op basis van IP-adres 240 op basis van wachtwoord 328 rhosts 329 awk 404 B B-adres 175 backquote 381
Index
Backup Domain Controller 305 bash 380 Bash-shell 371 basispermissie 107 bc 396 BDC 305 beheer op afstand 325 berekening uitvoeren 388 bericht 155 bestand inhoud bekijken 74 kopiëren 79 locken 287 soorten 73 verplaatsen 79 verwijderen 79 zoeken 75 bestandsnaam 72 bestandssysteem 12, 62 inrichting 65 beveiliging firewall 347 SASL 266 bit 178 bitrate 202 BLAH 384 boot.log 156 bootpartitie 11, 27 Bourne-shell 371 broadcast 183 broadcastadres 179 byte 178 C C programmeertaal 370 C-adres 175 C-shell 371 caching 254
429
cal 80 canonical lookup table 268 case 398, 406 cat 75, 376 Certificate Authority 245 chain 348 definiëren 351 DROP 360 FORWARD 349, 361 INPUT 349 OUTPUT 349 policy instellen 359 rules 351 ChallengeResponseAuthentication 329 CHAP 203 chat activeren 208 script 210 chmod permissies instellen 110 CIDR-notatie 180 CIFS 289 clear 80 client authenticatie 286 command substitution 381, 426 Common Internet File System 289 computer SHH 325 veilig inloggen 325 computeraccount maken 312 configuratie Apache-webserver 227 Cyrus IMAPd 275 grafische hulpprogramma’s 320 key-based authenticatie 338 modem 201 netwerkkaart 165 PPP-interface 199 protocol 204
430
Linux 4
Samba-PDC 305 seriële poort 200 server 165 virtuele hosts 236 werkstations aanpassen 312 configuratiebestand 66, 93 httpd.conf 230 configuratiebestanden netwerkinstellingen bewaren 193 configuratie van key-based authenticatie 338 connection tracking 363 console virtuele 44 cp 79 CPU 126 CPU-belasting 426 cron 132 cut 380 Cyrus IMAPd configureren 275 gebruikers toevoegen 277 mailserver 273 shellprompt 277 starten 276 D daemon opstarten 304 daemons 121 database gebruikers- 296 date 80 datum en tijd 154 declare 395 delimiter 380 Deny 240 device 48 bestand 67 device-ID 196 df 81
dhclient 187 DHCP-client 187 DHCP-server 172 directed broadcast 171 directive 232 Allow 240 Deny 240 Include 232 directory /bin 66 /boot 71 /dev 67 /etc 66 /home 71 /lib 66 /opt 71 /proc 71 /sbin 66 /usr 70 /var 70 directorystructuur 62 distributie main-stream 228 dmesg 41 DNS 254 CNAME-record 238 configuratie 261 DNS-server instellen 191 Domain Controller Backup 305 Primary 305 domein Windows aanmelden 313 domeinnaam 17 done 412 DoS 217 draadloze netwerkkaart 188 du 81 dual core 127
Index
E echo 376 editor 81 elif 402 else 402 encryptie SSL 249 WEP 191 WPA 191 entiteit 110 EOF 376 esac 408 Execute 294 Execute-permissie 375 exit-status 373 expr 392 ext2 13 ext3 13 ext4 13 extension 352 F facility 137 configureren 137 overzicht 137 FAQ 59 Fedora downloaden 1 installeren 23 Fedora/Red Hat grafisch gereedschap 97 Fedora Core 23 fg 129 fi 402 field separator internal 412 file 81 filter 151, 348 find 75 firewall 155 Netfilter 347 regels 348
431
flag 352 opties 352, 353 float 396 flow control 398 for 399, 411 FORWARD 349 fragment versturen 354 free 81 ftp 337 ftp-pakketje 361 functie 415 G gateway standaard- 170 gebruiker 93 eigenschappen 94 maken 298 opslaan 93 standaardinstellingen 100 voorkeursinstellingen 304 gebruikers-ID 296 wwwrun 229 gebruikersaccount 35 gebruikersauthenticatie toepassen 243 gebruikersbeheer 277 grafisch gereedschap 97 opdrachten 96 gebruikersdatabase 296 gebruikersinstellingen velden 96 gebruikersnaam 94 geschiedenis 82 getfacl 114 getopts 416, 418 GNOME-desktop 7 grep 49, 75, 413, 417 groep 93 maken 298
432
Linux 4
groepsbeheer opdrachten 105 groepsdirectory 299 groepsidentificatienummer 95 groepslidmaatschap 296 regelen 103 groepsomgeving beheer 102 groepspermissie 103 Group-ID 296 group-owner 103 Grub 40 H head 75 Help opvragen 50 help 58 here-document 376 homedirectory 43, 71, 95 host identiteit vaststellen 328 host-key 327 HostbasedAuthentication 329 hostbit 177 hostnaam 154 opgeven 30 HOWTO 51, 59 HTML 223 HTML-document 224 basis van webserver 224 HTTP 223 httpd.conf 230 inrichting 233 Hypertext Markup Language 223 Hyper Text Transfer Protocol 223 hyperthreading 127 I ICMP-bericht 358 ICMP-datagram 216
id 81 identificatienummer 95 if 398, 401 if...then...fi 398 ifconfig 181 secundair IP-adres toevoegen 182 ifdown 188 if then else 399 ifup 188 IgnoreUserKnownHosts 330 IMAP 254, 273 mailserver configureren 273 Include directive 232 info 50, 56 informatie 95 init 123 inloggen 42 onder andere gebruikersnaam 61 INPUT 349 input-bestand 149 inputmodus 83 installatie Engelstalig 5 Nederlands 5 SUSE Linux 3 instance 130 INT 423 internal field separator 412 internals getops 416 Internet Protocol 166 IP 166 adres 166 protocolstack 166 ip 181, 184 netwerkkaart beheren 184 IP-adres 166, 364 geregistreerd 350, 364 netwerkdeel 167 nodedeel 167
index
opbouw 167 registreren 169 subnetmasker 167 uniek 169 IP-configuratie 187 IpnG 171 iptables 348 actions 357 back-up maken 367 match extensions 355 NAT 364 policy 359 standaardgedrag bepalen 359 standaard parameters 352 iptables-save 367 ISP CHAP 203 PAP 203 J jobs 129 jokerteken 64 K KDE 7 Kerberos-authenticatie 316 KerberosAuthentication 330 KerberosOrLocalPasswd 330 kernel 381 ondersteuning NFS 281 kernelmodule 181 laden 194, 363 kernelsource 197 KILL 423 kill 130 killall 130 klasse A-adres 175 B-adres 175 C-adres 175 klasse C-adres meer dan één netwerk 178
433
klogd 137 known_hosts 327 Korne-shell 371 kvim 82 L less 46, 74 let 394 librarybestand 66 LILO 40 Linux afsluiten 88 als DHCP-client 187 als NFS-client 287 als NFS-server 281 als Samba-server 289 bestanden delen 281 Execute 294 grafische sessies weergeven 334 groep maken 298 installeren 1 opdracht 44 permissies 294 Read 294 Write 294 Linux-Apache-MySQL-PHP 224 Linuxant 188 Linux Standards Base 66 lmhosts 292 loadlin 41 local broadcast 170 locate 75 logbestand monitoren 153 roteren 156 logger 143 logging 142 procesactiviteit 137 login 61 loginnaam 42 logisch volume 11, 26 logname 81
434
Linux 4
logrotate 157 lokale tijd 6, 31 longest match 386 long integer 396 lookup table 257, 267 access 268 alias 270 canonical 268 relocated 269 transport 269 virtual 270 loopback 170 ls 64 M mail 156, 255 versturen vanuit scripts 255 mailfilter procmail 257 mailserver 253 configureren voor IMAP 273 Cyrus IMAPd 273 parameters 262 Postfix 253 Sendmail 253 main-stream-distributie 228 main.cf 261 makewhatis 55 man 50, 51 man.config 56 mangle 348 MASQUERADE 366 masquerading 349 master.cf configuratie 257 match extension 355 aanroepen 355 MBR 39 Message Transfer Agent 253 modem configureren 201 verbinding testen 203
more 75 mount 287 mounten 9, 391 mountpunt 12, 391 MTA 253 multicast 170 MX-record 254 MySQL 224 N NAT statisch 350 nat 348 NdisWrapper 188 nesting 402 Netfilter chains 348 firewall 347 rules 348 tables 348 netmask 183 netstat 219 netwerk activeren 18 firewall 347 voorzien van IP-configuratie 187 netwerkadres 179 netwerkinstellingen bewaren 193 netwerkkaart beheren met ip 184 configureren 165 configureren met ifconfig 181 draadloze ~ configureren 188 instellen 29 vaste ~ configureren 180 netwerkverbinding netstat 219 status testen 219 testen 215 testen met ping 215 Network Address Translation 166, 349
Index
Network File System 281 NFS bestanden delen 281 daemons 282 mounts 287 NFS-client 287 NFS-server 281 directory’s beschikbaar stellen 282 locken van bestanden 287 nice 136 nmbd 290 node 167 nodebit 177 O op basis van public/private-keys 328 opdracht 44 output bekijken 74 opdrachtmodus 83 opties instellen 87 OpenSSL 244 OpenSUSE downloaden 1 operator 110 % 393 * 393 + 393 - 393 / 393 pattern matching 385 substitution 383 opslaan 84 OPTARG 420 optie 44, 352 opties zoeken met grep 417 OPTIND 420 option 352 opties 353, 354 OUTPUT 349, 351 ownership 103 achteraf wijzigen 104
435
P PAM configuratie 318 PAP 203 partitie 26 partitionering 8 passphrase 340 passwd 60 PasswordAuthentication 330 Pattern matching operators 385 PCI-bus 194 PCI-ID 196 PDC 289, 305 Perl-script 370 permissie 93, 110 aanpassen 299 basis- 107 beheer 106 beperkingen 112 Execute 294 geavanceerd 108 instellen met chmod 110 Read 294 root 93 SGID 109 standaard- 112 sticky bit 109 SUID 109 Write 294 PID 122, 426 ping netwerkverbinding testen 215 pipe 369 piping 45 PKI-certificaat 245 maken 246 PNAME 426 POP 254, 273 Postfix componenten 256 configuratiebestanden 256
436
Linux 4
lookup tables 257, 267 main.cf 256 master.cf 256 Postfix-mailserver 253 main.cf 261 services 259 Post Office Protocol 254 POSTROUTING 349, 366 PPP 204 PPP-connectie handmatig tot stand brengen 207 PPP-interface configuratie 199 handmatige configuratie 200 ppp-off 213 ppp-on 209 ppp-on-dialer 210 ppp-script testen 214 PREROUTING 349, 351 priemgetal 396 Primary Domain Controller 289, 305 priority overzicht 139 private address range 364 private address ranges 170 private key 244, 338 passphrase invoeren 340 privésleutel 244 proces beheer 124 deactiveren 129 instances 130 nmbd 290 op achtergrond starten 128 prioriteit 136 queue 126 schedulen 132 smbd 290 soorten 121 winbdinbdd 290
procesactiviteit monitoring 125 procmail 257 configuratie inkomende mail 270 programmeertaal C 370 protocol configuratie 204 pseudo-bestandssysteem 159 pstree 122 PubKeyAuthentication 331 public key 244, 338 publieke sleutel 244 PuTTY 326 pwd 63 Q QoS 351 qpopper herdistributie mail 271 Quality of Service 351 queue 126 R randapparaat 48 Read 294 Red Hat Enterprise Server 1 redirection 45, 47 regels firewall tables 348 Reiser 13 rekenmachine bc 397 relocated lookup table 269 remote opdrachten 331 Request For Comments 166 RFC’s 166 roaming profile 304 root 61 permissies 93 route 191 router
Index
beveiligen met iptables 348 functionaliteit testen 219 NAT 364 traceroute 219 RPM 228 RSA-key 328 rsync 403 rule 348 S Samba 289 als fileserver 293 als PDC 304 computeraccounts toevoegen 313 gebruikersdatabase 313 Kerberos-authenticatie 316 processen 290 Samba-gebruiker maken 300 Samba-PDC configuratie 305 Samba-server 289 componenten 289 gebruiker bestaat twee keer 297 integreren in Active Directory 314 lid maken Active Directory 315 smb.conf 290 Samba Web Administration Tool 320 SASL beveiliging 266 scale 397 scp 337 bestanden oversturen 337 script argument 377 basiselementen 372 chat activeren 208 commentaarregels 372 interactief maken 375 naamgeving 375 opdrachten uitvoeren 373
437
syntaxisregel 372 testen 214 uitvoeren 374 scripten 370 Secure Authentication Sockets Layer 267 Secure Shell 325 Secure Sockets Layer 244 sed 413 SELinux 34 Sendmail 253 seriële poort bitrate 202 configuratie 200 snelheid 202 server configureren 165 contact opbouwen met ssh 331 Debian 2 directory’s beschikbaar stellen 282 Red Hat 2 SUSE 2 Server Message Blocks 289 serverversie voordelen 2 servicenaam 155 sessie-key 328 setfacl 114 Set Group ID 401 sftp 337 SGID 109, 401 share aanpassen 300 definitie 282 shebang 372 shell 44, 95 Bash 371 Bourne 371 C 371 Korne 371 opdracht terugvinden 373 soorten 371
438
Linux 4
sub- 374 Z 371 shellscript 369, 424 berekeningen uitvoeren 388 functies 415 opties 416 shellscripting 369 shutdown 89 SIGHUP 131 SIGKILL 130 signal 130 Simple Message Transfer Protocol 253 Single User Runlevel 40 slash 386 sleutel privé 244 publieke 244 SMB 289 smb.conf 290 smbd 290 smbfstab 292 smbusers 293 SMTP 253 snapshot 9 SNAT 366 software installeren 16, 32 sort 81 source 150, 374 sourcen 375 SSH 325 authenticatie 327 bestanden oversturen met scp 337 encryptie 327 ftp 338 Linux 326 PAM 327 port-forwarding 334 ssh 331 tunneling 334 veilig inloggen op andere computers
325 versleuteling 326 Windows 326 ssh 331 ssh-agent 340 configureren 341 SSL Apache configureren voor ~ 248 SSL-encryptie 249 standaarddirectory 65 standaardgateway 170 standaardpermissie umask 112 standaardroute instellen 191 standaardsubnetmasker 167 aanpassen 176 statement case 408 statisch NAT 350 sticky bit 109 stream editor 413 string 386 test uitvoeren 400 subnetmasker 167, 169, 172 aanpassen 176 standaard 175 subnetten 172 subshell 374 substitutie 392, 414 substitution operator 383 sudo 118 configuratie 118 SUID 109 superuser 42, 61 SUSE Linux grafisch gereedschap 97 installeren 3 SUSE Linux Enterprise Server 1 Swap 13
Index
SWAT 320 synopsis 52 syslog 137 configureren 137 syslog-mechanisme 404 syslog-ng 137, 144 syslog-ng.conf opbouw 149 syslog.conf 137 systeemeisen 3, 23 T taal instellen 5, 24 tabel nat OUTPUT 349 table 348 filter 348 mangle 348 nat 348 table filter chains 349 table mangle chains 351 OUTPUT 351 PREROUTING 351 table nat chains 349 POSTROUTING 349 PREROUTING 349 tac 75 tag 226 tail 75 tarball downloaden 228 TCP/IP 165 TDB 293 teken 64 met speciale betekenis 64 tekenreeks 400 tekst knippen 87
439
plakken 87 toevoegen 85 verwijderen 85 zoeken 75, 86 tekstbestand maken 81 TERM 423 test 399 then 401 threads 123 toegang beperken Allow 240 Deny 240 gebruikersnamen 241 webserver 240 toetsencombinaties ongeoorloofde 423 top 125 traceroute 219 transport lookup table 269 trap 424 Trivial Database 293 true 389 TTL 216 tunneling 334 U umask 112 uname 81 uname -r 381 until 399, 410 updatedb 75 USAGE 426 user-owner 103 uucp 254 V van encryptie technieken 326 variabele 377 bewerken 381, 382 OPTARG 420
440
Linux 4
variabelen OPTIND 423 vendor-ID 196 Verisign 245 versleuteling 326 Vfat 13 vi 82 afsluiten 84 editor 81 inputmodus 83 opdrachtmodus 83 starten 83 tekst zoeken 86 virtual lookup table 270 virtuele console 44 virtuele consoles 43 virtuele host configureren 236 directives 238 VMware 22 VMware Tools installeren 36 VNC 325 VNC remote beheer 20 volumegroep 11, 27 W wachtrij 126 wachtwoord 42, 60, 94 wall 81 wc 81 webserver 223 Apache 223 HTML-document 224 toegang beperken 240 werkstation configuratie aanpassen 312 whatis 54 whereis 375 while 389, 399, 409, 418 while true 409
who 81, 411 winbdinbdd 290 Windows aanmelden op domein 313 grafische sessie doorsturen 344 SSH 326 WPA-encryptie 191 Write 294 write 81 wwwrun 229 X X-win32 344 X Forwarding 344 XFS 13 xterm 44 Y YaST 18 YaST2 190 Z Z-shell 371