LINUX-BG   Адрес : http://www.linux-bg.org
Ограничаване на достъпа чрез mod_ssl
От: Пейо Попов
Публикувана на: 9-09-2005
Адрес на статията: http://www.linux-bg.org/cgi-bin/y/index.pl?page=article&id=programs&key=375405388

Увод

Mod_SSL е интерфейс на apache httpd към openssl. Той може да се използва както за шифриране на комуникацията между уеб сървъра и клиента, удостоверяване на идентичността на сървъра, а така и за ограничение на достъпа до ресурсите, които предлага. В тази статия ще се опитам да представя основите на конфигуриране на тези ограничения по начин подобен на този, по който ще бъдат ползвани на новата машина на Linux-BG.

За подръжката на mod_ssl

mod_ssl е стандартна част от всички дистрибуции, които предлагат apache httpd. Особеност при Дебиан, е че пакетът се казва libapache-mod-ssl. В дистрибуцията съществува и пакет apache-ssl, който представлява отделен уеб сървър използващ проекта apache-ssl.org, който проект не се разработва от години и е изместен почти навсякъде от mod_ssl, който се зарежда като модул на основния уеб сървър.

Въпреки, че няма разлики във функционалността на mod_ssl в 1.3.x и 2.0.x клоновете има проблем, който прави невъзможно изпращането на POST заявки при определени изисквания за сертификатна автентикация. Този проблем е породен от различния начин, по който 2.0.x клона обработва POST заявките и е описан в този коментар. Съществува и пач, който решава този проблем и аз съм компилирал и стартирал httpd с него, но тъй като автор на пача е Joe Orton, който поддържа пакета httpd в RHEL и Fedora и той не го е включил в дистрибуцията, предполагам, че има причини за това и не го ползвам, а и не препоръчвам на вас да го ползвате. Ще спомена по-долу конфигурациите, които са приложими засега само за 1.3.x клона, а на тези, които ползват 2.0.x клона, им препоръчвам да следят changelog-а на httpd пакета на своята дистрибуция както и следните два доклада в системите за доклад на грешки на:

Това са проблеми специфични за apache httpd 2.0.x клона, а ние ползваме доказалата се за стабилна 1.3.х версия и затова можем да ползваме пълните възможности на модула.

Начална конфигурация

Започваме с генерирането на сертификат за уеб сървъра, подписването му от нашата CA и поставянето им в конфгурационните директории:

# openssl req -new -sha1 -keyout newkey.pem -out newreq.pem
# ./CA.pl -signreq
# mv newcert.pem /etc/apache/ssl.crt/server.crt
# mv newkey.pem /etc/apache/ssl.key/server.key
# cp Linux-BG-CA/cacert.pem /etc/apache/ssl.crt/cacert.crt

Горният пример ще създаде частен ключ, който ще бъде криптиран и ще се иска парола при зареждането му от уеб сървъра. Първоначално така го бяхме направили, но бързо ни мина и го декриптирахме. За да не бъде криптиран използвайте опцията -nodes.

Дебиан не включва никаква примерна конфигурация на модула и затова е нужно да си я създадем сами. Това е нетипично за другите дистрибуци и аз ви съветвам да погледнете съдържанието на пакета си, примерните конфигурационни файлове и коментарите в тях. За останалите дистрибуции ви съветвам да не се отклонявате от стойностите, с които е конфигурирана общата част на модула по подразбиране. Долните настройки са мое дело и са правени като съм търсел консервативните и работещи със сигурност стойности, но в действителност може и да са възможни по-добри решения.

Продължаваме с общата конфигурация на mod_ssl, за която създаваме файла /etc/apache/conf.d/mod_ssl.conf.
В него описваме общите настройки на модула, които ще се опитам да поясня кратки коментари:

<IfModule mod_ssl.c>
# На кой порт слуша. Стандартно 443ти
Listen 443

# Допълнители mime типове за сертификатите и за листата с отменените сертификати
AddType application/x-x509-ca-cert .crt
AddType application/x-pkcs7-crl .crl

