LINUX-BG   Адрес : http://www.linux-bg.org
Достъп до уеб ресурси чрез Х.509 идентификация
От: Vesselin Markov
Публикувана на: 25-09-2006
Адрес на статията: http://www.linux-bg.org/cgi-bin/y/index.pl?page=article&id=advices&key=386394133

Достъп до уеб ресурси чрез Х.509 идентификация


Веселин Марков 09.2006


Този документ демонстрира метод на удостоверение при достъп до уеб ресурси, изискващ идентификация от страна на потребителя, базирана на X.509v3 сертификати.

Предупреждение: Потребителите на Internet Explorer няма да могат да видят графичните файлове към статията поради несъвместимост на браузъра с RFC2397 (data: URL scheme).



.: Въведение


Един от често използваните методи за идентификация на потребител е използване на схема, при която се изисква валидно потребителско име и парола. Колкото и добре утвърден да е този вариант, той има своите слабости - паролите не винаги биват подбирани сложни, което ги прави лесни за отгатване. Доста приложения които използват такава система са уязвими от атаки тип "груба сила", потребителските данни не винаги се предават по обезопасен начин и пр.

Регулиране на достъп базиран на IP адреси рядко е приложимо и почти винаги непрактично решение, не само когато потребителите са повече.

Друг метод, който се налага от финансови организации (а и не само) е форсиране на автентикация чрез клиентски сертификати, т.е. сървърът изисква наличието на определен файл от страна на клиента, за да разреши по-нататъшен достъп. Изпълнението на този вариант не е дотам тривиална задача, но сигурността при определяне на право за ползване на даден ресурс, значително се повишава.

Пример за ползите от такъв вид удостоверяване са непрекъснатите атаки с цел отгатване на потребител/парола при SSH. С използване на PKI система те отпадат.

Все повече уеб сървъри поддържат такъв тип клиент/сървър автентикация, а решението разглеждано от статията се базира на Apache и OpenSSL.



.: Изграждане и администриране на Достоврен Източник на Сертификати (Certificate Authority)


Този подход изисква създаване и извършване на следните операции при управление на CA:

1. Издаване на клиентски сертификати
2. Проверка за валидност в базата данни на CA
3. Отмяна/анулиране на сертификат, при:

  3.1. Изтекла валидност на сертификат
  3.2. Загуба на сертификат
  3.3. Компрометиран сертификат
  3.4. Друго събитие налагащо прекъсване на валидността му

4. Подновяване на сертификат


Следват някои указания, които ви биха били полезни при администриране на CA. По този начин ще създадете локално CA:

# mkdir -p CA/{newcerts,private,crl} && cd CA
# echo 01 > serial
# touch index.txt
# cp /etc/ssl/openssl.cnf-sample openssl.cnf
# vim openssl.cnf

Примерен cnf файл има в пакета OpenSSL. Направете промени където е необходимо
(име на CA директория, ключ/сертификат, валидност в дни и др. параметри).

# openssl req -new -x509 -keyout private/CA.key -out CA.crt -days 3650 -config openssl.cnf

Добре е Root CA сертификатът ви да има по-голяма валидност. Паролата за частния ключ трябва да бъде подбрана внимателно и да не се забравя.
Проверете информацията която сте попълнили така:

# openssl x509 -in CA.crt -noout -text

Издаване и подписване от CA на нов (потребителски) сертификат:

# openssl req -nodes -new -x509 -keyout 01req.pem -out 01req.pem -days 1095 -config openssl.cnf
# openssl x509 -x509toreq -in 01req.pem -signkey 01req.pem -out tmp.pem
# openssl ca -config openssl.cnf -policy policy_anything -out 01cert.pem -infiles tmp.pem
# mv 01req.pem 01key.pem ; rm -f tmp.pem

В момента 01key.pem съдържа частния ключ (и CSR), а 01cert.pem е подписаният от CA нов сертификат.
Запис за това събитие ще отиде и в index.txt; той трябва да започва с V, което е индикация сертификатът че е валиден. Други възможни стойности са R (revoked) и E (expired).

Трябва да установите процедура по редовно подновяване на базата данни на CA и проверка на сертификатите:

# openssl ca -updatedb -verbose -config openssl.cnf
# openssl verify -CAfile CA.crt XYZcert.pem

С времето, по различни причини ще ви се налага да анулирате съществуващи сертификати. По този начин ще създадете Certificate Revocation List (CRL), който трябва да бъде опресняван всеки път когато това се налага.

# openssl ca -revoke bad_cert.pem -keyfile private/CA.key -cert CA.crt -config openssl.cnf
# openssl ca -gencrl -keyfile private/CA.key -cert CA.crt -out crl/CA.crl -config openssl.cnf


Прочитане на CA.crl

# openssl crl -in crl/CA.crl -noout -text

  
 Certificate Revocation List (CRL):  
         Version 1 (0x0)  
         Signature Algorithm: sha1WithRSAEncryption  
         Issuer: /C=BG/ST=BG/L=BG/O=Example Corp./OU=IT 
 Department/CN=Example Corp. CA-1/emailAddress=hq@example.net  
         Last Update: Sep 25 08:18:41 2006 GMT  
         Next Update: Oct 25 08:18:41 2006 GMT  
 Revoked Certificates:  
     Serial Number: 02  
         Revocation Date: Sep 25 08:18:19 2006 GMT  
     Signature Algorithm: sha1WithRSAEncryption  
         2b:a4:f0:9d:92:bc:75:f2:04:2f:b8:0f:51:90:72:23:21:1d:  
         2c:b8:56:8b:e9:67:b9:a8:90:08:23:f9:10:89:ea:a9:26:c5:  
         cb:e6:6d:17:95:f8:87:ce:09:dc:5b:3f:66:b5:7e:69:eb:66:  
         a7:d5:cf:3b:8f:e5:01:98:83:4d:f8:8b:0b:28:7b:04:2d:ee:  
         e1:2b:99:96:ed:41:3f:9a:9b:62:d6:4e:f9:08:1d:d7:e2:e9:  
         9c:8e:fc:4f:8c:f2:6d:9d:85:09:7a:b7:70:83:ca:a6:cf:72:  
         80:0e:2a:0a:8f:82:dd:2f:c3:25:92:9a:de:20:6a:77:d9:cc:  
         1d:4f  
 

По подразбиране валидността на този лист е 30 дни. Тази стойност може да бъде променяна. Не е фатално ако пропуснете да го пре-генерирате след изтичането на този срок, стига да няма подлежащ на анулиране субект.

При подновяване на сертификат първо трябва да анулирате текущия (който може и да е с изтекла валидност), след което подписвате отново оригиналният (към него) CSR (Certificate Signing Request), като съобразявате новите дати.

# openssl ca -config openssl.cnf -policy policy_anything -out renewed-01cert.pem -infiles 01key.pem -startdate <сега> -enddate <предишен срок на валидност+1095 дни>

В 01key.pem присъства оригиналният CSR освен частният ключ.

В началото имахме създадени 01cert.pem и 01key.pem. За да могат да бъдат импортнати в браузър или S/MIME клиент за електронна поща, трябва да бъдат преобразувани в PKCS#12 вид. Такъв хранилищен файл съдържа частния ключ към сертификата, самия сертификат и този на CA. За да бъде защитен се ползва симетрично криптиране с парола, която трябва да предоставите на потребителя.

# openssl pkcs12 -export -in 01cert.pem -inkey 01key.pem -certfile CA.crt -name cust01 -out cust01.p12

При необходимост обратно може да бъде трансформиран в PEM файл:

# openssl pkcs12 -in cust01.p12 -out 01keys.pem -nodes

След като става дума за собствено-подписани сертификати от особено значение е сертификатът на локланото CA да бъде импортнат в браузъра на клиента като Trusted Authority. При всяка една грешка в последствие при клиент/сървър комуникация, следва да се потърси незабавно съдействие от администраторите на съответното CA. В противен случай следва да се разясни какво е сертификатен fingerprint и този низ да бъде известен на потребителя за справка:

# openssl x509 -fingerprint -noout -in /opt/CA/CA.crt
SHA1 Fingerprint=63:AC:75:46:BC:A6:B6:D4:F5:4A:37:1D:0F:F3:C2:9A:D8:1B:F1:C0




.: Конфигурация на Apache сървър


Едно от нещата които не трябва да се пропускат е да се упомене в конфигурационния файл, че директорията която ще защитаваме може да бъде достъпна само в SSL режим от httpd.conf:


<Directory /opt/apache2/htdocs/lock>
   SSLRequireSSL
</Directory>

...

Примерна конфигурация в httpd-ssl.conf

...

 SSLCACertificateFile /opt/CA/CA.crt
 SSLCARevocationFile /opt/CA/crl/CA.crl

<Location /lock>
   SSLRequireSSL
   SSLVerifyClient require
   SSLVerifyDepth 1
