Як я можу змусити апаш-запит отримати клієнтський сертифікат SSL, не вимагаючи його підтвердження щодо відомого CA?


9

Я використовую apache2 (2.2.3), щоб обслуговувати сайт, де я хотів би, щоб клієнти перевіряли сертифікати. Оскільки мені потрібно лише переконатися, що користувач, який представляє певний сертифікат, є тим самим користувачем, який раніше його подав, сертифікат ЦС, який підписує сертифікат, не має значення. Здається, що, використовуючи, SSLVerifyClient requireпотрібно SSLCACertificateFile ...(або SSLCACertificatePath ...), а потім apache буде приймати лише сертифікати, підписані CA в цьому файлі / шляху. Чи є спосіб отримати апаш, щоб прийняти будь-який сертифікат клієнта, незалежно від видачі / співу CA? (тобто переконайтеся, що клієнт має відповідний приватний ключ до представленого відкритого ключа, але не переймається підтвердженням сертифікату видачі / підписання)


Як ви плануєте відстежувати, які сертифікати мають автентифікацію?
Шейн Мадден

@ShaneMadden: Щось на зразок таблиці відображення сертифікатів внутрішніх ідентифікаторів користувачів. Механіка криптовалюти з відкритим ключем зайняла б місце обміну паролем.
Ісаак

2
Правильно - те, на що я звертаюсь, - це те, що Apache не робить сертифікати таблиці зіставленням внутрішніх ідентифікаторів користувачів. Якщо ви будете мати автентифікацію користувачів за допомогою клієнтських сертифікатів, чому б не дати користувачам сертифікати, які ви підписуєте? Як ви вже згадували, є постачальники OpenID, які роблять саме це. Apache's mod_sslбув розроблений для аутентифікації користувачів на основі відносин підписання сертифікатів; якщо ви хочете зневажати це з якихось причин, тоді вам потрібно буде впровадити автентифікацію сертифікатів у власному коді, який також обробляє відображення вашого сертифікату на користувача.
Шейн Мадден

@ShaneMadden: Я сподівався уникнути видачі сертифікатів, і якщо я прийму лише ті сертифікати, які я видав, сертифікати на основі смарт-карт виходять. Що б я не робив, якась частина системи буде проходити на рівні додатків, але, оскільки там є вся mod_sslтехніка, я сподівався, що вона може піклуватися про якусь роботу для мене.
Ісаак

