diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b24738d --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +.vs/ +.idea/ +.vscode/ +bin/ +obj/ +artifacts/ +TestResults/ +*.user +*.suo +*.pfx +*.key +*.pem +*.token +appsettings.Production.json diff --git a/README.md b/README.md index 73eec8a..7dfb308 100644 --- a/README.md +++ b/README.md @@ -1,29 +1,81 @@ -# Mobile Server Manager +# Server Monitor Manager -Мобильная система управления Linux-серверами: отчёты, безопасные команды, резервные копии и прямые SSH-сессии. +Лёгкая система мониторинга и безопасного управления Linux-серверами с одного ПК. Первый клиент создаётся для Windows; после стабилизации протокола появятся клиенты для других настольных систем и мобильных устройств. -## Структура +## Основные задачи -- `mobile/` — Flutter-клиент для Android и iOS; -- `src/ServerManager.Api/` — ASP.NET Core 10 API, Identity, TOTP 2FA и SignalR; -- `src/ServerManager.Agent/` — исходящий агент управляемого Linux-сервера; -- `deploy/` — установщик и systemd-файлы агента; -- `docs/` — архитектура и модель безопасности. +- единая панель для нескольких личных и рабочих серверов; +- CPU/load, память, корневой диск, задержка и uptime через ограниченный SSH forced-command; +- SSH-терминал и сохранённые подключения без передачи приватных ключей серверу управления; +- группы серверов, теги, избранное и сводные предупреждения; +- явное включение и ручное отключение защищённых связей между серверами; +- ограниченный доступ автоматизированных инструментов, например Hermes, к выбранному серверу разработки; +- маленький Linux-агент без тяжёлой панели, Docker и отдельной базы данных на каждом узле. -## Статус +## Архитектура -Проект находится на раннем этапе разработки. Первая версия API содержит базовую модель пользователей и серверов. Опасные команды, удалённое восстановление и SSH-терминал будут включаться только после реализации аудита, повторного подтверждения и проверки полномочий. +```text +Windows client + | + | HTTPS / WebSocket, mTLS + v +Control node (может работать на одном из ваших серверов) + ^ + | только исходящие соединения агентов + | +Linux agents ---- управляемые WireGuard links ---- Linux agents +``` -Сейчас форма мобильного входа является интерфейсным прототипом и намеренно не пропускает пользователя без API. Управление серверами в API требует включённой TOTP-2FA. Production-запуск заблокирован до подключения PostgreSQL и миграций; агент пока только собирает локальные метрики и не отправляет их без защищённой регистрации. +Мониторинг и межсерверные связи разделены. Регистрация агента не создаёт сетевого туннеля и не выдаёт доступ к SSH. Каждая связь создаётся отдельно, имеет список разрешённых адресов и портов, может иметь срок действия и всегда поддерживает ручной `Disconnect`. -## Требования для разработки +Подробности: [архитектура](docs/architecture.md), [модель безопасности](docs/security-model.md), [план разработки](docs/roadmap.md) и [контракт Linux-установщика](docs/installer-contract.md). -- .NET 10 SDK; -- Flutter stable с Android SDK; -- Android Studio или Android command-line tools; -- для сборки iOS — macOS с Xcode; -- PostgreSQL для production; SQLite используется только при локальной разработке. +## Планируемая структура -Секреты, токены агентов и приватные SSH-ключи не должны попадать в Git. +```text +src/ + ServerMonitorManager.Desktop/ WinUI 3, Windows-first + ServerMonitorManager.Core/ общие модели и сценарии + ServerMonitorManager.Agent/ лёгкий Linux-агент + ServerMonitorManager.Control/ API, события, аудит и координация +docs/ +deploy/ +tests/ +``` -Подробный результат проверки ПК и порядок подготовки среды находятся в [`docs/development-setup.md`](docs/development-setup.md). +## Текущий статус + +Проект находится на стадии первого тестируемого Windows MVP. Репозиторий переименован из `mobile-server-manager`, потому что первой целевой платформой теперь является Windows. Клиент создаёт отдельный Ed25519-ключ, сохраняет профили локально и получает живые метрики серверов через системный OpenSSH. + +Установочный скрипт Linux-части хранится в репозитории [`ochenstarik-ui/lightweight-server`](https://github.com/ochenstarik-ui/lightweight-server) под именем `ochenstarik-server-monitor-manager.sh`. Его копия находится в [`deploy/`](deploy/). Скрипт создаёт отдельного пользователя `ochenstarik-monitor` и SSH forced-command: ключ мониторинга не получает shell, PTY, port forwarding или право выполнять произвольные команды. + +## Быстрый тест на трёх серверах + +1. Запустите Windows-клиент и нажмите `SSH-ключ` → `Копировать`. +2. На каждом Ubuntu/Debian-сервере скачайте и запустите установщик: + +```bash +curl -fLO https://raw.githubusercontent.com/ochenstarik-ui/lightweight-server/main/ochenstarik-server-monitor-manager.sh +chmod 700 ochenstarik-server-monitor-manager.sh +bash -n ochenstarik-server-monitor-manager.sh +sudo ./ochenstarik-server-monitor-manager.sh install +``` + +3. Вставьте скопированный публичный ключ по запросу скрипта. +4. В приложении нажмите `Добавить сервер`, укажите IP/домен, текущий SSH-порт и пользователя `ochenstarik-monitor`. +5. Повторите для остальных серверов и нажмите `Обновить`. + +Приватный ключ хранится в локальном каталоге packaged-приложения Windows. Первый SSH-host key принимается в режиме `accept-new`, затем проверяется по отдельному `known_hosts` приложения. + +## Принципы безопасности + +- никаких общих root-паролей и приватных SSH-ключей в control node; +- на первом SSH-MVP — отдельный ключ мониторинга и pinned `known_hosts`; enrollment tokens появятся вместе с постоянным агентом; +- отдельная идентичность для пользователя, устройства, агента и автоматизации; +- опасные действия требуют повторного подтверждения и попадают в неизменяемый аудит; +- доступ Hermes выдаётся отдельному Unix-пользователю и SSH-ключу с минимальными правами; +- отключение Link удаляет маршруты и peer-конфигурацию, а не только скрывает кнопку в интерфейсе. + +## Лицензия и секреты + +Лицензия будет выбрана до публикации первого исходного релиза. Токены регистрации, ключи WireGuard, SSH-ключи, сертификаты устройств и production-конфигурация не должны попадать в Git. diff --git a/deploy/ochenstarik-server-monitor-manager.sh b/deploy/ochenstarik-server-monitor-manager.sh new file mode 100644 index 0000000..acd8289 --- /dev/null +++ b/deploy/ochenstarik-server-monitor-manager.sh @@ -0,0 +1,162 @@ +#!/usr/bin/env bash +set -Eeuo pipefail + +readonly APP_NAME="ochenstarik-server-monitor-manager" +readonly MONITOR_USER="ochenstarik-monitor" +readonly MONITOR_HOME="/var/lib/${APP_NAME}" +readonly MONITOR_COMMAND="/usr/local/libexec/ochenstarik-server-monitor" +readonly AUTHORIZED_KEYS="${MONITOR_HOME}/.ssh/authorized_keys" + +log() { printf '[+] %s\n' "$*"; } +warn() { printf '[!] %s\n' "$*" >&2; } +die() { printf '[x] %s\n' "$*" >&2; exit 1; } + +require_root() { + [[ "$EUID" -eq 0 ]] || die "Запустите скрипт через sudo" +} + +detect_system() { + [[ -r /etc/os-release ]] || die "Не найден /etc/os-release" + # shellcheck disable=SC1091 + . /etc/os-release + case "${ID:-}" in + ubuntu|debian) ;; + *) die "Поддерживаются Ubuntu и Debian; обнаружено: ${ID:-unknown}" ;; + esac + command -v systemctl >/dev/null 2>&1 || die "Требуется systemd" +} + +read_public_key() { + printf '\nВ Windows-приложении нажмите «SSH-ключ» → «Копировать».\n' + read -rp 'Вставьте публичный ключ: ' PUBLIC_KEY + PUBLIC_KEY="${PUBLIC_KEY//$'\r'/}" + [[ "$PUBLIC_KEY" =~ ^ssh-ed25519[[:space:]]+[A-Za-z0-9+/]+={0,3}([[:space:]].*)?$ ]] \ + || die "Ожидается публичный ключ формата ssh-ed25519 AAAA..." +} + +install_dependencies() { + apt-get update + DEBIAN_FRONTEND=noninteractive apt-get install -y \ + ca-certificates openssh-server openssh-client coreutils gawk + systemctl enable --now ssh +} + +verify_public_key() { + local key_file + key_file="$(mktemp)" + trap 'rm -f -- "${key_file:-}"' RETURN + printf '%s\n' "$PUBLIC_KEY" > "$key_file" + ssh-keygen -l -f "$key_file" >/dev/null \ + || die "ssh-keygen отклонил публичный ключ" + trap - RETURN + rm -f -- "$key_file" +} + +create_monitor_command() { + install -d -m 0755 -o root -g root "$(dirname "$MONITOR_COMMAND")" + [[ ! -L "$MONITOR_COMMAND" ]] \ + || die "Отказ от записи через символическую ссылку: $MONITOR_COMMAND" + cat > "$MONITOR_COMMAND" <<'EOF' +#!/usr/bin/env bash +set -Eeuo pipefail +export LC_ALL=C + +read_mem_value() { + awk -v key="$1" '$1 == key ":" { print $2; exit }' /proc/meminfo +} + +printf 'PROTOCOL=1\n' +printf 'HOSTNAME=%s\n' "$(hostname)" +printf 'UPTIME_SECONDS=%s\n' "$(cut -d. -f1 /proc/uptime)" +printf 'LOAD1=%s\n' "$(cut -d' ' -f1 /proc/loadavg)" +printf 'CPU_COUNT=%s\n' "$(getconf _NPROCESSORS_ONLN)" +printf 'MEM_TOTAL_KB=%s\n' "$(read_mem_value MemTotal)" +printf 'MEM_AVAILABLE_KB=%s\n' "$(read_mem_value MemAvailable)" +df -Pk / | awk 'NR == 2 { + printf "DISK_TOTAL_KB=%s\nDISK_AVAILABLE_KB=%s\n", $2, $4 +}' +printf 'KERNEL=%s\n' "$(uname -r)" +EOF + chown root:root "$MONITOR_COMMAND" + chmod 0755 "$MONITOR_COMMAND" +} + +create_monitor_user() { + if ! getent passwd "$MONITOR_USER" >/dev/null; then + useradd \ + --system \ + --create-home \ + --home-dir "$MONITOR_HOME" \ + --shell /bin/bash \ + "$MONITOR_USER" + fi + usermod --home "$MONITOR_HOME" --shell /bin/bash "$MONITOR_USER" + passwd -l "$MONITOR_USER" >/dev/null 2>&1 || true + + install -d -m 0750 -o "$MONITOR_USER" -g "$MONITOR_USER" "$MONITOR_HOME" + install -d -m 0700 -o "$MONITOR_USER" -g "$MONITOR_USER" "${MONITOR_HOME}/.ssh" + [[ ! -L "$AUTHORIZED_KEYS" ]] \ + || die "Отказ от записи через символическую ссылку: $AUTHORIZED_KEYS" + printf 'restrict,command="%s" %s\n' "$MONITOR_COMMAND" "$PUBLIC_KEY" > "$AUTHORIZED_KEYS" + chown "$MONITOR_USER:$MONITOR_USER" "$AUTHORIZED_KEYS" + chmod 0600 "$AUTHORIZED_KEYS" +} + +verify_sshd() { + sshd -t + sshd -T | grep -qi '^pubkeyauthentication yes$' \ + || die "В sshd отключена аутентификация по публичному ключу" +} + +show_status() { + local ssh_port="unknown" + if command -v sshd >/dev/null 2>&1; then + ssh_port="$(sshd -T 2>/dev/null | awk '$1 == "port" { print $2; exit }')" + fi + printf 'Пользователь: %s\n' "$MONITOR_USER" + printf 'SSH-порт: %s\n' "${ssh_port:-unknown}" + printf 'Команда: %s\n' "$MONITOR_COMMAND" + if [[ -x "$MONITOR_COMMAND" ]]; then + runuser -u "$MONITOR_USER" -- "$MONITOR_COMMAND" + else + warn "Серверная часть ещё не установлена" + fi +} + +install_server_part() { + read_public_key + install_dependencies + verify_public_key + create_monitor_command + create_monitor_user + verify_sshd + systemctl reload ssh + log "Серверная часть установлена" + log "Входящий порт не изменялся, новые правила UFW не создавались" + show_status +} + +uninstall_server_part() { + local answer + read -rp 'Удалить пользователя мониторинга и forced-command? [y/N]: ' answer + [[ "$answer" =~ ^[Yy]$ ]] || { log "Отменено"; return 0; } + rm -f -- "$MONITOR_COMMAND" + if getent passwd "$MONITOR_USER" >/dev/null; then + userdel --remove "$MONITOR_USER" 2>/dev/null || userdel "$MONITOR_USER" + fi + log "Серверная часть удалена" +} + +main() { + local action="${1:-install}" + require_root + detect_system + case "$action" in + install) install_server_part ;; + status) show_status ;; + uninstall) uninstall_server_part ;; + *) die "Использование: $0 [install|status|uninstall]" ;; + esac +} + +main "$@" diff --git a/docs/architecture.md b/docs/architecture.md new file mode 100644 index 0000000..41035a2 --- /dev/null +++ b/docs/architecture.md @@ -0,0 +1,85 @@ +# Архитектура Server Monitor Manager + +## 1. Компоненты + +Для первого тестирования используется переходный режим **SSH pull**: Windows-клиент вызывает на сервере ограниченный forced-command и получает snapshot. Постоянный агент и control node ниже описывают следующий этап после проверки UX на трёх серверах. + +### Desktop client + +Windows-first приложение на WinUI 3. Оно показывает состояние всех серверов, графики, события, терминалы и связи. Клиент хранит пользовательские секреты в Windows Credential Locker/DPAPI и не передаёт приватные SSH-ключи control node. + +### Control node + +Небольшой координационный сервис, который можно установить на одном из своих серверов. Он принимает исходящие mTLS-соединения агентов, хранит инвентарь, короткую историю метрик, правила оповещений, команды и аудит. Для одного пользователя достаточно SQLite; внешний PostgreSQL не является требованием MVP. + +Control node не становится обязательным маршрутизатором трафика между серверами. При возможности соединение идёт напрямую. Relay добавляется позже как явно включаемый режим для узлов за NAT. + +### Linux agent + +Один статически собранный бинарный файл. Агент читает `/proc`, `/sys` и разрешённые systemd-состояния, агрегирует метрики локально и отправляет их наружу. По умолчанию он запускается непривилегированным пользователем и не открывает входящих портов. + +Привилегированные операции выносятся в маленький отдельный helper с белым списком действий. Агент мониторинга не должен постоянно иметь `root` или `CAP_NET_ADMIN`. + +## 2. Потоки данных + +### Метрики + +Агент отправляет компактный snapshot каждые 5–15 секунд. Control node сохраняет сырые точки недолго, затем выполняет downsampling. При потере сети агент держит ограниченный дисковый буфер и не заполняет диск. + +Минимальный snapshot: + +- load average и использование CPU; +- использованная/доступная память и swap; +- заполнение и inode выбранных файловых систем; +- сетевые счётчики интерфейсов; +- uptime, температура при наличии датчиков; +- состояние выбранных systemd units; +- только метаданные процессов, разрешённые политикой. + +### Команды и терминал + +Произвольная shell-команда не является обычной командой агента. Для безопасных операций используются типизированные действия: перезапуск разрешённой службы, чтение журнала с ограничением, получение списка процессов. Полный терминал создаётся как отдельная SSH-сессия от desktop client. + +### Links между серверами + +Link — отдельный ресурс, а не свойство группы серверов: + +```text +Draft -> Connecting -> Active -> Disconnecting -> Disabled + \-> Failed +Active -> Expired -> Disabled +``` + +Каждый Link содержит: + +- source и destination; +- разрешённые IP/CIDR и TCP/UDP-порты; +- режим `manual` или TTL; +- WireGuard peer identities; +- владельца, причину и запись аудита; +- фактическое состояние обоих узлов. + +Control node передаёт каждому узлу только его часть конфигурации. Приватный WireGuard-ключ никогда не покидает узел. `Disconnect` удаляет peer и маршруты с обеих сторон; при недоступности одного узла команда остаётся обязательной и применяется при его следующем подключении. + +## 3. Сценарий Hermes + +1. На домашнем сервере создаётся отдельный пользователь, например `hermes-dev`, без root-доступа. +2. Рабочие каталоги и разрешённые команды ограничиваются Unix-правами, группами, контейнером или sandbox-профилем. +3. В Server Monitor Manager создаётся Link от сервера с Hermes к домашнему серверу только для адреса домашнего узла и SSH-порта. +4. Hermes использует собственный SSH-ключ или короткоживущий SSH-сертификат. +5. Пользователь нажимает `Connect`; после разработки — `Disconnect`. +6. Отключение Link разрывает сетевую достижимость, а отзыв SSH-сертификата/ключа остаётся вторым независимым барьером. + +## 4. Режимы развёртывания + +- **Single owner:** один control node, один пользователь, SQLite. Основной MVP. +- **Family/team:** несколько пользователей, роли и подтверждения. После MVP. +- **Direct local:** desktop подключается к агентам внутри одной сети без публичного control node. Возможен позже, но использует тот же протокол идентичности. + +## 5. Целевые ограничения MVP + +- агент: один бинарник, idle RAM до 50 МБ, CPU в простое менее 1%; +- control node: запуск без Kubernetes и обязательного Docker; +- отсутствие открытого agent API в интернет; +- работа при 50–100 серверах на одном небольшом control node; +- деградация без потери управления: графики могут иметь пробелы, но команды не выполняются повторно без idempotency key. diff --git a/docs/installer-contract.md b/docs/installer-contract.md new file mode 100644 index 0000000..acdd521 --- /dev/null +++ b/docs/installer-contract.md @@ -0,0 +1,39 @@ +# Контракт Linux-установщика + +Файл `ochenstarik-server-monitor-manager.sh` находится в `ochenstarik-ui/lightweight-server`; синхронная копия хранится в `deploy/` этого репозитория. + +## Первый тестовый этап: SSH pull + +До появления постоянного агента Windows-клиент получает метрики через OpenSSH. Установщик: + +- поддерживает Ubuntu/Debian с systemd; +- запрашивает публичный ключ `ssh-ed25519`, созданный Windows-клиентом; +- проверяет синтаксис ключа через `ssh-keygen`; +- устанавливает и включает OpenSSH Server, не меняя текущий SSH-порт; +- создаёт отдельного системного пользователя `ochenstarik-monitor` без пароля; +- устанавливает root-owned metrics command; +- записывает ключ как `restrict,command="..."`; +- не создаёт UFW-правил и не открывает дополнительных портов; +- поддерживает `install`, `status` и `uninstall`; +- допускает безопасный повторный запуск для замены ключа мониторинга. + +Forced-command отдаёт только строки `KEY=VALUE`: + +```text +PROTOCOL=1 +HOSTNAME=server-name +UPTIME_SECONDS=12345 +LOAD1=0.42 +CPU_COUNT=4 +MEM_TOTAL_KB=... +MEM_AVAILABLE_KB=... +DISK_TOTAL_KB=... +DISK_AVAILABLE_KB=... +KERNEL=... +``` + +Ключ мониторинга не должен позволять shell, PTY, agent forwarding, TCP forwarding или выполнение переданной клиентом команды. Полноценный SSH-терминал использует отдельную пользовательскую identity и не входит в этот ключ. + +## Будущий этап: постоянный агент + +После проверки UX на нескольких серверах SSH pull будет дополнен статическим агентом для потоковых метрик, systemd events, короткого локального буфера и управляемых WireGuard Links. Агент будет регистрироваться одноразовым token и работать по исходящему mTLS-соединению без входящего API. diff --git a/docs/roadmap.md b/docs/roadmap.md new file mode 100644 index 0000000..a30900b --- /dev/null +++ b/docs/roadmap.md @@ -0,0 +1,52 @@ +# План разработки + +## Этап 0 — фундамент + +- [x] переименовать проект в Server Monitor Manager; +- [x] разделить мониторинг, терминал и Links в архитектуре; +- [x] определить безопасный контракт установки агента; +- [ ] выбрать лицензию; +- [ ] настроить CI, форматирование, тесты и релизные checksum. + +## Этап 1 — Windows MVP + +- [x] установить .NET SDK и официальный WinUI 3 toolchain; +- [x] создать packaged WinUI 3 приложение с воспроизводимым CLI-запуском через WinApp; +- [x] реализовать shell: Overview, Servers, Links, Sessions, Settings; +- [x] добавить локальные demo-данные и адаптивный dashboard; +- [x] генерировать отдельный Ed25519 SSH-ключ и хранить его в локальном каталоге packaged-приложения; +- [x] сохранять профили серверов локально без паролей; +- [x] собрать и реально запустить x64-приложение. + +## Этап 2 — мониторинг одного сервера + +- [x] первый бездемонный Linux endpoint через SSH forced-command; +- [ ] статический постоянный Linux agent для amd64/arm64; +- [ ] control node с SQLite, mTLS enrollment и WebSocket событиями; +- [ ] CPU, RAM, disk, network, uptime и systemd units; +- [ ] ограниченный локальный буфер и downsampling; +- [ ] installer, update, rollback и uninstall; +- [ ] предупреждения о диске, памяти и недоступности. + +## Этап 3 — несколько серверов и терминал + +- [ ] группы, теги, поиск и сводные статусы; +- [ ] прямой SSH из Windows-клиента; +- [ ] known_hosts pinning и отдельные profiles; +- [ ] типизированные безопасные действия с аудитом; +- [ ] экспорт диагностики без секретов. + +## Этап 4 — Links и Hermes + +- [ ] WireGuard peer helper с минимальными привилегиями; +- [ ] policies по CIDR, протоколу, порту и TTL; +- [ ] connect/disconnect с подтверждением обоих узлов; +- [ ] обязательное отключение после reconnect; +- [ ] отдельная automation identity для Hermes; +- [ ] интеграционные тесты kill switch и частичных отказов. + +## Этап 5 — другие платформы + +- [ ] macOS и Linux desktop clients после стабилизации Core/API; +- [ ] Android/iOS как companion-клиенты; +- [ ] push-уведомления без передачи административных секретов стороннему push-провайдеру. diff --git a/docs/security-model.md b/docs/security-model.md new file mode 100644 index 0000000..bc6039a --- /dev/null +++ b/docs/security-model.md @@ -0,0 +1,56 @@ +# Модель безопасности + +## Защищаемые данные + +- учётные записи и сессии пользователей; +- device, agent, SSH и WireGuard identities; +- команды, терминальные сессии и аудит; +- topology серверов, адреса и метрики; +- права автоматизаций, включая Hermes. + +## Границы доверия + +Desktop client, control node и каждый agent считаются отдельными субъектами. Компрометация одного агента не должна выдавать ключи других узлов или право создавать новые Links. Control node координирует публичные параметры и политики, но не хранит приватные WireGuard/SSH-ключи узлов. + +В первом SSH-MVP control node отсутствует. Windows-клиент генерирует отдельный Ed25519-ключ, а сервер привязывает его к `restrict,command`. Этот ключ предназначен только для чтения ограниченного snapshot метрик и не используется для интерактивного терминала или Hermes. + +## Регистрация агента + +1. Пользователь создаёт одноразовый enrollment token со сроком жизни не более 10 минут. +2. Агент генерирует ключевую пару локально. +3. По TLS агент предъявляет token и публичный ключ. +4. Control node выдаёт agent certificate и помечает token использованным. +5. Последующие соединения требуют mTLS. Повторное использование token отклоняется. + +## Авторизация + +- read-only мониторинг отделён от управления; +- команды проверяются по типу ресурса и действию; +- полный терминал требует свежего подтверждения пользователя; +- создание Link требует точного набора маршрутов/портов, пустой набор не означает `allow all`; +- automation identity не наследует интерактивные права владельца; +- команды имеют срок действия, nonce/idempotency key и защиту от replay. + +## Аудит + +Записываются входы, регистрация устройств, изменение прав, команды, начало и завершение терминала, создание/подключение/отключение Link. Секреты и полный ввод терминала по умолчанию не журналируются. Аудит экспортируется во внешний append-only storage; локальный администратор control node всё равно считается способным изменить локальную БД. + +## Kill switch + +Отключение Link должно: + +1. перевести желаемое состояние в `Disabled`; +2. удалить peer и маршруты на доступных узлах; +3. заблокировать повторное автоматическое включение; +4. сохранить обязательную команду для временно недоступного узла; +5. показать пользователю разницу между желаемым и фактическим состоянием. + +Кнопка не должна сообщать «отключено», пока оба узла не подтвердили применение или интерфейс явно не показывает частичное отключение. + +## Не входит в первый MVP + +- выполнение произвольных root-команд из веб/API; +- хранение пользовательских приватных SSH-ключей на control node; +- автоматическое соединение всех серверов группы в одну flat network; +- публичный входящий порт агента; +- собственная криптография вместо TLS, SSH и WireGuard. diff --git a/src/ServerMonitorManager.Desktop/.gitignore b/src/ServerMonitorManager.Desktop/.gitignore new file mode 100644 index 0000000..dd39356 --- /dev/null +++ b/src/ServerMonitorManager.Desktop/.gitignore @@ -0,0 +1,54 @@ +## .NET / Visual Studio +[Bb]in/ +[Oo]bj/ +[Dd]ebug/ +[Rr]elease/ +.vs/ +*.user +*.suo +*.userosscache +*.sln.docstates +artifacts/ + +# Build logs +[Ll]og/ +[Ll]ogs/ +*.log +*.binlog + +# Test results +[Tt]est[Rr]esult*/ +*.trx +*.coverage +*.coveragexml + +# NuGet +*.nupkg +*.snupkg +*.nuget.props +*.nuget.targets +project.lock.json + +# MSIX packaging output +AppPackages/ +BundleArtifacts/ +*.msix +*.msixupload +*.appx +*.appxbundle +*.appxupload + +# Publish output +publish/ +*.pubxml +PublishScripts/ + +# Code analysis and tooling +_ReSharper*/ +*.DotSettings.user +*.dotCover +.idea/ + +# Generated files +Generated\ Files/ +*_wpftmp.csproj diff --git a/src/ServerMonitorManager.Desktop/App.xaml b/src/ServerMonitorManager.Desktop/App.xaml new file mode 100644 index 0000000..578439c --- /dev/null +++ b/src/ServerMonitorManager.Desktop/App.xaml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/src/ServerMonitorManager.Desktop/App.xaml.cs b/src/ServerMonitorManager.Desktop/App.xaml.cs new file mode 100644 index 0000000..ad15c41 --- /dev/null +++ b/src/ServerMonitorManager.Desktop/App.xaml.cs @@ -0,0 +1,44 @@ +using Windows.ApplicationModel; +using Windows.ApplicationModel.Activation; +using Windows.Foundation; +using Windows.Foundation.Collections; +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Controls; +using Microsoft.UI.Xaml.Controls.Primitives; +using Microsoft.UI.Xaml.Data; +using Microsoft.UI.Xaml.Input; +using Microsoft.UI.Xaml.Media; +using Microsoft.UI.Xaml.Navigation; +using Microsoft.UI.Xaml.Shapes; + +// To learn more about WinUI, the WinUI project structure, +// and more about our project templates, see: http://aka.ms/winui-project-info. + +namespace ServerMonitorManager_Desktop; + +/// +/// Provides application-specific behavior to supplement the default Application class. +/// +public partial class App : Application +{ + private Window? _window; + + /// + /// Initializes the singleton application object. This is the first line of authored code + /// executed, and as such is the logical equivalent of main() or WinMain(). + /// + public App() + { + InitializeComponent(); + } + + /// + /// Invoked when the application is launched. + /// + /// Details about the launch request and process. + protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args) + { + _window = new MainWindow(); + _window.Activate(); + } +} diff --git a/src/ServerMonitorManager.Desktop/Assets/AppIcon.ico b/src/ServerMonitorManager.Desktop/Assets/AppIcon.ico new file mode 100644 index 0000000..235dad2 Binary files /dev/null and b/src/ServerMonitorManager.Desktop/Assets/AppIcon.ico differ diff --git a/src/ServerMonitorManager.Desktop/Assets/LockScreenLogo.scale-200.png b/src/ServerMonitorManager.Desktop/Assets/LockScreenLogo.scale-200.png new file mode 100644 index 0000000..33f889e Binary files /dev/null and b/src/ServerMonitorManager.Desktop/Assets/LockScreenLogo.scale-200.png differ diff --git a/src/ServerMonitorManager.Desktop/Assets/SplashScreen.scale-200.png b/src/ServerMonitorManager.Desktop/Assets/SplashScreen.scale-200.png new file mode 100644 index 0000000..802c79d Binary files /dev/null and b/src/ServerMonitorManager.Desktop/Assets/SplashScreen.scale-200.png differ diff --git a/src/ServerMonitorManager.Desktop/Assets/Square150x150Logo.scale-200.png b/src/ServerMonitorManager.Desktop/Assets/Square150x150Logo.scale-200.png new file mode 100644 index 0000000..ddba42a Binary files /dev/null and b/src/ServerMonitorManager.Desktop/Assets/Square150x150Logo.scale-200.png differ diff --git a/src/ServerMonitorManager.Desktop/Assets/Square44x44Logo.scale-200.png b/src/ServerMonitorManager.Desktop/Assets/Square44x44Logo.scale-200.png new file mode 100644 index 0000000..9327dd7 Binary files /dev/null and b/src/ServerMonitorManager.Desktop/Assets/Square44x44Logo.scale-200.png differ diff --git a/src/ServerMonitorManager.Desktop/Assets/Square44x44Logo.targetsize-24_altform-unplated.png b/src/ServerMonitorManager.Desktop/Assets/Square44x44Logo.targetsize-24_altform-unplated.png new file mode 100644 index 0000000..e51416a Binary files /dev/null and b/src/ServerMonitorManager.Desktop/Assets/Square44x44Logo.targetsize-24_altform-unplated.png differ diff --git a/src/ServerMonitorManager.Desktop/Assets/Square44x44Logo.targetsize-48_altform-lightunplated.png b/src/ServerMonitorManager.Desktop/Assets/Square44x44Logo.targetsize-48_altform-lightunplated.png new file mode 100644 index 0000000..bf063eb Binary files /dev/null and b/src/ServerMonitorManager.Desktop/Assets/Square44x44Logo.targetsize-48_altform-lightunplated.png differ diff --git a/src/ServerMonitorManager.Desktop/Assets/StoreLogo.png b/src/ServerMonitorManager.Desktop/Assets/StoreLogo.png new file mode 100644 index 0000000..be865f0 Binary files /dev/null and b/src/ServerMonitorManager.Desktop/Assets/StoreLogo.png differ diff --git a/src/ServerMonitorManager.Desktop/Assets/Wide310x150Logo.scale-200.png b/src/ServerMonitorManager.Desktop/Assets/Wide310x150Logo.scale-200.png new file mode 100644 index 0000000..314d297 Binary files /dev/null and b/src/ServerMonitorManager.Desktop/Assets/Wide310x150Logo.scale-200.png differ diff --git a/src/ServerMonitorManager.Desktop/MainPage.xaml b/src/ServerMonitorManager.Desktop/MainPage.xaml new file mode 100644 index 0000000..55b3922 --- /dev/null +++ b/src/ServerMonitorManager.Desktop/MainPage.xaml @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +