API ВЕГА
English

rust-panosmcp

Асинхронный сервер Model Context Protocol на Rust для межсетевых экранов Palo Alto Networks PAN-OS

проект mechub — автоматизация сетевой безопасности под полным контролем владельца

Неофициальный проект сообщества. Это независимый проект сообщества, не связанный с Palo Alto Networks и не одобренный этой компанией. Названия продуктов и товарные знаки используются только для обозначения систем, с которыми взаимодействует программное обеспечение.

В репозитории представлена версия v0.16.2: сервер с защитой по bearer-токену, структурированным журналированием аудита, контролируемым жизненным циклом кандидатной конфигурации PAN-OS и защищённой упаковкой релизов. Аутентификацию и аудит обеспечивают общие крейты mecmcp-auth и mecmcp-audit.

Цель проекта — создать компактный, быстрый и готовый к эксплуатации сервер с таким же

уровнем безопасности, как у rust-junosmcp: аутентификацией по bearer-токену, ограничениями

доступа к устройствам и инструментам для каждого токена, TLS, строгими правилами запрета

небезопасной привязки к удалённым интерфейсам, ограничениями на размер входных

и выходных данных, аудируемыми операциями изменения конфигурации и эффективным повторным

использованием подключений.

Архитектура и план разработки описаны в PLAN.md. Границы

безопасности и блокирующие выпуск меры контроля зафиксированы в

THREAT_MODEL.md.

Структура рабочего пространства

rust-panosmcp/          # MCP binary and stdio adapter
rust-panosmcp-auth/     # bearer and secret-handling foundations
rust-panosmcp-core/     # inventory, PAN-OS client, validation, tool logic
config/                 # secret-free inventory examples
docs/                   # operator guidance and phase notes
fuzz/                   # isolated cargo-fuzz workspace
packaging/              # distroless/container and systemd assets
scripts/                # release, matrix, fuzz, and benchmark gates

Быстрый старт

Установка

Выберите один из трёх способов установки:

Архив релиза (Linux x86_64)

Скачайте последнюю версию со страницы релизов на GitHub. Файлы релиза имеют формат имени rust-panosmcp-v0.16.2-x86_64-unknown-linux-gnu.tar.gz; рядом с каждым архивом доступен соответствующий файл .sha256.

# Download and verify
curl -LO https://github.com/mechubsec/rustpanosmcp/releases/download/v0.16.2/rust-panosmcp-v0.16.2-x86_64-unknown-linux-gnu.tar.gz
curl -LO https://github.com/mechubsec/rustpanosmcp/releases/download/v0.16.2/rust-panosmcp-v0.16.2-x86_64-unknown-linux-gnu.tar.gz.sha256
sha256sum -c rust-panosmcp-v0.16.2-x86_64-unknown-linux-gnu.tar.gz.sha256

# Extract
tar xzf rust-panosmcp-v0.16.2-x86_64-unknown-linux-gnu.tar.gz
cd rust-panosmcp-v0.16.2

# Install the binary and systemd assets
sudo install -m 0755 bin/rust-panosmcp /usr/local/bin/rust-panosmcp
sudo install -m 0644 packaging/systemd/rust-panosmcp.sysusers /usr/lib/sysusers.d/rust-panosmcp.conf
sudo install -m 0644 packaging/systemd/rust-panosmcp.tmpfiles /usr/lib/tmpfiles.d/rust-panosmcp.conf
sudo install -m 0644 packaging/systemd/rust-panosmcp.service /etc/systemd/system/rust-panosmcp.service

# Create the service user and directories
sudo systemd-sysusers
sudo systemd-tmpfiles --create

# Generate the HMAC key for audit redaction (required).
# Guarded: NEVER overwrite an existing key. The key is what makes an HMAC-redacted
# device identifier comparable across audit history, so replacing it silently
# breaks correlation with every record already written. These steps are safe to
# re-run during an upgrade only because of this guard.
sudo sh -c '[ -f /etc/rust-panosmcp/audit-hmac.key ] ||
    head -c 32 /dev/urandom | base64 > /etc/rust-panosmcp/audit-hmac.key'
sudo chmod 0600 /etc/rust-panosmcp/audit-hmac.key
sudo chown rust-panosmcp:rust-panosmcp /etc/rust-panosmcp/audit-hmac.key

# Start the service
sudo systemctl daemon-reload
sudo systemctl enable --now rust-panosmcp

Эти команды создают отдельного системного пользователя rust-panosmcp и подготавливают каталоги /etc/rust-panosmcp (конфигурация, владелец — root) и /var/lib/rust-panosmcp (состояние). HMAC-ключ в /etc/rust-panosmcp/audit-hmac.key необходим для маскирования идентификаторов устройств в журналах аудита — без него служба не запустится. В распакованном архиве есть примеры конфигурации в каталоге config/. Перед запуском возьмите devices.example.json и tokens.example.json за основу для файлов в /etc/rust-panosmcp. Подробнее об устройстве systemd см. в каталоге packaging/systemd/.

LXC (Debian 13)

Для выделенного непривилегированного контейнера LXC на Proxmox или отдельной системы systemd-nspawn в архив релиза включён идемпотентный установщик, автоматизирующий описанную выше последовательность действий. Полное руководство по настройке, включая создание контейнера, см. в HOW-TO-SETUP-LXC.md.

# Download and verify
curl -LO https://github.com/mechubsec/rustpanosmcp/releases/download/v0.16.2/rust-panosmcp-v0.16.2-x86_64-unknown-linux-gnu.tar.gz
curl -LO https://github.com/mechubsec/rustpanosmcp/releases/download/v0.16.2/rust-panosmcp-v0.16.2-x86_64-unknown-linux-gnu.tar.gz.sha256
sha256sum -c rust-panosmcp-v0.16.2-x86_64-unknown-linux-gnu.tar.gz.sha256

# Extract and run the installer
tar xzf rust-panosmcp-v0.16.2-x86_64-unknown-linux-gnu.tar.gz
cd rust-panosmcp-v0.16.2
sudo packaging/lxc/install.sh

