Когда вы работаете в команде, где используется Python, вы наверняка сталкиваетесь с одной простой, но критичной проблемой: как безопасно хранить и использовать внутренние библиотеки? Публичный PyPI - это удобно, но он не для корпоративного использования. Там можно найти тысячи пакетов, но и тысячи вредоносных. В 2022 году в PyPI обнаружили более 20 пакетов, специально созданных для кражи криптовалюты. В 2024 году появились пакеты, имитирующие AI-инструменты, но на самом деле крадущие пароли. Если ваша команда использует публичный репозиторий без контроля - вы уже в зоне риска.
Почему публичный PyPI - не решение для бизнеса
PyPI содержит более 300 000 пакетов. Звучит впечатляюще, пока вы не узнаете, что в 2021 году исследователи из Университета Турку проанализировали 197 000 из них и нашли 749 000 потенциальных уязвимостей. В 46% всех пакетов есть хотя бы одна опасная конструкция: eval(), exec(), жёстко прописанные пароли, устаревшие хэш-функции вроде MD5 или SHA1. Даже если пакет выглядит безобидным - он может быть скомпрометирован через зависимость. Например, вы устанавливаете requests, но одна из его зависимостей - urllib3 - была изменена злоумышленником. Вы даже не заметите.
Вредоносные пакеты часто создаются быстро: аккаунт зарегистрирован вчера, пакет опубликован сегодня. У них нет истории, нет отзывов, нет поддержки. А вы всё равно скачиваете их, потому что они есть в requirements.txt. Это называется атака на цепочку поставок - и она работает, потому что разработчики доверяют автоматическим инструментам, а не проверяют код.
Что такое приватный PyPI-репозиторий и зачем он нужен
Приватный PyPI-репозиторий - это ваш собственный сервер, куда вы загружаете только те библиотеки, которые доверяете. Он не публичный. К нему могут подключаться только ваши серверы, CI/CD-системы и разработчики. Вы контролируете:
- Какие пакеты можно устанавливать
- Кто имеет право загружать новые версии
- Какие зависимости разрешены
- Как проверяется целостность файлов
Это не просто «локальный сервер». Это ваша защита от атак, от случайного внедрения вредоносного кода и от внезапного исчезновения пакета, который кто-то опубликовал и потом забросил. В 2023 году более 20% пакетов на PyPI перестали обновляться. Если ваш проект зависит от одного из них - вы рискуете остаться без поддержки. С приватным репозиторием такой проблемы нет: вы сами решаете, какие версии остаются актуальными.
Как настроить приватный репозиторий: три основных подхода
Существует несколько решений для создания приватного PyPI. Выбор зависит от вашего масштаба и инфраструктуры.
1. devpi - простой и гибкий
devpi - это лёгкий сервер на Python, который легко запускается на любом Linux-сервере. Он поддерживает кэширование пакетов из публичного PyPI, так что вы не теряете доступ к открытым библиотекам, но контролируете их версии. Если кто-то в команде хочет установить numpy==1.24.3, devpi сначала проверит, есть ли он в кэше. Если нет - скачает его из PyPI, сохранит у себя и отдаст. Это экономит трафик и ускоряет установку.
devpi не требует сложной настройки. Достаточно установить через pip:
pip install devpi-server devpi-web
Запустить:
devpi-server --create --start
И настроить доступ по логину и паролю. Для CI/CD можно использовать токены API - они не хранятся в коде, а передаются через переменные окружения.
2. Artifactory или Nexus - для крупных команд
Если у вас больше 50 разработчиков, несколько окружений (разработка, тестирование, продакшн) и вы используете не только Python, но и Java, Node.js, Docker - лучше взять Artifactory или Sonatype Nexus. Это enterprise-решения. Они поддерживают не только PyPI, но и другие типы репозиториев в одном интерфейсе. У них есть встроенные механизмы проверки уязвимостей, контроль версий, интеграция с LDAP/Active Directory и полный аудит всех действий.
Artifactory, например, может автоматически сканировать пакеты на наличие известных уязвимостей по базе NVD (National Vulnerability Database). Если кто-то попытается загрузить пакет с известной уязвимостью - система отклонит его. Это работает как «защита на входе».
3. Приватный PyPI на базе Warehouse (официальный сервер PyPI)
Если вы хотите полной совместимости с PyPI, можно развернуть собственный экземпляр Warehouse - официального сервера PyPI, написанного на Django. Это сложнее, чем devpi, но даёт вам полный контроль: вы можете включить или отключить любую функцию, настроить политику публикации, добавить двухфакторную аутентификацию. Подходит для команд, которые хотят полностью контролировать инфраструктуру и не боятся технической сложности.
Как обеспечить безопасность: 5 обязательных шагов
Просто запустить сервер - этого недостаточно. Безопасность начинается с правил.
- Отключите публичный доступ. Приватный репозиторий должен быть доступен только внутри вашей сети или через VPN. Никаких открытых портов наружу.
- Используйте токены, а не пароли. Вместо логина/пароля настройте API-токены. Они короткоживущие, привязаны к конкретному пользователю или сервису и могут быть отозваны в один клик. В CI/CD система использует токен, который хранится в секретах (например, в GitHub Secrets или GitLab CI Variables).
- Проверяйте хэши пакетов. Все пакеты должны иметь файлы
.sha256или.asc. Убедитесь, что ваш инструмент установки (pip) проверяет целостность. Вpip.confдобавьте:
[global]
trusted-host = pypi.yourcompany.local
verify = true
- Сканируйте пакеты на уязвимости. Используйте инструменты вроде
pip-auditили интеграцию с Artifactory. Они проверяют пакеты по базам CVE и сообщают, есть ли известные уязвимости в вашей версии. - Ограничьте права публикации. Только администраторы могут загружать новые пакеты. Разработчики - только обновлять версии существующих. Используйте RBAC (ролевой контроль доступа).
Как интегрировать с CI/CD
Когда вы работаете в команде, автоматизация - ключ к стабильности. Вот как настроить сборку в GitHub Actions:
name: Deploy Python Package
on:
push:
branches: [ main ]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
python-version: '3.12'
- run: pip install build twine
- run: python -m build
- run: twine upload --repository-url https://pypi.yourcompany.local/ dist/*
env:
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
Обратите внимание: TWINE_PASSWORD - это не пароль, а токен API, созданный в вашем приватном репозитории. Он не хранится в коде, не передаётся в логах, не попадает в историю Git. Если токен скомпрометирован - вы его отозвали и создали новый. Всё это делается через веб-интерфейс репозитория.
Что делать, если пакет уже был скомпрометирован?
Представьте: вы обнаружили, что в вашем requirements.txt есть пакет, который был заменён злоумышленником. Что делать?
- Немедленно удалите пакет из всех окружений.
- Проверьте, не использовался ли он в продакшене. Если использовался - смените все пароли, токены, ключи API, которые могли быть доступны во время его работы.
- Замените пакет на проверенную версию из вашего приватного репозитория.
- Запустите аудит всех зависимостей через
pip-auditили аналоги.
Важно: вредоносные пакеты редко остаются в системе после удаления. Они работают только при запуске. Но если они получили доступ к переменным окружения, токенам или сессиям - их нужно менять. Не ждите, пока что-то сломается. Действуйте сразу.
Какие инструменты помогут в будущем
PyPI уже внедряет новый стандарт - Trusted Publishers. Он использует OpenID Connect (OIDC) для аутентификации. Теперь вы можете настроить GitHub Actions так, чтобы он не использовал токены, а получал временный ключ от PyPI через OIDC. Этот ключ действует всего 5 минут и привязан только к конкретному репозиторию. Даже если злоумышленник получит доступ к вашему CI-серверу - он не сможет загрузить пакет, потому что не имеет доступа к вашему аккаунту в GitHub.
В будущем этот подход станет стандартом. Приватные репозитории тоже начнут поддерживать OIDC. Это значит, что вы сможете управлять доступом через вашу корпоративную систему аутентификации (например, Keycloak или Azure AD), а не через отдельные логины и пароли.
Вывод: безопасность - это процесс, а не настройка
Работа с приватными PyPI-репозиториями - это не про «поставить сервер и забыть». Это про культуру: кто может загружать пакеты, как проверяются зависимости, как реагируют на угрозы. Приватный репозиторий - это ваша первая линия обороны. Он не гарантирует 100% безопасности, но он делает вас неуязвимым для большинства атак, которые сейчас работают против публичного PyPI.
Начните с devpi. Настройте токены. Запретите прямой доступ к PyPI в CI. Сканируйте пакеты. Обучите команду. Это не займёт много времени - но остановит кибератаку, которая может стоить вам миллионов.
Как создать приватный PyPI-репозиторий бесплатно?
Самый простой способ - использовать devpi. Это бесплатное, открытое решение на Python. Установите его на любой Linux-сервер, настройте доступ по токену и кэшируйте пакеты из PyPI. Для небольших команд (до 20 человек) этого достаточно. Никаких лицензий, никаких платных подписок. Всё работает через командную строку.
Можно ли использовать приватный репозиторий без интернета?
Да, можно. Приватный репозиторий может работать полностью офлайн, если вы заранее загрузили в него все нужные пакеты. Для этого используйте команду pip download: скачайте все зависимости на машине с доступом в интернет, а затем скопируйте файлы в папку репозитория. После этого сервер будет отдавать их без интернета. Это особенно полезно для промышленных систем, где интернет запрещён по политике безопасности.
Как проверить, что пакет не содержит вредоносного кода?
Используйте pip-audit - инструмент от PyPA. Он проверяет установленные пакеты по базе известных уязвимостей (CVE). Также проверяйте: кто автор пакета, когда он был создан, есть ли у него история обновлений. Вредоносные пакеты часто имеют свежие аккаунты, мало загрузок и странные названия (например, "gptplus" или "claudeai-eng"). Если пакет не имеет документации или его исходный код не доступен - не доверяйте ему.
Чем отличается Artifactory от devpi?
Devpi - это лёгкий, простой сервер только для Python. Он идеален для небольших команд. Artifactory - это enterprise-платформа, которая поддерживает Python, Java, Docker, npm и другие форматы в одном месте. У Artifactory есть встроенные сканеры уязвимостей, контроль версий, интеграция с LDAP, аудит всех действий. Если у вас больше 50 разработчиков или вы используете несколько языков - Artifactory выгоднее.
Как настроить доступ к приватному репозиторию для разных команд?
Настройте роли: разработчики - могут только устанавливать пакеты; релиз-инженеры - могут загружать новые версии; администраторы - могут управлять пользователями и политиками. В devpi это делается через веб-интерфейс. В Artifactory - через LDAP-группы. Всё, что нужно - это токены с ограниченными правами. Никто не должен иметь доступ к публикации, если это не его задача.