OpenVPN LDAP-authenticatie werkt, maar de groepscontrole faalt: waar je moet kijken
Authenticatie kan slagen terwijl de groepscontrole iedereen afwijst. Loop het Authorization-blok, het lidmaatschapsattribuut en het directory-eindpunt na.
De inloggegevens worden geaccepteerd, de tunnel begint op te komen en dan mislukt de sessie met een melding over de groep in plaats van over het wachtwoord. Die combinatie plaatst de fout in de tweede helft van het werk van de LDAP-plugin: de binding en de wachtwoordcontrole slaagden, en de lidmaatschapsbeslissing die volgt niet. Beide helften lezen uit hetzelfde configuratieblok, daarom kan een correctie op één plek de andere onaangeroerd laten. Begin bij de logregel die de stap benoemt, niet bij het account waarmee je toevallig test.
Behandel de afwijzing als een autorisatieantwoord
De plugin voert een servicebinding uit, zoekt het account, verifieert het opgegeven wachtwoord en vraagt dan of dat account tot een toegestane groep behoort. Dat zijn vier afzonderlijke bewerkingen, en alleen de laatste gaat over groepen. Een afwijzing die na een geslaagde binding komt zegt dus niets over het wachtwoord, zelfs niet wanneer de client een algemene authenticatiefout toont. Het logniveau van de plugin verhogen vóór je de configuratie wijzigt, is wat de vier in de uitvoer scheidt.
Zoek de groepsbeoordeling zelf. Wanneer er helemaal geen groepsquery verschijnt, wordt het autorisatieblok niet bereikt, wat meestal betekent dat een richtlijn buiten het blok staat dat er eigenaar van is of dat een verplichte optie ontbreekt. Wanneer de query verschijnt en niets teruggeeft, beantwoordt het eindpunt of het filter een andere vraag dan degene die je bedoelde.
Bepaal of het lidmaatschap in het filter of in een groepsblok leeft
Er zijn twee ondersteunde vormen, en ze door elkaar halen is de manier waarop een werkende configuratie ophoudt te werken. De eerste duwt het lidmaatschap de gebruikerszoekopdracht in door om een attribuut op het gebruikersobject te vragen; de tweede laat de gebruikerszoekopdracht met rust en laat de plugin daarna het groepsobject opzoeken. Kies er één per implementatie en schrijf op welke je hebt gekozen.
<Authorization>
BaseDN "OU=People,DC=example,DC=org"
SearchFilter "(&(sAMAccountName=%u)(memberOf=CN=VPN Access,OU=Groups,DC=example,DC=org))"
RequireGroup false
</Authorization>Met die vorm beslist het filter alles, dus RequireGroup moet false zijn, anders gaat de plugin op zoek naar een groepsobject dat het filter nooit heeft genoemd. Het attribuut in het filter moet op het gebruikersobject bestaan en gevuld zijn, wat niet gegarandeerd is zodra groepen genest zijn.
De andere vorm houdt de zoekopdracht eenvoudig en voegt daarna een groepsopzoeking toe. Het groepsobject wordt expliciet benoemd, en de plugin vergelijkt de gebruiker met de leden die de directory daarvoor teruggeeft. Niets aan het gebruikersfilter verandert, wat deze vorm makkelijker te controleren maakt wanneer een ander team de groep beheert.
<Authorization>
BaseDN "OU=People,DC=example,DC=org"
SearchFilter "(sAMAccountName=%u)"
RequireGroup true
Group "CN=VPN Access,OU=Groups,DC=example,DC=org"
</Authorization>De blinde vlek is gedeeld: een eenvoudige lidmaatschapsvergelijking breidt geneste groepen niet uit, dus een account waarvan de toegang via een bovenliggende groep komt mislukt terwijl de console het lidmaatschap nog steeds toont. Active Directory stelt member op de groep beschikbaar, andere schema’s gebruiken uniqueMember, en naar het verkeerde attribuut wijzen levert een leeg resultaat op in plaats van een fout.
Kies een eindpunt dat het groepsobject bevat
De URL bepaalt welke directory de plugin vraagt, en een domeincontroller op poort 389 antwoordt alleen voor zijn eigen naamgevingscontext. Een globale catalogus op poort 3268 antwoordt voor het hele forest, alleen-lezen en met een gedeeltelijke attribuutset. Wanneer de accounts in het ene domein zitten en de VPN-groep in het andere, kan een zoekopdracht binnen één domein de gebruiker vinden en toch het lidmaatschap missen. Dat is het geval waarin het verplaatsen van de URL naar de cataloguspoort de afwijzing oplost, en het is ook het geval waarin mensen te ver generaliseren.
De gedeeltelijke attribuutset is de grens: op een attribuut dat de catalogus niet bevat kan niet worden gefilterd, dus dezelfde wijziging kan de ene implementatie laten werken en de andere niets laten teruggeven. Bevestig wat het eindpunt werkelijk teruggeeft voor de echte gebruiker en groep voordat je het blok herschrijft. Verwijzingen en TLS zijn weer aparte zaken, want een verwijzing moet worden gevolgd en een eindpunt dat TLS vereist heeft de bijbehorende vertrouwensbestanden nodig.
Houd accountstatus en zoekbereik in hun eigen velden
De uitgeschakeld-vlag hoort in het filter, niet in de groepscontrole. In Active Directory is het de tweede bit van userAccountControl, en zonder die voorwaarde authenticeert een uitgeschakeld account met een geldig wachtwoord en mislukt daarna bij de groepsstap, wat op een autorisatiefout lijkt. Zoekbereik hoort in de basis-DN, omdat beginnen bij de domeinroot langzamer is en objecten buiten de organisatie-eenheid kan raken die je wilde dekken.
Houd ook de rechten van het bind-account nauw. Brede directoryrechten maken van een verkeerd geconfigureerd filter een geslaagde zoekopdracht en verbergen de fout tot iemand het account controleert. Wijzig lidmaatschap in de directory zelf, nooit in een lokale uitzonderingenlijst, zodat het uitschakelen van het account genoeg is om toegang te verwijderen. Als een ander team de groep beheert, spreek dan het attribuut af dat zij vullen voordat je er een filter op schrijft.
Bewijs het resultaat met drie accounts
Voer de configuratie uit tegen drie identiteiten: een toegestaan lid, een geldig account buiten de groep en een account dat is uitgeschakeld. Als alle drie worden afgewezen, is de binding of de groepsquery stuk; als alle drie worden geaccepteerd, wordt er helemaal geen groepsvoorwaarde toegepast. Een gemengd resultaat is het enige dat bewijst dat de configuratie de gevallen onderscheidt die voor jou belangrijk zijn.
Lees dezelfde drie antwoorden rechtstreeks uit de directory voordat je de plugin de schuld geeft. De eerste query toont het groepattribuut waarvan het filter afhangt, en de tweede toont de waarde voor accountbeheer. Vervang door je eigen basis-DN, account en eindpunt:
ldapsearch -H ldap://dc01.example.org:3268 -x -D "[email protected]" -W -b "DC=example,DC=org" "(sAMAccountName=alice)" memberOf
ldapsearch -H ldap://dc01.example.org:3268 -x -D "[email protected]" -W -b "DC=example,DC=org" "(sAMAccountName=bob)" userAccountControlEen gebruiker wiens memberOf leeg terugkomt is een directoryfeit, geen pluginfout, en een account dat na uitschakeling nog steeds authenticeert betekent dat het filter de voorwaarde voor accountbeheer mist. Herstel eerst dat bewijs en voer daarna de drie-accounttest opnieuw uit. Houd de logregel die de mislukte stap benoemde naast de configuratiewijziging, zodat de volgende persoon autorisatie van authenticatie kan scheiden zonder de zoekopdracht te herhalen.