Lighttpd+SSL с функцией проверки клиентского сертификата.

Документация связанная с установкой, настройкой и работой пользовательского ПО
Ответить
Аватара пользователя
Raven
Бородатый сис
Бородатый сис
Сообщения: 2800
Зарегистрирован: 03 мар 2010, 15:12
ОС: RHEL 8
Откуда: Из серверной

Lighttpd+SSL с функцией проверки клиентского сертификата.

Сообщение Raven » 26 авг 2010, 13:20

Я очень люблю web-сервер lighttpd - шустрый, наглый, конфигурабельный (не то что nginx) и самое главное - в отличие от Apache его проживание в системе практически незаметно (не зря же именно на нем живет http://www.youtube.com). Но вот толковой документации (тем более русскоязычной) в сети по нему найти практически не возможно. А недавно начальство меня озадачило - нужно было поднять сервер в локальной сети с копией нашего сайта. Самая большая загвоздка заключалась в том, что на сайте используется проверка клиентских сертификатов, чего я в лайти раньше ненаблюдал, но нутром чувствовал, что есть такая возможность.

Итак, комп с установленной FreeBSD 7.3 у меня имелся, лайти там уже был настроен на отдачу статистики по траффу (комп используется еще и в качестве шлюха). Но поскольку настроен он был еще при Царе Горохе, я решил его заодно и немного подновить.

Обновляем порты, ставим проги

Редактируем /etc/supfile, приводим его к следующему виду:

Код: Выделить всё

*default tag=.
*default host=cvsup.elcat.kg
*default prefix=/usr
*default base=/var/db
*default release=cvs delete use-rel-suffix compress

ports-all release=cvs
Сохраняем, и обновляем порты:

Код: Выделить всё

# cvsup -L 2 /etc/supfile
После успешного (надеюсь) обновления портов, нам необходимо будет обновить веб-сервер. Идем в /usr/ports/www/lighttpd и даем команду

Код: Выделить всё

# make deinstall install clean
кстати, сразу хотелось бы предупредить, что в последних портах lighttpd сменился путь файла конфига - теперь он лежит не в /usr/local/etc, а в /usr/local/etc/lighttpd, и конфиг теперь модульный, но если у вас есть готовый старый конфиг - смело бекаптьте его до обновления, а после скопируйте в /usr/local/etc/lighttpd - работать будет. :)
Итак, лайти мы обновили, теперь пришла очередь пыха. Лезем в /usr/local/lib/php/20060613 и грохаем (предварительно забэкапив) все что там увидим. Идем в /usr/ports/lang/php52 и выполняем там ту же нехитрую команду

Код: Выделить всё

# make deinstall install clean
после чего должен выскочить диалог конфигуратора, который мы приводим примерно к следующему виду:

Изображение
Обязательно установите "крыжики" напротив значений CGI, FastCGI, FPM. Зачем? Чуть позже будет ясно. *JONKLY*

После пересборки идем в /usr/ports/lang/php5-extensions и повторяем команду make. На вопросы конфигуратора отвечаем исходя из нужд своего сервера. Чтож, пока собирается можно сходить за пЫвом.

Для того чтобы еще немножко ускорить работу пыха ставим eaccelerator

Код: Выделить всё

# cd /usr/ports/www/eaccelerator
# make deinstall install clean
Конфигурим php

После установки нужно тщательно проверить конфиг php (обычно это /usr/local/etc/php.ini) на правильность и безошибочность. Что? У вас нету конфига? Не беда, создадим его

Код: Выделить всё

# cp /usr/local/etc/php.ini-dist /usr/local/etc/php.ini
Дописываем в конец файла конфиг eaccelerator'а

Код: Выделить всё

[eAccelerator]
eaccelerator.shm_size="64" 
eaccelerator.cache_dir="/tmp/eaccelerator" 
eaccelerator.enable="1" 
eaccelerator.optimizer="1" 
eaccelerator.check_mtime="1"
eaccelerator.debug="0" 
eaccelerator.filter="" 
eaccelerator.shm_max="1M"
eaccelerator.shm_ttl="3600"
eaccelerator.shm_prune_period="0" 
eaccelerator.shm_only="0" 
eaccelerator.compress="1" 
eaccelerator.compress_level="9"
Затем проверяем существует ли папка /tmp/eaccelerator (если нет естественно надо создать) и права на нее, которые должны принадлежать пользователю www из группы www.

Лезем в /usr/local/etc/php/ и проверяем файл extensions.ini - инсталяшки любят прописывать модули по нескольку раз или вообже приводят последнюю строку к такому виду:

Код: Выделить всё

extension=mysql.soextension=eaccelerator.so
Исправляем несоответствия, если таковые имеются.

Теперь надо настроить php-fpm, конфиг его значится как /usr/local/etc/php-fpm.conf. Исправлять в нем особо нечего, все в принципе достаточно грамотно настроено по умолчанию. Проверим пользователя

Код: Выделить всё

                        Unix user of processes
                        <value name="user">www</value>

                        Unix group of processes
                        <value name="group">www</value>
Кому-то из вас может не понравиться порт, слушаемый им, его тоже можно изменить

Код: Выделить всё

                        Address to accept fastcgi requests on.
                        Valid syntax is 'ip.ad.re.ss:port' or just 'port' or '/path/to/unix/socket'
                        <value name="listen_address">127.0.0.1:9000</value>
И я у себя попросил его писать в лог

Код: Выделить всё

                Error log file
                <value name="error_log">/var/log/php-fpm/php-fpm.log</value>

                Log level
                <value name="log_level">notice</value>
На этом с пыхом вроде все.

Настраиваем лайти

Предположим что у нас нет ни конфига, ни сертификатов. В такой ситуации я предпочитаю начинать все с чистого листа.

Код: Выделить всё

server.document-root = "/usr/local/www" #Корневая директория вашего веб-сервера
server.port = 80 # Порт слушаемый для http
server.username = "www" # Имя пользователя, от имени которого запускается сервер
server.groupname = "www" # Группа пользователя
server.bind  = "192.168.0.10" # Привязываем сервер к определенному адресу
server.tag ="lighttpd 1.4.27/FreeBSD 7.3" # Тут можно написать хоть "IIS/Win32" - это будет отображаться в строке идентификации сервера
server.event-handler = "freebsd-kqueue" # Метод разбивки на пуллы (!) Подходит только для FreeBSD, для других ОС методы свои

#Говорим куда писать логи
server.errorlog            = "/var/log/lighttpd/error.log" 
accesslog.filename         = "/var/log/lighttpd/access.log"

# Подключаем модули
server.modules              = (
            "mod_access",
            "mod_accesslog",
            "mod_fastcgi",
            "mod_cgi",
            "mod_rewrite",
            "mod_auth",
            "mod_compress",
            "mod_alias"
)


# Расписываем типы файлов
mimetype.assign             = (
  ".pdf"          =>      "application/pdf",
  ".sig"          =>      "application/pgp-signature",
  ".spl"          =>      "application/futuresplash",
  ".class"        =>      "application/octet-stream",
  ".ps"           =>      "application/postscript",
  ".torrent"      =>      "application/x-bittorrent",
  ".dvi"          =>      "application/x-dvi",
  ".gz"           =>      "application/x-gzip",
  ".pac"          =>      "application/x-ns-proxy-autoconfig",
  ".swf"          =>      "application/x-shockwave-flash",
  ".tar.gz"       =>      "application/x-tgz",
  ".tgz"          =>      "application/x-tgz",
  ".tar"          =>      "application/x-tar",
  ".zip"          =>      "application/zip",
  ".mp3"          =>      "audio/mpeg",
  ".m3u"          =>      "audio/x-mpegurl",
  ".wma"          =>      "audio/x-ms-wma",
  ".wax"          =>      "audio/x-ms-wax",
  ".ogg"          =>      "audio/x-wav",
  ".wav"          =>      "audio/x-wav",
  ".gif"          =>      "image/gif",
  ".jpg"          =>      "image/jpeg",
  ".jpeg"         =>      "image/jpeg",
  ".png"          =>      "image/png",
  ".xbm"          =>      "image/x-xbitmap",
  ".xpm"          =>      "image/x-xpixmap",
  ".xwd"          =>      "image/x-xwindowdump",
  ".css"          =>      "text/css",
  ".html"         =>      "text/html",
  ".htm"          =>      "text/html",
  ".js"           =>      "text/javascript",
  ".asc"          =>      "text/plain",
  ".c"            =>      "text/plain",
  ".conf"         =>      "text/plain",
  ".text"         =>      "text/plain",
  ".txt"          =>      "text/plain",
  ".dtd"          =>      "text/xml",
  ".xml"          =>      "text/xml",
  ".mpeg"         =>      "video/mpeg",
  ".mpg"          =>      "video/mpeg",
  ".mov"          =>      "video/quicktime",
  ".qt"           =>      "video/quicktime",
  ".avi"          =>      "video/x-msvideo",
  ".asf"          =>      "video/x-ms-asf",
  ".asx"          =>      "video/x-ms-asf",
  ".wmv"          =>      "video/x-ms-wmv",
  ".bz2"          =>      "application/x-bzip",
  ".tbz"          =>      "application/x-bzip-compressed-tar",
  ".tar.bz2"      =>      "application/x-bzip-compressed-tar" 
 )

# Делаем возможной http-авторизацию. Заморачиваться с шифрованием не стал - ктож меня будет из локалки-то ломать?
auth.debug = 2
auth.backend = "plain"
auth.backend.plain.userfile = "/usr/local/etc/lighttpd/.lighttpdpassword" # Файл с паролями

# Запускаем  FastCGI посредством php-fpm
fastcgi.server = ( ".php" =>
  ((
              "host" => "127.0.0.1",
                 "port" => 9000,
      )
    )
 )

#Подключаем модуль CGI для запуска перлов
cgi.assign                 = ( ".pl"  => "/usr/bin/perl",
                               ".cgi" => "/usr/bin/perl" )

# Определяем индексы
index-file.names = ( "index.html", "index.php", "index.pl", "index.cgi" )

# А вот теперь самое интересное - виртуалхосты
#Первый хост я использую для netams, который у меня использует базу данных на PostgreSQL, которая в свою очередь управляется через веб-морду phpPgAdmin
$HTTP["host"] =~ "(^|\.)stat\.svyaznoy\.kg$" {
server.document-root = "/usr/local/www/netams"
dir-listing.activate = "disable" # показывать-ли содержимое папки? Нет.
dir-listing.encoding = "utf-8" # Кодировка отображения содержимого папки
alias.url = ( "/pgadmin" => "/usr/local/www/phpPgAdmin") # Алиас для phpPgAdmin
server.errorlog = "/var/log/lighttpd/stat.error.log" # Куда же без логов  :) 
accesslog.filename = "/var/log/lighttpd/stat.access.log" 
server.error-handler-404 = "/e404.php" # Страница ошибки
# Для доступа к определенным папкам используется http-авторизация. Тут и расписываем что куда.
auth.require = ( "/cgi-bin/admin/" => 
(
"method" => "basic",
"realm" => "Password protected area",
"require" => "user=admin"
)
)
# Поскольку netams складывает свою перловую кашу с граблями в поддиректории, появилась необходимость расписать что куда.
$HTTP["url"] =~ "/cgi-bin/" {
      cgi.assign = ( ".pl" => "/usr/local/bin/perl",
      ".cgi" => "/usr/bin/perl" )
  }
$HTTP["url"] =~ "/cgi-bin/admin/" {
        cgi.assign = ( ".pl" => "/usr/bin/perl",
              ".cgi" => "/usr/bin/perl" )
                }
}

# А теперь собственно то, ради чего все и затевалось - SSL

$HTTP["host"] =~ "(^|\.)gate\.svyaznoy\.kg$" {
server.document-root = "/usr/local/www/test"
dir-listing.activate = "enable"
dir-listing.encoding = "utf-8"
server.errorlog = "/var/log/lighttpd/gate.error.log"
accesslog.filename = "/var/log/lighttpd/gate.access.log"
server.error-handler-404 = "/e404.php"
}

# При работе с SSL лайти не понимает имен сервера, так что придется использовать непосредственно IP-адресацию
$SERVER["socket"] == "192.168.0.10:443" {
  ssl.engine                  = "enable" # Включаем SSL
  ssl.ca-file                   = "/usr/local/etc/lighttpd/ca.crt" # Путь к кормевому сертификату (если у вас его нет можно просто исключить эту строчку)
  ssl.pemfile                   = "/usr/local/etc/lighttpd/ca.pem" # Путь к сертификату сервера
  server.name                 = "gate.svyaznoy.kg" # Описываем имя сервера
  server.document-root        = "/usr/local/www/secure/" # Папка, содержимое которой нам и надо защитить 
  ssl.verifyclient.activate  = "enable" # Включаем проверку клиентского сертификата. Если эту и 2 последующие строки исключить, сервер не будет запрашивать проверку, а будет прописывать в браузер временную копию сертификата
  ssl.verifyclient.enforce   = "enable"
  ssl.verifyclient.depth     = "1"
# Алиас для phpMyAdmin
  alias.url = ( "/pma" => "/usr/local/www/secure/phpMyAdmin")
}
Создаем сертификаты
Отходя от этой точки будем считать, что openssl у вас как и у меня уже установлен (еще одной переустановки на сегодня я не выдержу :))

В принципе если вам не нужна проверка сертификатов, а просто необходимо шифрование можно не заморачиваться и просто создать .pem-файл простой командой

Код: Выделить всё

openssl req -new -x509 -keyout ca.pem -out ca.pem -days 365 -nodes
Но мне нужна была проверка. Оговорюсь сразу - файы закрытого ключа и серверного сертификата у меня имелись, но для чистоты эксперимента обьясню как их создать.

Создаем каталог ssl и начинаем в нем шаманить

Код: Выделить всё

# mkdir /usr/local/etc/lighttpd/ssl
# cd /usr/local/etc/lighttpd/ssl
# touch index.txt
# echo "01" > serial
# touch ca.cfg
Редактируем файл ca.cfg до подобного содержания

Код: Выделить всё

[ ca ]
default_ca = CA_CLIENT
[ CA_CLIENT ]
dir                            =   /usr/local/etc/lighttpd/ssl
certs                          =   $dir
new_certs_dir                  =   $dir
database                       =   $dir/index.txt
serial                         =   $dir/serial
certificate                    =   $dir/са.crt
private_key                    =   $dir/са.key
default_days                   =   3650
default_crl_days               =   3
default_md                     =   md5
policy                         =   policy_anything
[ policy_anything ]
countryName                    = optional
stateOrProvinceName            = optional
localityName             =   optional
organizationName         =   optional
organizationalUnitName   =   optional
commonName               =   supplied
emailAddress             =   optional
Cоздаем сертификат для сервера. В процессе спросит свойства ключа, заполнять по желанию. Единственное замечание - в поле common name желательно прописать имя вашего домена.

Код: Выделить всё

# openssl req -newkey rsa:2048 -nodes -keyout ca.key -x509 -days 3650 -out ca.crt

Generating a 2048 bit RSA private key
.................+++
.+++
writing new private key to 'ca.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:KG
State or Province Name (full name) [Some-State]:Kyrgyzstan
Locality Name (eg, city) []:Bishkek
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Svyaznoy
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:gate.svyaznoy.kg
Email Address []:
Создаем pem-файл для сервера.

Код: Выделить всё

cat ca.key ca.crt > ca.pem
Создаем клиентский сертификат. В процессе аналогично интересуются про страну, имя и т.д.

Код: Выделить всё

openssl req -new -newkey rsa:2048 -nodes -keyout user.key -out user.csr
На вопросы

Код: Выделить всё

A challenge password []:
An optional company name []:
просто нажимаем Enter.

Подписываем и конвертируем клиентский сертификат. Вместо 12345 в нижеследующем коде пишем пароль для защиты сертификата, который у вас запросят при импортировании сертификата в браузер.

Код: Выделить всё

