Jak mogę poprosić Apache o certyfikat klienta SSL bez konieczności weryfikacji go w stosunku do znanego urzędu certyfikacji?

9

Używam apache2 (2.2.3) do obsługi witryny, na której chciałbym, aby klienci uwierzytelniali się za pomocą certyfikatów. Ponieważ muszę jedynie zweryfikować, czy użytkownik przedstawiający konkretny certyfikat jest tym samym użytkownikiem, który przedstawiał ten certyfikat w przeszłości, urząd certyfikacji podpisujący certyfikat nie ma znaczenia. Wydaje się jednak, że używanie SSLVerifyClient requirewymaga SSLCACertificateFile ...(lub SSLCACertificatePath ...), a następnie apache akceptuje tylko certyfikaty podpisane przez urząd certyfikacji w tym pliku / ścieżce. Czy istnieje sposób, aby apache zaakceptował dowolny certyfikat klienta, niezależnie od wydającego / śpiewającego urzędu certyfikacji? (tj. sprawdź, czy klient ma odpowiedni klucz prywatny do prezentowanego klucza publicznego, ale nie zawracaj sobie głowy weryfikacją wystawiającego / podpisującego urzędu certyfikacji)

Izaak
źródło
Jak planujesz śledzić, które certyfikaty zostały uwierzytelnione?
Shane Madden
@ShaneMadden: Coś w rodzaju certyfikatów mapujących tabele na wewnętrzne identyfikatory użytkowników. Mechanika kryptografii klucza publicznego zajęłaby miejsce wymiany hasła.
Izaak
2
Racja - dochodzę do wniosku, że Apache nie wykonuje certyfikatów mapowania tabel na wewnętrzne identyfikatory użytkowników. Jeśli chcesz, aby użytkownicy uwierzytelniali się za pomocą certyfikatów klienta, dlaczego nie dać użytkownikom certyfikatów, które podpisujesz? Jak już wspomniałeś, istnieją dostawcy OpenID, którzy właśnie to robią. Apache mod_sslzostał zaprojektowany do uwierzytelniania użytkowników na podstawie relacji podpisywania certyfikatów; jeśli z jakiegoś powodu wolisz to zignorować, musisz zaimplementować uwierzytelnianie certyfikatu we własnym kodzie, który obsługuje również mapowanie certyfikatu na użytkownika.
Shane Madden
@ShaneMadden: Miałem nadzieję uniknąć wydawania certyfikatów i jeśli zaakceptuję tylko te certyfikaty, które wydałem, certyfikaty oparte na kartach inteligentnych zostaną wydane. Niezależnie od tego, co zrobię, część systemu będzie się odbywać na poziomie aplikacji, ale ponieważ jest tam cały mod_sslpark maszynowy, miałem nadzieję, że może on zająć się częścią mojej pracy.
Izaak
1
@ShaneMadden Jedną z zalet optional_no_cajest to, że może być lepszy dla interfejsu użytkownika, ponieważ można wyświetlić komunikat o błędzie HTTP, jeśli coś jest nie tak z certyfikatem (nie można inaczej, ponieważ zły certyfikat klienta przerwałby połączenie przed warstwą HTTP ). Jest to również przydatne, jeśli chcesz wypróbować alternatywne sposoby weryfikacji certyfikatu (np. WebID ). Masz rację, ale chcesz coś zrobić z weryfikacją, a to naprawdę działałoby tylko wtedy, gdy żądanie jest obsługiwane przez kod (np. W PHP / CGI / Java), a nie w przypadku plików.
Bruno,

Odpowiedzi:

10

Jak już odkryłeś, możesz wyłączyć weryfikację certyfikatu na poziomie uzgadniania SSL / TLS w Apache Httpd za pomocą SSLVerifyCLient optional_no_ca.

Drugim problemem, z którym będziesz musiał się zmierzyć, jest zmusienie klienta do wysłania certyfikatu. Ponieważ certyfikat nie powinien znajdować się w infrastrukturze PKI, mogą one być samopodpisane i mieć różnych wystawców.

Podczas żądania certyfikatu klienta serwer wysyła do klienta CertificateRequestwiadomość TLS podczas uzgadniania. Ta wiadomość zawiera certificate_authoritieslistę:

Lista nazw wyróżniających dopuszczalnych urzędów certyfikacji. Te nazwy wyróżniające mogą określać pożądaną nazwę wyróżniającą dla głównego urzędu certyfikacji lub dla podrzędnego urzędu certyfikacji; dlatego ten komunikat może być użyty do opisania zarówno znanych źródeł, jak i pożądanej przestrzeni autoryzacji. Jeśli lista Certificate_authorities jest pusta, wówczas klient MOŻE wysłać dowolny certyfikat odpowiedniego ClientCertificateType, chyba że istnieje jakieś zewnętrzne uzgodnienie inaczej.

