Files
NODEDC_PLATFORM/device-plane/docs/ROBOT2B_B2_VPS_CONFIGURATION_BIBLE_2026-08-06.md
T

25 KiB
Raw Blame History

Robot2B B2 VPS — конфигурационная Библия

Замороженная историческая конфигурация — 10.08.2026

Не применять описанные ниже backhaul, relay, Tailscale/SSH LocalForward, Synology enrollment или открытие 9921. Целевой транспорт заменён на Core-initiated mTLS full-duplex channel по docs/ADR_0001_CORE_INITIATED_EDGE_CHANNEL.md. Документ сохраняется как evidence уже выполненных экспериментов и текущего predecessor VPS.

Статус документа: живой manual реализации от 2026-08-06.

Контур: Robot2B / NODE.DC Device Plane.

VPS: 155.212.211.15, hostname koffyvngij.

1. Назначение

VPS является минимальным публичным Device Edge для трекеров Arnavi B2. Он не владеет бизнес-логикой, протоколом, БД, карточками устройств, визуализацией или командами. Его единственная целевая функция — принять ограниченный поток raw TCP на 155.212.211.15:9921, не интерпретируя пакет, и передать его по шифрованному private backhaul в уже существующий device-gateway NODE.DC.

Gelios остаётся отдельным legacy-источником. Эта конфигурация не меняет Gelios, DNS device.nodedc.ru, маршруты B2 или command transport.

flowchart LR
  B2["Arnavi B2 trackers"]
  VPS["Device Edge VPS\n155.212.211.15:9921"]
  TS["Tailscale userspace\nSOCKS5 127.0.0.1:1055"]
  SSH["SSH local forward\n127.0.0.1:19921"]
  TARGET["Synology device-backhaul-target\n100.109.216.21:2222"]
  GW["device-gateway\n127.0.0.1:9921"]
  CORE["device-control-core + PostgreSQL"]
  FOUNDRY["Foundry / visualization"]
  GELIOS["Gelios legacy source"]

  B2 -->|"raw TCP, planned route"| VPS
  VPS --> TS -->|"grant: tag:device-edge-vps → TCP/2222 only"| SSH --> TARGET --> GW --> CORE --> FOUNDRY
  GELIOS -->|"independent legacy ingest"| CORE

2. Красные границы

  • На VPS нет базы данных и durable telemetry storage.
  • VPS не разбирает Arnavi/B2 protocol и не принимает решения по IMEI.
  • IMEI остаётся claimed identifier, а не доказательством владения устройством.
  • Неизвестное устройство должно попадать в quarantine/discovery lifecycle.
  • Command transport отключён. Команды через VPS или Gelios не вводятся.
  • Gelios не выключается и не перетирается новым потоком.
  • На Synology не публикуется Docker-порт 2222; доступ только через private Tailscale Serve.
  • Public VPS не является пользовательским tailnet-узлом. Его service identity tag:device-edge-vps может инициировать только TCP к 100.109.216.21:2222.
  • VPS не принимает subnet routes, DNS tailnet, exit-node capability или Tailscale SSH. Доступ к DSM, MacBook и другим tailnet-узлам запрещён.
  • Приватные ключи, auth keys, токены и пароли не входят в Git, deploy artifacts, Ops или этот документ.
  • До отдельного pilot/cutover не меняются device.nodedc.ru и настройки B2.

3. Фактический predecessor VPS

Снято до первого apply:

  • Ubuntu 24.04.4 LTS, kernel 6.8.0-137-generic, KVM/QEMU.
  • 1 vCPU, 961 MiB RAM, swap отсутствует.
  • Root filesystem около 8.7 GiB; свободно около 6.4 GiB.
  • eth0: 155.212.211.15/32, default gateway 100.100.1.1.
  • Публично слушал только TCP/22; TCP/9921 был закрыт.
  • Docker, Node.js, Tailscale и WireGuard отсутствовали.
  • fail2ban, NTP и unattended upgrades были активны.
  • UFW был inactive, nftables/iptables использовали INPUT ACCEPT.
  • SSH допускал root/password и forwarding; это устранено foundation-переходом.

