Конфигурация#

Angie работает с текстовым конфигурационным файлом. Файл конфигурации angie.conf находится по пути conf-path, указанном при компиляции, по умолчанию в /etc/angie.

Файл конфигурации состоит из контекстов:

  • events – обработка соединений

  • http – трафик HTTP

  • mail – Mail трафик

  • stream – TCP и UDP трафик

Директивы, расположенные вне этих контекстов, считаются директивами контекста main.

user angie; # директива в контексте 'main'

events {
    # конфигурация обработки соединений
}

http {
    # Конфигурация трафика HTTP, для всех вложенных виртуальных серверов

    server {
        # конфигурация виртуального HTTP сервера 1
        location /one {
            # конфигурация обработки HTTP запросов с URI, начинающимися с '/one'
        }
        location /two {
            # конфигурация обработки HTTP запросов с URI, начинающимися с '/two'
        }
    }

    server {
        # конфигурация виртуального HTTP сервера 2
    }
}

stream {
    # Конфигурация трафика TCP/UDP, для всех вложенных виртуальных серверов
    server {
        # конфигурация виртуального TCP сервера 1
    }
}

Чтобы облегчить управление конфигурацией, рекомендуется использование директивы include в основном файле конфигурации angie.conf для включения в него специализированных файлов.

include /etc/angie/http.d/*.conf;
include /etc/angie/stream.d/*.conf;

Наследование#

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

Перезагрузка конфигурации#

При любом изменении конфигурации, для применения изменений процесс Angie необходимо либо перезапустить процесс полностью, предварительно проверив конфигурацию синтаксически:

$ sudo angie -t && sudo service angie restart

либо перезагрузить, что позволит не прерывать обработку текущих соединений.

$ sudo angie -t && sudo service angie reload

Единицы измерения#

Размеры в конфигурационном файле можно указывать в байтах, килобайтах (суффиксы k и K) или мегабайтах (суффиксы m и M), например, «1024», «8k», «1m».

Интервалы времени можно задавать в миллисекундах, секундах, минутах, часах, днях и т.д., используя следующие суффиксы:

ms

миллисекунды

s

секунды

m

минуты

h

часы

d

дни

w

недели

M

месяцы, 30 дней

y

годы, 365 дней

В одном значении можно комбинировать различные единицы, указывая их в порядке от более к менее значащим, и по желанию отделяя их пробелами. Например, «1h 30m» задает то же время, что и «90m» или «5400s». Значение без суффикса задает секунды. Рекомендуется всегда указывать суффикс.

Некоторые интервалы времени можно задать лишь с точностью до секунд.

Настройка хэшей#

Для быстрой обработки статических наборов данных, таких как имена серверов, значения директивы map, MIME-типы, имена полей заголовков запросов, Angie использует хэш-таблицы. Во время старта и при каждой переконфигурации Angie подбирает минимально возможный размер хэш-таблиц с учетом того, чтобы размер корзины, куда попадают ключи с совпадающими хэш-значениями, не превышал заданного параметра (hash bucket size). Размер таблицы считается в корзинах. Подбор ведется до тех пор, пока размер таблицы не превысит параметр hash max size. Для большинства хэшей есть директивы, которые позволяют менять эти параметры, например, для хэшей имен серверов директивы называются server_names_hash_max_size и server_names_hash_bucket_size.

Параметр hash bucket size всегда выравнивается до размера, кратного размеру строки кэша процессора. Это позволяет ускорить поиск ключа в хэше на современных процессорах, уменьшив число обращений к памяти. Если hash bucket size равен размеру одной строки кэша процессора, то во время поиска ключа число обращений к памяти в худшем случае будет равно двум — первый раз для определения адреса корзины, а второй — при поиске ключа внутри корзины. Соответственно, если Angie выдал сообщение о необходимости увеличить hash max size или hash bucket size, то сначала нужно увеличивать первый параметр.

Настройка HTTPS-серверов#

Чтобы настроить HTTPS-сервер, необходимо включить параметр ssl на слушающих сокетах в блоке server, а также указать местоположение файлов с сертификатом сервера и секретным ключом:

server {
    listen              443 ssl;
    server_name         www.example.com;
    ssl_certificate     www.example.com.crt;
    ssl_certificate_key www.example.com.key;
    ssl_protocols       TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
    ssl_ciphers         HIGH:!aNULL:!MD5;
#...
}

Сертификат сервера является публичным. Он посылается каждому клиенту, соединяющемуся с сервером. Секретный ключ следует хранить в файле с ограниченным доступом (права доступа должны позволять главному процессу Angie читать этот файл). Секретный ключ можно также хранить в одном файле с сертификатом:

ssl_certificate     www.example.com.cert;
ssl_certificate_key www.example.com.cert;

при этом права доступа к файлу следует также ограничить. Несмотря на то, что и сертификат, и ключ хранятся в одном файле, клиенту посылается только сертификат.

С помощью директив ssl_protocols и ssl_ciphers можно ограничить соединения использованием только «сильных» версий и шифров SSL/TLS. По умолчанию Angie использует:

ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;

поэтому их явная настройка в общем случае не требуется.

Оптимизация HTTPS-сервера#

SSL-операции потребляют дополнительные ресурсы процессора. На мультипроцессорных системах следует запускать несколько рабочих процессов, не меньше числа доступных процессорных ядер. Наиболее ресурсоемкой для процессора является операция SSL-рукопожатия, в рамках которой формируются криптографические параметры сессии. Существует два способа уменьшения числа этих операций, производимых для каждого клиента: использование постоянных (keepalive) соединений, позволяющих в рамках одного соединения обрабатывать сразу несколько запросов, и повторное использование параметров SSL-сессии для предотвращения необходимости выполнения SSL-рукопожатия для параллельных и последующих соединений. Сессии хранятся в кэше SSL-сессий, разделяемом между рабочими процессами и настраиваемом директивой ssl_session_cache. В 1 мегабайт кэша помещается около 4000 сессий. Таймаут кэша по умолчанию равен 5 минутам. Он может быть увеличен с помощью директивы ssl_session_timeout. Вот пример конфигурации, оптимизированной под многоядерную систему с 10-мегабайтным разделяемым кэшем сессий:

worker_processes auto;

http {
    ssl_session_cache   shared:SSL:10m;
    ssl_session_timeout 10m;

    server {
        listen              443 ssl;
        server_name         www.example.com;
        keepalive_timeout   70;

        ssl_certificate     www.example.com.crt;
        ssl_certificate_key www.example.com.key;
        ssl_protocols       TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
        ssl_ciphers         HIGH:!aNULL:!MD5;
    #...

Цепочки SSL-сертификатов#

Некоторые браузеры могут выдавать предупреждение о сертификате, подписанном общеизвестным центром сертификации, в то время как другие браузеры без проблем принимают этот же сертификат. Так происходит потому, что центр, выдавший сертификат, подписал его промежуточным сертификатом, которого нет в базе данных сертификатов общеизвестных доверенных центров сертификации, распространяемой вместе с браузером. В подобном случае центр сертификации предоставляет «связку» сертификатов, которую следует присоединить к сертификату сервера. Сертификат сервера следует разместить перед связкой сертификатов в скомбинированном файле:

$ cat www.example.com.crt bundle.crt > www.example.com.chained.crt

Полученный файл следует указать в директиве ssl_certificate:

server {
    listen              443 ssl;
    server_name         www.example.com;
    ssl_certificate     www.example.com.chained.crt;
    ssl_certificate_key www.example.com.key;
#...
}

Если сертификат сервера и связка сертификатов были соединены в неправильном порядке, Angie не запустится и выдаст сообщение об ошибке:

SSL_CTX_use_PrivateKey_file(» … /www.example.com.key») failed

(SSL: error:0B080074:x509 certificate routines: X509_check_private_key:key values mismatch)

поскольку Angie попытается использовать секретный ключ с первым сертификатом из связки вместо сертификата сервера.

Браузеры обычно сохраняют полученные промежуточные сертификаты, подписанные доверенными центрами сертификации, поэтому активно используемые браузеры уже могут иметь требуемые промежуточные сертификаты и не выдать предупреждение о сертификате, присланном без связанной с ним цепочки сертификатов. Убедиться в том, что сервер присылает полную цепочку сертификатов, можно при помощи утилиты командной строки openssl, например:

$ openssl s_client -connect www.godaddy.com:443

Certificate chain
 0 s:/C=US/ST=Arizona/L=Scottsdale/1.3.6.1.4.1.311.60.2.1.3=US
     /1.3.6.1.4.1.311.60.2.1.2=AZ/O=GoDaddy.com, Inc
     /OU=MIS Department/CN=www.GoDaddy.com
     /serialNumber=0796928-7/2.5.4.15=V1.0, Clause 5.(b)
   i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc.
     /OU=http://certificates.godaddy.com/repository
     /CN=Go Daddy Secure Certification Authority
     /serialNumber=07969287
 1 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc.
     /OU=http://certificates.godaddy.com/repository
     /CN=Go Daddy Secure Certification Authority
     /serialNumber=07969287
   i:/C=US/O=The Go Daddy Group, Inc.
     /OU=Go Daddy Class 2 Certification Authority
 2 s:/C=US/O=The Go Daddy Group, Inc.
     /OU=Go Daddy Class 2 Certification Authority
   i:/L=ValiCert Validation Network/O=ValiCert, Inc.
     /OU=ValiCert Class 2 Policy Validation Authority
     /CN=http://www.valicert.com//emailAddress=info@valicert.com

Совет

При тестировании конфигураций с SNI необходимо указывать опцию -servername, так как openssl по умолчанию не использует SNI.

В этом примере субъект («s») сертификата №0 сервера www.GoDaddy.com подписан издателем («i»), который в свою очередь является субъектом сертификата №1, подписанного издателем, который в свою очередь является субъектом сертификата №2, подписанного общеизвестным издателем ValiCert, Inc., чей сертификат хранится во встроенной в браузеры базе данных сертификатов.

Если связку сертификатов не добавили, будет показан только сертификат сервера №0.

Единый HTTP/HTTPS сервер#

Можно настроить единый сервер, который обслуживает как HTTP-, так и HTTPS-запросы:

server {
    listen              80;
    listen              443 ssl;
    server_name         www.example.com;
    ssl_certificate     www.example.com.crt;
    ssl_certificate_key www.example.com.key;
#...
}

Выбор HTTPS-сервера по имени#

Типичная проблема возникает при настройке двух и более серверов HTTPS, слушающих на одном и том же IP-адресе:

server {
    listen          443 ssl;
    server_name     www.example.com;
    ssl_certificate www.example.com.crt;
#...
}

server {
    listen          443 ssl;
    server_name     www.example.org;
    ssl_certificate www.example.org.crt;
#...
}

В такой конфигурации браузер получит сертификат сервера по умолчанию, т.е. www.example.com, независимо от запрашиваемого имени сервера. Это связано с поведением протокола SSL. SSL-соединение устанавливается до того, как браузер посылает HTTP-запрос, и Angie не знает имени запрашиваемого сервера. Следовательно, он лишь может предложить сертификат сервера по умолчанию.

Наиболее старым и надежным способом решения этой проблемы является назначение каждому HTTPS-серверу своего IP-адреса:

server {
    listen          192.168.1.1:443 ssl;
    server_name     www.example.com;
    ssl_certificate www.example.com.crt;
#...
}

server {
    listen          192.168.1.2:443 ssl;
    server_name     www.example.org;
    ssl_certificate www.example.org.crt;
#...
}

SSL-сертификат с несколькими именами#

Существуют и другие способы, которые позволяют использовать один и тот же IP-адрес сразу для нескольких HTTPS-серверов. Все они, однако, имеют свои недостатки. Одним из таких способов является использование сертификата с несколькими именами в поле SubjectAltName сертификата, например www.example.com и www.example.org. Однако, длина поля SubjectAltName ограничена.

Другим способом является использование wildcard-сертификата, например *.example.org. Такой сертификат защищает все поддомены указанного домена, но только на заданном уровне. Под такой сертификат подходит www.example.org, но не подходят example.org и www.sub.example.org. Два вышеуказанных способа можно комбинировать. Сертификат может одновременно содержать и точное, и wildcard имена в поле SubjectAltName, например example.org и *.example.org.

Лучше поместить сведения о файле сертификата с несколькими именами и файле с его секретным ключом на уровне конфигурации http, чтобы все серверы унаследовали их единственную копию в памяти:

ssl_certificate     common.crt;
ssl_certificate_key common.key;

server {
    listen          443 ssl;
    server_name     www.example.com;
#...
}

server {
    listen          443 ssl;
    server_name     www.example.org;
#...
}

Указание имени сервера#

Более общее решение для работы нескольких HTTPS-серверов на одном IP-адресе — расширение Server Name Indication протокола TLS (SNI, RFC 6066), которое позволяет браузеру передать запрашиваемое имя сервера во время SSL-рукопожатия, а значит сервер будет знать, какой сертификат ему следует использовать для соединения. Сейчас SNI поддерживается большинством современных браузеров, однако может не использоваться некоторыми старыми или специализированными клиентами.

Совет

В SNI можно передавать только доменные имена, однако некоторые браузеры могут ошибочно передавать IP-адрес сервера в качестве его имени, если в запросе указан IP-адрес. Полагаться на это не следует.

Чтобы использовать SNI в Angie, соответствующая поддержка должна присутствовать как в библиотеке OpenSSL, использованной при сборке бинарного файла Angie, так и в библиотеке, подгружаемой в момент работы. OpenSSL поддерживает SNI начиная с версии 0.9.8f, если она была собрана с опцией конфигурации ‑‑enable‑tlsext. Начиная с OpenSSL 0.9.8j эта опция включена по умолчанию. Если Angie был собран с поддержкой SNI, то при запуске Angie с ключом «-V» об этом сообщается:

$ angie -V
...
TLS SNI support enabled
...

Однако если Angie, собранный с поддержкой SNI, в процессе работы подгружает библиотеку OpenSSL, в которой нет поддержки SNI, Angie выдает предупреждение:

Angie was built with SNI support, however, now it is linked dynamically to an OpenSSL library which has no tlsext support, therefore SNI is not available