</Location>

</VirtualHost>

Тук почти всичко е ясно, с изключение може би на директивата SSLVerifyDepth. Когато е със стойност 1, единствено клиентски сертификати които са подписани от гореспоменатото CA биват допускани до съответния ресурс.

Когато правите промяна по CRL листа трябва да накарате уеб сървъра да го прочете наново.

# kill -SIGHUP `cat httpd.pid`

[Sun Sep 24 17:14:36 2006] [notice] SIGHUP received. Attempting to restart
[Sun Sep 24 17:14:36 2006] [notice] Apache configured -- resuming normal operations




.: Примери


Ако работите повече в конзола, можете да използвате SSL/TLS клиента от OpenSSL, за да проверите дали нещата работят както се очаква.

# openssl s_client -connect secure.example.net:443 -cert /opt/CA/01cert.pem -key /opt/CA/01key.pem

CONNECTED(00000003)  
 depth=0 /C=BG/ST=BG/L=BG/O=Example Corp./OU=IT 
 Department/CN=secure.example.net/emailAddress=hq@example.net  
 verify error:num=18:self signed certificate  
 verify return:1  
 depth=0 /C=BG/ST=BG/L=BG/O=Example Corp./OU=IT 
 Department/CN=secure.example.net/emailAddress=hq@example.net  
 verify return:1  
 ---  
 Certificate chain  
  0 s:/C=BG/ST=BG/L=BG/O=Example Corp./OU=IT 
 Department/CN=secure.example.net/emailAddress=hq@example.net  
    i:/C=BG/ST=BG/L=BG/O=Example Corp./OU=IT 
 Department/CN=secure.example.net/emailAddress=hq@example.net  
 ---  
 Server certificate  
 -----BEGIN CERTIFICATE-----  
 MIICnzCCAggCCQDctSBIGHvahjANBgkqhkiG9w0BAQUFADCBkzELMAkGA1UEBhMC  
 QkcxCzAJBgNVBAgTAkJHMQswCQYDVQQHEwJCRzEWMBQGA1UEChMNRXhhbXBsZSBD  
 b3JwLjEWMBQGA1UECxMNSVQgRGVwYXJ0bWVudDEbMBkGA1UEAxMSc2VjdXJlLmV4  
 YW1wbGUubmV0MR0wGwYJKoZIhvcNAQkBFg5ocUBleGFtcGxlLm5ldDAeFw0wNjA5  
 MjQyMDIwMzZaFw0wNjExMjMyMDIwMzZaMIGTMQswCQYDVQQGEwJCRzELMAkGA1UE  
 CBMCQkcxCzAJBgNVBAcTAkJHMRYwFAYDVQQKEw1FeGFtcGxlIENvcnAuMRYwFAYD  
 VQQLEw1JVCBEZXBhcnRtZW50MRswGQYDVQQDExJzZWN1cmUuZXhhbXBsZS5uZXQx  
 HTAbBgkqhkiG9w0BCQEWDmhxQGV4YW1wbGUubmV0MIGfMA0GCSqGSIb3DQEBAQUA  
 A4GNADCBiQKBgQChrUNqM9bF4rU/B2C/hEZNRTP7HzofkD6qMqde5qy+wVqOaVaq  
 WaQPa7WUoq+aL/q4O0t1I/4D2vS9UO/Xf8eVUWZNyZH3pNq+YEjq/rQHCDVYqzV/  
 V+mnBy9Xta9payWwzTXaav0FLvtkEfAH0dcBrLrOOByOX+hLAKHxMAoVKQIDAQAB  
 MA0GCSqGSIb3DQEBBQUAA4GBAISu8yHDX6x1n6Xc7rPI/b1EFJGg09XbaGYTc55O  
 i59dslOx9R4yFaxTIi2LHfguO3I5Q4HGRT5EctmUIVu6schEQb1tzx0HWzDsTLG2  
 YQyhZF49gudmAtk1nFggV4uhWP2XLWwBxzMa+oQ5K8p++fHUhSuvFw5iejf13PHz  
 6S+g  
 -----END CERTIFICATE-----  
 subject=/C=BG/ST=BG/L=BG/O=Example Corp./OU=IT 
 Department/CN=secure.example.net/emailAddress=hq@example.net  
 issuer=/C=BG/ST=BG/L=BG/O=Example Corp./OU=IT 
 Department/CN=secure.example.net/emailAddress=hq@example.net  
 ---  
 No client certificate CA names sent  
 ---  
 SSL handshake has read 1239 bytes and written 340 bytes  
 ---  
 New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA  
 Server public key is 1024 bit  
 Compression: NONE  
 Expansion: NONE  
 SSL-Session:  
     Protocol  : TLSv1  
     Cipher    : DHE-RSA-AES256-SHA  
     Session-ID: 
 067A93FD93C798641CE87C9DFE7C47939B56FC61B9A791C103771A756E83B9A8  
     Session-ID-ctx:  
     Master-Key: 
 E2645E27AC78634AC4BED831A8C6913FF949A9A81F1A687328C4E8DBD371FC47BCB71A513DAA706F4FEA41A9814397EB  
     Key-Arg   : None  
     Start Time: 1159130361  
     Timeout   : 300 (sec)  
     Verify return code: 18 (self signed certificate)  
 ---  
   
 GET /lock/ HTTP/1.0  
   
 depth=0 /C=BG/ST=BG/L=BG/O=Example Corp./OU=IT 
 Department/CN=secure.example.net/emailAddress=hq@example.net  
 verify error:num=18:self signed certificate  
 verify return:1  
 depth=0 /C=BG/ST=BG/L=BG/O=Example Corp./OU=IT 
 Department/CN=secure.example.net/emailAddress=hq@example.net  
 verify return:1  
 read R BLOCK  
   
 HTTP/1.1 200 OK  
 Date: Sun, 24 Sep 2006 20:39:31 GMT  
 Server: Apache  
 Last-Modified: Sat, 16 Sep 2006 09:45:00 GMT  
 ETag: "4f6e2-3-fe8c1f00"  
 Accept-Ranges: bytes  
 Content-Length: 3  
 Connection: close  
 Content-Type: text/html  
   
 Certificate accepted  
   
 