SSLPassPhraseDialog builtin

# Не съм запознат със спецификите на Дебиан и затова взимам консервативно и работещо със сигурност решение:
SSLSessionCache dbm:/var/run/ssl_scache
# В RedHat работи така:
# SSLSessionCache shmcb:/var/cache/mod_ssl/scache(512000)

# 5 мин. трябва да са достатъчно. Това ще е нужно да го променяте само, ако сайта ви е специфичен и/или ви трябва много да оптимизирате.
SSLSessionCacheTimeout 300

# mutex-ите при нас работят така:
SSLMutex file:/var/run/ssl_mutex

# Източници на случайни числа
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
# Или може би ще ползваме:
#SSLRandomSeed startup file:/dev/urandom 512
#SSLRandomSeed connect file:/dev/urandom 512

# Журнали
SSLLog /var/log/apache/ssl_engine_log

# Ниво на детайл (възможни са: none, error, warn, info, trace, debug)
# След като се уверим, че работи вероятно ще минем на error само
SSLLogLevel warn

# Специално вниманите заслужават потребителите на любимия Internet Explorer:
SetEnvIf User-Agent “.*MSIE.*” nokeepalive ssl-unclean-shutdown downgrade-1.0 force-response-1.0

Конфигурационните директиви за заключени между <IfModule mod_ssl.c> и </IfModule>, за да не предизвикат грешки, ако модулът не е зареден.

Специфични настройки за виртуалния хост

Минаваме към специфичните настройки за виртуалния хост:

# Ако имаме повече от един виртуален ssl хост може да ползваме:
# Include /etc/apache/vhosts/*.vhost

<VirtualHost 212.50.10.155:443>

# Тия си ги знаете
ServerName linux-bg.org
ServerAlias www.linux-bg.org
DocumentRoot /home/path/

# Пуск машина
SSLEngine on

# Със стари версии на SSL протокола не се занимаваме:
SSLProtocol all -SSLv2
# Същото ще е и ако напишем долното, защото TLSv1 и SSLv3 са синоними
# SSLProtocol TLSv1

# Използвани шифри. Те може да се променят в &lt:Directory контейнери.
# Тук допускаме шифри, които се подържат от всеки скорошен браузър
SSLCipherSuite HIGH:MEDIUM

# Указваме къде се намират сертификата, ключа и сертификата на нашето CA
SSLCACertificateFile /etc/apache/ssl.crt/cacert.crt
SSLCertificateFile /etc/apache/ssl.crt/server.crt
SSLCertificateKeyFile /etc/apache/ssl.key/server.key

# Ако трябва да възстановявате верига на доверие ползваме долната директива. Друг начин е просто да конкатенираме сертификатите.
# SSLCertificateChainFile /etc/apache/ssl.crt/certchain.crt

# За директориите съдържащи много сертификати се ползва:
# openssl c_rehash /dir

# Листи с отменени сертификати. Тук се включват сертификати, които са компроментирани, загубени или просто сме ги издали, за да си играем с тях:
SSLCARevocationFile /etc/apache/ssl.crl/server.crl
# Лист на отменените сертификати се генерира чрез командата:
# openssl ca -gencrl -out /etc/apache/ssl.crl/server.crl

# Нямаме под-удостоверители —  всичко си го подписваме ние. Ако имахме SubCA ще трябваше да увеличим долната стойност с едно за всяко междинно звено:
SSLVerifyClient 1

# Ако са ни нужни променливи на обкръжението за cgi скриптовете ни:
#<Directory /home/path/cgi-bin&>
# SSLOptions +StdEnvVars
#</Directory>

# За да гледаме какво точно се случва може да наблюдаваме заявките, които нашия сървър получава:
CustomLog /var/log/apache/ssl_request_log \
“%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \”%r\” %b”

</VirtualHost>

Настройки за ограничаване на достъпа

Тези настройки също се правят в рамките на виртуалния хост, но тук ще са отделно, за да илюстрират някои от възможностите. За тях се изисква предоставянето на PKCS#12 сертификат от страна на потребителя. Как се създава той може да прочетете в статията за Postfix и TLS.

