от Пейо Попов(9-09-2005)

рейтинг (25)   [ добре ]  [ зле ]

Printer Friendly Вариант за отпечатване

Увод

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 подръжка >>