Перейти к основному содержимому

Кэширование статики веб-сайтов

Услуга - CDN для сайтов

CDN для сайта решает следующие проблемы:

  • снижение нагрузки на origin-сервер, который обслуживает сайт
  • увеличение скорости загрузки статического контента: картинки, видео, скрипты, шрифты, стили и т.д.
  • размытие DDoS атак за счет большого кол-ва серверов
  • защита от атак на приложение: инъекции, XSS и т.д.
  • автоматический выпуск и продление SSL/TLS сертификата
  • автоматическое масштабирование при увеличении нагрузки на сайт

Доступно два варианта подключения CDN для сайта(домена):

  • через делегирование домена
  • через создание CNAME-записи для домена

Домены

Для кэширования статических файлов сайтов в системе создаются и настраиваются объекты domain (домены). Они делятся по типам.

Типы доменов

  • delegated
  • cname

Подключение через делегирование

Для включения CDN для домена через делегирование потребуются доменное имя сайта и от одного до двух его IP-адресов.
После подключения услуги все статические данные будут выгружаться через ближайшие к конечному клиенту серверы CDN.

Плюсы:

  • после включения статика грузится через CDN
  • не нужны дополнительные действия

Минусы:

  • необходимость делегации домена на указанного DNS-провайдера

Подключение через CNAME

Для включения CDN для домена через CNAME потребуется только доменное имя.
После подключения услуги будет выдано специальное доменное имя, при обращении к которому все статические данные будут выгружаться через ближайшие к конечному клиенту серверы CDN. При обращении по основному доменному имени сайта статика не кэшируется. Чтобы использовать собственное доменное имя для раздачи статики, необходимо загрузить SSL/TLS сертификат для этого домена. После загрузки сертификата создать CNAME запись в Вашем DNS, где имя записи - требуемое доменное имя для раздачи статики через CDN, а контент записи - сгенерированное системой и выданное при создании специальное доменное имя.

Плюсы:

  • не требуется делегация домена
  • есть возможность создать специальный домен (CNAME для выданного при подключении) для статических данных. Например, example.com - основной домен, cdn.example.com - домен для статики

Минусы:

  • после включения необходимы доработки сайта для корректного обращения за статическими данными через CNAME

TLS/SSL сертификаты

Для любого типа домена можно выпустить бесплатный сертификат от Let's Encrypt.
Данный сертификат будет обновляться автоматически каждые 60 дней. Также есть возможность загружать собственный сертификат, но обновлять его придется вручную.

Защита сайта при помощи WAF

Web application firewall - защита на уровне приложения. WAF расположен между сайтом и его пользователями. Файервол анализирует запросы от пользователей ("хороших" и "плохих"), отправляемых на сайт, и отсеивает "плохие". Таким образом, запросы от ботов, хакеров, спамеров и т.п. не попадают на атакуемый сайт и не нагружают/ломают его.

WAF для работы использует набор основных правил OWASP Core Rule Set (CRS). Для подробного ознакомления с правилами перейдите по ссылке.

Объект waf подключаются к домену как второстепенный: domain.waf

Режимы работы

У WAF есть три режима: защита выключена, защита включена, включено только обнаружение и логирование аномальных (опасных) запросов.

Принцип работы

Для работы WAF используется набор правил OWASP Core Rule Set. Каждое правило имеет оценку аномалии (Anomaly Scoring) - уровень потенциальной опасности запроса, и его тип. Например, оценка - 5, тип - CRITICAL.

Соотношение типов аномалий и их значений по умолчанию:

  • CRITICAL - 5
  • ERROR - 4
  • WARNING - 3
  • NOTICE - 2

Входящий на сайт запрос и исходящий ответ проходят проверку цепочкой правил по различным видам атак, и, если правило "совпадает", то оценка аномалий суммируется с предыдущим значением. Суммарная оценка аномалий считается отдельно для запроса и ответа. После превышения входящего или исходящего порога суммарной оценки аномалий запрос блокируется. По умолчанию входящий и исходящий пороги суммарной оценки равны 5.

Уровень паранойи

Уровень паранойи позволяет определить агрессивность набора правил, используемых для проверки запросов и ответов сайта. Для настройки доступно два уровня паранойи: исполнительный и блокирующий. По умолчанию оба уровня равны 1. Исполнительный уровень паранойи выполняет проверку запроса, но, в отличие от блокирующего уровня, никогда не блокирует его, а только фиксирует срабатывание в логах.
На высоких уровнях паранойи возможны ложные срабатывания, из-за которых валидные запросы могут быть отброшены. Для обработки ложных блокировок необходима настройка индивидуальных исключений из правил. Для создания исключений обратитесь в группу поддержки для включения кастомного режима.

Уровень паранойи 1

Базовый уровень безопасности с минимальной возможностью ложных срабатываний. Это уровень подходит для всех, кто использует HTTP-сервер в Интернете.

Уровень паранойи 2

Уровень для работы с реальными пользовательскими данными. Например, интернет-магазин. На данном этапе возможны ложные срабатывания.

Уровень паранойи 3

Безопасность онлайн-банкинга на высоком уровне с большим количеством ложных срабатываний. На данном уровне ложных срабатываний не избежать.

Уровень паранойи 4

Самый высокий уровень безопасности (параноидальный). Будьте готовы к большому количеству ложных срабатываний.

Стратегия использования уровня паранойи для действующего сайта:

  1. использовать значение 1 как для исполнительного, так и для блокирующего уровней
  2. убедиться в отсутствии ложных срабатываний
  3. повысить испонительный уровень паранойи
  4. при наличии ложных срабатываний устранить их путем введения исключений
  5. повысить блокирующий уровень паранойи до исполнительного

Выборочный режим

Для плавного введения WAF в действующую инфраструктуру рекомендуется использовать выборочный режим (Sampling Mode). Максимальное значение параметра 100, минимальное - 1. Значение по умолчанию - 100. Данный параметр указывает на процент обрабатываемых запросов правилами CRS. Таким образом, чем выше значение параметра, тем болшее количество запросов от общего числа проходит проверку.

Использование режима выборки означает, что CRS обеспечивает относительно низкую безопасность, если процент выборки установлен на низком уровне. Идея состоит в том, чтобы со временем увеличить этот процент с 1% до 2%, до 5%, 10%, 20%, 50%, и, в конечном счете, до 100%, когда правила будут применяться ко всему трафику.

Логирование запросов

При срабатывании защиты сайта от вредоносного запроса в системе сохраняется запись события. Каждая запись содержит параметры данного запроса (request, response), правила, по которым запрос был отброшен, текстовое описание угрозы и прочие второстепенные поля.

Просмотр логов доступен по специальному API-методу.

Locations

locations - это второстепенные объекты, подключаемые к доменам. Они нужны для возможности разделения логики при обращении к сайту по разным путям. Например:

  • https://example.com/cahced-location - при обращении по данному url кэшировать данные в браузере
  • https://example.com/no-cahced-location - при обращении по данному url запретить кэшировать данные в браузере

В указанных примерах locations - это /cahced-location и /no-cahced-location.

Для каждого объекта location можно указывать набор HTTP-заголовков, которые управляют обработкой запросов и ответов.

headers — заголовки ответа, которые CDN добавляет к выдаче для конечных пользователей. Они помогают управлять кэшированием (например, Cache-Control), включать дополнительные механизмы безопасности (X-Frame-Options, Content-Security-Policy) или передавать диагностическую информацию.

request_headers — заголовки, которые CDN проксирует на origin при обращении к исходному серверу. Их используют для передачи дополнительных атрибутов маршрутизации, A/B-тестирования или иных метаданных, необходимых backend-системам клиента.

