Распределенные системы. Паттерны проектирования - [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