4. Канонические переходы

Конфигурация разделена на независимые data-only артефакты. Порядок нельзя переставлять.

  1. foundation:
    • pin статических Node.js и Tailscale runtimes;
    • service account nodedc-edge;
    • key-only SSH;
    • default-deny nftables, публично только TCP/22;
    • отдельный ED25519 backhaul key, сгенерированный на VPS;
    • userspace tailscaled, но без скрытого auth key;
    • TCP/9921 закрыт.
  2. Внешняя регистрация и сегментация nodedc-b2-vps в существующем tailnet:
    • заменить default wildcard policy на проверяемую deny-by-default policy;
    • назначить tag:device-edge-vps, тем самым удалить user ownership;
    • разрешить тегу только 100.109.216.21:2222/tcp;
    • отрицательно проверить Synology 22/5001, MacBook 22 и другие узлы;
    • только после этого вернуть Tailscale service в состояние Running.
  3. Synology backhaul-vps-enrollment:
    • принять только публичный VPS key через enrollment;
    • заменить прежний Mini key;
    • пересоздать только device-backhaul-target;
    • сохранить Device Plane, PostgreSQL, Tailscale Serve и Gelios;
    • при ошибке автоматически вернуть прежний key и target generation.
  4. VPS backhaul:
    • pinned Synology host key;
    • key-only SSH через Tailscale userspace SOCKS5;
    • 127.0.0.1:19921 -> 127.0.0.1:9921;
    • публичный TCP/9921 всё ещё закрыт.
  5. VPS relay:
    • открыть публичный TCP/9921;
    • bounded opaque relay на 127.0.0.1:19921;
    • loopback health на 127.0.0.1:18221.
  6. Отдельный pilot: изменить адрес сервера у ограниченной группы B2. Это не часть конфигурации VPS.

5. Идентичности и ключи

5.1 Management SSH

Команда с MacBook:

ssh -i ~/.ssh/nodedc_b2_vps \
  -o IdentitiesOnly=yes \
  -o StrictHostKeyChecking=yes \
  root@155.212.211.15

В Ops и manual фиксируются только путь и fingerprints:

  • локальный private key path: ~/.ssh/nodedc_b2_vps;
  • MacBook management public key fingerprint: SHA256:DYYy1E3DaxIQGC0jnsW6SP7gXdBHUy3A1zn4pvgVUEw (ED25519);
  • VPS SSH server host key fingerprint: SHA256:mhqNn2S6zstkYL7VFdvt3SYHv1nLjB4J7/s57RrKG6w (ED25519).

Foundation принудительно задаёт:

  • PermitRootLogin prohibit-password;
  • AuthenticationMethods publickey;
  • PasswordAuthentication no;
  • KbdInteractiveAuthentication no;
  • forwarding, agent forwarding, X11 и tunnels запрещены;
  • MaxAuthTries 3, LoginGraceTime 20.

В /root/.ssh/authorized_keys остаются две management identity:

  • MacBook ED25519 — fingerprint выше;
  • provider recovery key beget-access-key, RSA 1024, fingerprint SHA256:9W1cgovqOlegteEWV0r5j4OjJgG0PGr97eVmpUBjg54.

RSA-1024 provider key — остаточный риск. Он не удалён автоматически, потому что отзыв внешнего recovery-доступа является отдельным необратимым решением. После подтверждения владельца нужно либо удалить его отдельным каноническим переходом, либо документировать как принятый break-glass access.

5.2 VPS backhaul client identity

Private key генерирует root-owned runner непосредственно на VPS:

  • private: /var/lib/nodedc-b2-vps/trust/backhaul_ed25519, owner nodedc-edge на foundation и nodedc-backhaul после backhaul apply, mode 0400;
  • public: /var/lib/nodedc-b2-vps/trust/backhaul_ed25519.pub, mode 0444;
  • fingerprint: SHA256:HHTiDYiCRxSiKjBLCip6JMSzGfLGrDz5g8SIkosJcVw;
  • public key: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGUlvJ8a83qov9DHO2S/BHbVAEH4Chyc4v/DKwOIWeES nodedc-device-edge-vps-backhaul.