CORS заголовки (cors_headers) настраиваются отдельно. Имена и количество CORS-заголовков предопределены. Подробнее про CORS.

Управление кэшем

Для каждого домена доступны методы очистки и повторного наполнения кэша. Данные методы используются при фактической замене существующих статических файлов сайта без изменения пути к ним. При очистке кэша статика удаляется и наполняется при последующих первых запросах от пользователей сайта. При повторном наполнении кэш серверов удаляется и наполняется заново автоматически. Возможна частичная очистка кеша только для объектов, путь к которым соответствуют указанным паттернам. Очистку и наполнение кэша допускается вызывать не чаще, чем один раз в 30 минут.

Ограничение доступа

Для доменов доступна функция ограничения доступа из определенных стран.

Подписанные ссылки

Подписанные ссылки — это временные уникальные ссылки, позволяющие получить доступ к объектам на сайте без прямого публичного доступа. Они защищают контент и позволяют выдавать ограниченный по времени доступ к скачиванию или загрузке объектов.

Для генерации подписанной ссылки используется секретный ключ, который должен храниться как в системе Arviol, так и у клиента в защищённом месте. Клиент генерирует подписанные ссылки самостоятельно. Ниже приведен код функции для генерации подписанных ссылок на Python 3.

import binascii
import hashlib
import hmac
import time
from urllib.parse import urlparse

def sign_url(url: str,
secret_key: str,
acl: str = "*",
lifetime: int = 31_536_000,
) -> str:
"""
Generate a signed URL with an expiration token for access control

Args:
url (str): URL to be signed
secret_key (str): Secret key for signing (UTF-8 string)
acl (str): Access control list, defaults to "*" (all paths)
lifetime (int): Token lifetime in seconds, defaults to 1 year

Returns:
str: Signed URL with token appended as query parameter

Example usage:
>>> sign_url(
... url="https://example.com/private/example.jpg",
... secret_key="secret",
... acl="/private/*",
... lifetime=60 * 60 * 7,
... )
'https://example.com/private/example.jpg?token=exp=1759879396~acl=/private/*~hmac=4fdb5e8bd60bbdeca1ddbeb93677de595a02d424e8211a3c0fb17e3735950db4'
"""

exp = int(time.time() + lifetime)
token_params = f"exp={exp}~acl={acl}"
key_hex = secret_key.encode("utf-8").hex()

token_hmac = hmac.new(
key=binascii.a2b_hex(key_hex.encode()),
msg=token_params.encode(),
digestmod=hashlib.sha256,
)
token_digest = token_hmac.hexdigest()
token = f"{token_params}~hmac={token_digest}"

if urlparse(url).query:
return f"{url}&token={token}"

return f"{url}?token={token}"

Параметр lifetime - срок действия ссылки в секундах. Параметр acl - шаблон пути к ресурсам, на которые распространяется действие ссылки, относительно базового URL сайта. Примеры acl:

  • * - все файлы (используется по умолчанию)
  • /media/private_* - все файлы в папке media с префиксом private_
  • /media/* - только файлы в папке media и вложенных папках
  • /media/example.mp4 - только файл example.mp4 в папке media
примечание

acl подключается для локации и должен содержать имя локации. Например, для ограничения доступа к локации сайта https://example.com/private значение acl будет /private/*

Если клиент подозревает, что ключ скомпрометирован, он может сменить ключ. В этом случае все ранее выданные подписанные ссылки перестанут работать, обеспечивая безопасность доступа.

Иерархия объектов

Итоговая иерархия объектов управления кэшированием статики веб-сайтов:

{
"domain": {
"name": "example.com",
"type": "delegated",
"ssl_cert": {},
"waf": {},
"locations": [
{
"headers": [],
"request_headers": [
{
"key": "X-Origin-Routing",
"value": "beta"
}
],
"cors_headers": {}
}
],
"other_params": "..."
}
}