Przeglądarki używają tego, aby wybrać certyfikat klienta do wysłania (jeśli taki istnieje).

(Należy zauważyć, że część dotycząca pustej listy znajduje się tylko w specyfikacji od TLS 1.1. SSL 3.0 i TLS 1.0 milczą na ten temat, a w praktyce również będzie działać.)

Dostajesz na to dwie opcje.

  • Jeśli oczekiwane certyfikaty klienta zostaną podpisane przez siebie, wszyscy będą mieć różnych wystawców. Ponieważ nie będziesz wiedział, czego się spodziewać, serwer będzie musiał wysłać pustą listę. Aby to zrobić, użyj SSLCADNRequestFiledyrektywy i wskaż plik, który zawiera tylko pustą linię (jeśli dobrze pamiętam, nie działa z całkowicie pustym plikiem).

  • Druga (mniej czysta) opcja. Jest uzgodnienie nazwy wyróżniającej wystawcy wspólnej dla wszystkich oczekiwanych certyfikatów klienta, niezależnie od tego, czy rzeczywiście zostały wydane przez ten certyfikat urzędu certyfikacji (lub czy ten urząd certyfikacji w ogóle istnieje). W ten sposób znacznie złamiesz model PKI (więcej).

    Jeśli zgadzasz się na nazwę wyróżniającą emitenta, CN=Dummy CAna przykład (na przykład). Każdy może zbudować samopodpisany certyfikat, używając CN=Dummy CAjako nazwy wyróżniającej podmiotu (i nazwy wyróżniającej wystawcy), ewentualnie z różnymi kluczami. Chociaż SSLCADNRequestFiledyrektywa przewiduje skonfigurowanie certyfikatów do tworzenia listy, nie są one wcale używane do weryfikacji certyfikatu klienta, jest to po prostu skomplikowany (ale naturalny w kontekście innych dyrektyw) sposób konfigurowania certificate_authoritieslisty. Jeśli jako usługa umieścisz samopodpisany certyfikat z tymi nazwami SSLCADNRequestFile, spowoduje to CertificateRequestużycie komunikatu TLS CN=Dummy CAna certificate_authoritiesliście (są to tylko nazwy, a nie certyfikaty na tym etapie). Klient będzie wtedy mógł odebrać swój własny certyfikat z DN emitentaCN=Dummy CA, niezależnie od tego, czy jego podpis mógłby zostać zweryfikowany przez ten certyfikat (te same klucze), czy nie, ponieważ i tak nie jest wymagana weryfikacja podpisu.

To powiedziawszy, pamiętaj, że przy pomocy SSLVerifyCLient optional_no_canie jest przeprowadzana prawdziwa weryfikacja certyfikatu (przypuszczam, że możesz sprawdzić SSL_CLIENT_VERIFYzmienną, jeśli ręczna weryfikacja jest tylko rezerwowym rozwiązaniem PKI, którą i tak skonfigurowałeś). Na tym etapie dowiesz się tylko, że klient ma klucz prywatny dla certyfikatu klucza publicznego, który przedstawił (gwarantowany przez CertificateVerifywiadomość TLS ): jeśli chcesz uwierzytelnić niektóre, musisz wykonać jakąś formę weryfikacji sortować. (Nie możesz ufać żadnej treści certyfikatu, czyli powiązaniu między jego kluczem publicznym a zawartymi w nim nazwami / atrybutami).

Nie działa to dobrze w przypadku plików, ale możesz to zrobić dla aplikacji (np. PHP / CGI / ... nawet Java, jeśli przekażesz certyfikat do serwera proxy Java). Jednym z podstawowych sposobów jest posiadanie znanej listy kluczy publicznych, lub możesz przyjrzeć się pomysłom w FOAF + SSL / WebID .

Bruno
źródło
2

Użycie SSLVerifyCLient optional_no_ca(zamiast require) powoduje, że apache nie sprawdza wystawiającego urzędu certyfikacji (a zatem nie potrzebuje pliku certyfikatu lub ścieżki certyfikatu). Pozwala to klientowi / użytkownikowi nie przesłać certyfikatu, więc sprawdzenie, czy certyfikat został w ogóle wykorzystany, musi zostać wykonane osobno.

(Najwyraźniej po prostu nie przeczytałem dokładnie mod_ssldokumentacji).

Izaak
źródło