Достъп само с електронен подпис

07.05.2017 Security 0 Comments

Бях си поставил за цел на огранича достъпа до един уеб сайт (или поддомейн) само за потребители с електронен подпис. Важно уточнение: в тази статия не става въпрос за подписване на документи с електронен подпис! Идеята е, когато потребителя посети уеб сайта, браузъра да му покаже прозорчето за избор на сертификат (електронен подпис), потребителя да избере сертификата, да въведе своя ПИН номер и, при успешна идентфикация, да може да ползва този уеб сайт. Браузъра ще изпрати към уеб сървъра важна информация за сертификата и потребителя. Би могло дори да се въведе достъп до уеб сайта само със сертификат, без нужда от потребителско име и парола.

Или не знам как да търся в интернет, или това е специфичен проблем за България, но срещнах доста трудности. Основната причина беше, че root сертификатите на българските издатели на УЕП не са включени в официалните списъци. Ключовата стъпка от целия процес, който описвам по-долу, всъщност е добавянето на техните root сертификати като trusted authority от страна на сървъра. В случая аз използвам личен електронен подпис, издаден от Инфонотари и съм добавил само техния root сертификат. В идеалния случай би трябвало да добавя root сертификатите на Информационно обслужване, Банксервиз, Спектър и СЕП България, за да си гарантирам, че всички потребители от България, притежаващи УЕП, ще имат достъп до сайта.

Това упражнение няма как да се случи на споделен хостинг. Причината е описана по-горе – root сертификатите на българските издатели липсват в офицалните списъци и никой не ги инсталира допълнително за споделен хостинг. Използвал съм най-малкия виртуален сървър на DigitalOcean, който ми струваше цели 6 цента ($0.06) докато постигна успех, но след като сега имам готова “рецепта”, цялото упражнение ми отнема около 10 минути. Пресмятайки спрямо цената на час ($0.007), отнело ми е около 8 часа и половина докато успея 😉

Инсталирания сертификат на сървъра е от безплатните на Let’s Encrypt и тази статия включва описание как се инсталира.