Отново поясненията ще бъдат като коментари:

# За общия случай нямаме никакво ограничение. Т.е. не поставяме никакви условия потребителя да ни представи сертификат, нито за полетата на този сертификат:
SSLVerifyClient none

# А защо не и да приемем сертификат, ако има такъв. Това не би се използвало на много места, но може да се укаже удачно решение за някои специфични случаи:
# SSLVerifyClient optional

# За наистина интересните места ние повишаваме изискванията:
<Location /secure>
# Сега вече повишаваме и изискванията като допускаме само 3 комбинации от шифри, защото всички имаме свястни браузъри. Това ще наложи предоговаряне на шифрите, ако по някаква причина е била избрана по-слаба комбинация.
SSLCipherSuite HIGH:-MD5:-ADH:-3DES

# С долната директива искаме да ни бъде представен подписан от нас валиден сертификат. Тази директива се комбинира с SSLVerifyClient 1 и това означава, че искаме този сертификат да е подписан от нас.
SSLVerifyClient require

# От тук надолу за httpd 2.0.x става трудно:
# Или пък може да го изискаме изрично, като укажем, че в полето за организация трябва да сме ние:
# SSLRequire %{SSL_CLIENT_S_DN_O} eq “Linux-BG”

# Също така е възможно и да дадем достъп и само на отделни подгрупи в нашата организация. Примерно администраторите на пощенския или уеб сървъра може да си достъпват контролните панели:
# SSLRequire %{SSL_CLIENT_S_DN_O} eq “Linux-BG” and \
# %{SSL_CLIENT_S_DN_OU} in {”Web Admin”, “Mail Admin”}

</Location>

# Възможността да проверяваме стойностите в сертификатните полета означава, че може и да създадем директории, които да са достъпни през уеб само от един единствен потребител
<Location /secure/peio>
SSLVerifyClient require
SSLRequire %{SSL_CLIENT_S_DN_CN} eq “Peio Popov”
</Location>

За да прегледаме сертификатните полета може да използваме командата:

openssl x509 -subject -noout -in cert.pem

Ако искаме да видим целия сертификат в текстови вид ползваме:

openssl x509 -text -noout -in cert.pem

Понякога може да ни се наложи да ограничим достъпа до някоя директория във виртуален хост, който е достъпен и по http. За да пренасоча всички заявки към https аз ползвам mod_rewrite:

RewriteEngine On
RewriteBase /dir
RewriteCond %{SERVER_PORT} ^80$
RewriteRule ^(.*)$ https://servername/dir/$1 [R,L]

Възможности на SSLRequire

Синтаксисът на SSLRequire директивата е изключително гъвкав и ни позволява да въвеждаме изключително разнообразни ограничения и съм сигурен, че всеки ще намери нужните средства, за да задоволят нуждите му. Нека само спомена, че освен всички параметри на сертификата разполагаме и със стандартните променливи на обкръжението (CGI 1.0) и apache и може да ги включваме и тях в изрази като викаме променливата под формата на %{ИмеНаПроменлива}.
Освен богатството от променливи ние имаме и възможностите на BNF нотацията да сравняваме реални и желани стойности (включително и възможност да създаваме функции), а освен това може и да посочваме файл, от който да четем.

Имайки предвид тези богати възможности горните примери са само начално въведение, за запознаване със синтаксиса им и аз не виждам смисъл да се опитвам да изброявам всичките им възможни приложения.

За четене
mod_ssl е изключително добре и достъпно документиран. Всеки, който се запознае с документацията му ще може да използва неговите пълни възможности. Все пак е добре и да погледнете спецификите и отворените проблеми свързани с пакетите в системата за следене на грешки на дистрибуцията ви.


<< Играй на думи | Postfix с TLS подръжка >>

Авторите на сайта, както и техните сътрудници запазват авторските права върху собствените си материали публикувани тук, но те са 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.

Изпълнението отне: 1 wallclock secs ( 0.16 usr + 0.02 sys = 0.18 CPU)