В Synology staging этот public key хранится по пути:

/volume1/docker/nodedc-device-plane/enrollment/device-edge-vps-backhaul.pub

Private key никогда не покидает VPS.

Foundation генерирует ключ до появления публичного relay, поэтому его временным владельцем является nodedc-edge. Backhaul transition атомарно создаёт nodedc-backhaul, передаёт ему каталог trust и ключ и валидирует mode. Relay запускается как третий пользователь nodedc-relay; он не может читать ни private key, ни Tailscale state. Даже локальный доступ relay к SOCKS5 не расширяет полномочия: tailnet grant разрешает только target 2222, где аутентификация дополнительно требует private key пользователя nodedc-backhaul.

5.3 Synology backhaul target identity

  • Tailnet IP: 100.109.216.21.
  • Private SSH endpoint: 100.109.216.21:2222 через Tailscale Serve.
  • User: device-backhaul.
  • PermitOpen: только 127.0.0.1:9921.
  • Host key fingerprint: SHA256:QERJ5CIUXRj0nLChGT6HMtoX+WTaeaEY5ZgaWqT8d30.
  • Public host key: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJsmoyS+0Tbhz9VXxrSxXwNMFpfbdTckCilObOnKdlEc nodedc-device-plane-backhaul-target.
  • VPS pinned known_hosts: /var/lib/nodedc-b2-vps/trust/backhaul_known_hosts.

5.4 Tailscale service identity и grant

Живая policy сохранена 2026-08-06. Каноническая копия: device-plane/deployment/tailscale-device-edge-policy.hujson.

  • autogroup:member -> autogroup:self, все протоколы: сохраняет привычный доступ пользователя только между собственными user-owned устройствами;
  • tag:device-edge-vps -> device-plane-backhaul, только tcp:2222;
  • device-plane-backhaul = 100.109.216.21;
  • tag owner: только autogroup:admin;
  • policy test требует accept 100.109.216.21:2222 и deny для Synology 22/5001, MacBook 22, nodedc-device-edge:22.

Назначение тега удалило dcctouch@gmail.com из поля Managed by; живой VPS управляется tag:device-edge-vps. После включения проверено с самого VPS:

  • 100.109.216.21:2222 — reachable;
  • 100.109.216.21:22 — blocked;
  • 100.109.216.21:5001 — blocked;
  • 100.114.248.4:22 — blocked;
  • 100.64.19.31:22 — blocked.

Enrollment запускается с --accept-dns=false --accept-routes=false --ssh=false. Runner для backhaul/relay дополнительно требует BackendState=Running, online hostname nodedc-b2-vps и ровно один tag tag:device-edge-vps.

6. Runtime и файловая система VPS

6.1 Root-owned source/runtime

  • runner: /usr/local/sbin/nodedc-b2-vps-deploy;
  • live root: /opt/nodedc-b2-vps;
  • deploy state: /var/lib/nodedc-b2-vps-deploy;
  • inbox: /var/lib/nodedc-b2-vps-deploy/inbox;
  • applied/failed artifacts: applied/, failed/;
  • backups: backups/;
  • journals: state/applied.jsonl, state/failed.jsonl;
  • lock: state/deploy.lock;
  • service state/trust: /var/lib/nodedc-b2-vps.

6.2 Pinned runtimes

  • Node.js 22.23.2; archive SHA-256 d60acfe00a2932254bb0ad20e01b0d74397a0875595de719654b214f4b03f307.
  • Tailscale 1.102.2; archive SHA-256 ad2cde12f8de95f7b93a1e0401e652291c603d42b9d60a33fb1741eb38ab04d8.

Docker не устанавливается: для 961 MiB RAM он не нужен и добавляет лишний daemon/state surface.

