Auteur Heinrich Wilhelm Kloepping <henk@opensource.nl> 17 December 2003 Snow B.V. Inleiding Dit document beschrijft theorie en praktijk rond het authenticeren van gebruikers die willen werken op een Linux (SuSE 8.1) gebaseerde machine middels LDAP koppelingen met een Novell eDirectory database. Theorie Om te kunnen werken met een Linux systeem moet er voor een gebruiker een aantal zaken bekend zijn, zoals: - een naam - een numeriek ID - een wachtwoord - een ID voor de (default) groep waarin hij valt - welk werkgebied hij krijgt - welk programma er voor hem wordt gestart Deze gebruikersattributen worden in een database bijgehouden. Bij onder meer het inloggen worden deze attributen uit de database gehaald en gebruikt voor het zetten van de juiste omgeving voor de gebruiker. Of de gebruiker werkelijk is wie hij zegt te zijn (authenticatie) kan op diverse manieren worden bepaald, veelal wordt nog een wachtwoord gebruikt. Het inloggen op een Linux systeem verloopt dan in grote lijnen als volgt: de gebruiker tikt achter de "login:" prompt initeel een identificerende tekenreeks in (zijn gebruikersnaam). Deze naam wordt dan gebruikt als zoeksleutel in een database om een aantal noodzakelijke attributen te vinden, zoals het UID, GID en het wachtwoord. Vervolgens wordt de gebruiker gevraagd om het bijbehorende wachtwoord ("Password:") in te voeren. Dit wachtwoord wordt dan versleuteld en dan vergeleken met het gevonden attribuut "versleuteld wachtwoord" voor de eerder opgegeven gebruiker. Komt dit overeen, wordt de gebruiker ingelogged: het voor de gebruiker in de database gedefinieerde programma wordt opgestart met het UID en GID wat werd gevonden (meestal een shell) etc. Er zijn 2 gangbare systemen om de configuratiedata toegankelijk te maken: een systeem wat baseert op lokale databases (bestanden) en een systeem wat gebruik maakt van centrale databases. In dit document beschrijven we de stappen om van decentrale naar centrale raadpleging van deze databases te komen. Lokale databases Linux (Unix) systemen gebruiken van oudsher lokake bestanden om informatie over de systeemgebruikers in op te slaan (/etc/password, /etc/shadow, /etc/group). In deze files staan velden met daarin data zoals gebruikers- naam, UID, GID, GECOS veld, login shell, versleuteld wachtwoord etc. Een aantal van deze velden worden gebruikt om de gebruiker te kunnen authenti- ceren. Andere dienen om bijvoorbeeld UID nummers te converteren naar de lognaam van de gebruiker of om de lognaam van de gebruiker te kunnen converteren naar zijn volledige naam. In feite vormen de bestanden een eenvoudige database. Nadeel van dit systeem is dat je op elke host een set van bestanden bij moet houden, met daarin veelal dezelfde data. Als je meer dan een paar systemen hebt wordt onderhoud al snel problematisch en wordt beveiliging moeilijk. Als iemand zijn wachtwoord wil hebben gewijzigd, moet hij bijvoorbeeld op alle systemen waar hij op mag werken aanloggen en de wijziging doorvoeren. Als iemand niet langer werkt bij een bepaald bedrijf moet de beheerder op alle systemen waar hij een account had dit account blokkeren of verwijderen. Dat kan makkelijk eens vergeten worden met alle mogelijk kwalijke gevolgen van dien. Daarnaast komt het voor dat dezelfde gebruikersnaam op verschillende systemen aan verschillende UID's wordt gekoppeld of dat verschillende gebruikersnamen op verschillende systemen aan hetzelfde UID zijn geknoopt etc. Kort en goed: een nachtmerrie voor de beheerder(s). +-----------------------------------+ ^ |host001 (linux) -> userdatabase#1 | | +-----------------------------------+ | +-----------------------------------+ user |host002 (windows)-> userdatabase#2 | | +-----------------------------------+ potientieel 'n' | +-----------------------------------+ VERSCHILLENDE | |host003 (novell) -> userdatabase#3 | wachtwoorden (en | +-----------------------------------+ andere attributen)! ... ... | +-----------------------------------+ V |hostn (os) -> userdatabase#n | +-----------------------------------+ Centrale databases Daarom zijn een aantal alternatieven verzonnen, die gebruik maken van centrale databases, die via het netwerk geraadpleegt kunnen worden, de zogenaamde 'directory services'. Bekende voorbeelden zijn NIS/NIS+ (Network Information Systems, Sun) en systemen die gebruik maken van LDAP (Leightweight Directory Access Protocol). In plaats van systeemgebonden databases worden in dat geval centrale databases opgezet, die via het netwerk kunnen worden geraadpleegd (en zogemuteerd). +-----------------+ ^ |host001 (linux) |>-----+ | +-----------------+ | | +-----------------+ | user |host002 (windows)|>-----+-------> [DATABASE SERVER] | +-----------------+ | | +-----------------+ | user heeft dus 1 set | |host003 (novell) |>-----+ van attributen voor | +-----------------+ | alle 'n' systemen. ... ... ... | +-----------------+ | | |hostn (os) |>-----+ v +-----------------+ Unix/Linux specifieke data in de centrale database Linux/Unix accounts vereisen data die niet nodig is voor andere typen machines. Daarom moet in de database een aantal schema's aanwezig zijn, welke bij nieuwere versies van Novell eDirectory standaard mee worden geleverd of middels zogenaamde 'snap-ins' eenvoudig kunnen worden geinstalleerd. Deze schema's zijn gestandaardiseerd binnen RFC 2307 "An approach for Using LDAP as a Network Information Service", L. Howard, 1998. Versie 8.7.1 van de eDirectory software is standaard voorzien van schema's die corresponderen met de beschrijving in RFC 2307. => In een afzonderlijk document beschrijft Guido Benning (Pink Roccade) op welke wijze de Novell server kan worden geconfigureerd om met deze schema's te werken. Unix/Linux client software Zoals eenvoudig te constateren valt dient aan de clientzijde ook het een en ander geregeld te worden: daar moet de software aanwezig zijn om het LDAP protocol te spreken en om met de ontvangen data zaken te kunnen regelen. - op een Linux machine worden zaken die met authenticatie te maken hebben vaak geregeld middels Pluggable Authentication Modules (PAM). - er is verder op moderne Unix systemen ook een manier om binnen de standaard Unix bibliotheken van buitenaf te regelen waar informatie wordt opgezocht: lokaal of extern. Dit wordt gedaan middels een configuratiebestand, het /etc/nsswitch.conf bestand. In onze testopstelling hebben we met beide ge-experimenteerd, zie navolgende hoofdstukken. - omdat de host- passwd- en group-databases op een Linux machine vaak geraadpleegd worden en deze data relatief statisch is wordt om performance redenen vaak gebruik gemaakt van een lokale kopie van de data (cacheing). Op een standaard SuSE 8.1 distributie wordt hiervoor de "name service cache daemon" - nscd - gebruikt, zie ook nscd.conf(5). ************************************************************** * In de testomgeving hebben we extra logging aangezet op de * * Novell machine, zodat we konden zien welke queries er door * * de (Linux) client werden uitgevoerd etc. - zie ook het do- * * cument van document van Guido Benning. Wel moet dan de * * nscd deamon UIT worden gezet. Doe je dat niet dan zal op * * de client de lokale cache worden gebruikt en zie je dus * * geen verkeer tussen de LDAP (Novell) server en de client. * * Vergeet niet in acceptatietest- en productie-omgevingen * * nscd weer in te schakelen. * * * * Ik wijs op de waarschuwing in /etd/nscd.conf over gebruik * * van host database cacheing: * * * * "Host cache is insecure!!! The mechanism in nscd to * * cache hosts will cause your local system to not be * * able to trust forward/reverse lookup checks. DO NOT USE * * THIS if your system relies on this sort of security * * mechanism. Use a caching DNS server instead." * * * ************************************************************** Wat is PAM? PAM (Pluggable Authentication Modules) is een systeem waarmee op modulaire wijze controle voor toegang tot een toepassing geregeld kan worden. PAM is op veel Unix systemen in gebruik, onder meer HP/UX, Sun en Linux. PAM-"aware" toepassingen roepen binnen een gestandaardiseerd framework (API) modules aan om tot authenticatie te komen. Het bijzondere is dat de systeembeheerder degene is die kan regelen hoe bevoegdheden worden uitgegeven: de authenticatie wordt volledig buiten de toepassing getrokken. Een programmeur hoeft slechts de PAM-API aan roepen, de beheerder regelt dan vervolgens wat er gedaan wordt door binnen een bestand aan te geven welke modules er gebruikt moeten worden. Een PAM module kan bijvoorbeeld een bestand uitlezen, of een smartcard, of via een netwerk aan een database om gegevens vragen. In feite kan een PAM module alles wat de beheerder ook zou kunnen, er is bijvoorbeeld een module die kijkt of je wel een HOME-directory hebt en zo niet deze voor je aanmaakt. PAM modules zijn 'stapelbaar': dat wil zeggen dat je een serie van modules kunt doorlopen, die onder elkaar data uitwisselen. De totale keten van modules "beslist" dan of men al dan niet is bevoegd. pam_ldap.so Er is een PAM module die (in samenwerking met een andere PAM module) in staat is om middels LDAP contact te zoeken met een LDAP server. Deze module wordt als vrij verkrijgbare broncode gedistribueerd (en is standaard onderdeel van de SuSE 8.1 distributie). Ze wordt geconfigureerd middels het bestand /etc/ldap.conf (aka /etc/openldap/ldap.conf, op mijn systemen is dit een symlink - HWK). Wat is NSS? Het Unix (Linux) besturingssysteem maakt gebruik van diverse standaard bibliotheken. Programma's roepen, om bepaalde functies te verrichten, deze bibliotheken ("the C library") aan. Een aantal van deze functies maakt gebruik van databases, historisch meestal "platte" tekstfiles (/etc/password, /etc/hosts etc.) om configuratiedata uit op te vragen. Voorbeelden van namen van dergelijke functies zijn gethostbyname(3) (vertaling hostnamen naar IP adressen vice versa), getpwent(3) (ophalen van gebruikers gerelateerde gegevens) en getgrent(3) (ophalen van aan Unix user groups gerelateerde data). Toen er meer en meer gebruik werd gemaakt van centrale databases besloot men in de standaard bibliotheken code op te nemen waarmee je (ook) deze databases kon benaderen. Bijvoorbeeld bij de vertaling van een hostnaam naar een IP adres: de bibliotheek keek vroeger alleen in het lokale bestand /etc/hosts, later zat er er code in die ook keek of er een DNS aanwezig was. Omdat er veel verschillende databases met configuratie-items waren (NIS, NIS+, WINS, LDAP, bestanden..) werd de code er niet helderder op. En als er weer iemand een nieuwe methode verzon om configuratiedata op te slaan moest de code weer overhoop. Binnen de Linux standaard bibliotheken (libc.so.6 e.v.) werd dit daarom (nog) eleganter opgelost: middels de zogenaamde NSS (Name Service Switch"), een oorspronkelijk van Sun afkomstig idee. In een extern bestand (/etc/nsswitch.conf) kan de beheerder voor een aantal diensten aangeven welke bijhorende configuratiedatabases gebruikt moeten/mogen worden. De standaard C bibliotheek laadt dan een dienstgebonden module (een "gewoon" shared object) waarin de code staat die bepaalt WELKE database wordt geraadpleegd (en hoe). Deze dienstgebonden modules staan in /lib en hebben als naam "libnss_", gevolgd door de naam van de dienst die gebruikt wordt om de data op te halen, waarna dan de reeks ".so." en een volgnummer, bijvoorbeeld /lib/libnss_ldap.so.2. Zie verder ook nsswitch(5). De Novell eDirectory De Novell eDirectory software implementeert ook zo'n gedistribueerde database, waarin diverse (hierarchisch gegroepeerde) data in kan worden bijgehouden. De opslagformaten van data en de samenhang tussen de data wordt gedefinieerd in zogenaamde "schema's". Binnen de database kan data voor verschillende besturingssystemen worden bijgehouden. Zo kan de eDirectory ook worden gebruikt om Unix login gerelateerde gegevens in bij te houden zoals UID, GID, naam van de home directory en de naam van de login shell. Er is daarbij een koppeling aanwezig tussen de data en de noodzakelijke converteringen worden op de centrale database (automatisch) uitgevoerd. Dit heeft als voordeel dat zowel Windows, Linux/Unix en Novell gebaseerde systemen gebruik kunnen maken van bijvoorbeeld hetzelfde wachtwoord. Met andere woorden: ongeacht op welk systeem je wilt werken, je hoeft maar 1 gebruikersnaam en wachtwoord te onthouden. +-----------------+ ^ |host001 (linux) |>-----+ | +-----------------+ | | +-----------------+ | +--------------+ user |host002 (windows)|>-----+-------> | Novell | | +-----------------+ | | eDirectory | | +-----------------+ | | server | | |host003 (novell) |>-----+ | + schema's | | +-----------------+ | +--------------+ ... ... ... | +-----------------+ | | |hostn (os) |>-----+ v +-----------------+ Aanvullend valt nog te melden dat de Novell eDirectory database redundant uitgevoerd kan worden: de database kan worden gedistribueerd over diverse machines, die dan elk wel een onderling compatible versie van de eDirectory software moeten draaien. Onderling samenwerkende machines die een gezamenlijke eDirectory definieren maken gebruik van dezelfde schema's: wijzigingen in een schema op 1 machine worden doorgezet naar alle andere nodes. LDAP front-end De data in de eDirectory kan voor Unix/Linux beschikbaar worden gemaakt op twee manieren: ofwel door rechtstreeks tegen de eDirectory server te authenticeren ofwel middels een koppeling met een LDAP server. Dit laatste vereist dat er een LDAP front-end wordt geinstalleerd op een Novell machine waarop eDirectory draait: +-----------------+ ^ |host001 (linux) |>-----+ | +-----------------+ | | +-----------------+ | ldap +--------------+ user |host002 (windows)|>-----+-------> |LDAP FRONT END| | +-----------------+ | |--------------| | +-----------------+ | | eDirectory | | |host003 (novell) |>-----+ | server | | +-----------------+ | +--------------+ ... ... ... | +-----------------+ | | |hostn (os) |>-----+ v +-----------------+ Wat is LDAP? Het Lightweight Directory Access Protocol (LDAP) is een in RFC 1777 gedefinieerde opzoekdienst (directory service) die binnen TCP/IP netwerken kan worden gebruikt. Binnen deze dienst worden gegevens zo opgeslagen dat ze heel snel terug te lezen zijn - de database is dus bij uitstek geschikt voor data die je niet al te vaak wilt wijzigen maar wel heel vaak wilt raadplegen, zoals - inderdaad - gebruikers- systeem- en systeemgroep-gegevens. LDAP maakt gebruik van een client-server model. Data wordt gegroepeerd onder een zogenaamde "Distinguished Name", zie RFC 1779. LDAP kent client authenticatie en toegangscontrole, zodat toegang tot data afgeschermd kan worden voor onbevoegden. Praktijk Opbouw van onze testomgeving +---------------------+ +---------------------+ | FS-37 | | FS-35 | | Novell 6.0 | | Novell 6.5 | | 10.1.1.72 | | 10.1.1.71 | | E-dir 8.7.0 <------+--+> E-dir 8.7.1 -------+----> o posixAccount | | | | | o shadowAccount | LDAP V3 (10410.57) | | | o posixGroup +-----+---------------+ +---------------------+ o Account | v Linux laptop SuSE 8.1 Aanpak We wilden een testopstelling bouwen waarbinnen het mogelijk moest zijn om gebruikers op een Linux (SuSE 8.1) host te laten aanloggen waarbij hun wachtwoord werd getoetst aan de data op een Novell eDirectory, die middels het LDAP protocol toegankelijk is. Uit onderzoek op het Internet bleek dat er veel informatie over dit onderwerp beschikbaar is, helaas vaak tegenstrijdig, deels niet van toepassing op onze situatie, deels verouderd. De juiste methode voor onze setup bleek: Op de Novell eDirectory ... (voor details betreffende de Novell stappen zie het document van Guido Benning) 0. verifieren dat voor deze versie van de Novell eDirectory er geen schema-wijzigingen nodig zijn om de auxiliary class extensions "posixAccount","posixGroup" en "shadowAccount" te kunnen gebruiken. Voor onze versies was er geen schemawijziging nodig, maar voor een aantal oudere versie is dit mogelijk wel nodig. Zie voor meer informatie http://developer.novell.com/research/appnotes/2002/june/02/apv.html 1. regelen dat het LDAP front-end bij de eDirectory gegevens mag komen (middels een zogenaamde "proxy-user"), 2. versleutelde LDAP te activeren [noot: de onversleutelde toegang kan in de TEST-omgeving open worden gelaten, dit vereenvoudigd het testen], 3. een aantal ConsoleOne snap-ins installeren zodat de al aanwezige schema's voor Unix ook gebruikt kunnen worden, 4. een tweetal mappings te verwijderen, 5. een testgebruiker aan te maken 6. aan het user-object voor die testgebruiker een aantal 'auxiliary class extensions' toevoegen: "posixAccount","posixGroup" en "shadowAccount". De attributen binnen deze extension moeten vervolgens van een zinvolle inhoud worden voorzien (voorbeelden van dergelijke attributen zijn "uidNumber", "gidNumber" en "gecos"). Aan de client (Linux) kant .. 7. het bestand /etc/(openldap/)ldap.conf correct te vullen, zie bijlage 1 voor uitleg en voorbeelden. 8. [voor deze test moet (ook) de unencrypted connectie met LDAP open staan] te testen of we de LDAP server kunnen bereiken, e.g.: ldapsearch -x "(&(objectclass=posixAccount)(uid=test))" \ "uidNumber" "gidNumber" "homeDirectory" "loginShell" \ "gecos" "description" Je moet nu als antwoord een soortgelijk scherm zien: -------------------------------------------------------------------- # extended LDIF # # LDAPv3 # filter: (&(objectclass=posixAccount)(uid=test)) # requesting: uidNumber gidNumber homeDirectory loginShell gecos \ description # # test, USR, DEV, UNKNOWN, NL dn: cn=test,ou=USR,ou=DEV,o=UNKNOWN,C=NL loginShell: /bin/false homeDirectory: /home/test gecos: T. Est-Gebruiker gidNumber: 777 uidNumber: 222 description: Testgebruiker # search result search: 2 result: 0 Success # numResponses: 2 # numEntries: 1 -------------------------------------------------------------------- 9. de configuratie van PAM op orde te brengen, zie bijlage II voor een werkend voorbeeld. [Noot: PAM is een onderwerp op zich, zie de referentiesites]. A. het bestand /etc/nsswitch.conf te configureren, zie bijlage III B. Testen: Verifieer of de nscd daemon loopt, zo ja: breng hem down middels "/etc/init.d/nscd stop". Verifieer dat de binnen Novell aangegeven homedirectory voor de gebruiker 'test' NIET aanwezig is. Verifieer dat er GEEN gebruiker 'test' in /etc/passwd aanwezig is. Schakel de Novell LDAP monitor aan. Start op de Linux machine "netstat -CnAinet" op om de netwerk activiteiten te kunnen monitoren. Werkt PAM? Log op de Linux machine in: tik na de "login:" prompt het woord 'test' en druk op [Enter]. Hou de Novell monitor in het oog: je moet onmiddellijk nadat je 'test' hebt ingetoetst een query zien voorbijkomen (en zien beantwoorden) op het relevante posixAccount object. De netstat moet een verbinding met de LDAP server op poort 636 tonen. Na het verschijnen van de "Password:" prompt tik je het Novell wachtwoord in. Je ziet weer activiteit op de Novell machine en binnen netstat. Vervolgens zie je dat de gespecificeerde home directory wordt aangemaakt en wordt je ingelogged in de binnen Novell gespecificeerde shell. Werkt NSS? Tik ter verificatie als gebruiker 'test' in 'ls -l': je ziet nu een hele hoop queries op de Novell machine en krijgt daarna een 'normale' listing te zien, waarin de eigenaar van de files als 'test' wordt getoond. B. als alles werkt: toegang tot poort 389 (onversleutelde LDAP) uitzetten op de Novell/LDAP server. C. en de nscd caching daemon weer starten: /etc/rc.d/nscd start. --------------------------------------------------------------------8<------ Bijlage I /etc/ldap.conf aka /etc/openldap/ldap.conf ---------------------------------------------------------------------------- # Enable authentication for Linux hosts against a Novell eDirectory # based LDAP server. # # Version 1.0, HWK - Wed Dec 17 10:50:39 CET 2003 # Initial version. # # ----------------------------------------------------------------------- # Specify the ldap server to connect to. Use a name or IP number. If you # use a name, make sure it can be resolved without the aid of the ldap # server itself :). To specify (a) failover server(s) you may provide # additional space separated names/adresses, i.e. "host 10.1.1.72 10.1.1.1" # host 10.1.1.72 # ----------------------------------------------------------------------- # Queries to the ldap server will always be based on the context provided # below. This is only an example, please specify your own base. Often # it is your domain name, e.g. fortean.org: base o=fortean,c=org # base o=unknown,c=nl # ----------------------------------------------------------------------- # We want to use encryption, all the way. Using the "ssl on" statement # results in the use of ssl encrypted communication to port 636 instead # of port 389 (the default unencrypted ldap port). You may want to # check this: use netstat -CnAinet. # ssl on # ----------------------------------------------------------------------- # Since we are using a Novell e-directory based server (with a LDAP front # end) we specify "pam_password nds". This will result in removing the # password first and update it in cleartext, which is necessary for NDS, # so I'm told. I have not tested this, YMMV [HWK]. # pam_password nds # ----------------------------------------------------------------------- # scratchpad.. # # By default we bind 'anonymously' to obtain the UID etc. fields, but # you may use a username (binddn) and password (bindpw). They are used # to bind to the LDAP server and should be configured withing Novell # eDirectory to have sufficient rights to browse the proper objects. # # http://developer.novell.com/research/appnotes/2002/june/02/apv.html # #binddn cn=ldapr,ou=dev,o=fortean,c=org #bindpw bigsecret --------------------------------------------------------------------8<------ --------------------------------------------------------------------8<------ Bijlage II /etc/pam.d/login ---------------------------------------------------------------------------- #%PAM-1.0 auth required pam_securetty.so auth required pam_nologin.so auth sufficient pam_ldap.so auth required pam_unix_auth.so try_first_pass auth required pam_env.so auth required pam_mail.so # account sufficient pam_ldap.so account required pam_unix_acct.so # password required pam_pwcheck.so nullok password required pam_ldap.so password required pam_unix2.so use_first_pass # session required pam_mkhomedir.so skel=/etc/skel umask=0022 session required pam_unix2.so none # or debug or trace session required pam_limits.so --------------------------------------------------------------------8<------ --------------------------------------------------------------------8<------ Bijlage III /etc/nsswitch.conf ---------------------------------------------------------------------------- # # /etc/nsswitch.conf # # For more information, please read the nsswitch.conf.5 manual page. # passwd: files ldap shadow: files ldap group: files ldap hosts: files dns networks: files dns services: files protocols: files rpc: files ethers: files netmasks: files netgroup: files publickey: files bootparams: files automount: files nis aliases: files --------------------------------------------------------------------8<------