Гайд · TNWS AI

Почему --api-key в vLLM не защищает весь сервер и как проверить схему доступа

4 мин—

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

Задача и применимость

Вопрос читателя: «почему api key vLLM не защищает все endpoints invocations». Для vLLM OpenAI-compatible server на 20 сентября 2026 года. Руководство рассматривает безопасное развёртывание собственного сервера, а не получение доступа к чужому. Все проверки проводятся только на подконтрольном локальном экземпляре.

Для воспроизводимости запишите фактическую версию установленного vLLM, модельный checkpoint и параметры запуска. Путь /models/your-chat-checkpoint либо /models/your-embedding-checkpoint в команде ниже — заполнитель, а не реальный файл. Наличие GPU, объём памяти и условия лицензии весов проверяются до запуска. Демонстрация не утверждает, что ответ модели заранее известен по буквам.

Проверенные возможности

Официальная документация предупреждает: --api-key либо VLLM_API_KEY аутентифицирует только пути с префиксами /v1, /v2 и /inference; другие маршруты на том же сервере могут быть незащищены. Особо упомянут /invocations, который предоставляет аналогичные возможности инференса. Нельзя считать один флаг полноценной защитой всего HTTP-сервера.

Пошаговая процедура

  1. Разверните тестовый сервер на loopback, не публикуя порт в интернет.
  2. Запишите список всех маршрутов, которые доступны вашим клиентам.
  3. Для /v1 проверьте отрицательный тест без ключа и положительный с тестовым ключом.
  4. Для остальных маршрутов проектируйте сетевое ограничение или reverse proxy.
  5. Проведите аудит правил доступа к каждому пути перед внешним развёртыванием.

Команда для тестового запуска на локальном адресе (подставьте законно полученный checkpoint):

vllm serve /models/your-chat-checkpoint --host 127.0.0.1 --port 8000 --api-key YOUR_TEST_TOKEN

Готовый запрос и контроль ответа

В приведённом фрагменте используется стандартная библиотека Python и простой общий помощник для отправки JSON. Подставьте при необходимости Bearer-токен через защищённую переменную окружения и проверьте, что ваш сервер его ожидает.

import json, urllib.request
BASE = "http://127.0.0.1:8000"
def call(path, payload):
    data = json.dumps(payload, ensure_ascii=False).encode("utf-8")
    request = urllib.request.Request(BASE + path, data=data,
        headers={"Content-Type": "application/json"}, method="POST")
    with urllib.request.urlopen(request, timeout=120) as reply:
        return json.load(reply)

import urllib.error
url = "http://127.0.0.1:8000/v1/models"
try:
    urllib.request.urlopen(url, timeout=5)
except urllib.error.HTTPError as error:
    print("Без ключа статус:", error.code)
request = urllib.request.Request(url, headers={
    "Authorization": "Bearer YOUR_TEST_TOKEN"})
with urllib.request.urlopen(request, timeout=5) as reply:
    print("С ключом:", reply.status, "моделей:",
          len(json.load(reply).get("data", [])))

Пример входа и ожидаемого результата

Вход — два GET /v1/models к собственному серверу: первый без тестового ключа, второй с ним. Ожидается отказ первому при включённой защите и успешный ответ второму. Эти два ответа проверяют только /v1, а не безопасность остальных путей; исследование охвата проводится конфигурацией прокси.

Как интерпретировать результат

Распространённая ошибка — поднять vLLM с --api-key на интерфейсе 0.0.0.0 и решить, что все пути защищены. Документация прямо говорит обратное; отдельные маршруты могут дать те же возможности инференса за пределами покрываемых префиксов. Не пытайтесь лечить проблему сложным секретом: секрет не работает там, где аутентификация маршрута не применяется. Безопаснее по умолчанию оставить bind на 127.0.0.1 и организовать доступ приложения через серверный backend с явным списком разрешённых путей.

Развёртывание без потери контекста

Reverse proxy должен проверять аутентификацию до всех внешне доступных маршрутов и, при необходимости, вовсе блокировать административные/диагностические пути. Протестируйте и GET, и POST на своём контуре с тестовыми учётными данными; не полагайтесь только на наличие заголовка Authorization в клиентском коде. Ротация ключа, журналы доступа и rate limiting нужны отдельно. Код здесь не демонстрирует обращение к незащищённому инференс-маршруту, чтобы не предлагать ложную схему доступа; контроль проводится через конфигурационный аудит.

Проверки качества и границы метода

Документируйте, какие процессы имеют доступ к порту 8000, как трафик шифруется между приложением и модельным сервером, и где хранится тестовый ключ. Не вставляйте реальный ключ в публикуемый код, журнал команд или пользовательский браузер. После обновления vLLM перечитайте таблицу защищённых маршрутов: покрытия API могут измениться. Перед открытием сервера запустите внутренний аудит правил reverse proxy и сетевых ACL, затем проверьте отказ на каждом неподтверждённом пути.

Даже правильная защита путей API не даёт разделения данных разных клиентов внутри пользовательского приложения. Если вы обрабатываете чат-истории или RAG-документы, проверяйте tenant и права на сервере приложения до отправки prompt в vLLM. Отказ /v1/models без ключа показывает лишь один положительный сигнал; его нельзя писать в отчёте как «вся система безопасна». Если вы не можете гарантировать закрытую сеть и прокси, не публикуйте модельный сервер напрямую.

Критерии готовности

  1. Отрицательный тест к /v1 выполнен локально.
  2. Остальные маршруты учтены в правилах прокси или закрытой сети.
  3. Секрет не попал в клиентский код.

Типичные ошибки и чего не делать

  • Не считать --api-key защитой всех endpoints.
  • Не открывать порт наружу сразу после локального теста.
  • Не хранить ключ в публичном репозитории.

Частые вопросы

Защищает ли --api-key /v1?

Да, документация относит /v1 к покрываемым префиксам.

Защищает ли он все маршруты?

Нет.

Что нужно дополнительно?

Закрытая сеть и защита разрешённых путей на прокси.

Официальные источники

Частые вопросы

Защищает ли --api-key /v1?

Да, документация относит /v1 к покрываемым префиксам.

Защищает ли он все маршруты?

Нет.

Что нужно дополнительно?

Закрытая сеть и защита разрешённых путей на прокси.

Читайте также

Комментарии

Пока тихо. Скажите первое слово