6.3 systemd units

  • nodedc-b2-tailscaled.service:
    • user nodedc-edge;
    • userspace networking, без TUN;
    • socket /run/nodedc-b2-vps/tailscaled.sock;
    • SOCKS5 127.0.0.1:1055;
    • MemoryMax=160M;
    • разрешены AF_UNIX AF_INET AF_INET6 AF_NETLINK.
  • nodedc-b2-backhaul.service:
    • user nodedc-backhaul, единственный читатель backhaul private key;
    • strict host key pinning;
    • local forward 127.0.0.1:19921;
    • MemoryMax=64M.
  • nodedc-b2-relay.service:
    • user nodedc-relay, без credential access;
    • public 0.0.0.0:9921;
    • health 127.0.0.1:18221;
    • upstream 127.0.0.1:19921;
    • MemoryMax=192M.

Все units используют NoNewPrivileges, ProtectSystem=strict, ProtectHome=yes, PrivateTmp, PrivateDevices, ограничение address families, tasks и file descriptors.

7. Firewall и порты

Foundation nftables policy:

  • input: default drop;
  • loopback, established/related и ICMP разрешены;
  • новый TCP/22 ограничен 30/minute, burst 60;
  • TCP/9921 отсутствует;
  • forward: default drop;
  • output: accept.

Relay policy добавляет:

  • drop новых соединений на TCP/9921 сверх 300/second;
  • accept TCP/9921 после rate guard.

Портовая матрица:

Endpoint Видимость Владелец Стадия
155.212.211.15:22 public OpenSSH foundation
127.0.0.1:1055 loopback tailscaled SOCKS5 foundation
127.0.0.1:19921 loopback SSH local forward backhaul
127.0.0.1:18221 loopback relay health relay
155.212.211.15:9921 public bounded relay relay
100.109.216.21:2222 tailnet grant только для VPS tag Synology target existing
127.0.0.1:9921 на Synology loopback device-gateway existing

8. Relay limits

  • max concurrent sessions: 128;
  • max sessions per source IP: 16;
  • max new connections/minute/source IP: 60;
  • max tracked source IPs: 4096;
  • max bytes per direction/session: 64 MiB;
  • session timeout: 300000 ms;
  • source policy: public-ipv4-only;
  • protocol inspection: disabled на VPS;
  • command transport: disabled.

9. Установленный foundation release

Принят 2026-08-06:

  • patch: device-edge-vps-foundation-20260806-003;
  • artifact SHA-256: 1be852f144e9f0fea32af70bebd07a2607b6a1818825094bd4c1b4062064716a;
  • foundation-time runner SHA-256: 3f42d23431937e70c16ce1fd346fb84a706e506ae99d89eaf11780ff1ad56c03;
  • current promoted runner SHA-256: 5ccdc1b53ce0688e7c120976e82937842bc8491a2e05eb5f280165accfd40b6c;
  • backup: device-edge-vps-foundation-20260806-003-20260806-151415;
  • terminal result: deploy-ok;
  • fresh MacBook key-only SSH acceptance: success.

Два предыдущих ID терминальны и никогда не должны применяться повторно:

  • ...-001: tailscaled заблокирован отсутствием AF_NETLINK; automatic rollback ok;
  • ...-002: cloud-init 50-cloud-init.conf опередил 90-* и сохранил PasswordAuthentication yes; automatic rollback ok;
  • ...-003: исправлены AF_NETLINK и ранний 00-nodedc-b2-vps.conf; acceptance успешна.

Следующие exact isolation-aware artifacts стадированы в VPS inbox и не применяются до своих predecessor barriers:

  • backhaul device-edge-vps-backhaul-20260806-002, SHA-256 830750da8f9590ca4db458ec9e90f4d48ad8d1403160d3878a968b54e9eb6913;
  • relay device-edge-vps-relay-20260806-002, SHA-256 305a6de769f24b2c6cee801426ec43b98a44d10e08cad75a96fd65d20b16b697.

