NDS SQUID HOWTO 2000 Völgyesi Péter, Synergon BEVEZETO Ebben a rövid HOWTO-ban választ kaphatsz a következo kérdésekre: Hogyan kell Squid proxy cache-hez authentikációs modult írni Hogyan exportálja ki a Netware az NDS adatbázisát LDAP segítségével Miképpen muködik a PKI a Netware világban Hogyan lehet OpenSSL-lel mezítlábas CA szervert kialakítani Hogyan lehet Novell kulcsokat aláírni OpenSSL-lel Végül: hogyan lehet NDS szerverrel hitelesíteni a proxy felhasználókat Mivel elég sok és nagy területeket érint a megoldandó feladat, ezért sok helyen elég felületesen (és célratöroen) fogom ismertetni a környezetet. Az egyes lépések megértéséhez nem árt, ha nagyjából tudod, mi az az LDAP és az SSL. Az ismertetett és tesztelt szoftververziók: Novell Netware 5 Squid 2.2 OpenSSL 0.9.5 Netscape Communicator 4.5 SQUID AUTHENTIKÁCIÓ A dolognak ez a legegyszerubb része. A Squid ezt a feladatot külso (általunk) megírt programok segítségével végzi. A kongurációs le-ban meghatározott programból szintén ott meghatározott számút indít el, melyeket round-robin szeruen kérdezget, ha hitelesítésre van szüksége. Ezek a programok a Squid-del a standard input/output csatornákon beszélgetnek. Egy ilyen hitelesítéssel kapcsolatos párbeszéd: Squid: <username> <password> Program: OK A fenti példában sikerült a belépés. Ha nem sikerült volna a program ERR tokent adott volna a standard kimenetén. Elég primitív módon a Squid szóközzel elválasztott username/password párokat tartalmazó sorokat küld tehát, melyekre a fenti válaszok egyikét várja. A külso program folyamatosan fut a Squid futása alatt, tehát nem teljesen CGI jellegu a muködés. A kongurációs le-ban a következo sorok gondoskodnak a külso programról: authenticate_program <programname> <parameters > authenticate_children <number> authenticate_ttl <sec> Az elso a program elérési útjáról, valamint a paramétereirol gondoskodik, a második az indítandó és párhuzamosan futó processek számát határozza meg, míg az utolsó a Squid belso authentikációs cacheének elévülési idejét szabályozza (hogy ne kelljen minden HTTP kérés esetén a külso programhoz fordulni).
A hitelesítéshez természetesen az ACL-eket is be kell tekerni, erre most csak egy nagyon triviális esetet mutatok (mindenkinek hitelesítenie kell magát): acl all src 0.0.0.0/0.0.0.0 acl password proxy_auth REQUIRED http_access allow password http_access deny all NDS LDAP FELÜLET Ez már egy kicsit összetettebb dolog, és a mi szempontunkból nem is annyira lényeges az alapos megértése. Amire szükség lesz, az a Novell szerverre telepített LDAP szerver (ill. gateway) modul. Ennek feltelepítése után rögtön látható a szerver NDS fája az LDAP felületen. Ahhoz, hogy SSL-es LDAP-ot is tudjon a Novell, ahhoz a következo részben ismertett PKI Services Netware elemet is fel kell telepíteni a szerverre. Erre gyelmezteto üzenetet a Netware konzolon is láthetunk. A kiexportált NDS fa az LDAP felületen az o=<treename> DN-nel látszik az alapbeállítások szerint. Az adott fa adminisztrátorának a DN-ja: cn=admin, o=<treename> alakú. Az egyes NDS bejegyzések ill. context-ek ez alatt helyezkednek el. Az adott LDAP attribútumok (és így a DN-eket felépítok is) és az NDS attribútumok közötti megfeleltetést szabályozni lehet Novell Adminisztrációs felületén (Windows alatt futó nwadmin).ennek megváltoztatása az alapértelmezettol azonban nem szükséges a mi szempontunkból. A hitelesítés a következoképpen fog történni a kiexportált LDAP felületen: 1. Megadott felhasználó megkeresése az LDAP fában a felhasználói név alapján. Ehhez a kereséshez még anonymous-ként csatlakozunk az LDAP kiszolgálóhoz. Erre a keresésre azért van szükség, hogy megtaláljuk a felhasználó teljes DN-jét. A keresést fuszerezni lehet adott attribútum meglétével az adott felhasználói rekordban, mely feljogosítja ot a proxy használatra. Egy ilyen search lter-re példa: (and (uid=<username>) (proxyallowed=yes) ) 2. Ha létezik ilyen entry, akkor a visszakapott DN-nel és a Squid-tol kapott jelszóval megpróbálunk bind-olni az LDAP szerverhez. Ha ez sikerül, akkor küldhetjük is a standard outputra az OK tokent. Egyébként ERR. NOVELL PKI SERVICES A feladat igazi szépsége itt kezdodik. A Novell ugyanis nem hajlandó alapértelmezésben cleartext kapcsolaton keresztül LDAP bind muveletet végrehajtani. Ez egyébként becsületére legyen mondva. Viszont így csak az anonymous keresés az egyetlen lehetoség, amit induláskor tudunk csinálni. Lehetoség van a cleartext jelszavak engedélyezésére, és ez jelen esetben logikusnak is tunik (hiszen a proxy authentikáció egyébként is cleartext). Azonban, ha erre kérünk egy becsületes Novell rendszergazdát, lehet hogy nyolc napon túl gyógyuló mellékhatásoknak leszünk kitéve. Egyébként pedig az izgalmas kihívást pont ez a rész jelenti. A Netware 5 része a Novell PKI Services szoftvermodul. Ennek telepítése során kriptográai algoritmusokkal, protokollokkal, SSL-lel és egy CA szerverrel bovül a Novell szerver. A telepítés után lehetoségünk van a Windows-os adminisztrációs felületen CA szerver létrehozására. Ezt a gyökérben található Security címkére jobb gombbal kattintva kezdeményezhetjük. (Create/ CA Server). Az így létrehozott CA szerver(eke)t használhatjuk a szintén gyökérbol nyíló NDS fa speciális ún. KeyMaterial objektumok aláírására.
A KeyMaterial objektumokat szintén jobb gombbal hozhatjuk létre. Ezen objektumok tartalmazzák a generált publikus kulcspárt, valamint az erre kapott aláírásokat. Egy ilyen KeyMaterial-t aztán hozzárendelhetjük olyan elemekhez, melyeknek szükségük van nyilvános kulcsú titkosításra (pl. LDAP SSL kapcsolat létrehozására) A kulcsokat létrehozhatjuk standard módon, ekkor a Novell saját CA-ja automatikusan aláírja a generált kulcsot. Ha custom kulcspárt (ill. KeyMaterial-t) hozunk létre, akkor lehetoség van külso CA szerverrel aláíratni a kulcsokat. Ekkor nem aláírást, hanem certicate request-et generál a Novell szerver. Fontos, hogy ekkor magát a külso CA-t hitelesíto Certicate is bekerüljön a KeyMaterial objektumba. E nélkül nem fog sikerülni a külso aláírás importja. Mi a megoldáshoz a külso CA megoldást fogjuk használni egy speciális (és nehezen áthidalható ok miatt). Tehát a Novell szerveren nem szükséges CA szerver létrehozása. OPENSSL Az OpenSSL nyílt forrású csomag alapvetoen egy kriptográai ill PKI-vel kapcsolatos rutingyujtemény (C library), mely funkciókhoz egy parancssori programot is biztosítottak. Az OpenSSL telepítése UniX környezetben nem igényel különleges ismereteket, így most csak a make install utánni feladatokról beszélnék. CA létrehozása A legfontosabb elso lépés, hogy hozzunk létre egy CA szervert. Ehhez célszeru lesz új könyvtárt csinálnunk, és a továbbiakban bemutatott minden parancsot itt végrehajtani. A CA kialakítás lépései tehát: 1. Aláíráshoz szükséges kulcs generálása: openssl genrsa -des -out ca.key 512 2. Saját magunk aláírása: openssl req -new -x509 -days 365 -key ca.key -out ca.crt A kérdésekre lehetoleg úgy válaszoljunk, hogy a CA szerver DN-je így nézzen ki: O=<CANAME>. Ezt úgy érhetjük el, ha a legtöbb kérdésre csak egy. karakterrel válaszolunk és csak az Organization-t töltjük ki. Ez azért nagyon fontos, mert különben nagyon nehezen fogjuk elfogadtatni ezt a CA szervert a Novell-es KeyMaterial-lal Ezek hatására elkészült a mezítlábas CA szerver, mely kulcsát a ca.key le-ban és a root certicate-jét a ca.crt le-ban tárolja. Figyeljünk arra, hogy olyan kulcshosszakat ill. algoritmusokat használjunk, amit egy exportkorlátozott Novell szerver is kezelni tud! (A fenti példa pontos követése esetén ilyen probléma nem lesz.) Hogyan írjunk alá Novell-es kulcsokat A következo feladat a Novell-es aláíráskérések teljesítése, ehhez célszeru a doksi végén mellékelt scriptet használni (forrás: Apache modssl). Ennek segítségével az aláírás ilyen egyszeru:./sign.sh <ldapkey>.csr A paraméterben meghatározozz le a Novell által generált kérést tartalmazza Base64 kódolásban. A parancs hatására generálódik egy <ldapkey>.crt le, ami a kiadott aláírás. Ezt kell visszaetetni a Novelles KeyMaterial-ba. Mielott ezt megtetnnénk, szükséges a CA szerver root certicate-jének (ca.crt) importálása a KeyMaterialba (A trusteed ca címszó alá).
NETSCAPE LDAP SDK Az LDAP SDK-ra azért van szükségünk, hogy az auth. modult megírjuk ill. lefordítsuk. Ez ingyenesen elértheto a Netscape ill. Mozilla homepage-ekrol. Azért nem az OpenLDAP-ot használjuk, mert még mindig nincs 2.0-s, ami tudni fogja az SSL-t. Mivel az API jól dokumentált és nem is kell ismernünk, ha a mellékelt programot használjuk, ezért most csak az SSL-lel kapcsolatos részletekre térnék ki. Az SDK azt a certicate és key adatbázist használja, amit a böngészo is használ (cert7.db ill. key3.db le-ok). Ezek eloállítására ill. módosítására az API nem képes, ezért ezt egy böngészo programmal kell neki létrehoznunk. A sikeres muködéshez egy olyan certicate adatbázisra lesz szükség, melyben az OpenSSL-es CA szerverünk trusteed CA szerverként szerepel. Sajnos közvetlenül nem tudunk CA certicate-et importálni a böngészobe. Így a következo trükköt alkalmazzuk: kiállítunk egy személyre szóló certicate-et az OpenSSL-lel, ezt importáljuk a browser-be, aminek hatására az OpenSSL-es CA szerver is bekerül az adatbázisba, amit aztán grant-elünk. Az így elkészített adatbázist használhatjuk már az auth. programhoz. Ennek a pontos lépései: 1. Személyes kulcspár eloállítása: openssl genrsa -des -out personal.key 512 2. Erre a kulcspárra aláírás kérés: openssl req -new -key personal.key -out personal.csr 3. Ennek aláírása:./sign.sh personal.csr 4. PKCS#12 konverzió (ezért fontos, hogy 0.9.5-ös vagy újabb OpenSSL-ünk legyen): openssl pkcs12 -export -in personal.crt -inkey personal.key - certle ca.crt -name "MY CERTIFICATE" -out personal.p12 5. A personal.p12 importálása a böngészoben a személyes certicate-ek közé 6. Az így bekerült root CA grant-elése a böngészoben 7. A cert7.db valamint a key3.db lemásolása.
A SZÜKSÉGES PROGRAM Végül lássuk az authentikációs programot: /* * ldap_auth.c * * * Usage ldap_auth <hostname> <ndstree> <uidattr> */ #include <stdio.h> #include <string.h> #include "ldap.h" #include "ldap_ssl.h" int authenticate ( const char *server, const char *tree, const char *uid_att, const char *user, const char *passwd ) { LDAP *ld; LDAPMessage *result; LDAPMessage *e; char lter[200]; char *dn; int rc; /* no null usernames or passwords accepted */ if (user == NULL strcmp(user, "") == 0) return 0; if (passwd == NULL strcmp(passwd, "") == 0) return 0; strcpy(lter, uid_att); strcpy(lter+strlen(uid_att), "="); strcpy(lter+strlen(uid_att)+1, user); 0; /* attempt server connection */ if ((ld = ldapssl_init(server, LDAPS_PORT, 1)) == NULL) return rc = ldap_search_ext_s(ld, tree, LDAP_SCOPE_SUBTREE, lter, NULL, 0, NULL, NULL, LDAP_NO_LIMIT, 0, &result); if (rc!= LDAP_SUCCESS) { ldap_unbind(ld); return 0; for (e = ldap_rst_entry(ld, result); e!= NULL; e = ldap_next_entry(ld, e)) { dn = ldap_get_dn(ld, e); if (ldap_simple_bind_s(ld, dn, passwd) == LDAP_SUCCESS) { ldap_unbind(ld); return 1;
ldap_unbind(ld); return 0; int main(int argc, char **argv) { char buf[256]; char *user, *passwd; char *server, *tree, *uid_att; if (argc!= 4) { fprintf(stderr, "Usage: ldap_auth <server> <tree> <uidattr>\n"); exit(1); server = argv[1]; tree = argv[3]; uid_att = argv[4]; if ( ldapssl_client_init ("cert7.db", NULL) < 0 ) { fprintf(stderr, "Cannot initialize SSL client\n"); exit(1); while (fgets(buf, 256, stdin)!= NULL) { user = strtok(buf, " "); passwd = strtok(null, " \n"); if (authenticate(server, tree, uid_att, user, passwd)) { printf("ok\n"); else { printf("err\n"); fflush(stdout); exit(0);
AZ ALÁÍRÓ SCRIPT #!/bin/sh ## ## sign.sh -- Sign a SSL Certicate Request (CSR) ## Copyright (c) 1998-2000 Ralf S. Engelschall, All Rights Reserved. ## # argument line handling CSR=$1 if [ $# -ne 1 ]; then echo "Usage: sign.sign <whatever>.csr"; exit 1 if [! -f $CSR ]; then echo "CSR not found: $CSR"; exit 1 case $CSR in *.csr ) CERT="`echo $CSR sed -e 's/\.csr/.crt/'`" ;; * ) CERT="$CSR.crt" ;; esac # make sure environment exists if [! -d ca.db.certs ]; then mkdir ca.db.certs if [! -f ca.db.serial ]; then echo '01' >ca.db.serial if [! -f ca.db.index ]; then cp /dev/null ca.db.index # create an own SSLeay cong cat >ca.cong <<EOT [ ca ] default_ca = CA_own [ CA_own ] dir =. certs = \$dir new_certs_dir = \$dir/ca.db.certs database = \$dir/ca.db.index serial = \$dir/ca.db.serial RANDFILE = \$dir/ca.db.rand certicate = \$dir/ca.crt private_key = \$dir/ca.key default_days = 365 default_crl_days = 30 default_md = md5 preserve = no policy = policy_anything [ policy_anything ] countryname = optional stateorprovincename = optional localityname = optional organizationname = optional organizationalunitname = optional
commonname emailaddress EOT = supplied = optional # sign the certicate echo "CA signing: $CSR -> $CERT:" openssl ca -cong ca.cong -out $CERT -inles $CSR echo "CA verifying: $CERT <-> CA cert" openssl verify -CAle ca.crt $CERT # cleanup after SSLeay rm -f ca.cong rm -f ca.db.serial.old rm -f ca.db.index.old # die gracefully exit 0