# Configure the inventory and mint the first token
sudo vi /etc/rust-panosmcp/devices.json
sudo rust-panosmcp token add \
  --tokens-file /var/lib/rust-panosmcp/tokens.json \
  --name initial-token \
  --devices fw-example \
  --tools list_devices,gather_device_facts,execute_panos_op,get_panos_config

# Start the service
sudo systemctl enable --now rust-panosmcp.service

Установщик создаёт пользователя rust-panosmcp и каталоги с помощью systemd-sysusers и systemd-tmpfiles, устанавливает бинарный файл и unit-файл, создаёт пустой tokens.json с правами доступа 0600 и не перезаписывает существующий /var/lib/rust-panosmcp/mutation-state.json (журнал аудита наборов изменений). По умолчанию служба принимает подключения по адресу http://127.0.0.1:30031/mcp. Параметры переопределения переменных среды и особенности обновления описаны в packaging/lxc/install.sh.

Docker / GHCR

Предварительно собранные образы публикуются в ghcr.io/mechubsec/rustpanosmcp при выпуске каждого релизного тега. Процесс сборки описан в .github/workflows/release-image.yml. Полное руководство по настройке, включая режимы с двумя участниками и для лабораторной среды, см. в HOW-TO-SETUP-DOCKER.md.

# Pull the image
docker pull ghcr.io/mechubsec/rustpanosmcp:latest

По умолчанию CMD привязывает сервер к 127.0.0.1:30031 внутри контейнера. Поэтому обычный запуск

docker run без -p, --host, --allowed-host и --allowed-origin

завершится без ошибок, но сервер будет недоступен извне контейнера. Используйте

HOW-TO-SETUP-DOCKER.md, чтобы запустить docker run в рабочем режиме с двумя участниками

или в лабораторном режиме. В руководстве приведены нужная публикация порта и флаги,

которые уже передаются во встроенном ENTRYPOINT. Также можно воспользоваться

включённым файлом compose.example.yaml.

Запуск с Docker (stdio)

Для MCP-клиентов, которые запускают сервер через stdin/stdout, подготовьте файл инвентаризации той же структуры, что и config/devices.example.json:

{
  "version": 1,
  "policy": {
    "mode": "allowlist",
    "allow": ["show system info", "show interface all"]
  },
  "devices": [
    {
      "name": "panos-demo",
      "endpoint": "https://panos-demo.example.net",
      "vsys": "vsys1",
      "api_key": { "type": "env", "name": "PANOS_DEMO_API_KEY" },
      "tags": ["lab", "read-only"]
    }
  ]
}

Перед запуском контейнера экспортируйте переменную API-ключа. Такой способ передачи позволяет не указывать ключ в командной строке, однако доступ к Docker daemon всё ещё может раскрыть значения переменных среды при проверке контейнера. Для более надёжной защиты используйте описанный ниже в разделе конфигурации вариант с API-ключом в файле ({"type":"file","path":"/protected/path"}) и подключите этот файл только для чтения с правами 0600.

export PANOS_DEMO_API_KEY=replace-with-runtime-secret

Настройте файлы инвентаризации и состояния так, чтобы контейнерный пользователь (uid:gid 65532:65532) имел к ним права на чтение и запись. Файлы с секретами должны иметь права 0600. На уровне процесса stdio не обеспечивает аутентификацию: запускающий процесс может использовать все устройства из подключённого файла инвентаризации и все инструменты. Ограничьте доступ, включив в этот файл только необходимые устройства и используя роль PAN-OS API только для чтения. Каталог состояния должен быть доступен для записи, поскольку сервер сохраняет в нём состояние аудита.

mkdir -p state
chmod 0600 devices.json
sudo chown 65532:65532 devices.json state

docker run --rm -i \
  --user 65532:65532 \
  -e PANOS_DEMO_API_KEY \
  -v "$PWD/devices.json:/etc/rust-panosmcp/devices.json:ro" \
  -v "$PWD/state:/var/lib/rust-panosmcp" \
  ghcr.io/mechubsec/rustpanosmcp:0.15.0 \
  --transport stdio

В ENTRYPOINT образа уже указаны пути к конфигурации, токену, состоянию и ключу аудита, поэтому не добавляйте эти флаги после имени образа. Путь к токену используется только для HTTP. Эта команда не запускает HTTP и не включает TLS для прослушивателя: параметр --transport stdio заменяет CMD образа, в том числе параметры привязки HTTP и порта. Подключение к межсетевому экрану по-прежнему выполняется через HTTPS с учётом настроек доверия TLS из файла инвентаризации.

Сборка из исходного кода

Требуется Rust версии 1.89 или новее (MSRV).

git clone https://github.com/mechubsec/rustpanosmcp.git
cd rustpanosmcp
cargo build --release --locked
./target/release/rust-panosmcp --version

Запуск (stdio)

Возьмите за основу config/devices.example.json, не добавляйте реальный файл инвентаризации в Git и задайте секрет среды, на который он ссылается:

export PANOS_LAB_API_KEY='runtime-secret'
cargo run --locked --release -- --device-mapping /absolute/path/devices.json

Запуск (streamable-http с аутентификацией)

Сначала создайте токен с минимальными привилегиями, затем запустите TLS-транспорт Streamable HTTP:

cargo run --locked --release -- \
  --device-mapping /etc/rust-panosmcp/devices.json \
  token add \
  --tokens-file /etc/rust-panosmcp/tokens.json \
  --name read-only-client \
  --devices fw-example \
  --tools list_devices,gather_device_facts,execute_panos_op,get_panos_config

cargo run --locked --release -- \
  --device-mapping /etc/rust-panosmcp/devices.json \
  --transport streamable-http \
  --host 0.0.0.0 --port 30031 \
  --tokens-file /etc/rust-panosmcp/tokens.json \
  --tls-cert /etc/rust-panosmcp/server.crt \
  --tls-key /etc/rust-panosmcp/server.key \
  --allowed-host mcp.example.net \
  --allowed-origin https://client.example.net

Надёжно сохраните stdout первой команды: новый bearer-секрет отображается только один раз. Информацию о ротации токенов, перезагрузке, правилах отказа, развёртывании за обратным прокси и настройках безопасности по умолчанию см. в docs/PHASE2_OPERATIONS.md. Сведения об инвентаризации и настройках TLS межсетевого экрана для Phase 1 приведены в docs/PHASE1_OPERATIONS.md.

Далее: Изучите рабочий процесс ролей reader, writer и reviewer в MCP.

Статус

В Phase 1 реализованы проверенный список устройств и поставщики секретов, строгая проверка HTTPS с системными корневыми сертификатами, пользовательским CA или точным закреплением сертификата узла, асинхронные вызовы PAN-OS XML API с пулом соединений, типизированные ошибки, тайм-ауты, отмена запросов, ограничения объёма вывода и семафор для каждого устройства.

В Phase 2 добавлены bearer-токены, в которых хранятся только дайджесты, точные области действия для устройств и инструментов, атомарная перезагрузка списка устройств и токенов, TLS Streamable HTTP, проверка Host/Origin, ограничения размера тела запроса, лимиты частоты запросов по IP и токену, а также трассировка запросов, безопасная для аудита. Оба транспорта используют одни и те же 27 инструментов, описанных ниже в справочнике инструментов MCP. Область действия токена * даёт доступ только к 16 инструментам для чтения (list_devices, gather_device_facts, execute_panos_op, get_panos_config, list_panos_entries, get_panos_entry_digest, list_panorama_device_groups, list_panorama_templates, get_panorama_push_status, list_panos_rulebase_entries, get_panos_ha_state, get_panos_license_info, get_panos_content_status, get_panos_software_status, test_panos_security_policy_match, query_panos_logs); для 11 инструментов управления жизненным циклом и изменения конфигурации необходимо явно указать их названия.

В Phase 3 добавлены включаемые по желанию отпечатки candidate-конфигурации, строгая политика XPath, блокировки конфигурации PAN-OS, последовательная обработка запросов для каждого устройства, применение изменений, просмотр различий и полная проверка, частичный откат с областью действия администратора, согласование заданий и структурированный аудит изменений. Для инструментов записи требуются явно заданные области действия токена; * по-прежнему предоставляет доступ только для чтения.

В Phase 4 добавлены distroless-образ с закреплённым дайджестом и запуском от непривилегированного пользователя, защищённый модуль systemd, рекомендации по развёртыванию с доступом только для чтения, матрица семейств выпусков PAN-OS, пять целей для фаззинга парсеров, побайтно воспроизводимые архивы, документация по безопасности и эксплуатации, а также опубликованные результаты измерений для Rust и Python.

В v0.2 добавлены сохраняемые наборы изменений из нескольких действий, разрешения на XPath и действия с привязкой к токену и сроком действия, сериализация по канонической конечной точке и независимое подтверждение, привязанное к точным владельцу, устройству, отпечатку и дайджесту действий. Подтверждённые наборы применяются под одной блокировкой конфигурации PAN-OS. Если последующее действие завершается ошибкой, изменения автоматически откатываются от имени администратора. Далее используется существующий жизненный цикл: просмотр различий, полная проверка, фиксация или отмена. См. docs/V0.2_CHANGE_SETS.md.

В v0.2.1 снятие блокировки конфигурации PAN-OS стало подтверждаемым переходом состояния: записи о фиксации или отмене сбрасывают config_lock_held только после того, как устройство подтвердит снятие блокировки. Если снять блокировку не удалось, это состояние сохраняется как indeterminate и требует явного согласования. Также в docs/V0.2.1_ACCEPTANCE.md зафиксированы результаты проверки TLS с настройками доверия по умолчанию и развёртывания в лабораторной среде.

В v0.2.2 обновлены поддерживаемый граф зависимостей Rust и GitHub Actions; при этом интерфейсы инструментов PAN-OS, авторизации, списка устройств и состояний изменения конфигурации из v0.2.1 сохранены. Опубликованный выпуск и результаты контролируемого развёртывания в лабораторной среде приведены в docs/V0.2.2_ACCEPTANCE.md. Поддержка multi-vsys, HA и Panorama пока отложена.

В v0.3.0 аутентификация переведена на общий crate mecmcp-auth. Собственные реализации токенов, хранилища и файлов токенов в этом репозитории заменены общим crate, тестируемым отдельно. Набор инструментов PAN-OS, области авторизации, список устройств и интерфейсы состояний изменения конфигурации не изменились. Изменились два аспекта, важные для операторов: файл tokens.json должен иметь права доступа 0600, иначе сервер откажется запускаться; версия конверта на диске теперь сохраняется при записи, поэтому файл, затронутый этим выпуском, останется читаемым для предыдущего выпуска. Инструкции по обновлению см. в CHANGELOG.md.

Полностью пройдены тесты приёмки для HTTPS-заглушки, сквозных сценариев MCP и межсетевого экрана panosvm в лабораторной среде, настроенной явно. Phase 1 завершён; воспроизводимые результаты приведены в docs/PHASE1_ACCEPTANCE.md.

Результаты приёмки Phase 2 приведены в docs/PHASE2_ACCEPTANCE.md. Результаты приёмки изменений конфигурации — в docs/PHASE3_ACCEPTANCE.md, требования к эксплуатации — в docs/PHASE3_OPERATIONS.md.

Результаты приёмки выпуска Phase 4 приведены в docs/PHASE4_ACCEPTANCE.md. Развёртывание в production-среде, ротация, резервное копирование и восстановление, а также обновления описаны в docs/OPERATIONS.md. См. также docs/COMPATIBILITY.md, docs/BENCHMARKS.md и SECURITY.md. Рекомендации по созданию учётных записей администраторов PAN-OS с минимально необходимыми привилегиями (они отличаются от описанных выше bearer-ролей MCP) см. в docs/PANOS_ADMIN_ROLES.md.

Справочник по инструментам MCP

Сервер предоставляет 27 инструментов MCP, сгруппированных по типу операций:

Инструменты только для чтения

  • list_devices — Возвращает список устройств PAN-OS, доступных авторизованному пользователю, и безопасные метаданные; никогда не выдаёт ключи API.

  • gather_device_facts — Получает с авторизованного устройства имя хоста, модель, серийный номер, версию, IP-адрес управления и время работы.

  • execute_panos_op — Выполняет на авторизованном устройстве команду PAN-OS XML только для чтения с корневым элементом ``; объём вывода ограничен.

  • get_panos_config — Читает running- или candidate-конфигурацию PAN-OS по проверенному XPath /config на авторизованном устройстве.

  • list_panos_entries — Постранично получает дочерние элементы `` контейнера со списком правил или объектов в виде структурированного JSON. Если rulebase слишком велик, результат помечается как усечённый, а не возвращается ошибка.

  • get_panos_entry_digest — Получает запись конфигурации PAN-OS по указанному XPath и вычисляет её хеш; инструмент предназначен для выявления изменений отдельного правила.

  • list_panorama_device_groups — Возвращает список групп устройств Panorama и серийные номера входящих в них межсетевых экранов.

  • list_panorama_templates — Возвращает список шаблонов Panorama и имена объявленных в них переменных.

  • get_panorama_push_status — Получает общий статус задания commit-all/push в Panorama и статус для каждого целевого межсетевого экрана по идентификатору задания.

  • list_panos_rulebase_entries — Возвращает правила безопасности, правила NAT, адресные объекты или объекты служб для vsys в виде структурированного JSON с постраничной выдачей и отметкой об усечении.

  • get_panos_ha_state — Получает на авторизованном устройстве состояние высокой доступности PAN-OS: включена ли она, режим, состояние локального узла и партнёра.

  • get_panos_license_info — Получает на авторизованном устройстве сведения о лицензиях PAN-OS: функцию, серийный номер, дату выдачи, срок действия и статус истечения.

  • get_panos_content_status — Получает на авторизованном устройстве сведения о версии контента PAN-OS: версию, дату выпуска, статус загрузки и актуальность.

  • get_panos_software_status — Получает на авторизованном устройстве сведения о версии программного обеспечения PAN-OS: версию, дату выпуска, статус загрузки, актуальность и наличие более новой версии.

  • test_panos_security_policy_match — Проверяет, какому правилу безопасности PAN-OS будет соответствовать смоделированный пакет, если такое правило найдётся, на авторизованном устройстве.

  • query_panos_logs — Получает за ограниченный период журналы PAN-OS: traffic, threat, system или config. Результат всегда ограничен по объёму.

Инструменты жизненного цикла candidate-конфигурации (изменение конфигурации)

  • get_candidate_fingerprint — Возвращает отпечаток SHA-256 для всех поддеревьев candidate-конфигурации, разрешённых оператору.

  • stage_panos_config — Добавляет в candidate-конфигурацию PAN-OS одно изменение: set или delete, ограниченное политикой и проверяемое по ожидаемому отпечатку.

  • diff_panos_candidate — Возвращает ограниченную сводку изменений PAN-OS для candidate-конфигурации с указанным отпечатком.

  • validate_panos_candidate — Проверяет подготовленную candidate-конфигурацию и разрешает фиксацию только для той же конфигурации с тем же отпечатком.

  • commit_panos_candidate — Фиксирует только успешно проверенную операцию с точным отпечатком candidate-конфигурации.

  • discard_panos_candidate — Отменяет подготовленную операцию с помощью частичного отката candidate-конфигурации с областью действия администратора.

  • get_panos_operation — Возвращает безопасный статус принадлежащей пользователю операции жизненного цикла candidate-конфигурации PAN-OS.

Инструменты для наборов изменений (v0.2+)

  • create_panos_change_set — Планирует и сохраняет от 1 до 64 упорядоченных действий над candidate-конфигурацией PAN-OS с учётом списка устройств и областей XPath/действий, разрешённых для токена.

  • approve_panos_change_set — Подтверждает точный дайджест набора изменений, если срок его действия не истёк; подтверждение собственного набора запрещено.

  • get_panos_change_set — Возвращает точные действия, дайджест, подтверждение, срок действия и состояние операции для проверки или восстановления.

  • apply_panos_change_set — Применяет независимо подтверждённый набор изменений с одной блокировкой конечной точки и конфигурации; при частичной ошибке выполняется откат.

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

Configuration

Три примера файлов в config/ демонстрируют доступные параметры конфигурации:

  • devices.example.json — перечень устройств с настройками аутентификации, режимами проверки TLS (системные корневые сертификаты, пользовательский CA или точное закрепление конечного сертификата), ограничениями параллельных операций для каждого устройства и необязательным переопределением администратора для операций с кандидатами.

  • tokens.example.json — структура хранилища токенов Bearer: хранение только дайджестов, списки разрешённых устройств и инструментов для каждого токена, необязательные разрешения на изменение (корни XPath, допустимые действия) и временные метки истечения срока действия.

  • devices.mutation.example.json — вариант перечня устройств с примерами настройки корней для изменений и полей рабочего процесса кандидатов, доступных администратору.

В файлах перечня устройств учётные данные не хранятся напрямую: api_key каждого устройства содержит ссылку — {"type": "env", "name": "VAR_NAME"} для переменной среды или {"type": "file", "path": "/protected/path"} для секретного файла с ограниченными правами доступа.

Политика команд (execute_panos_op, test_panos_security_policy_match)

Параметр верхнего уровня policy в файле перечня устройств определяет, какие операционные команды будет выполнять execute_panos_op. То же правило применяется к команде ``, которую формирует сервер и выполняет test_panos_security_policy_match:

  • mode: "allowlist" (запрет при отсутствии явного разрешения; режим по умолчанию) — команда отклоняется, если не соответствует записи в allow (или в allowed_pipes, если вывод передаётся по каналу).

Именно к этому режиму приводится новый файл перечня устройств и файл без раздела policy. В config/devices.example.json приведён начальный набор команд только для чтения:

"policy": {
  "mode": "allowlist",
  "allow": [
    "show system info",
    "show interface all",
    "show routing route",
    "show running security-policy",
    "show session info",
    "test security-policy-match"
  ]
}