Обясненията започват още от създаване на droplet, инсталиране на Apache и РНР. Ако вече имате всичко това, преминете направо към т. 5 от статията. Използвам Apache защото certbot-a на Let’s Encrypt може да конфигурира сертификата на сървъра самостоятелно. При Nginx има малко повече писане, но не е нещо особено.

  1. Създайте нов droplet в DigitalOcean и му добавете домейн. Аз използвах най-малкия, от $5 на месец. За ОС си избрах най-новото Убунту – 17.04х64, то съм тествал успешно и на 16.04 LTS. Също така добавих и SSH ключ за по-лесен и сигурен достъп.
  2. Влезте през SSH и инсталирайте Apache и PHP
    $ apt-get update
    $ apt-get upgrade
    $ apt-get install apache2 php7.0 libapache2-mod-php7.0
  3. Създайте виртуален хост. Ако програмката на Let’s encrypt за сертификати не открие хостове, различни от default, ще Ви попита за домейн за който да направи сама виртуалния хост или пък ако открие, ще Ви покаже списък от който да си изберете за кой домен да се създаде сертификат. Аз предпочитам сам да си направя виртуалния хост, но ако оставите това действие на certbot-a, имайте в предвид, че може да наложи да го редактирате, поне в частта му за DocumentRoot
  4. Инсталирайте си сертификат за Вашия уеб сайт. Аз използвах безплатните сертификати на Let’s Encrypt. Разработили са програма, която ще Ви зададе няколко въпроса, ще премине сама през цялата процедура и накрая ще имате уеб сайт, достъпен през HTTPS, който има валиден сертификат.
    $ add-apt-repository ppa:certbot/certbot
    $ apt-get update
    $ apt-get install python-certbot-apache 
    $ certbot --apache
  5. Добавяне на ново trusted authority. Няма да влизам в обяснения къде и как се съхраняват сертификатите на сървърите, какви са форматите и т.н. Ще обясня само конкретните стъпки, нужни за добавяне на root сертификатите на българските издатели на УЕП.
    1. Направете си директория за всеки от издателите във /usr/share/ca-certificates, например:
      $ mkdir /usr/share/ca-certificates/inotary
    2. Добавете root сертификата на този издател. Има ги на офицалните им интернет страници, например за Инфонотари – “Публичен регистър” -> “Удостоверения на Инфонотари” -> “InfoNotary CSP Root”. Файла се казва in-csp-root.cer, но ще трябва да го промените във PEM формат (онзи, който се отваря с текстов редактор и в начало пише —-BEGIN CERTIFICATE bla bla bla —) и да има разширение crt.
      $ scp ~/Downloads/in-csp-root.cer root@your-domain.com:/usr/share/ca-certificates/inotary
      $ openssl x509 -inform der -in in-csp-root.cer -outform pem -out in-csp-root.crt
      $ rm in-csp-root.cer

      Повторете тази стъпка за всеки доставчик на УЕП, който искате да поддържате!

    3. Реконфигуриране. Не знам как точно да го обясня, но ОС трябва да знае за тези нови сертификати. Процена е напълно автоматизиран и се стартира само с един ред. Директорията /usr/share/ca-certificates ще бъде сканирана и всички налични сертификати а) ще бъдат включени в един общ файл само като пътища до crt файловете, а след това б) съдържанието на сертификатите ще бъде проченето и всички ще бъдат добавени в един голям файл.
      $ dpkg-reconfigure ca-certificates
  6. Промени във виртуалния хост, който трябва да бъде достъпен само с УЕП:
        $ SSLCACertificateFile /etc/ssl/certs/ca-certificates.crt
        $ SSLVerifyClient require
        $ SSLVerifyDepth 10
        $ SSLOptions +StdEnvVars
    1. SSLCACertificateFile – това е файла със всички сертификати на trusted authorities, за които Вашата ОС е конфигурирана.
    2. SSLVerifyClient – приема няколко стойности, посочената required означава винаги да се изисква сертификат от клиента.
    3. SSLVerifyDepth – сертификатите са един вид йерархични структури от данни. Аз например използвам личен УЕП, за който Инфонотари има отделен удостоверителен сертификат. Вместо да инсталирам всички сертификати на Инфонотари, аз съм исталирал само техния основен. Ако за тази опция използвате стойност 1, това означава, че сървъра ще търси “директно съвпадение” и няма да може да удостовери че моя личен УЕП е част от Инфонотари root УЕП. Ако обаче му разреша да търси до няколко нива по-навътре, ще успее от Инфонотари root сетрификата да мине по-надолу по веригата и да открие и удостовери личния УЕП.
    4. SSLOptions – тук има много варианти, но това, което за сега ми трябва е основните данни на сетрификата да бъдат изпратени на уеб сървъра, където вече РНР има достъп. В тези данни няма нищо секретно – имената на потребителя, неговият имейл адрес, сериен номер на УЕП, информация за издателя на сертификата, начална дата, крайна дата, брой дни до края.
  7. OCSP – това е протокол/стандарт за допълнителна проверта на сертификати – Вашият уеб сървър (или пък програмен код) трябва да се свърже със OCSP сървъра на издателя и да провери дали този сертификат все още е валиден. Apache разполага с такъв модул и според документацията е достатъчно да се разреши опцията SSLOCSPEnable, което аз направих, тествах, не се счупи, но и в последствие в phpinfo ($_SERVER) не видях нищо, което да подсказва че тази проверка е направена, както и резултата от нея. Има вариант да си направите тази проверка като част от Вашия програмен код.

 

Специални благодарности на Christian Weiske за тази статия от 2011 година – Using SSL Client Certificates with PHP
Special thanks to Christian Weiske for a 2011 article – Using SSL Client Certificates with PHP

 

Submit a comment