За по-подробна информация, използвайте '-debug', '-msg' или '-state'. Ако се опитате да използвате анулиран или невалиден сертификат, следва да получите следните съобщения:


(httpd error_log)
[Sun Sep 24 17:31:01 2006] [error] Certificate Verification: Error (23): certificate revoked
[Sun Sep 24 17:31:01 2006] [error] Re-negotiation handshake failed: Not accepted by client!?
[Sun Sep 24 17:34:54 2006] [error] Certificate Verification: Error (20): unable to get local issuer certificate
[Sun Sep 24 17:37:41 2006] [error] Certificate Verification: Error (10): certificate has expired

(s_client)
>>> TLS 1.0 ChangeCipherSpec [length 0001]
01
>>> TLS 1.0 Handshake [length 0010], Finished
14 00 00 0c d7 82 fa 4c dc d9 31 7a 83 e5 2e ef
02 2c
2873:error:14094414:SSL routines:SSL3_READ_BYTES:sslv3 alert certificate revoked:s3_pkt.c:1057:SSL alert number 44
2873:error:140940E5:SSL routines:SSL3_READ_BYTES:ssl handshake failure:s3_pkt.c:994:


[ ЕКРАННИ СНИМКИ ]

accept cert dialogue


firefox cert mngr


browser



.: Приложение


Това решение може да се използва от всяка една организция, без значение дали става въпрос за Интранет или външни потребители, когато са необходими допълнителни методи на защита до даден ресурс. При правилна реализация има висока ефикасност. Самото администриране на локалното CA трябва да се извършва по адекватен начин. Възможно е и процесът да се автоматизира.



.: Връзки


[1] http://httpd.apache.org/docs/2.2/mod/mod_ssl.html
[2] http://www.openssl.org/docs/





<< Използване на IPSET, IPTABLES и IPMARK | Конфигуриране на мултимедийна клавиатура в Linux >>

Авторите на сайта, както и техните сътрудници запазват авторските права върху собствените си материали публикувани тук, но те са copyleft т.е. могат свободно да бъдат копирани и разпространявани с изискването изрично да се упоменава името на автора, както и да се публикува на видно място, че те са взети от оригиналния им URL-адрес на този сървър (http://www.linux-bg.org). Авторските права на преводните материали принадлежат на техните автори. Ако с публикуването тук на някакъв материал неволно са нарушени нечии права - след констатирането на този факт материалът ще бъде свален.

All trademarks, logos and copyrights mentioned on this site are the property of their respective owners.
Linux is copyright by Linus Torvalds.
© Линукс за българи ЕООД 2007
© Slavei Karadjov 1999 - 2006

All rights reserved.

Изпълнението отне: 0 wallclock secs ( 0.16 usr + 0.03 sys = 0.19 CPU)