Записи списка разрешённых команд сопоставляются с точными путями тегов элементов из XML-структуры самой команды, а не с текстом CLI. Сокращения не раскрываются: например, сокращённая команда sh sys info будет отклонена так же, как и любая другая команда, которой нет в allow. Для выполнения test_panos_security_policy_match в режиме allowlist обязательна запись test security-policy-match. Без неё каждый вызов будет отклонён независимо от остальных настроек.

  • mode: "blocklist" (разрешение по умолчанию при отсутствии запрета; устаревший режим) — разрешены все команды, кроме тех, что соответствуют правилу запрета в blocklist.commands устройства. Для обратной совместимости файл перечня устройств с правилами запрета, но без явного ключа policy.mode, загружается в этом режиме. При запуске сервер выводит одно предупреждение WARN, поскольку в режиме blocklist с разрешением по умолчанию нет списка разрешённых команд, который мог бы подстраховать при отсутствии подходящего правила.

Для новых развёртываний следует указывать mode: "allowlist".

Каждое устройство может расширить общие списки policy.allow и policy.allowed_pipes, добавив собственные записи в массивы blocklist.allow и blocklist.allowed_pipes. Они объединяются так же, как сейчас объединяются правила запрета blocklist.commands.

При любом отклонении команды — в обоих режимах — в журнал аудита записывается причина, указанная базовой библиотекой политики.

Журнал аудита

В версии v0.4.0 добавлено структурированное журналирование аудита с помощью общей библиотеки mecmcp-audit. Для каждого вызова инструмента создаётся одно событие с указанием вызывающей стороны, целевых устройств, результата и продолжительности выполнения.

Аудит жизненного цикла набора изменений предоставляет отдельное подтверждение согласования: событие approve_panos_change_set содержит идентификатор набора изменений и дайджест его отпечатка. Это подтверждает, что другой субъект проверил именно тот дайджест, который позднее был применён через apply_panos_change_set.

Параметры аудита

  • --audit-format {text|json} — формат событий: text (по умолчанию, для чтения человеком) или json (для машинного разбора).

  • --audit-log-file — записывать события аудита в файл.

  • --audit-journald — отправлять события аудита в журнал systemd.

  • --audit-redact — заменять указанные поля (имена устройств, идентификаторы вызывающей стороны) псевдонимами на основе HMAC, чтобы передавать журнал в SIEM без раскрытия операционных идентификаторов.

  • --audit-hmac-key-file — путь к ключу HMAC для редактирования данных; обязателен, если включён --audit-redact.

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

Передача в хранилище событий

Журнал аудита не должен оставаться на этом хосте. Этот сервер следует общему для семейства продуктов стандарту — AUDIT-FORWARDING-STANDARD.md.

Запись аудита, существующая только на машине, где она была создана, — это не журнал аудита, а файл на компьютере, оператор которого может быть тем, о ком эта запись составлена.

Формирование записей (реализовано сейчас)

--audit-format json \
--audit-log-file /var/lib/rust-panosmcp/audit.jsonl

Формат JSON обязателен. Формат text предназначен для чтения в терминале и не подходит для машинного разбора. Файл — это артефакт, предназначенный для оператора; его необходимо ротировать, поскольку сервер никогда не очищает его содержимое.

Передача данных (описана, но пока не реализована)

Записи напрямую добавляются в ssdf.audit в виде строк с хеш-цепочкой согласно объединённому контракту SSDF для доказательных данных. Благодаря этому можно обнаружить удаление или изменение строки. Работа отслеживается в mecmcp#292.

Более простой вариант передачи через syslog был разработан, но отклонён: он работоспособен, однако записи в нём не связаны хеш-цепочкой. Все остальные звенья этой схемы изначально защищены от незаметного изменения: дайджесты плана связывают согласования, согласования указывают отдельного субъекта, а token_verified_fields отделяет подтверждённые данные о происхождении от заявленных. Незащищённый последний этап лишил бы систему этой гарантии именно там, где она необходима аудитору. Обоснование зафиксировано в стандарте.

Интерпретация результатов

token_verified_fields указывает поля происхождения данных, достоверность которых подтверждена токеном.

Остальные поля этой группы — client_name, model_id, session_id — заявлены клиентом и ничем не аутентифицированы. Не считайте их равноценными подтверждённым полям.

request_id связывает событие транспортного уровня, событие обработчика и (в Junos) комментарий к фиксации на устройстве.

Безопасность

Полную информацию см. в документах THREAT_MODEL.md и SECURITY.md. Основные положения:

  • Для HTTP обязательна аутентификация — используются токены Bearer, хранение которых ограничено дайджестами SHA-256; секреты в открытом виде не сохраняются.

  • По умолчанию доступны только loopback-интерфейсы — для HTTP за пределами loopback требуется TLS или явный параметр --allow-insecure-bind; для TLS за пределами loopback требуется --allowed-host.

  • Проверка TLS всегда включена — используются системные корневые сертификаты, пользовательский пакет CA или точное закрепление конечного сертификата; доверие при первом использовании и отключение проверки не поддерживаются.

  • Ограниченный ввод-вывод — ограничение размера вывода (512 KiB по умолчанию, максимум 5 MiB), ограничение размера тела запроса (1 MiB по умолчанию), тайм-ауты для всех вызовов PAN-OS.

  • Изменения проходят аудит — операции с кандидатами выполняются последовательно для каждого устройства, фиксируют субъекта и отпечаток, требуют явной фиксации после проверки и сохраняют состояние блокировок и заданий для последующего восстановления.

Справочник CLI

      Проверенный JSON-файл инвентаризации устройств [по умолчанию: devices.json]

