Linux authenticatie middels LDAP/Novell/PAM
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<------