openssl ca -config ca.cfg -in user.csr -out user.crt -batch
openssl pkcs12 -export -in user.crt -inkey user.key -certfile ca.crt -out user.pfx -passout pass:12345
В результате получаем файл user.pfx, который в последствии установим на клиентскую машину. Файлы ca.crt, ca.pem и ca.key копируем в указанный в lighttpd.conf каталог.

Добиваем хвосты.
Создаем файл паролей

Код: Выделить всё

# touch /usr/local/etc/lighttpd/.lighttpdpassword
# echo "admin:вашсуперпуперпароль" > /usr/local/etc/lighttpd/.lighttpdpassword
Дописываем в /etc/rc.conf все, что необходимо

Код: Выделить всё

php_fpm_enable="YES"
php_fpm_config="/usr/local/etc/php-fpm.conf"
lighttpd_enable="YES"
Ну и стартуем:

Код: Выделить всё

# /usr/local/etc/rc.d/php-fpm start
# /usr/local/etc/rc.d/lighttpd start
Автор: Raven
При копировании статьи ссылка на http://sysadmins.el.kg обязательна.
Я не злопамятный, я просто часто ковыряю логи
Аватара пользователя
Gen1us2k
Модератор
Модератор
Сообщения: 771
Зарегистрирован: 02 мар 2010, 16:13

Re: Lighttpd+SSL с функцией проверки клиентского сертификата

Сообщение Gen1us2k » 26 авг 2010, 14:24

tnx. поковыряю на досуге. мож перейду
Изображение
Home: Windows Heaven
Home: Debian 6
For Servers: Debian || RHEL Based || Gentoo || FreeBSD
Аватара пользователя
Gen1us2k
Модератор
Модератор
Сообщения: 771
Зарегистрирован: 02 мар 2010, 16:13

Re: Lighttpd+SSL с функцией проверки клиентского сертификата

Сообщение Gen1us2k » 05 дек 2010, 17:47

начал ставить, так же как и автор на фре.
ЗЫ php-frm_enable="YES"
lighttpd_enable="YES"
чтобы стартовал при загрузке?
Изображение
Home: Windows Heaven
Home: Debian 6
For Servers: Debian || RHEL Based || Gentoo || FreeBSD
Аватара пользователя
Raven
Бородатый сис
Бородатый сис
Сообщения: 2800
Зарегистрирован: 03 мар 2010, 15:12
ОС: RHEL 8
Откуда: Из серверной

Re: Lighttpd+SSL с функцией проверки клиентского сертификата

Сообщение Raven » 06 дек 2010, 09:22

Gen1us2k
да
Я не злопамятный, я просто часто ковыряю логи
Аватара пользователя
Gen1us2k
Модератор
Модератор
Сообщения: 771
Зарегистрирован: 02 мар 2010, 16:13

Re: Lighttpd+SSL с функцией проверки клиентского сертификата

Сообщение Gen1us2k » 06 дек 2010, 12:37

спасибо, поставил )
правда с десятой попытки..
ИМХО система портов во фре самая плохая. в генте она по удобнее...
ЗЫ осталось добавить все виртуалхосты
Изображение
Home: Windows Heaven
Home: Debian 6
For Servers: Debian || RHEL Based || Gentoo || FreeBSD
Аватара пользователя
Raven
Бородатый сис
Бородатый сис
Сообщения: 2800
Зарегистрирован: 03 мар 2010, 15:12
ОС: RHEL 8
Откуда: Из серверной

Re: Lighttpd+SSL с функцией проверки клиентского сертификата

Сообщение Raven » 06 дек 2010, 12:51

Raven писал(а):$HTTP["host"] =~ "(^|\.)gate\.svyaznoy\.kg$" {server.document-root = "/usr/local/www/test"dir-listing.activate = "enable"dir-listing.encoding = "utf-8"server.errorlog = "/var/log/lighttpd/gate.error.log"accesslog.filename = "/var/log/lighttpd/gate.access.log"server.error-handler-404 = "/e404.php"}
Копируй и переписывай под свои нужды
Я не злопамятный, я просто часто ковыряю логи
Ответить

Вернуться в «Документация *nix»