-t, --transport Транспорт MCP [по умолчанию: stdio] [допустимые значения: stdio, streamable-http] -H, --host Числовой адрес привязки для Streamable HTTP [по умолчанию: 127.0.0.1] -p, --port TCP-порт для Streamable HTTP [по умолчанию: 30031] --tokens-file Абсолютный путь к файлу токенов-носителей, содержащему только дайджесты --state-file Абсолютный путь к закрытому JSON-файлу для хранения состояния наборов изменений и операций --lab-mode Запустить без контроля двух лиц: наборы изменений одобряются при создании --approval-timeout-secs Срок действия одобрения набора изменений в секундах [по умолчанию: 900] --allow-plane-owned-writes Разрешить деструктивные операции на устройствах под управлением управляющей плоскости --allow-direct-commit Разрешить фиксировать операцию без одобрения набора изменений --tls-cert Абсолютный путь к сертификату в формате PEM; требуется --tls-key --tls-key Абсолютный путь к закрытому ключу в формате PEM; требуется --tls-cert --allow-no-auth Отключить аутентификацию по токену-носителю для локального интерфейса loopback, используемого только при разработке --allow-insecure-bind Разрешить незашифрованное подключение не через loopback за доверенным TLS-прокси --allowed-host Дополнительное допустимое значение HTTP Host. Для нескольких значений указывайте параметр повторно --allowed-origin Допустимый URL источника браузера. Для нескольких значений указывайте параметр повторно --ip-rate-per-minute Максимальное число запросов от одного IP-адреса за скользящую минуту [по умолчанию: 120] --token-rate-per-minute Максимальное число запросов от одного аутентифицированного токена за скользящую минуту [по умолчанию: 240] --request-body-limit Максимальный размер тела запроса Streamable HTTP в байтах [по умолчанию: 1048576] --max-inflight-requests Максимальное число одновременных запросов в обработке от всех клиентов. 0 = без ограничений [по умолчанию: 64] --max-inflight-requests-per-token Максимальное число одновременных запросов в обработке для одного токена-носителя. 0 = без ограничений [по умолчанию: 16] --max-inflight-requests-per-target Максимальное число одновременных запросов в обработке для одного целевого устройства. 0 = без ограничений [по умолчанию: 4] --max-sessions Максимальное число одновременных сессий MCP. 0 = без ограничений [по умолчанию: 128] --max-sessions-per-token Максимальное число одновременных сессий MCP для одного токена-носителя. 0 = без ограничений [по умолчанию: 16] --enable-metrics Публиковать метрики Prometheus без аутентификации по адресу /metrics (только для streamable-http) --audit-format Формат журнала аудита: text или json [по умолчанию: text] --audit-log-file Необязательный путь к отдельному JSON-файлу журнала аудита --audit-journald Включить приёмник аудита journald для событий с target="audit" --audit-redact Необязательная политика маскирования отдельных полей (например, devices=hmac,host=drop) --audit-hmac-key-file Файл ключа HMAC для маскирования данных аудита (обязателен, если в audit-redact запрошен hmac) --ssdf-audit-endpoint Конечная точка ClickHouse для приёмника данных SSDF. Включает конвейер --ssdf-audit-server-id Идентификатор цепочки для этого средства записи. Обязателен, если задана конечная точка --ssdf-audit-database База данных ClickHouse с таблицей аудита [по умолчанию: ssdf] --ssdf-audit-user Учётная запись только для записи INSERT [по умолчанию: ssdf_audit] --ssdf-audit-password-file Файл с паролем учётной записи для записи. Права доступа должны быть 0600 --ssdf-audit-verify-user Учётная запись только для чтения SELECT, используемая для чтения верхней границы и хвостовых записей [по умолчанию: ssdf_audit_verify] --ssdf-audit-verify-password-file Файл с паролем учётной записи для чтения. Права доступа должны быть 0600 --ssdf-audit-ca-file Сертификат центра сертификации в формате PEM для проверки сертификата ClickHouse. Обязателен для https:// --ssdf-audit-outbox Надёжная очередь исходящих данных для закрытых сегментов. Обязательна, если задана конечная точка --ssdf-audit-ledger Журнал доставки. Обязателен, если задана конечная точка --ssdf-audit-interval-secs Интервал между попытками доставки в секундах. Должен быть положительным [по умолчанию: 30] --ssdf-audit-records-per-segment Число записей в сегменте до его закрытия и помещения в очередь [по умолчанию: 64] -h, --help Показать справку (подробности — с помощью '--help') -V, --version Показать версию

Подкоманды Token: add Создать токен, сохранить только его дайджест и однократно вывести секрет list Показать имена токенов и области действия без секретов и дайджестов revoke Отозвать токен по имени rotate Заменить секрет токена, сохранив его области действия set-scopes Заменить области действия или права на изменение токена, сохранив его секрет

Подкоманды State: resolve Пометить операцию с неопределённым результатом как завершённую после ручной сверки с PAN-OS">

Secure, async MCP server for PAN-OS firewalls

Usage: rust-panosmcp [OPTIONS] [COMMAND]

Commands:
  token  Manage the digest-only bearer-token store
  state  Perform offline recovery on the private mutation-state file
  help   Print this message or the help of the given subcommand(s)

