česky | english
NOTA BENE - ROZPRACOVÁNO - Vaše příspěvky a úvahy
Pro Technology Knowledge Base - Pro Technology Knowledge Base - Overview - Pro Technology Knowledge Base - Server - Tento článek najdete také v podpoře pro správce systémů (System Administrators)
Další články, které napsal DanielBlack: OSDC-2009 Žádná-další-zatracená-hesla - OSDC Program 2009 listopad 25-27
Identifikace klientskými certifikáty na serveru Apache
|
Tento článek předpokládá, že jste si pro Apache stáhli kořenové certifikáty CAcert do souborů root.crt a class3.crt. Nové kořenové certifikáty CAcert si však stahujete jako soubory root_X0F.crt nebo class3_x14E228.crt, kde číslo za X je hexadecimální pořadové číslo nových kořenových certifikátů CAcert (15 a 1 368 616). Nejjednodušší je přejmenovat tyto stažené soubory s novými kořenovými certifikáty původními jmény uvedenými v dalším textu článku. |
|
Klientská strana identifikace u Apache není založena na dokumentaci httpd mod_ssl a byla použita v řadě systémů CACert, jako seznamy a webmail (pro štáb). Konfigurace Apache pro identifikaci klientské strany by se měly objevit ve směrnici VirtualHost, ačkoli mohou existovat podle jiných směrnic, jako Umístění. Tyto direktivy jsou doplněny ke konfiguraci SSL serveru, ačkoli raději používám SSLCACertificatePath a nepoužívám SSLCertificateChainFile.
Základní identifikace klientské strany
Toto je pro případ, že chceme, aby byl web přístupný pouze certifikátem. V tomto případě jakýmkoli certifikátem ze sady CA.
# Ověření klienta
SSLVerifyClient optional
SSLVerifyDepth 3
SSLCADNRequestPath /usr/share/ca-certificates/cacert.org/
# ošetření chyb
RewriteEngine on
RewriteCond %{SSL:SSL_CLIENT_VERIFY} !=SUCCESS
RewriteRule .? - [F]
ErrorDocument 403 "You need a client side certificate issued by CAcert to access this site"
(Pro přístup k tomuto webu potřebujete klientský certifikát vydaný CAcert.org)
SSLCADNRequestPath obsahuje cestu certifikátů, které bude tento web přijímat. To bude potřebné ve formátu openssl obsahujícím odkazy z subject_hash do souboru viz dále. Balíčky openssl obsahují skript rehash nebo c_rehash, který je může vygenerovat použitím příkazu c_rehash /usr/share/ca-certificates/cacert.org/.
drwxr-xr-x 2 root root 4096 2009-05-14 23:22 .
drwxr-xr-x 9 root root 4096 2007-05-16 23:12 ..
lrwxrwxrwx 1 root root 8 2009-05-14 23:22 5ed36f99.0 -> root.crt
-rw-r--r-- 1 root root 2151 2007-03-04 05:23 class3.crt
lrwxrwxrwx 1 root root 10 2009-05-14 23:22 e5662767.0 -> class3.crt
-rw-r--r-- 1 root root 2569 2007-03-04 05:23 root.crt
Všimněte si výše, že jsem napsal direktivu SSLVerifyClient optional (SSLVerifyClient nepovinný). To je kvůli chybové hlášce při SSLVerifyClient required (SSLVerifyClient povinný) a osoba bez instalovaného certifikátového přístupu k webu je spíše neintuitivní (Firefox - požadavek na zlepšení). Jednoduché direktivy Rewrite na konci znamenají, že je stránka zakázaná s chybou jako při ErrorDocument. Budete potřebovat instalovat a povolit mod_rewrite, abyste to mohli použít.
Povolit určité certifikáty - podle seznamu
K výše uvedeným direktivám přidáme:
SSLOptions +FakeBasicAuth
SSLRequireSSL
AuthName "Admin Only Area"
AuthType Basic
AuthUserFile /var/www/.htpasswd
require valid-user
Přitom /var/www/.htpasswd se podobá:
/CN=Daniel Black/emailAddress=daniel@cacert.org:xxj31ZMTZzkVA
Část s heslem xxj31ZMTZzkVA je vždy stejná. První část obdržíte příkazem openssl x509 -noout -subject -in certificate.crt, kde certificate.crt je certifikát, kterému chcete udělit přístup.
Povolit určité certifikáty - výrazem
Někdy potřebujete říci: ano, přijmi jakýkoli certifikát z CAcertu, který nese e-mailovou adresu @example.com a nestarej se o udržování dlouhých seznamů. To je možné takto:
SSLRequire %{SSL_CLIENT_S_DN_Email} =~ m/^[^@]*@example\.com$/
Celý seznam je zde: http://httpd.apache.org/docs/trunk/mod/mod_ssl.html#sslrequire. Některé certifikáty obsahují více e-mailových adres než jednu, takže:
SSLRequire %{SSL_CLIENT_S_DN_Email} =~ m/^[^@]*@example\.com$/
or %{SSL_CLIENT_S_DN_Email_0} =~ m/^[^@]*@example\.com$/
or %{SSL_CLIENT_S_DN_Email_1} =~ m/^[^@]*@example\.com$/
or %{SSL_CLIENT_S_DN_Email_2} =~ m/^[^@]*@example\.com$/
or %{SSL_CLIENT_S_DN_Email_3} =~ m/^[^@]*@example\.com$/
Měli byste také změnit chybové hlášení (viz výše), aby oznámilo, že certifikáty pro @example.com se také požadují.
Žurnálové soubory (logfiles)
Standardní kombinovaný žurnálový soubor (logfile) v Apache má pole pro uživatelské jméno (username), to se však při používání klientských certifikátů nevyužívá. Udržovat žurnál ve stejném formátu je však vhodná, pokud jej budete někdy chtít analyzovat, aniž musíte přizpůsobit analyzující software.
Použijte tedy CustomLog s kombinovaným formátem žurnálu a změňte %u (username) na e-mailovou adresu %{SSL_CLIENT_S_DN_Email} (nebo jinou proměnnou dle SSL_CLIENT*, která Vám bude užitečná).
Identifikace ve webových aplikacích
Řada webových aplikací může použít proměnnou prostředí REMOTE_USER pro řízení přístupu do různých částí webové aplikace. Tyto webové aplikace obvykle popisují použití této schopnosti s identifikací Apache Basic nebo Apache Digest. Můžete zde použít SSL certifikáty.
Použijte možnost SSL SSLUserName s proměnnou prostředí obsahující jméno uživatele (username): Proměnné prostředí. SSL_CLIENT_S_DN_Email je užitečná, ačkoli záleží na webové aplikaci a uživatelích, zda je přípustné používat e-mail jako uživatelské jméno.
CustomLog /var/log/apache2/ssl_access.log "%h %l %{SSL_CLIENT_S_DN_Email}x %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\""
Kontrola odvolaných certifikátů
OCSP (Online Certificate Status Protocol, protokol stavu certifikátů on-line) se dá použít ke kontrole, zda nebyly certifikáty odvolány. To mohou za Vás kontrolovat jen verze Apache 2.3 a vyšší (OCSPEnable).
Používáte-li Apache verze 2.2 nebo nižší, budete muset použít ke kontrole odvolání CRL, protože tyto verze nepodporují OCSP. Musíte tedy vytvořit úlohu pro cron, která stáhne aktuální CRL a nastaví Apache na jeho použití:
Vytvořte adresář, kam se CRL uloží. Obvykle je dobré místo /var/local/ssl/crls.
Vytvořte úlohu cron, která CRL stáhne. Připravil jsem shell script, který jenom uložíte do /etc/cron.hourly (nebo daily nebo jinak). Skript vyžaduje rsync, c_rehash utilitu z openssl a závisí na service apache2 reload k opětnému zavedení konfigurace Apache. Upravte ho podle svých potřeb, máte-li nastavení, které nevykazuje tyto závislosti.
- Do konfigurace Apache dejte:
SSLCARevocationPath /var/local/ssl/crls/
- Poprvé spusťte skript úlohy cron - zároveň zavede novou konfiguraci Apache.
- Zkontrolujte, zda všechno správně funguje.
Příspěvky a úvahy
24.05.2010-UlrichSchroeter
Win32 (s Cygwin) podrobnosti implementace: 1.) Openssl rehash, ani c_rehash, ani perl skript c_rehash mi nefungují. Ani Sysinternals Junction, ani jiná řešení nedělají, co očekávám. Po dvou dnech neúspěchů jsem přestal hledat, jak to obejít, a rozhodl jsem se vytvořit dvě základní části skriptů ručně z příkazového řádku DOS: $>openssl x509 -noout -hash <root.crt poznamenal jsem si výsledek haše a přidal ho do následujícího příkazového řádku Cygwin, příkazu ln $>ln --symbolic --no-target-directory root.crt 5ed36f99.0 (poslední argument) $>openssl x509 -noout -hash <class3.crt poznamenal jsem si výsledek haše a přidal ho do následujícího příkazového řádku Cygwin, příkazu ln: $>ln --symbolic --no-target-directory class3.crt e5662767.0 (poslední argument) Poznámka: příkaz 'ln' se v Cygwin používá s jinou syntaxí. 2.) SSLRequire mi nefunguje pod Apache/2.2.11 (Win32) mod_ssl/2.2.11 OpenSSL/0.9.8e ... Konfigurační syntaxi pro Apache: SSLRequire %{SSL_CLIENT_S_DN_Email} =~ m/^[^@]*@example\.com$/ or %{SSL_CLIENT_S_DN_Email_0} =~ m/^[^@]*@example\.com$/ or %{SSL_CLIENT_S_DN_Email_1} =~ m/^[^@]*@example\.com$/ or %{SSL_CLIENT_S_DN_Email_2} =~ m/^[^@]*@example\.com$/ or %{SSL_CLIENT_S_DN_Email_3} =~ m/^[^@]*@example\.com$/ musím změnit na: SSLRequire ( (%{SSL_CLIENT_S_DN_Email} in {"alias@example.com"}) or (%{SSL_CLIENT_S_DN_Email} in {"alias2@example.com"}) ) všechno v jednom řádku, části jsou v kulatých závorkách (), jinak vždy dostanu při startu služby chyby: "The Apache service terminated with service-specific error 1" (Služba Apache ukončena chybou 1) nebo chyby spojení: "failed, reason: SSL requirement expression not fulfilled" (selhalo, důvod: výraz požadovaný SSL není vyplněn) 3.) do http.conf jsem přidal základní definice pro Alias: Alias /users/ "D:/Apache/Apache2/wwwroot2/users" <Directory "D:/Apache/Apache2/wwwroot2/users"> SSLOptions +FakeBasicAuth +StdEnvVars +ExportCertData Options Indexes MultiViews AllowOverride None Order allow,deny Allow from all </Directory> a do ssl.conf jsem přidal příkaz SSLrequire do sekce location: <Location /user1/> SSLRequire (( ( %{SSL_CLIENT_S_DN_Email} in {"alias@example.com"} ) or ( %{SSL_CLIENT_S_DN_Email} in {"alias2@example.com"}) ) and ( %{SSL_CLIENT_V_REMAIN} > 0 ) and (( %{SSL_CLIENT_I_DN_CN} in {"CA Cert Signing Authority"}) or ( %{SSL_CLIENT_I_DN_CN} in {"CAcert Class 3 Root"}) )) </Location> Příkaz SSLRequire musí být celý na jednom řádku (!) (viz bod 2) SSL_CLIENT_V_REMAIN kontroluje klientský certifikát, zda už nevypršel. SSL_CLIENT_I_DN_CN kontroluje kořenový (třídy 1) a zprostředkující (třídy 3) údaj vydavatele CAcert v klientských certifikátech. s úctou Uli ;-)
21.05.2011-u60
skript běžící jednou týdně nebo jednou za dva týdny (s instalovanými cygwin) wget -nc http://crl.cacert.org/revoke.crl wget -nc http://crl.cacert.org/class3-revoke.crl rem for all 0 files delete old hash 0 files for %%a in (*.r0.lnk) do attrib -R %%a for %%a in (*.r0.lnk) do del %%a openssl crl -in revoke.crl -inform DER -out revoke-cacert_root_now.crl -outform PEM openssl crl -noout -hash<revoke-cacert_root_now.crl>temphash.tmp set /p hash= <temphash.tmp ln --symbolic --no-target-directory revoke-cacert_root_now.crl %hash%.r0 openssl crl -in class3-revoke.crl -inform DER -out revoke-cacert_class3_now.crl -outform PEM openssl crl -noout -hash<revoke-cacert_class3_now.crl>temphash.tmp set /p hash= <temphash.tmp ln --symbolic --no-target-directory revoke-cacert_class3_now.crl %hash%.r0 ## nezapomeňte restartovat Apache démona / službu
27.05.2011-u60
Pro kontrolu na úrovni aplikace pomocí php nad Apache si musíte trochu zaprogramovat v php. Příklad je v tomto článku:
02.06.2011-u60
Konfigurace pro smíšené prostředí "klientské certifikáty vyžadovány" / "klientské certifikáty nevyžadovány" 1. Konfigurujte svůj https server Apache, aby standardně nepožadoval klientské certifikáty kromě určitých částí: /secure/ část vyžadující klientské certifikáty /unsecure/ část, kde se klientské certifikáty nevyžadují, také sem dát "přistávací" stránku /other/ pokud mají být ostatní adresáře povinně zabezpečeny klientskými certifikáty, přidejte do httpd.conf direktivu <adresář ..> jako pro /secure/, přidejte do .htaccess jako níže v příkladu /secure/.htaccess httpd.conf ......................................... [...] # standardní port 80 - konfigurace /secure/.htaccess <Directory .../WWWROOT/secure/> ...................................... # #Trvalá redirekce RewriteEngine on # #z http://../secure/.* RewriteCond %{SERVER_PORT} !^443$ # #do //../unsecure/index.php RewriteRule ^(.*)$ /unsecure/index.php [R=301,L] AllowOverride All ...................................... </Directory> [...] <IfModule mod_ssl.c> Include conf/ssl.conf </IfModule> [...] ......................................... ssl.conf ......................................... <VirtualHost _default_:443> SSLEngine on SSLVerifyDepth 3 #Klíče serveru SSLCertificateFile /Apache/Apache2/conf/ssl.crt/your-pub-server-key.pem SSLCertificateKeyFile /Apache/Apache2/conf/ssl.key/your-private-server-key.pem #Ověření souboru klíčů serveru proti CA SSLCertificateChainFile /Apache/Apache2/conf/ssl.crt/cacert-chain.pem # Před-definice ověření klientských certifikátů, která je potřebná v dalších direktivách <directory ..> SSLCACertificateFile /Apache/Apache2/conf/cacert.org/root.crt SSLCACertificatePath I:/Apache/Apache2/conf/ssl.vrf/ SSLCADNRequestPath /Apache/Apache2/conf/ssl.vrf/ # Certificate Revocation Lists (CRL): SSLCARevocationFile /Apache/Apache2/conf/ssl.crl/revoke-cacert_root.crl SSLCARevocationFile /Apache/Apache2/conf/ssl.crl/revoke-cacert_class3.crl # EOT standardních definic # KLIENTSKÉ CERTIFIKÁTY NEVYŽADOVÁNY <Directory /unsecure/> ### Ověření klienta NE SSLVerifyClient none </Directory> # KLIENTSKÉ CERTIFIKÁTY VYŽADOVÁNY <Directory /Apache/Apache2/WWWROOT/secure/> ## SSLRequireSSL ### Ověření klienta SSLVerifyClient require SSLVerifyDepth 3 #SSLCADNRequestPath /Apache/Apache2/conf/ssl.vrf/ viz předkonfigurace SSLRequire ( ( %{SSL_CLIENT_V_REMAIN} > 0 ) and (( %{SSL_CLIENT_I_DN_CN} in {"CA Cert Signing Authority"}) or ( %{SSL_CLIENT_I_DN_CN} in {"CAcert Class 3 Root"}) )) ### ošetření chyb RewriteEngine on RewriteCond %{SSL:SSL_CLIENT_VERIFY} !=SUCCESS RewriteRule .? - [F] ErrorDocument 403 "You need a valid client certificate from CAcert.Org to access this page on this site." (Pro přístup k této stránce na tomto webu potřebujete mít platný certifikát od CAcert.org.) </Directory> </VirtualHost> ......................................... php scripty /unsecure/index.php ......................................... [...] <script language="javascript" type="text/javascript"> <!-- function $(id) { return document.getElementById(id); } // --> </script> [...] Description/Warning: You need a valid client cert installed in your browser to continue with client cert login (Popis/Varování: Pro pokračování v přihlášení klientským certifikátem potřebujete mít v prohlížeči instalován platný klientský certifikát.) [...] <form action="https://../secure/login.php" method="post" id="login"> <input type="submit" value="Cert Login"> <button onclick="$('login').action='/unsecure/cancel-infopage.html';$('login').submit();">Cancel</button> </form> [...] ......................................... /secure/login.php ......................................... <?php $user = $_SERVER["SSL_CLIENT_S_DN_CN"]; $email = $_SERVER["SSL_CLIENT_S_DN_Email"]; $server = $_SERVER["SSL_SERVER_S_DN_CN"]; $clisscert = $_SERVER["SSL_CLIENT_I_DN_CN"]; if ($_SERVER["SSL_CLIENT_VERIFY"]!="SUCCESS") { header ("Location: /unsecure/index.php"); exit; } else { ?> [html kód sem] [...] <h2>Úspěšné přihlášení klientským certifikátem</h2> <p>Nazdar <?php echo $user; ?>,<br> Úspěšně jste se přihlásil k <?php echo $server; ?><br> svým klientským certifikátem vydaným <?php if ($clisscert=="CAcert Class 3 Root") { echo $clisscert." (zprostředkujícím certifikátem třídy 3)"; } else { echo $clisscert." (kořenovým certifikátem třídy 1)"; } ?>.<br> <br> Tuto stránku vidíte jen po úspěšné identifikaci platným klientským certifikátem.<br> Nyní máte povolen přístup do oblastí s omezeným přístupem na základě klientského certifikátu.<br> Klidně pokračujte ve své cestě tímto webem...</p> </body> </html> <?php } ?> .........................................
YYYYMMDD-YourName (Vaše_jméno)
Text / Vaše příspěvky, úvahy a úryvky e-mailů, prosím