Распределенные системы. Паттерны проектирования - [25]

Шрифт
Интервал

Ограничение частоты запросов и защита от атак типа «отказ в обслуживании» (DoS) Некоторые специалисты проектируют сайты с учетом защиты  от  DoS-атак.  Все  больше  разработчиков  сегодня  проектируют  программные  интерфейсы.  В  связи  с  этим  отказ  в  обслужива-нии может произойти из-за того, что разработчик некорректно  настроил клиент, либо из-за того, что инженер, ответственный  за  доступность  сайта,  случайно  запустил  нагрузочные  тесты  96 Часть II. Паттерны проектирования обслуживающих систем на  рабочем  сервере.  Следовательно,  имеет  смысл  добавить  в  кэширующую  прослойку  защиту  от  отказа  в  обслуживании,  установив  ограничение  частоты  запросов.  Большинство  об-ратных  HTTP-прокси,  например  Varnish,  поддерживают  нечто  похожее.  В  частности,  у  Varnish  есть  модуль  throttle,  который  можно  настроить  так,  чтобы  он  ограничивал  частоту  запросов  с  определенным  путем  с  конкретных  IP-адресов,  в  том  числе  для анонимных или зарегистрированных пользователей. Если  вы  развертываете  API,  целесообразно  иметь  достаточно  низкий  лимит  запросов  для  анонимных  пользователей,  кото-рый можно повысить после регистрации. Требуя авторизации,  мы  сможем  проводить  аудит,  чтобы  определить,  чьи  действия  привели к неожиданно высокой нагрузке. Ограничение частоты  запросов  также  служит  барьером  для  потенциальных  взлом-щиков, которым понадобится замаскироваться под нескольких  пользователей, чтобы успешно реализовать атаку. Когда  количество  запросов  от  одного  пользователя  достигает  определенного лимита, сервер вернет ему ошибку с кодом 429,  означающую превышение количества максимально допустимых  запросов.  Многим  пользователям  нужно  будет  знать,  сколько  еще  они  могут  сделать  запросов,  прежде  чем  достигнут  лими-та.  В  связи  с  этим  вам  может  понадобиться  добавить  в  HTTP-заголовок  информацию  о  количестве  оставшихся  запросов.  Для  подобной  информации  нет  стандартного  поля  в  HTTP-заголовке,  однако  многие  API  возвращают  одну  из  разновид-ностей поля  X-RateLimit-Remaining .

SSL-мост

Вдобавок к кэшированию с целью повышения производитель-ности пограничный слой приложения также может выполнять  функции  SSL-моста.  Даже  если  вы  планируете  использовать  SSL  для  взаимодействия между  внутренними  слоями  прило-

Глава 5. Реплицированные сервисы с распределением нагрузки 97 жения, вам все равно придется применять разные сертификаты  для внешнего слоя и для взаимодействия внутренних сервисов.  В самом деле, каждый внутренний сервис должен использовать  свой  собственный  сертификат,  чтобы  можно  было  обеспечить  независимое развертывание слоев. 

К сожалению, Varnish нельзя применять для организации SSL-моста,  но  nginx  имеет  такую  функциональность.  Стало  быть,  в паттерне stateless-приложения нужен третий слой — он будет  представлять  собой  реплицированный  набор  nginx-серверов,  который обеспечит функцию SSL-моста для HTTPS-трафика  и передаст его в расшифрованном виде кэширующему серверу  Varnish.  HTTP-трафик  попадет  в  веб-кэш  Varnish,  который  переадресует его веб-приложению (рис. 5.8).

Рис. 5.8. Пример реплицированного stateless-сервиса 98 Часть II. Паттерны проектирования обслуживающих систем Практикум. Развертывание nginx и SSL-моста Следующая инструкция описывает, как добавить SSL-мост на ос-нове nginx к уже развернутому реплицированному сервису и кэшу.

пользоваться инструментом openssl. Данная инструкция

подразумевает, что файл сертификата носит имя server.crt, а файл секретного ключа — server.key. Самоподписанные сертификаты вызывают предупреждения безопасности во всех современных браузерах и никогда не должны ис-

Первый шаг — загрузить сертификат в Kubernetes: kubectl create secret tls ssl --cert=server.crt --key=server.key После загрузки сертификата в Kubernetes необходимо создать  и настроить nginx для поддержки SSL:

events {

worker_connections 1024;

}

http {

server {

listen 443 ssl;

server_name my-domain.com www.my-domain.com; ssl on;

ssl_certificate /etc/certs/tls.crt;

ssl_certificate_key /etc/certs/tls.key; location / {

proxy_pass http://varnish-service:80; proxy_set_header Host $host;

proxy_set_header X-Forwarded-For

$proxy_add_x_forwarded_for;

Глава 5. Реплицированные сервисы с распределением нагрузки 99 proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; }

}

}

Как и в случае с Varnish, нужно преобразовать файл конфигу-рации в объект  ConfigMap  такой командой: kubectl create configmap nginx-conf --from-file=nginx.conf После загрузки сертификата и настройки nginx пришло вре-мя  создать  прослойку  реплицированных stateless-серверов  nginx:

apiVersion: extensions/v1beta1

kind: Deployment

metadata:

name: nginx-ssl

spec:

replicas: 4

template:

metadata:

labels:

app: nginx-ssl

spec:

containers:

- name: nginx

image: nginx

ports:

- containerPort: 443