Options:
  -f, --device-mapping <DEVICE_MAPPING>
          Проверенный JSON-инвентарь устройств [по умолчанию: devices.json]
  -t, --transport <TRANSPORT>
          Транспорт MCP [по умолчанию: stdio] [допустимые значения: stdio, streamable-http]
  -H, --host <HOST>
          Числовой адрес привязки для Streamable HTTP [по умолчанию: 127.0.0.1]
  -p, --port <PORT>
          TCP-порт для Streamable HTTP [по умолчанию: 30031]
      --tokens-file <TOKENS_FILE>
          Абсолютный путь к файлу токенов Bearer, содержащему только дайджесты
      --state-file <STATE_FILE>
          Абсолютный путь к закрытому JSON-файлу для постоянного хранения наборов изменений и состояния операций
      --lab-mode
          Запуск без контроля по принципу двух лиц: наборы изменений утверждаются при создании
      --approval-timeout-secs <APPROVAL_TIMEOUT_SECS>
          Время действия утверждения набора изменений в секундах [по умолчанию: 900]
      --allow-plane-owned-writes
          Разрешить деструктивные операции на устройствах, принадлежащих плоскости управления
      --allow-direct-commit
          Разрешить фиксацию операции без утверждения набора изменений
      --tls-cert <TLS_CERT>
          Абсолютный путь к сертификату PEM; требует `--tls-key`
      --tls-key <TLS_KEY>
          Абсолютный путь к закрытому ключу PEM; требует `--tls-cert`
      --allow-no-auth
          Отключить Bearer-аутентификацию для локального интерфейса разработки
      --allow-insecure-bind
          Разрешить незашифрованное подключение не к loopback-интерфейсу за доверенным TLS-прокси
      --allowed-host <ALLOWED_HOST>
          Дополнительное допустимое значение HTTP Host. Для нескольких значений укажите параметр повторно
      --allowed-origin <ALLOWED_ORIGIN>
          Допустимый URL источника браузера. Для нескольких значений укажите параметр повторно
      --ip-rate-per-minute <IP_RATE_PER_MINUTE>
          Допустимое число запросов от одного исходного IP-адреса за скользящий минутный интервал [по умолчанию: 120]
      --token-rate-per-minute <TOKEN_RATE_PER_MINUTE>
          Допустимое число запросов на один аутентифицированный токен за скользящий минутный интервал [по умолчанию: 240]
      --request-body-limit <REQUEST_BODY_LIMIT>
          Максимальный размер тела запроса Streamable HTTP в байтах [по умолчанию: 1048576]
      --max-inflight-requests <MAX_INFLIGHT_REQUESTS>
          Максимальное число одновременно обрабатываемых запросов от всех вызывающих сторон. 0 = без ограничений [по умолчанию: 64]
      --max-inflight-requests-per-token <MAX_INFLIGHT_REQUESTS_PER_TOKEN>
          Максимальное число одновременно обрабатываемых запросов на один токен Bearer. 0 = без ограничений [по умолчанию: 16]
      --max-inflight-requests-per-target <MAX_INFLIGHT_REQUESTS_PER_TARGET>
          Максимальное число одновременно обрабатываемых запросов на целевое устройство. 0 = без ограничений [по умолчанию: 4]
      --max-sessions <MAX_SESSIONS>
          Максимальное число одновременных сеансов MCP. 0 = без ограничений [по умолчанию: 128]
      --max-sessions-per-token <MAX_SESSIONS_PER_TOKEN>
          Максимальное число одновременных сеансов MCP на один токен Bearer. 0 = без ограничений [по умолчанию: 16]
      --enable-metrics
          Открыть доступ к метрикам Prometheus без аутентификации по адресу /metrics (только для streamable-http)
      --audit-format <AUDIT_FORMAT>
          Формат журнала аудита: `text` или `json` [по умолчанию: text]
      --audit-log-file <AUDIT_LOG_FILE>
          Необязательный путь к отдельному файлу журнала аудита в формате JSON
      --audit-journald
          Включить приём аудиторских событий journald с `target="audit"`
      --audit-redact <AUDIT_REDACT>
          Необязательная политика маскирования отдельных полей (например, `devices=hmac,host=drop`)
      --audit-hmac-key-file <AUDIT_HMAC_KEY_FILE>
          Файл ключа HMAC для маскирования аудита (обязателен, если в audit-redact запрошен hmac)
      --ssdf-audit-endpoint <SSDF_AUDIT_ENDPOINT>
          Конечная точка ClickHouse для приёмника свидетельств SSDF. Включает конвейер
      --ssdf-audit-server-id <SSDF_AUDIT_SERVER_ID>
          Идентификатор цепочки для этого средства записи. Обязателен, если указана конечная точка
      --ssdf-audit-database <SSDF_AUDIT_DATABASE>
          База данных ClickHouse с таблицей аудита [по умолчанию: ssdf]
      --ssdf-audit-user <SSDF_AUDIT_USER>
          Учётная запись с правами только на INSERT [по умолчанию: ssdf_audit]
      --ssdf-audit-password-file <SSDF_AUDIT_PASSWORD_FILE>
          Файл с паролем учётной записи для записи. Права доступа должны быть 0600
      --ssdf-audit-verify-user <SSDF_AUDIT_VERIFY_USER>
          Учётная запись с правами только на SELECT для чтения верхней границы и хвоста [по умолчанию: ssdf_audit_verify]
      --ssdf-audit-verify-password-file <SSDF_AUDIT_VERIFY_PASSWORD_FILE>
          Файл с паролем учётной записи для чтения. Права доступа должны быть 0600
      --ssdf-audit-ca-file <SSDF_AUDIT_CA_FILE>
          Корневой сертификат PEM для проверки сертификата ClickHouse. Обязателен для `https://`
      --ssdf-audit-outbox <SSDF_AUDIT_OUTBOX>
          Надёжная очередь исходящих данных для закрытых сегментов. Обязательна, если указана конечная точка
      --ssdf-audit-ledger <SSDF_AUDIT_LEDGER>
          Журнал доставки. Обязателен, если указана конечная точка
      --ssdf-audit-interval-secs <SSDF_AUDIT_INTERVAL_SECS>
          Интервал между попытками доставки в секундах. Должен быть положительным числом [по умолчанию: 30]
      --ssdf-audit-records-per-segment <SSDF_AUDIT_RECORDS_PER_SEGMENT>
          Число записей в сегменте, после которого сегмент закрывается и помещается в очередь [по умолчанию: 64]
  -h, --help
          Показать справку (подробности: '--help')
  -V, --version
          Показать версию

Подкоманды для токенов:
  add         Создать токен, сохранить только его дайджест и однократно вывести секрет
  list        Показать имена токенов и области действия без секретов и дайджестов
  revoke      Отозвать токен с указанным именем
  rotate      Заменить секрет токена, сохранив его области действия
  set-scopes  Заменить области действия или разрешения на изменение, сохранив секрет токена

Подкоманды для состояния:
  resolve  Пометить неопределённую операцию как завершённую после ручной сверки PAN-OS

--lab-mode

--lab-mode отменяет требование второго субъекта для лабораторной среды с одним оператором, где контроль по принципу «двух человек» был бы лишь формальностью. По умолчанию режим отключён; его следует оставить отключённым везде, где важна безопасность инфраструктуры.