1
@ShaneMadden Однією з переваг optional_no_caє те, що він може бути кращим для користувальницького інтерфейсу, оскільки ви можете відобразити повідомлення про помилку HTTP, якщо щось не так із сертифікатом (ви не могли інакше, оскільки поганий сервер клієнта припинив би з'єднання до рівня HTTP ). Це також корисно, якщо ви хочете спробувати альтернативні способи перевірки cert (наприклад, WebID ). Ви маєте рацію, хотіли б хоч щось перевірити, і це справді спрацює лише тоді, коли запит обробляється кодом (наприклад, в PHP / CGI / Java), а не з файлами.
Бруно

Відповіді:


10

Як ви виявили, ви можете відключити перевірку сертифікатів на рівні рукостискання SSL / TLS в межах Apache Httpd, використовуючи SSLVerifyCLient optional_no_ca.

Друга проблема, з якою ви збираєтеся зіткнутися з тим, що ви намагаєтеся зробити, - це змусити клієнта надіслати сертифікат. Оскільки ваш сертифікат не повинен бути в межах PKI, він може підписатись і мати різних емітентів.

Під час запиту клієнтського сертифіката сервер надсилає клієнту CertificateRequestTLS-повідомлення під час ручної передачі. Це повідомлення містить certificate_authoritiesсписок:

Список відомих імен прийнятних сертифікаційних органів. Ці розрізнені імена можуть визначати бажане відмінне ім’я для кореневого ЦЗ або для підлеглого ЦА; таким чином, це повідомлення може бути використане для опису як відомих коренів, так і потрібного простору авторизації. Якщо список сертифікатів_авторитетів порожній, клієнт МОЖЕ надсилати будь-який сертифікат відповідного ClientCertificateType, якщо немає зовнішньої домовленості, яка суперечить.

Браузери використовують це, щоб вибрати, який сертифікат клієнта надсилати (якщо такий є).

(Зверніть увагу, що частина про порожній список міститься лише в специфікації від TLS 1.1. SSL 3.0 і TLS 1.0 про це мовчать, і на практиці це також буде працювати.)

Ви отримуєте два варіанти для цього.

  • Якщо клієнтські сертифікати, які ви очікуєте, підписуватимуться самостійно, всі вони матимуть різних емітентів. Оскільки ви не знаєте, що очікувати, серверу потрібно буде надіслати порожній список. Для цього скористайтеся SSLCADNRequestFileдирективою та вкажіть її на файл, який містить лише порожній рядок (якщо я добре пам’ятаю, він не працює з повністю порожнім файлом).

  • Другий (менш чистий) варіант. Погодьтесь щодо DN-емітента, спільного для всіх клієнтських сертифікатів, яких ви очікуєте, незалежно від того, чи вони були видані цим сертифікатом CA (чи є, чи існує ЦА чи ні). Роблячи це, ви б значно порушили модель PKI (більше).

    Якщо ви погоджуєтесь з DN-емітентом, наприклад CN=Dummy CA(наприклад). Будь-який бажаючий може створити сертифікат, який підписує власний підпис, використовуючи CN=Dummy CAяк суб’єкт DN (і видавець DN), можливо, за допомогою різних ключів. Хоча SSLCADNRequestFileдиректива очікує, що вона буде налаштована сертифікатами для складання списку, вони взагалі не використовуються для перевірки клієнтського сертифіката, це просто складний (але природний у контексті інших директив) спосіб налаштування certificate_authoritiesсписку. Якщо ви, як сервіс, вкладете сертифікат cert з такими іменами SSLCADNRequestFile, який підписується , це зробить CertificateRequestповідомлення TLS CN=Dummy CAу certificate_authoritiesсписку (це лише імена, а не церти на цьому етапі). Потім клієнт зможе отримати власний сертифікат у видачі DNCN=Dummy CA, незалежно від того, чи може його підпис підтверджений цим сертифікатом (тими самими ключами) чи ні, оскільки жодна перевірка підпису в цих кроках жодного разу не бере участь.

З цього SSLVerifyCLient optional_no_caприводу пам’ятайте, що при цьому не проводиться справжня перевірка сертифікатів (я думаю, ви могли перевірити SSL_CLIENT_VERIFYзмінну, якщо ваша ручна перевірка є лише резервним рішенням для PKI, який ви все одно налаштували). Все, що ви знаєте на цьому етапі, - це те, що клієнт має приватний ключ для представленого ним сертифіката відкритого ключа (гарантованого CertificateVerifyповідомленням TLS ): вам потрібно буде виконати певну форму перевірки, якщо ви хочете, щоб там була автентифікація деяких сортувати. (Ви не можете довіряти жодному змісту сертифіката, тобто будь-якій прив'язки між його відкритим ключем та іменами / атрибутами, які він містить.)

Це не буде добре для файлів, але ви можете зробити це для програми (наприклад, PHP / CGI / ... навіть Java, якщо ви передасте сертифікат на проксі-сервер Java). Одним із основних способів було б мати заздалегідь відомий список відкритих ключів, або ви можете подивитися на ідеї у FOAF + SSL / WebID .


2

Використання SSLVerifyCLient optional_no_ca(замість require) змушує apache не перевіряти видачу CA (і, отже, не потрібен файл або шлях сертифіката CA). Це дозволяє клієнту / користувачеві не подавати сертифікат, тому перевірка того, що сертифікат був використаний взагалі, потрібно робити окремо.

(Мабуть, я просто не зміг детально прочитати mod_sslдокументацію.)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.