← Cloudflare One / cloudflare-one / traffic-policies / http-policies
Безопасность реестра пакетов
Gateway умеет обнаруживать загрузки программных пакетов в семи основных экосистемах пакетов и позволяет управлять трафиком цепочки поставок с помощью политик. Когда разработчик или CI/CD-конвейер загружает пакет через Gateway, прокси определяет протокол реестра по URL-адресу запроса и извлекает экосистему пакета, его имя, версию и пространство имён. После этого вы можете писать политики HTTP с использованием pkg.* селекторы, чтобы разрешать или блокировать загрузку пакетов с любой необходимой степенью детализации: от блокировки целой экосистемы до ограничения одной версии пакета.
Как это работает
Обнаружение пакетов полностью основано на структуре URL HTTP-запроса. Gateway распознаёт контракт API каждого поддерживаемого протокола реестра, а не имя хоста, обслуживающего трафик. Это означает, что обнаружение работает одинаково независимо от того, идёт ли трафик к официальному публичному реестру, локально размещённому зеркалу, корпоративному прокси-реестру, такому как Artifactory или Nexus, или любой другой совместимой конечной точке. Если путь URL соответствует структуре известной загрузки из реестра, Gateway классифицирует его.
Обнаружение работает в режиме fail-open. Если URL-адрес невозможно классифицировать как загрузку пакета, запрос обрабатывается как обычный трафик, не связанный с пакетами. Сбой классификации никогда не блокирует и не нарушает установку пакета.
Поддерживаемые экосистемы
Gateway обнаруживает загрузки пакетов для следующих экосистем:
| Ecosystem | Пример шаблона артефакта | Пространство имён |
|---|---|---|
| npm | /{package}/-/{package}-{version}.tgz |
Scope (например, @babel) |
| PyPI | /packages/{hash}/{hash}/{hash}/{package}-{version}.whl |
, |
| RubyGems | /gems/{package}-{version}.gem |
, |
| Cargo | /crates/{package}/{package}-{version}.crate |
, |
| Go | /{module}/@v/{version}.zip |
Путь к модулю |
| Maven | /maven2/{group}/{artifact}/{version}/{artifact}-{version}.jar |
Group ID |
| NuGet | /{package}/{version}/{package}.{version}.nupkg |
, |
Обнаруженная операция
Первый выпуск обнаруживает скачать только операции. Download является единственной операцией, для которой имя пакета, версию и экосистему можно определить по пути URL для всех поддерживаемых реестров. Другие операции, такие как resolve (поиск метаданных) и publish, используют другие конечные точки, хосты или методы HTTP, для распознавания которых требуются дополнительные признаки помимо пути URL.
Селекторы
Следующие параметры доступны для Политики HTTP с действиями Allow и Block:
| Селектор | UI name | Пример API | Описание |
|---|---|---|---|
pkg.ecosystem |
Экосистема пакета | pkg.ecosystem == "npm" |
Экосистема пакета, определённая по URL-адресу запроса. |
pkg.name |
Имя пакета | pkg.name == "lodash" |
Имя пакета, извлечённое из URL-адреса загрузки. |
pkg.version |
Версия пакета | pkg.version == "4.17.21" |
Версия пакета, извлечённая из URL-адреса загрузки. Поддерживает точное совпадение и операторы сравнения с учётом экосистемы. |
pkg.namespace |
Пространство имён пакета | pkg.namespace == "@babel" |
Пространство имён пакета, если экосистема его поддерживает. Для npm это scope, для Maven, group ID, а для Go, путь модуля. |
pkg.purl |
URL пакета | pkg.purl == "pkg:npm/[email protected]" |
URL пакета (PURL) ↗ полученный на основе обнаруженных координат. Доступно только в API. |
Создание выражений в дашборде
В панели управления Экосистема пакета является основным селектором. При его выборе открываются вложенные поля для указания имени пакета, версии и namespace. Применяются следующие правила:
- Прежде чем станут доступны остальные поля пакета, необходимо выбрать экосистему.
- Чтобы включить вложенные поля, нужно выбрать ровно одну экосистему. Если вы используете
inилиnot inоператор для сопоставления нескольких экосистем, вложенные поля имени пакета, версии и пространства имён отключаются. - Прежде чем добавить ограничение версии, нужно указать имя пакета.
- Поле пространства имён доступно только для экосистем, которые его поддерживают. Название поля меняется в зависимости от выбранной экосистемы: Область действия для npm, Group ID для Maven и Пространство имен модуля для Go.
-
pkg.purl(Package URL) недоступен в панели управления. Используйте API, чтобы написать выражения, которые сопоставляются по PURL.
При прямом использовании API эти селекторы можно свободно комбинировать в выражениях wirefilter без указанных ограничений.
Операторы сравнения версий
pkg.version селектор поддерживает операторы сравнения с учётом экосистемы в дополнение к точному совпадению строк. Каждая экосистема использует собственную семантику версионирования:
| Ecosystem | Стандарт версионирования |
|---|---|
| npm | SemVer |
| Cargo | SemVer |
| PyPI | PEP 440 |
| RubyGems | Gem::Version |
| Go | Версии модулей Go |
| Maven | Порядок версий Maven |
| NuGet | Нормализация и упорядочение NuGet |
Поддерживаются следующие операторы сравнения:
| Оператор | Синтаксис API | Описание |
|---|---|---|
| равно | == |
Нормализованное сравнение равенства с использованием правил идентификации, специфичных для экосистемы. |
| not equals | != |
Отрицание нормализованного равенства. |
| больше | > |
Версия больше указанного значения с учётом собственного порядка сортировки. |
| больше или равно | >= |
Версия больше указанного значения или равна ему. |
| меньше | < |
Версия меньше указанного значения. |
| меньше или равно | <= |
Версия меньше указанного значения или равна ему. |
Если строку версии не удаётся разобрать по правилам версионирования экосистемы, либо если обнаруженная экосистема не соответствует контексту сравнения, сравнение не возвращает совпадений. Сюда входит !=, то есть версия, которую невозможно разобрать, не соответствует ничему.
Примеры политик
Заблокировать все загрузки из определенной экосистемы
Чтобы заблокировать загрузку всех пакетов PyPI во всей организации:
| Селектор | Оператор | Значение | Действие |
|---|---|---|---|
| Экосистема пакета | является | pypi |
Block |
Выражение Wirefilter:
pkg.ecosystem == "pypi"Заблокировать конкретный пакет
Чтобы блокировать известный вредоносный или нежелательный пакет npm независимо от версии:
| Селектор | Оператор | Значение | Логика | Действие |
|---|---|---|---|---|
| Экосистема пакета | является | npm |
И | Block |
| Имя пакета | является | event-stream |
Выражение Wirefilter:
pkg.ecosystem == "npm" and pkg.name == "event-stream"Заблокировать уязвимые версии пакета
Чтобы заблокировать все версии lodash ниже 4.17.21, являющаяся версией, в которой исправлена уязвимость CVE-2021-23337:
| Селектор | Оператор | Значение | Логика | Действие |
|---|---|---|---|---|
| Экосистема пакета | является | npm |
И | Block |
| Имя пакета | является | lodash |
И | |
| Версия пакета | меньше | 4.17.21 |
Выражение Wirefilter:
pkg.ecosystem == "npm" and pkg.name == "lodash" and pkg.version < "4.17.21"Ограничьте использование пакетов авторизованным зеркалом реестра
Чтобы разрешить загрузку пакетов npm только через корпоративный экземпляр Artifactory и заблокировать остальные загрузки npm, создайте две политики:
Политика 1. Allow для санкционированного зеркала (более высокий приоритет):
| Селектор | Оператор | Значение | Логика | Действие |
|---|---|---|---|---|
| Экосистема пакета | является | npm |
И | Allow |
| Host | является | npm.internal.example.com |
Выражение Wirefilter:
pkg.ecosystem == "npm" and http.request.host == "npm.internal.example.com"Политика 2. Block всех остальных загрузок npm (более низкий приоритет):
| Селектор | Оператор | Значение | Действие |
|---|---|---|---|
| Экосистема пакета | является | npm |
Block |
Выражение Wirefilter:
pkg.ecosystem == "npm"Поскольку обнаружение основано на протоколе реестра, а не на имени хоста, как публичный registry.npmjs.org и ваше внутреннее зеркало по адресу npm.internal.example.com определяются как трафик npm. Политика 1 (с более высоким приоритетом) разрешает утвержденное зеркало, а политика 2 блокирует все остальное.
Заблокировать конкретный пакет, если он получен не с разрешенного хоста
Чтобы разрешить загрузку конфиденциального внутреннего пакета только через корпоративный реестр, заблокировав его для всех остальных источников:
Политика 1. Allow с санкционированного узла (более высокий приоритет):
| Селектор | Оператор | Значение | Логика | Действие |
|---|---|---|---|---|
| Экосистема пакета | является | npm |
И | Allow |
| Пространство имён пакета | является | @acme |
И | |
| Имя пакета | является | internal-sdk |
И | |
| Host | является | npm.internal.example.com |
Выражение Wirefilter:
pkg.ecosystem == "npm" and pkg.namespace == "@acme" and pkg.name == "internal-sdk" and http.request.host == "npm.internal.example.com"Политика 2. Block со всех остальных узлов (более низкий приоритет):
| Селектор | Оператор | Значение | Логика | Действие |
|---|---|---|---|---|
| Экосистема пакета | является | npm |
И | Block |
| Пространство имён пакета | является | @acme |
И | |
| Имя пакета | является | internal-sdk |
Выражение Wirefilter:
pkg.ecosystem == "npm" and pkg.namespace == "@acme" and pkg.name == "internal-sdk"Обнаружение и зеркала
Обнаружение пакетов классифицирует трафик на основе структуры пути URL в API загрузки каждого реестра. Оно не полагается на сопоставление со списком известных имён хостов реестров. Благодаря этому любой сервер, раздающий пакеты по совместимой схеме URL, определяется одинаково, независимо от того, является ли он:
- Официальный публичный реестр (например,
registry.npmjs.orgилиpypi.org) - Корпоративный реестр прокси, например JFrog Artifactory, Sonatype Nexus или AWS CodeArtifact
- Локально размещённое зеркало
- Конечная точка реестра за CDN
http.request.host селектор остаётся доступным для политик, которым необходимо различать конкретные хосты реестра. Комбинируя pkg.* селекторы с http.request.host, вы можете создавать правила, применяющие разные действия в зависимости от того, откуда загружается пакет.
Логирование
Когда Gateway обнаруживает загрузку пакета, метаданные пакета добавляются в HTTP-журнал Gateway. Эти данные доступны в Журналы активности Gateway и через Logpush.
Поля журнала активности
В журнале активности Gateway доступны следующие поля пакета:
| Поле | Описание |
|---|---|
| Экосистема пакета | Обнаруженный тип реестра (например, npm, pypi, cargo). |
| URL пакета (PURL) | Строка Package URL, полученная из обнаруженных координат (например, pkg:npm/[email protected]). |
поля Logpush
Метаданные пакета доступны в PackageInfo объект в gateway_http Набор данных Logpush:
| Поле | Type | Описание |
|---|---|---|
PackageInfo.Ecosystem |
string |
Обнаруженная экосистема пакетов. |
PackageInfo.Namespace |
string |
Пространство имён пакета, если применимо. |
PackageInfo.Name |
string |
Имя пакета. |
PackageInfo.Version |
string |
Строка версии пакета. |
PackageInfo.Purl |
string |
Строка Package URL. |
Ограничения
- Обнаружение пакетов требует Расшифровка TLS чтобы она была включена. Пакеты, загруженные через соединения, которые обходят проверку TLS (из-за политик Do Not Inspect или приложений в список ограничений проверки) не обнаруживаются.
- Некоторые языковые runtime и HTTP-клиенты используют собственные хранилища доверенных сертификатов, отдельные от операционной системы. Если сертификат, используемый для проверки (например, управляемый сертификат Cloudflare), установлен только в хранилище доверия ОС, загрузка пакетов такими клиентами может завершаться ошибками проверки сертификата. См. Установите сертификат вручную с инструкциями по добавлению сертификата в хранилища доверенных сертификатов конкретных приложений, включая Python, Node.js, Ruby, Rust, Java и Go.
- Только скачать операции. Поиск метаданных (resolve), публикация пакетов и другие операции реестра не классифицируются.
- При сравнении версий используются собственные правила сортировки каждой экосистемы. Сравнение версий между разными экосистемами не поддерживается.
- Синтаксис диапазонов, зависящий от экосистемы (например, npm
^1.2.3, PyPI~=1.4, или нотация интервалов Maven) не поддерживается. Используйте отдельные операторы сравнения (>,<,>=,<=) вместо этого.