Что меняется и что остаётся без изменений:

  • Отмена требования применяется автоматически при создании набора изменений. Отдельной команды для отмены нет, а последовательность действий остаётся такой же, как в production: создание → применение.

  • Планирование, дайджест плана, обнаружение отклонений и повторная проверка во время применения выполняются по-прежнему. Lab mode отменяет требование второго проверяющего, но не удаляет запись об изменении.

  • Одобрение никогда не подделывается. В записи набора изменений, созданного с отменой требования, указывается approver: null и approval_waiver: "lab-mode", а также сохраняется дайджест отмены, рассчитанный по (change_set_id, plan_digest, owner, approved_at). Его можно криптографически отличить от настоящего одобрения двумя людьми, и задним числом переименовать его нельзя. Это важно, если впоследствии потребуется подтвердить, какие изменения действительно прошли разделение обязанностей.

  • При каждом запуске сервера с включённым режимом выводится заметное предупреждение.

Чтобы тестировать запись в одиночку, не отменяя контроль, создайте два токена с разными именами: одним создайте набор изменений, другим одобрите его. Субъектом считается имя токена, а самоодобрение запрещено. Так один человек сможет пройти весь жизненный цикл изменений, сохранив контроль. Это предпочтительный вариант везде, где формальная процедура имеет значение.

Включение режима

Добавьте флаг в unit сервиса. При установке из пакета используйте drop-in-файл, а не редактируйте поставляемый unit: иначе обновление может незаметно удалить настройку.

sudo systemctl edit rust-panosmcp

При замене ExecStart его нужно указать полностью. Поэтому скопируйте поставляемую команду и добавьте флаг, не сокращая её. Удаление других аргументов может незаметно изменить расположение файла состояния или настройки транспорта:

[Service]
# Перед заменой очистите поставляемый ExecStart: иначе systemd добавит новую команду к существующей.
ExecStart=
ExecStart=/usr/local/bin/rust-panosmcp \
    --device-mapping /etc/rust-panosmcp/devices.json \
    --transport streamable-http \
    --host 127.0.0.1 \
    --port 30031 \
    --tokens-file /var/lib/rust-panosmcp/tokens.json \
    --state-file /var/lib/rust-panosmcp/mutation-state.json \
    --lab-mode

Перед применением сверьте команду с packaging/systemd/rust-panosmcp.service: именно поставляемые аргументы являются эталоном, а этот пример может устареть.

sudo systemctl daemon-reload && sudo systemctl restart rust-panosmcp

Убедитесь, что настройка вступила в силу. В текстовом сообщении при запуске используется lab mode, а в описании результата — approval_waiver=lab-mode:

sudo journalctl -u rust-panosmcp --since='5 minutes ago' | grep -i lab

Ожидаемый вывод:

Aug 15 12:34:56 host rust-panosmcp[1234]: lab mode enabled: change sets are approved on creation with no second principal. Records carry approval_waiver=lab-mode. Do not run this against production devices.

Для токенов утверждающих требуется значение human

approve_panos_change_set принимает только второго субъекта, чей токен помечен как actor_type: human. Токенам, выпущенным без --actor-type, присваивается значение unknown; в качестве утверждающих они не принимаются. Токены типа agent также не подходят. Выпускайте токены утверждающих командой rust-panosmcp token add ... --actor-type human. Сеансы stdio не содержат сведений о вызывающей стороне и не могут использоваться для одобрения; одобрение выполняется через аутентифицированный HTTP.

--allow-direct-commit

Если commit_panos_candidate вызывается для операции, созданной непосредственно через stage_config, а не через create_panos_change_set / approve_panos_change_set / apply_panos_change_set, он выполняет подготовку, проверку и фиксацию в рамках одного жизненного цикла без независимой проверки вторым субъектом: для неё просто нет набора изменений. По умолчанию этот режим отключён: без указанного флага фиксация отклоняется до любого обращения к межсетевому экрану — одинаково для stdio и HTTP. В stdio отсутствует контекст вызывающей стороны, поэтому этот способ не может считаться более доверенным, чем аутентифицированный сеанс.

Остаточный риск. --allow-direct-commit — это обходной путь, а не устранение проблемы. Оператор, включающий этот флаг, принимает решение о том, что для данного развёртывания допустимо выполнять именно этот сценарий без независимой проверки. Это решение:

  • Сопровождается заметным сообщением при запуске, как и в случае с --lab-mode.

  • Фиксируется в журнале при каждом вызове. Для вызова commit_panos_candidate, выполненного с включённым флагом, в записи аудита указывается direct_commit_allowed=true. Отказ также фиксируется: authorization=denied и reason=direct_commit_disabled.

Флаг не добавляет проверку вторым субъектом — он лишь делает заметным выполнение операции без такой проверки. По возможности используйте процесс с набором изменений (create_panos_change_set → approve_panos_change_set → apply_panos_change_set), а этот флаг оставьте для операций, которые действительно невозможно выполнить по этой схеме.

Включите флаг так же, как --lab-mode: добавьте --allow-direct-commit в ExecStart unit сервиса через systemd drop-in-файл, полностью скопировав поставляемую команду. Убедитесь, что настройка вступила в силу. В отличие от сообщения о lab mode, это сообщение намеренно не включено в схему аудита с данными по отдельным вызовам, поэтому найдите обычное сообщение при запуске:

sudo journalctl -u rust-panosmcp --since='5 minutes ago' | grep -i "allow-direct-commit is enabled"

Проверка

cargo fmt --all -- --check
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo test --workspace --locked
cargo check --manifest-path fuzz/Cargo.toml --bins --locked
scripts/verify-packaging.sh

Создайте детерминированный архив релиза с помощью scripts/build-release.sh либо

скомпилируйте проект дважды и проверьте побайтовое совпадение результатов с помощью

scripts/verify-reproducible-build.sh. Инструкции по установке в контейнере и через systemd

приведены в руководстве для операторов.

Лицензия

Лицензия MIT.


проект mechub · детерминированность определяет результат · модель объясняет · человек одобряет

github.com/fastrevmd-lab