Версии ...-001 не применялись и recoverably перемещены из inbox в /var/lib/nodedc-b2-vps-deploy/withdrawn/*.superseded-by-002, потому что в них все три процесса использовали один Unix account nodedc-edge.

10. Synology VPS enrollment release

Стадировано, но до авторизации Tailscale и root plan/apply не считается применённым:

  • runner candidate: /volume1/docker/nodedc-deploy/runner-install/candidates/nodedc-deploy.device-plane-backhaul-vps-enrollment-20260806-011;
  • runner SHA-256: 453228c41b411d9c925091c77dc94e501f2eb3534fc241db0d2e58f0a28e12e2;
  • artifact: /volume1/docker/nodedc-deploy/inbox/nodedc-device-plane-device-plane-backhaul-vps-enrollment-20260806-001.tgz;
  • artifact SHA-256: 576dabdafde5e3b2de09c7265127928c4b463e7b40dd554fd71babc16cc70e08;
  • VPS enrollment public-key file SHA-256: c2718c117fd09965386524d32fa9816d9d2d9cf00b59010dcf8bcf78f29bea8c.

Root-переход на Synology:

sudo sha256sum \
  /volume1/docker/nodedc-deploy/runner-install/candidates/nodedc-deploy.device-plane-backhaul-vps-enrollment-20260806-011

sudo install -o root -g root -m 0755 \
  /volume1/docker/nodedc-deploy/runner-install/candidates/nodedc-deploy.device-plane-backhaul-vps-enrollment-20260806-011 \
  /usr/local/sbin/nodedc-deploy

sudo /usr/local/sbin/nodedc-deploy verify-install

sudo /usr/local/sbin/nodedc-deploy plan \
  /volume1/docker/nodedc-deploy/inbox/nodedc-device-plane-device-plane-backhaul-vps-enrollment-20260806-001.tgz

# Apply только после review exact plan.
sudo /usr/local/sbin/nodedc-deploy apply \
  /volume1/docker/nodedc-deploy/inbox/nodedc-device-plane-device-plane-backhaul-vps-enrollment-20260806-001.tgz

Ожидаемый plan обязан показать:

  • predecessor patch device-plane-backhaul-target-tailnet-serve-20260804-002;
  • predecessor artifact SHA 219408705dd4d80a962ed00eeb53a69df0b9ab6458443734d5c9cd1d1f795eba;
  • build none;
  • recreate только device-backhaul-target;
  • next fingerprint SHA256:HHTi…osJcVw;
  • public ingress disabled;
  • Docker port publication disabled;
  • Tailscale Serve, router/NAT/firewall, PostgreSQL и Gelios unchanged;
  • automatic rollback на previous key + target recreate.

11. Внешняя регистрация Tailscale

На VPS auth key не хранится. Для первой регистрации root запускает:

/opt/nodedc-b2-vps/runtime/tailscale/tailscale \
  --socket=/run/nodedc-b2-vps/tailscaled.sock \
  up \
  --hostname=nodedc-b2-vps \
  --accept-dns=false \
  --accept-routes=false \
  --ssh=false

Одноразовый login URL не копируется в Ops. До включения service владелец tailnet обязан сохранить policy и назначить tag из раздела 5.4. Backhaul plan требует BackendState=Running, online hostname nodedc-b2-vps и exact service tag.

12. Сборка VPS artifacts

Из корня repository platform:

NODEDC_DEVICE_EDGE_VPS_RUNTIME_DIR=/tmp \
node infra/deploy-runner/build-device-edge-vps-artifact.mjs \
  foundation <unique-patch-id>

node infra/deploy-runner/build-device-edge-vps-artifact.mjs \
  backhaul <unique-patch-id>

node infra/deploy-runner/build-device-edge-vps-artifact.mjs \
  relay <unique-patch-id>

Builder создаёт deterministic archive с manifest.env, files.txt и payload/. В artifact запрещены .env, keys, trust, runtime, logs, uploads, node_modules и symlinks. Foundation дополнительно проверяет pinned runtime digests.

Каждый release:

  1. собрать дважды и сравнить SHA-256;
  2. проверить file list и отсутствие секретов;
  3. скопировать exact artifact в VPS inbox;
  4. выполнить свежий plan;
  5. review границ;
  6. выполнить один exact apply;
  7. считать deploy-ok терминальным результатом и не запускать apply повторно.

13. Rollback model

VPS runner перед mutation создаёт backup exact partition и сохраняет текущий nft ruleset и service enablement. При ошибке:

  • candidate services останавливаются;
  • source/config возвращаются;
  • nftables и SSH config восстанавливаются;
  • service enablement возвращается;
  • при failed foundation удаляются созданные live/runtime roots и service user;
  • при failed backhaul ключ возвращается nodedc-edge, а созданный nodedc-backhaul удаляется;
  • при failed relay созданный nodedc-relay удаляется;
  • artifact переносится в failed/;
  • failed ID и digest становятся терминальными.

Synology VPS enrollment отдельно сохраняет previous authorized_keys. При любой ошибке он:

  • удаляет candidate marker;
  • атомарно возвращает прежний restricted key;
  • пересоздаёт только device-backhaul-target;
  • проверяет target, три preserved Device Plane services, Tailscale Serve и loopback 9921.

14. Развёртывание аналогичного VPS

Перед клонированием нельзя просто переиспользовать текущий artifact. Нужно создать новый descriptor/release с новыми параметрами:

  1. Получить чистый Ubuntu 24.04 LTS VPS и зафиксировать hostname, public /32, gateway, CPU/RAM/disk.
  2. Добавить отдельный ED25519 management key и проверить fresh connection.
  3. Зафиксировать server host key fingerprint с доверенного канала.
  4. Проверить active fail2ban/NTP/unattended upgrades и отсутствие listeners, кроме TCP/22.
  5. Изменить pin в runner/descriptor: RUNTIME_HOST, PUBLIC_IPV4, management/server fingerprints и Tailscale node name.
  6. Не переносить private backhaul key: новый VPS должен сгенерировать новую пару самостоятельно.
  7. Собрать deterministic foundation с новым terminal patch ID.
  8. Promoted runner проверить отдельным verify-install.
  9. Сделать plan → review → apply.
  10. Зарегистрировать новый tailnet node без сохранения auth key.
  11. Скопировать только public backhaul key в новый enrollment path.
  12. Выполнить отдельный Synology key rotation/grant transition.
  13. Только после принятого private backhaul применять relay.
  14. Только после relay acceptance перенаправлять ограниченный pilot B2.

15. Acceptance checklist

  • Foundation artifact deterministic и secret-free.
  • Foundation accepted с automatic rollback coverage.
  • Fresh key-only SSH с MacBook работает.
  • Public TCP/9921 не открыт на foundation.
  • Отдельный VPS backhaul public key создан и pinned.
  • Synology enrollment key, runner candidate и artifact стадированы.
  • Tailnet node nodedc-b2-vps авторизован и Running.
  • Tailnet wildcard grant удалён; VPS tagged и negative-route tests пройдены.
  • Isolation-aware VPS runner promoted и verify-install-ok.
  • Synology runner candidate promoted и verify-install-ok.
  • Synology enrollment plan reviewed и deploy-ok.
  • VPS backhaul artifact deploy-ok.
  • VPS relay artifact deploy-ok.
  • Public TCP/9921 принят внешним probe.
  • Pilot B2 route согласован отдельно.
  • Provider RSA-1024 recovery key удалён или принят как documented risk.

16. Исходники и проверки

Канонические файлы:

  • infra/deploy-runner/nodedc-b2-vps-deploy;
  • infra/deploy-runner/build-device-edge-vps-artifact.mjs;
  • infra/deploy-runner/test_device_edge_vps_artifact.py;
  • device-plane/vps/config/;
  • device-plane/vps/systemd/;
  • device-plane/deployment/device-edge-vps-*-v1.json;
  • infra/deploy-runner/nodedc-deploy;
  • infra/deploy-runner/build-device-plane-backhaul-vps-enrollment-artifact.mjs;
  • infra/deploy-runner/test_device_plane_backhaul_vps_enrollment_artifact.py.

Проверки на момент документа:

  • VPS artifact tests: 9/9 OK;
  • Device Plane targeted runner/artifact tests: 48/48 OK;
  • полный platform npm test: 41/41 OK во внешнем сетевом sandbox;
  • Python compilation: OK;
  • systemd unit syntax: OK; отсутствие binaries до foundation было ожидаемым;
  • nft -c foundation/relay: OK;
  • effective candidate OpenSSH policy: key-only;
  • git diff --check: OK для целевых файлов.