This file is a merged representation of a subset of the codebase, containing specifically included files and files not matching ignore patterns, combined into a single document by Repomix. The content has been processed where empty lines have been removed. This section contains a summary of this file. This file contains a packed representation of a subset of the repository's contents that is considered the most important context. It is designed to be easily consumable by AI systems for analysis, code review, or other automated processes. The content is organized as follows: 1. This summary section 2. Repository information 3. Directory structure 4. Repository files (if enabled) 5. Multiple file entries, each consisting of: - File path as an attribute - Full contents of the file - This file should be treated as read-only. Any changes should be made to the original repository files, not this packed version. - When processing this file, use the file path to distinguish between different files in the repository. - Be aware that this file may contain sensitive information. Handle it with the same level of security as you would the original repository. - Some files may have been excluded based on .gitignore rules and Repomix's configuration - Binary files are not included in this packed representation. Please refer to the Repository Structure section for a complete list of file paths, including binary files - Only files matching these patterns are included: bin/**, cmd/**, lib/**, layers/**, state/*.sh, config.env - Files matching these patterns are excluded: state/snapshots/**, *.xml - Files matching patterns in .gitignore are excluded - Files matching default ignore patterns are excluded - Empty lines have been removed from all files - Files are sorted by Git change count (files with more changes are at the bottom) bin/ zarya cmd/ a.sh disks.sh errors.sh logs.sh net.sh pack.sh pods.sh run.sh session.sh snap.sh unseal.sh up.sh layers/ 00_host.sh 01_net.sh 02_tier0.sh 03_talos.sh 04_apps.sh gc.sh reset.sh lib/ common.sh kdbx_parser.py log.sh net.sh session.sh vault.sh state/ 00_workstation.sh 01_pve.sh 02_vps.sh 03_vyos.sh 04_tier0.sh 05_k8s.sh config.env This section contains the contents of the repository's files. #!/bin/bash set -euo pipefail ZARYA_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" source "${ZARYA_DIR}/lib/common.sh" SUBCMD="${1:-help}" shift || true case "${SUBCMD}" in p|pod|pods) exec "${ZARYA_DIR}/cmd/pods.sh" "$@" ;; e|err|errors) exec "${ZARYA_DIR}/cmd/errors.sh" "$@" ;; l|log|logs) exec "${ZARYA_DIR}/cmd/logs.sh" "$@" ;; n|net) exec "${ZARYA_DIR}/cmd/net.sh" "$@" ;; d|df|disks) exec "${ZARYA_DIR}/cmd/disks.sh" "$@" ;; unseal) exec "${ZARYA_DIR}/cmd/unseal.sh" "$@" ;; login|start) exec "${ZARYA_DIR}/cmd/session.sh" "start" "$@" ;; logout|clean) exec "${ZARYA_DIR}/cmd/session.sh" "clean" "$@" ;; up) exec "${ZARYA_DIR}/cmd/up.sh" "$@" ;; run) exec "${ZARYA_DIR}/cmd/run.sh" "$@" ;; a|apply) exec "${ZARYA_DIR}/cmd/a.sh" "$@" ;; snap) exec "${ZARYA_DIR}/cmd/snap.sh" "$@" ;; pack) exec "${ZARYA_DIR}/cmd/pack.sh" "$@" ;; reset|nuke) exec "${ZARYA_DIR}/layers/reset.sh" "$@" ;; gc) exec "${ZARYA_DIR}/layers/gc.sh" "$@" ;; help|--help|-h) cat <] [-s ] [-A] Просмотр подов z errors Мгновенный триаж сломанных сервисов z logs [-f] [-t ] Логи любого сервиса без ввода неймспейса z net Сетевой радар доступности узлов (1 сек) z disks Срез пулов astra/terra и ZVOL томов K8s Управление и сессия: z login [TTL] Открытие смены (YubiKey + RAM) z logout Мгновенная очистка RAM z unseal Распечатывание OpenBao Vault Деплой и IaC: z up [layer] Макро-слои (host, net, tier0, talos, apps, all) z run Плейбуки Ansible (01, 02) z a [-auto-approve] OpenTofu apply в RAM-изоляции Телеметрия и LLM: z snap Снятие полного .md аудита в snapshots/ z pack [code|state|atlas] Сборка контекста Repomix EOF ;; *) log_err "Неизвестная команда: ${SUBCMD}. Введите 'z help'." exit 1 ;; esac #!/bin/bash set -euo pipefail ZARYA_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" source "${ZARYA_DIR}/lib/common.sh" unseal_vault run_isolated bash -c "cd '${REPO_ROOT}/tofu' && tofu apply $*" #!/bin/bash set -uo pipefail ZARYA_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" source "${ZARYA_DIR}/lib/common.sh" echo -e "${BLUE}=== ФИЗИЧЕСКИЕ ПУЛЫ ХОСТА PROXMOX (ZFS) ===${NC}" ssh -n -o BatchMode=yes -o ConnectTimeout=2 proxmox "zpool list -o name,size,alloc,free,cap,health" 2>/dev/null || log_err "PVE недоступен" echo "" echo -e "${BLUE}=== ПОЛЬЗОВАТЕЛЬСКИЕ ДАТАСЕТЫ TIER-0 (/astra/data) ===${NC}" ssh -n -o BatchMode=yes -o ConnectTimeout=2 proxmox "zfs list -o name,used,avail,refer,mountpoint -r astra/data" 2>/dev/null || true echo "" echo -e "${BLUE}=== ТОМА ДИСКОВ KUBERNETES (ZVOL) ===${NC}" kubectl get pvc -A -o custom-columns=NAMESPACE:.metadata.namespace,NAME:.metadata.name,STATUS:.status.phase,VOLUME:.spec.volumeName,SIZE:.status.capacity.storage 2>/dev/null || log_err "K8s API недоступен" #!/bin/bash set -uo pipefail ZARYA_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" source "${ZARYA_DIR}/lib/common.sh" has_errors=false echo -e "${YELLOW}=== ТРИАЖ АВАРИЙ И СБОЕВ (K8s / Host / VyOS) ===${NC}" bad_pods=$(kubectl get pods -A --field-selector=status.phase!=Running,status.phase!=Succeeded --no-headers 2>/dev/null | grep -v 'Completed' || true) if [[ -n "${bad_pods}" ]]; then has_errors=true echo -e "${RED}[K8S] Проблемные поды:${NC}" echo "${bad_pods}" | awk '{printf " %-16s %-36s %s\n", $1, $2, $3}' fi pve_failed=$(ssh -n -o BatchMode=yes -o ConnectTimeout=1 proxmox "systemctl --failed --no-legend --plain" 2>/dev/null || echo "UNREACHABLE") if [[ "${pve_failed}" == "UNREACHABLE" ]]; then has_errors=true echo -e "${RED}[PVE] Гипервизор недоступен по SSH${NC}" elif [[ -n "${pve_failed}" ]]; then has_errors=true echo -e "${RED}[PVE] Упавшие systemd-сервисы:${NC}" echo "${pve_failed}" | awk '{print " " $1}' fi vyos_failed=$(ssh -n -o BatchMode=yes -o ConnectTimeout=1 vyos_router "systemctl --failed --no-legend --plain" 2>/dev/null || echo "UNREACHABLE") if [[ "${vyos_failed}" == "UNREACHABLE" ]]; then has_errors=true echo -e "${RED}[VyOS] Роутер недоступен по SSH${NC}" elif [[ -n "${vyos_failed}" ]]; then has_errors=true echo -e "${RED}[VyOS] Упавшие systemd-сервисы:${NC}" echo "${vyos_failed}" | awk '{print " " $1}' fi if [[ "$has_errors" == false ]]; then echo -e "${GREEN}✔ Все системы в норме. Сбоев не обнаружено.${NC}" fi #!/bin/bash set -uo pipefail ZARYA_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" source "${ZARYA_DIR}/lib/common.sh" query="${1:-}" if [[ -z "${query}" ]]; then log_err "Использование: z logs <сервис> [-f] [-t <строки>]" exit 1 fi shift follow_arg="" tail_val="50" while [[ $# -gt 0 ]]; do case "$1" in -f|--follow) follow_arg="-f"; shift ;; -t|--tail) tail_val="$2"; shift 2 ;; *) shift ;; esac done pod_info=$(kubectl get pods -A --no-headers 2>/dev/null | awk -v q="${query}" 'tolower($1) ~ tolower(q) || tolower($2) ~ tolower(q) {print $1, $2; exit}') if [[ -z "${pod_info}" ]]; then log_err "Под с именем '${query}' не найден ни в одном namespace." exit 1 fi ns=$(echo "${pod_info}" | awk '{print $1}') pod=$(echo "${pod_info}" | awk '{print $2}') log_info "Логи ${ns}/${pod} (tail: ${tail_val}):" exec kubectl logs -n "${ns}" "${pod}" --tail="${tail_val}" ${follow_arg} #!/bin/bash set -uo pipefail ZARYA_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" source "${ZARYA_DIR}/lib/common.sh" echo -e "${BLUE}=== СЕТЕВОЙ РАДАР ИНФРАСТРУКТУРЫ (Таймаут 1 сек) ===${NC}" printf "%-22s %-20s %-12s %s\n" "УЗЕЛ" "АДРЕС" "СТАТУС" "ЗАДЕРЖКА" echo "------------------------------------------------------------------" check_target() { local name="$1" local host="$2" local port="$3" local start end dur start=$(date +%s%N) if nc -z -w 1 "${host}" "${port}" 2>/dev/null; then end=$(date +%s%N) dur=$(( (end - start) / 1000000 )) printf "%-22s %-20s \033[32m%-12s\033[0m %d ms\n" "${name}" "${host}:${port}" "UP" "${dur}" else printf "%-22s %-20s \033[31m%-12s\033[0m -\n" "${name}" "${host}:${port}" "DOWN" fi } check_target "Proxmox Host (PVE)" "192.168.1.177" 8006 check_target "Edge Router (VyOS)" "192.168.1.2" 22 check_target "Technitium DNS" "10.0.10.11" 53 check_target "OpenBao Vault" "10.0.10.12" 8200 check_target "Forgejo GitOps" "10.0.10.13" 3000 check_target "NFS Storage (NAS)" "10.0.10.14" 2049 check_target "Traefik L2 VIP" "10.0.30.200" 443 check_target "Perimeter VPS" "153.76.194.24" 443 #!/bin/bash set -euo pipefail ZARYA_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" mode="${1:-state}" case "${mode}" in state) echo "==> Снятие свежего аудита..." "${ZARYA_DIR}/state/collect_state.sh" all >/dev/null 2>&1 || true echo "==> Упаковка среза состояния Repomix (zarya-state.xml)..." repomix --config "${ZARYA_DIR}/repomix.state.json" echo "✔ Файл zarya-state.xml готов для отправки в LLM." ;; code) echo "==> Упаковка кодовой базы zarya (zarya-code.xml)..." repomix --config "${ZARYA_DIR}/repomix.config.json" echo "✔ Файл zarya-code.xml готов." ;; atlas) echo "==> Упаковка чистой инфраструктуры atlas (atlas-code.xml)..." cd "${ATLAS_DIR}" && repomix echo "✔ Файл atlas/repomix-output.xml готов." ;; *) echo "Использование: z pack [state|code|atlas]" exit 1 ;; esac #!/bin/bash set -u watch_mode=false ns_filter="" query="" all_namespaces=false while [[ $# -gt 0 ]]; do case "$1" in -w|--watch) watch_mode=true; shift ;; -n|--namespace) ns_filter="$2"; shift 2 ;; -s|--service) query="$2"; shift 2 ;; -A|--all) all_namespaces=true; shift ;; all) all_namespaces=true; shift ;; *) query="$1"; shift ;; esac done render_pods() { local raw if [[ "$all_namespaces" == true ]]; then raw=$(kubectl get pods -A -o wide 2>/dev/null || true) elif [[ -n "$ns_filter" ]]; then raw=$(kubectl get pods -n "$ns_filter" -o wide 2>/dev/null || true) elif [[ -n "$query" ]]; then raw=$(kubectl get pods -A -o wide 2>/dev/null | awk -v q="$query" 'NR==1 || tolower($1) ~ tolower(q) || tolower($2) ~ tolower(q)' || true) else raw=$(kubectl get pods -A -o wide 2>/dev/null | awk 'NR==1 || ($1 !~ /^(kube-system|flux-system|cert-manager|external-secrets)$/ && $4 != "Completed")' || true) fi echo "$raw" | awk ' BEGIN { ERR = "\033[38;2;255;46;76m" RUN = "\033[38;2;180;190;254m" WARN = "\033[38;2;250;179;135m" HEAD = "\033[38;2;147;154;183m" RST = "\033[0m" } NR==1 { print HEAD $0 RST; next } { if ($0 ~ /CrashLoopBackOff|Error|OOMKilled|ImagePullBackOff/) { print ERR $0 RST } else if ($0 ~ /ContainerCreating|Pending|Terminating|Init:/ || ($0 ~ /Running/ && $2 ~ /^0\//)) { print WARN $0 RST } else if ($0 ~ /Running/) { print RUN $0 RST } else { print $0 } }' } if [[ "$watch_mode" == true ]]; then trap 'tput cnorm 2>/dev/null || true; echo ""; exit 0' INT TERM tput civis 2>/dev/null || true clear while true; do tput cup 0 0 2>/dev/null || true render_pods tput ed 2>/dev/null || true sleep 1 done else render_pods fi #!/bin/bash set -euo pipefail ZARYA_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" source "${ZARYA_DIR}/lib/common.sh" resolve_playbook() { local id="$1" local found found=$(find "${REPO_ROOT}/ansible/playbooks" -maxdepth 1 -name "${id}_*.yml" | head -n1) if [[ -z "${found}" ]]; then log_err "Плейбук с префиксом [${id}] не найден в ansible/playbooks/" exit 1 fi echo "${found}" } if [[ $# -eq 0 ]] || [[ "${1:-}" == "list" ]]; then echo -e "${BLUE}=== Каталог плейбуков (${REPO_ROOT}/ansible/playbooks/) ===${NC}" for pb in $(ls -1 "${REPO_ROOT}/ansible/playbooks"/[0-9][0-9]_*.yml 2>/dev/null | sort); do echo " $(basename "${pb}")" done exit 0 fi for id in "$@"; do pb_path=$(resolve_playbook "${id}") log_info "==> Исполнение: $(basename "${pb_path}")..." run_isolated ansible-playbook -i "${REPO_ROOT}/ansible/inventory.yml" "${pb_path}" done log_ok "Плейбуки выполнены." #!/bin/bash set -euo pipefail ZARYA_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" source "${ZARYA_DIR}/lib/common.sh" action="${1:-start}" shift || true case "${action}" in start|login) hours="${1:-1}" ensure_prerequisites load_secrets_to_ram "${hours}" unseal_vault log_ok "Сессия Zarya активна (TTL: ${hours} ч)." ;; clean|logout) rm -f "${RAM_CACHE}" /dev/shm/.atlas_core log_ok "RAM-кэш и ключи уничтожены." ;; esac #!/bin/bash set -uo pipefail ZARYA_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" target="${1:-all}" "${ZARYA_DIR}/state/collect_state.sh" "${target}" #!/bin/bash set -euo pipefail ZARYA_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" source "${ZARYA_DIR}/lib/common.sh" ensure_prerequisites unseal_vault #!/bin/bash set -euo pipefail ZARYA_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" source "${ZARYA_DIR}/lib/common.sh" target="${1:-all}" case "${target}" in host) run_isolated "${ZARYA_DIR}/layers/00_host.sh" ;; net) run_isolated "${ZARYA_DIR}/layers/01_net.sh" ;; tier0) run_isolated "${ZARYA_DIR}/layers/02_tier0.sh" ;; talos) run_isolated "${ZARYA_DIR}/layers/03_talos.sh" ;; apps) "${ZARYA_DIR}/layers/04_apps.sh" ;; all) run_isolated "${ZARYA_DIR}/layers/00_host.sh" run_isolated "${ZARYA_DIR}/layers/01_net.sh" run_isolated "${ZARYA_DIR}/layers/02_tier0.sh" run_isolated "${ZARYA_DIR}/layers/03_talos.sh" "${ZARYA_DIR}/layers/04_apps.sh" log_ok "Инфраструктура Atlas развернута." ;; *) log_err "Неизвестный слой: ${target}. Доступны: host, net, tier0, talos, apps, all" exit 1 ;; esac #!/bin/bash set -euo pipefail source "$(dirname "${BASH_SOURCE[0]}")/../lib/common.sh" ensure_prerequisites load_secrets_to_ram log_info "[Layer 0: PVE Host] Подготовка хоста, шаблонов и базовых директорий ZFS..." ansible-playbook -i "${REPO_ROOT}/ansible/inventory.yml" "${REPO_ROOT}/ansible/playbooks/01_pve_host_day0.yml" log_info "[Layer 0: PVE Host] Инициализация compute-скелетов ВМ и LXC через OpenTofu..." cd "${REPO_ROOT}/tofu" && tofu apply \ -target=proxmox_virtual_environment_vm.vyos_router \ -target=proxmox_virtual_environment_container.dns0 \ -target=proxmox_virtual_environment_container.vault0 \ -target=proxmox_virtual_environment_container.git0 \ -target=proxmox_virtual_environment_container.storage0 \ -target=proxmox_virtual_environment_container.registry0 \ -target=proxmox_virtual_environment_vm.talos_master_1 \ -target=proxmox_virtual_environment_vm.talos_worker_1 \ -target=proxmox_virtual_environment_vm.talos_worker_2 \ -auto-approve log_info "[Layer 0: PVE Host] Применение постоянных ZFS-маунтов (mp) на созданные LXC..." ansible-playbook -i "${REPO_ROOT}/ansible/inventory.yml" "${REPO_ROOT}/ansible/playbooks/01_pve_host_day0.yml" log_ok "Layer 0 готов: хост настроен, ВМ и LXC созданы, ZFS смонтирован." #!/bin/bash set -euo pipefail source "$(dirname "${BASH_SOURCE[0]}")/../lib/common.sh" ensure_prerequisites load_secrets_to_ram log_info "[Layer 1: VyOS & Perimeter] Накатка конфигурации сети..." ansible-playbook -i "${REPO_ROOT}/ansible/inventory.yml" "${REPO_ROOT}/ansible/playbooks/02_vyos_network_day0.yml" log_ok "Layer 1 готов." #!/bin/bash set -euo pipefail source "$(dirname "${BASH_SOURCE[0]}")/../lib/common.sh" ensure_prerequisites load_secrets_to_ram log_info "[Layer 2: Tier-0 Air-Gap] Развертывание базовой инфраструктуры (Registry, DNS, Vault)..." for pb in 03_zot_registry.yml 04_technitium_dns.yml 05_openbao_vault.yml; do ansible-playbook -i "${REPO_ROOT}/ansible/inventory.yml" "${REPO_ROOT}/ansible/playbooks/${pb}" done log_info "[Layer 2: Tier-0 Air-Gap] Распечатывание OpenBao Vault..." unseal_vault log_info "[Layer 2: Tier-0 Air-Gap] Наполнение Vault секретами через OpenTofu..." cd "${REPO_ROOT}/tofu" && tofu apply -auto-approve log_info "[Layer 2: Tier-0 Air-Gap] Развертывание зависимых сервисов (Forgejo, NAS Storage)..." for pb in 06_forgejo_git.yml 07_nas_storage.yml; do ansible-playbook -i "${REPO_ROOT}/ansible/inventory.yml" "${REPO_ROOT}/ansible/playbooks/${pb}" done log_info "[Layer 2: Tier-0 Air-Gap] Автоматическая первичная синхронизация Git в Forgejo (SEC-03 RAM auth)..." CURRENT_BRANCH=$(git -C "${REPO_ROOT}" branch --show-current 2>/dev/null || echo "master") git -C "${REPO_ROOT}" push -u http://10.0.10.13:3000/atlas/atlas.git "${CURRENT_BRANCH}" 2>/dev/null || \ git -C "${REPO_ROOT}" push http://10.0.10.13:3000/atlas/atlas.git "${CURRENT_BRANCH}" 2>/dev/null || true log_ok "Layer 2 готов. Базовые сервисы, секреты и GitOps-репозиторий развернуты." #!/bin/bash set -euo pipefail source "$(dirname "${BASH_SOURCE[0]}")/../lib/common.sh" ensure_prerequisites load_secrets_to_ram unseal_vault log_info "[Layer 3: Talos & Kubernetes] Проверка конфигураций машинных манифестов..." if [[ ! -f "${REPO_ROOT}/talos/clusterconfig/controlplane.yaml" ]]; then log_info "Генерация машинных конфигураций Talos..." cd "${REPO_ROOT}" && talos/generate_config.sh fi log_info "[Layer 3: Talos & Kubernetes] Бутстрап кластера..." cd "${REPO_ROOT}/talos" && ./bootstrap.sh sync_k8s_vault_token log_ok "Layer 3 готов." #!/bin/bash set -euo pipefail source "$(dirname "${BASH_SOURCE[0]}")/../lib/common.sh" ensure_prerequisites log_info "[Layer 4: Apps] Применение манифестов FluxCD..." kubectl apply -f "${REPO_ROOT}/kubernetes/bootstrap/sync.yaml" log_ok "Layer 4 готов." #!/bin/bash set -uo pipefail source "$(dirname "${BASH_SOURCE[0]}")/../lib/common.sh" ensure_prerequisites log_info "🧹 Запуск генеральной очистки кластера (dep gc)..." # 1. Удаление зомби-нод в статусе NotReady NOT_READY_NODES=$(kubectl get nodes --no-headers 2>/dev/null | grep 'NotReady' | awk '{print $1}' || true) if [[ -n "${NOT_READY_NODES}" ]]; then for node in ${NOT_READY_NODES}; do log_warn "Удаляем мертвую ноду: ${node}" kubectl delete node "${node}" --timeout=5s 2>/dev/null || true done fi # 2. Мгновенная зачистка зависших в Terminating kubectl get pods -A --no-headers 2>/dev/null | awk '/Terminating/ {print $1, $2}' | while read -r ns pod; do log_warn "Принудительно удаляем: ${ns}/${pod}" kubectl -n "${ns}" delete pod "${pod}" --force --grace-period=0 2>/dev/null || true done # 3. Сброс бэкоффа для упавших подов (CrashLoopBackOff, Error, OOMKilled, CreateContainerConfigError) kubectl get pods -A --no-headers 2>/dev/null | grep -E 'CrashLoopBackOff|Error|OOMKilled|CreateContainerConfigError|ImagePullBackOff' | awk '{print $1, $2}' | while read -r ns pod; do log_info "Сбрасываем упавший под: ${ns}/${pod}" kubectl -n "${ns}" delete pod "${pod}" --force --grace-period=0 2>/dev/null || true done # 4. Очистка завершенных одноразовых Job COMPLETED_JOBS=$(kubectl get jobs -A --field-selector status.successful=1 --no-headers 2>/dev/null | awk '{print $1, $2}' || true) if [[ -n "${COMPLETED_JOBS}" ]]; then echo "${COMPLETED_JOBS}" | while read -r ns job; do kubectl -n "${ns}" delete job "${job}" >/dev/null 2>&1 || true done fi log_ok "Кластер очищен. Все сервисы пересоздаются против живых БД и NFS." #!/bin/bash set -euo pipefail source "$(dirname "${BASH_SOURCE[0]}")/../lib/common.sh" RESET_WIPE_HISTORY="${RESET_WIPE_HISTORY:-false}" log_warn "ВНИМАНИЕ! Инициирована процедура полного уничтожения инфраструктуры Proxmox VE." log_info "Очистка текущей RAM-сессии. Требуется физическая повторная аутентификация..." rm -f "${RAM_CACHE}" /dev/shm/.atlas_core read -s -p "Master Password для подтверждения сноса: " KP_PASS echo "" yk_args=() if ykman info >/dev/null 2>&1; then yk_args=("-y" "2") log_info "Приготовьтесь к аппаратному подтверждению (касание YubiKey)..." fi tmp_verify="/dev/shm/.verify_$$" if ! echo "${KP_PASS}" | timeout 15 keepassxc-cli export "${yk_args[@]}" "${KDBX_PATH}" -f xml > "${tmp_verify}" 2>/dev/null; then log_err "Аппаратная проверка провалена или таймаут касания. Доступ заблокирован." rm -f "${tmp_verify}" unset KP_PASS if [[ "${RESET_WIPE_HISTORY}" == "true" ]]; then history -c 2>/dev/null || true fi exit 1 fi rm -f "${tmp_verify}" unset KP_PASS log_ok "Аппаратная проверка YubiKey и пароля подтверждена." read -r -p "Введите 'CONFIRM-DESTRUCTION' для безвозвратного уничтожения: " confirm if [[ "${confirm}" != "CONFIRM-DESTRUCTION" ]]; then log_warn "Отмена операции." exit 0 fi log_info "Снятие защиты и уничтожение виртуальных машин и контейнеров на Proxmox..." ssh proxmox bash << 'SSHEOF' for id in 100 201 202 203; do qm stop $id --skiplock 1 2>/dev/null || true qm destroy $id --purge 1 --destroy-unreferenced-disks 1 2>/dev/null || true done for id in 101 102 103 104 105; do pct set $id -protection 0 2>/dev/null || true pct stop $id --skiplock 1 2>/dev/null || true pct destroy $id --purge 1 --force 1 2>/dev/null || true done SSHEOF log_info "Очистка локального стейта OpenTofu..." rm -f "${REPO_ROOT}/tofu/terraform.tfstate"* "${REPO_ROOT}/tofu/.terraform.tfstate.lock.info" rm -f "${RAM_CACHE}" /dev/shm/.atlas_core if [[ "${RESET_WIPE_HISTORY}" == "true" ]]; then history -c 2>/dev/null || true fi log_ok "Сервер зачищен до голого железа." #!/bin/bash set -euo pipefail ZARYA_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" export ATLAS_DIR="${ATLAS_DIR:-$HOME/Projects/atlas}" export REPO_ROOT="${ATLAS_DIR}" source "${ZARYA_DIR}/config.env" 2>/dev/null || true source "${ZARYA_DIR}/lib/log.sh" source "${ZARYA_DIR}/lib/net.sh" source "${ZARYA_DIR}/lib/vault.sh" source "${ZARYA_DIR}/lib/session.sh" import sys import xml.etree.ElementTree as ET import os dump_file = sys.argv[1] cache_file = sys.argv[2] key_file = sys.argv[3] ttl_sec = sys.argv[4] pve_endpoint = sys.argv[5] vault_addr = sys.argv[6] tree = ET.parse(dump_file) root = tree.getroot() for h in root.findall(".//History"): h.clear() for g in root.findall(".//Group"): name = g.find("./Name") if name is not None and name.text == "Recycle Bin": g.clear() entries = {} for entry in root.findall(".//Entry"): title = "" username = "" password = "" notes = "" for string in entry.findall("./String"): key_elem = string.find("./Key") val_elem = string.find("./Value") if key_elem is not None and val_elem is not None and key_elem.text: k = key_elem.text v = val_elem.text or "" if k == "Title": title = v.strip() elif k == "UserName": username = v.strip() elif k == "Password": password = v.strip() elif k == "Notes": notes = v.strip() if title and title not in entries: entries[title] = { "username": username, "password": password, "notes": notes } ssh_loaded = False for title in ("Atlas Core Key", "AtlasCoreKey", "Atlas Core"): entry_data = entries.get(title, {}) for field in ("password", "notes"): val = entry_data.get(field, "") if "-----BEGIN" in val or "PRIVATE KEY" in val: with open(key_file, "w") as kf: kf.write(val.strip() + "\n") os.chmod(key_file, 0o600) ssh_loaded = True break if ssh_loaded: break if not ssh_loaded: sys.stderr.write("Внимание: приватный SSH-ключ не найден в полях Password/Notes записи Atlas Core Key.\n") with open(cache_file, "w") as f: f.write(f"# TTL_SECONDS={ttl_sec}\n") f.write(f"export PROXMOX_VE_API_TOKEN={repr(entries.get('ProxmoxAPI', {}).get('password', ''))}\n") f.write(f"export TF_VAR_proxmox_api_token={repr(entries.get('ProxmoxAPI', {}).get('password', ''))}\n") f.write(f"export TF_VAR_state_passphrase={repr(entries.get('TofuState', {}).get('password', ''))}\n") f.write(f"export PROXMOX_VE_ENDPOINT={repr(pve_endpoint)}\n") f.write(f"export VAULT_ADDR={repr(vault_addr)}\n") f.write(f"export VAULT_TOKEN={repr(entries.get('OpenBaoToken', {}).get('password', ''))}\n") f.write(f"export VAULT_UNSEAL_KEY={repr(entries.get('OpenBaoUnseal', {}).get('password', ''))}\n") f.write(f"export TECHNITIUM_PASSWORD={repr(entries.get('Technitium', {}).get('password', 'admin'))}\n") f.write(f"export TF_VAR_vaultwarden_admin_token={repr(entries.get('VaultwardenAdmin', {}).get('password', ''))}\n") f.write(f"export TF_VAR_forgejo_runner_token={repr(entries.get('ForgejoRunnerToken', {}).get('password', ''))}\n") f.write(f"export TF_VAR_forgejo_oidc_client_id={repr(entries.get('ForgejoOIDC', {}).get('username', 'forgejo'))}\n") f.write(f"export TF_VAR_forgejo_oidc_secret={repr(entries.get('ForgejoOIDC', {}).get('password', ''))}\n") f.write(f"export ATLAS_PUSH_TOKEN={repr(entries.get('AtlasPushToken', {}).get('password', ''))}\n") f.write(f"export VYOS_WG_PRIVATE_KEY={repr(entries.get('VyosWG', {}).get('password', ''))}\n") os.chmod(cache_file, 0o600) #!/bin/bash # Log formatting and color definitions RED='\033[0;31m' GREEN='\033[0;32m' BLUE='\033[0;34m' YELLOW='\033[1;33m' NC='\033[0m' log_info() { echo -e "${BLUE}==>${NC} $*"; } log_ok() { echo -e "${GREEN}✔${NC} $*"; } log_warn() { echo -e "${YELLOW}⚠${NC} $*"; } log_err() { echo -e "${RED}✖${NC} $*"; } #!/bin/bash # Network routing and terminal prerequisites ensure_prerequisites() { local target_ip="${VAULT_ADDR#*//}" target_ip="${target_ip%%:*}" if ! ip route get "${target_ip}" 2>/dev/null | grep -q "${VYOS_ROUTER_IP}"; then log_info "Восстанавливаем маршрут к ${NET_PREFIX} через VyOS (${VYOS_ROUTER_IP})..." sudo ip route replace "${NET_PREFIX}" via "${VYOS_ROUTER_IP}" 2>/dev/null || true fi # Регистрация Git Credential Helper (доменный и прямой IP Tier-0) local target_helper="!${REPO_ROOT}/deploy.sh git-credential" local current_helper current_helper=$(git config --global --get credential."https://${GIT_HOST}".helper 2>/dev/null || true) if [[ "${current_helper}" != "${target_helper}" ]]; then git config --global credential."https://${GIT_HOST}".helper "${target_helper}" fi local direct_helper direct_helper=$(git config --global --get credential."http://10.0.10.13:3000".helper 2>/dev/null || true) if [[ "${direct_helper}" != "${target_helper}" ]]; then git config --global credential."http://10.0.10.13:3000".helper "${target_helper}" fi # Нативная привязка IdentityFile для всех C2-хостов и LXC-контейнеров local ssh_hosts="proxmox pve0 vyos vyos_router 10.0.* dns0 vault0 git0 storage0 registry0" if [[ -f "${HOME}/.ssh/config" ]] && ! grep -q "IdentityFile ${RAM_KEY}" "${HOME}/.ssh/config"; then printf "\nHost %s\n IdentityFile %s\n IdentitiesOnly yes\n" "${ssh_hosts}" "${RAM_KEY}" >> "${HOME}/.ssh/config" fi } #!/bin/bash # Session state in RAM tmpfs and YubiKey integration load_secrets_to_ram() { local hours="${1:-$DEFAULT_SESSION_TTL}" local now now=$(date +%s) ensure_prerequisites # Валидация сессии по наличию непустых кэша секретов и SSH-ключа if [[ -f "${RAM_CACHE}" ]] && [[ -f "${RAM_KEY}" ]] && [[ -s "${RAM_KEY}" ]]; then local created age cached_ttl created=$(stat -c %Y "${RAM_CACHE}" 2>/dev/null || echo 0) age=$(( now - created )) cached_ttl=$(grep '^# TTL_SECONDS=' "${RAM_CACHE}" 2>/dev/null | cut -d= -f2 || echo 3600) if [[ "${cached_ttl}" -ne 0 ]] && (( age >= cached_ttl )); then log_warn "Время сессии истекло ($(( age / 60 )) мин >= $(( cached_ttl / 60 )) мин). Инвалидация кэша..." rm -f "${RAM_CACHE}" "${RAM_KEY}" else return 0 fi fi local ttl_seconds if [[ "${hours}" -eq 0 ]]; then ttl_seconds=0 else ttl_seconds=$(( hours * 3600 )) fi log_info "🔐 Вход в защищенный контур C2..." read -s -p "Master Password: " KP_PASS echo "" local yk_args=() if ykman info >/dev/null 2>&1; then yk_args=("-y" "2") log_info "YubiKey обнаружен. Приготовьтесь к аппаратному подтверждению (1 касание)..." fi # Атомарный 1-Touch экспорт всей базы KDBX в RAM (ровно 1 касание YubiKey на всю сессию) local tmp_dump="/dev/shm/.kdbx_dump_${now}_$$.xml" rm -f "${tmp_dump}" touch "${tmp_dump}" chmod 600 "${tmp_dump}" if ! echo "${KP_PASS}" | keepassxc-cli export "${yk_args[@]}" "${KDBX_PATH}" -f xml > "${tmp_dump}" 2>/dev/null; then log_err "Ошибка расшифровки базы KDBX (неверный пароль или таймаут касания YubiKey)" rm -f "${tmp_dump}" unset KP_PASS return 1 fi unset KP_PASS python3 "${REPO_ROOT}/scripts/lib/kdbx_parser.py" "${tmp_dump}" "${RAM_CACHE}" "${RAM_KEY}" "${ttl_seconds}" "${PVE_ENDPOINT}" "${VAULT_ADDR}" rm -f "${tmp_dump}" log_ok "База расшифрована за 1 касание. Ключ и секреты в RAM (TTL: ${hours}ч)" } run_isolated() { ensure_prerequisites load_secrets_to_ram ( set -a source "${RAM_CACHE}" set +a "$@" ) } #!/bin/bash # OpenBao Vault operations and Kubernetes Secret synchronization sync_k8s_vault_token() { if kubectl --request-timeout=2s cluster-info >/dev/null 2>&1; then log_info "Синхронизация токена OpenBao в Kubernetes..." local bao_tok bao_tok=$(grep '^export VAULT_TOKEN=' "${RAM_CACHE}" 2>/dev/null | cut -d= -f2- | tr -d '"'"'") if [[ -n "${bao_tok}" ]]; then kubectl create namespace external-secrets --dry-run=client -o yaml | kubectl apply -f - >/dev/null 2>&1 || true kubectl -n external-secrets create secret generic openbao-token \ --from-literal=token="${bao_tok}" \ --dry-run=client -o yaml | kubectl apply -f - >/dev/null 2>&1 kubectl -n external-secrets rollout restart deployment external-secrets >/dev/null 2>&1 || true log_ok "Токен OpenBao в Kubernetes актуализирован." fi fi } unseal_vault() { local unseal_key target_vault_addr seal_status resp unseal_key=$(grep '^export VAULT_UNSEAL_KEY=' "${RAM_CACHE}" 2>/dev/null | cut -d= -f2- | tr -d '"'"'") target_vault_addr=$(grep '^export VAULT_ADDR=' "${RAM_CACHE}" 2>/dev/null | cut -d= -f2- | tr -d '"'"'") target_vault_addr="${target_vault_addr:-$VAULT_ADDR}" seal_status=$(curl -s --connect-timeout 2 "${target_vault_addr}/v1/sys/seal-status" 2>/dev/null || echo "") if [[ -z "${seal_status}" ]]; then log_warn "OpenBao (${target_vault_addr}) недоступен. Пропуск ансила." return 0 fi if echo "${seal_status}" | grep -q '"sealed":true'; then log_info "OpenBao запечатан. Ансил..." resp=$(printf '{"key":"%s"}' "${unseal_key}" | curl -s -X POST -H "Content-Type: application/json" --data-binary @- "${target_vault_addr}/v1/sys/unseal") if echo "${resp}" | grep -q '"sealed":false'; then log_ok "OpenBao успешно распечатан." sync_k8s_vault_token else log_err "Ошибка ансила OpenBao: ${resp}" return 1 fi else log_ok "OpenBao распечатан." sync_k8s_vault_token fi } #!/bin/bash set -uo pipefail REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" echo "## 0. Рабочая станция администратора (Operator Environment)" echo "### Инфраструктурные SSH-хосты (~/.ssh/config):" echo '```text' if [[ -f ~/.ssh/config ]]; then awk '/^Host (router|proxmox|vyos|10\.|fin21|ded|incserv)/, /^$/' ~/.ssh/config else echo "Файл ~/.ssh/config не найден" fi echo '```' echo "### Рабочие алиасы и функции оператора (Active Workflow Aliases):" echo '```bash' if [[ -f ~/.bashrc ]] && grep -q '# >>> ATLAS C2 WORKFLOW >>>' ~/.bashrc; then sed -n '/# >>> ATLAS C2 WORKFLOW >>>/,/# <<< ATLAS C2 WORKFLOW <<>>' else echo "# Маркер # >>> ATLAS C2 WORKFLOW >>> не найден в ~/.bashrc" fi echo '```' echo "### Статус RAM-кэша секретов (/dev/shm/.atlas_secrets_cache):" echo '```text' if [[ -f /dev/shm/.atlas_secrets_cache ]]; then stat -c "Размер: %s байт | Права: %a | Создан: %y" /dev/shm/.atlas_secrets_cache else echo "Кэш секретов в RAM отсутствует" fi echo '```' echo "### Проверка Git Credential Helper (git.svo88.space):" echo '```text' printf "protocol=https\nhost=git.svo88.space\n" | git credential fill 2>&1 | awk -F= '/^username/ {print "Username:", $2} /^password/ {print "Password: [PRESENT in RAM]"}' || echo "Credential helper не вернул учетных данных" echo '```' echo "### Ядро, память, ZRAM и параметры Coredump:" echo '```text' echo -n "Kernel: "; uname -r echo -n "Swapon: "; swapon --show 2>&1 || echo "swapon недоступен" zramctl 2>&1 || echo "zramctl недоступен" echo "Coredump config:" cat /etc/systemd/coredump.conf.d/*.conf 2>/dev/null || grep -E "Storage|ProcessSizeMax" /etc/systemd/coredump.conf 2>/dev/null || echo "Дефолтная конфигурация coredump" echo '```' echo "### Токены безопасности и ключи в ssh-agent:" echo '```text' echo "Active SSH Agent keys:" ssh-add -l 2>&1 || true echo "YubiKey / FIDO2 Status:" ykman info 2>/dev/null || echo "Токен YubiKey не обнаружен" echo '```' echo "### Зеркала пакетов Pacman (Mirrorlist):" echo '```text' grep -E "^Server|^\[" /etc/pacman.conf /etc/pacman.d/* 2>/dev/null | head -n 15 || echo "Нет данных о зеркалах" echo '```' echo "### Маршрутизация на хосте (Routing to C2):" echo '```text' ip route show | grep -E "10.0.|192.168." || echo "Маршруты к ЦОД не обнаружены" echo '```' echo "### Версии локальных инструментов:" echo '```text' echo -n "OpenTofu: "; tofu version 2>/dev/null | head -n1 || echo "not installed" echo -n "Kubectl: "; kubectl version --client -o yaml 2>/dev/null | grep gitVersion | head -n1 || echo "not installed" echo -n "Talosctl: "; talosctl version --client --short 2>/dev/null || echo "not installed" echo '```' echo "### Состояние локального Git-репозитория (SSOT Source):" echo '```text' git -C "${REPO_ROOT}" status -sb echo "Последний коммит: $(git -C "${REPO_ROOT}" log -1 --format='%h - %s (%cr)')" echo "Remote URL: $(git -C "${REPO_ROOT}" remote -v 2>/dev/null | head -n1 | awk '{print $1, $2}' || echo 'no remote')" echo '```' echo "---" #!/bin/bash set -uo pipefail SSH_CMD="ssh -n -o BatchMode=yes -o ConnectTimeout=3 proxmox" echo "## 1. Гипервизор Proxmox VE (192.168.1.177)" echo "### Память хоста, Uptime и Температура CPU:" echo '```text' timeout 4s ${SSH_CMD} "uptime; echo ''; free -h; echo ''; sensors 2>/dev/null | grep -E 'Tctl|Package|temp1' || cat /sys/class/thermal/thermal_zone*/temp 2>/dev/null | awk '{print \"CPU Temp: \" \$1/1000 \"°C\"}'" 2>&1 || echo "PVE недоступен" echo '```' echo "### Здоровье физических дисков (SMART):" echo '```text' timeout 5s ${SSH_CMD} "for d in sda sdb sdc sdd sde sdf; do echo -n \"/dev/\$d: \"; smartctl -H /dev/\$d 2>/dev/null | grep -E 'result|PASSED|FAILED' || echo 'N/A'; done" 2>&1 || echo "SMART недоступен" echo '```' echo "### Статус шифрования ZFS (Encryption & Keys):" echo '```text' timeout 4s ${SSH_CMD} "zfs get encryption,keystatus,keyformat,keylocation astra terra 2>/dev/null" 2>&1 || echo "Ошибка сбора шифрования ZFS" echo '```' echo "### Здоровье и емкость ZFS-пулов:" echo '```text' timeout 4s ${SSH_CMD} "zpool list -o name,size,alloc,free,frag,cap,health; echo ''; zfs list -o name,used,avail,refer,mountpoint -r astra terra" 2>&1 || echo "Ошибка сбора ZFS" echo '```' echo "### Физическая емкость каталогов на /terra:" echo '```text' timeout 5s ${SSH_CMD} "du -sh /terra/* 2>/dev/null" 2>&1 || echo "Ошибка чтения /terra" echo '```' echo "### Блочные устройства хоста и тома ZVOL (lsblk):" echo '```text' timeout 4s ${SSH_CMD} "lsblk -o NAME,FSTYPE,SIZE,MOUNTPOINTS" 2>&1 || echo "Ошибка сбора lsblk" echo '```' echo "### Виртуальные диски K8s и ВМ (ZVOLs на astra):" echo '```text' timeout 4s ${SSH_CMD} "zfs list -t volume -o name,volsize,used,referenced" 2>&1 || echo "Ошибка чтения ZVOL" echo '```' echo "### Модули ядра (nfsd, zfs):" echo '```text' timeout 4s ${SSH_CMD} "lsmod | grep -E '^(nfsd|zfs) '" 2>&1 || echo "Модули не загружены" echo '```' echo "### Теги сетевых карт ВМ 100 (VyOS) в Proxmox:" echo '```text' timeout 4s ${SSH_CMD} "qm config 100 2>/dev/null | grep -E '^net[0-9]'" 2>&1 || echo "Ошибка чтения qm config 100" echo '```' echo "### Точки монтирования LXC-контейнеров (/etc/pve/lxc/*.conf):" echo '```text' timeout 4s ${SSH_CMD} "grep -H -E '^mp[0-9]:' /etc/pve/lxc/*.conf 2>/dev/null" 2>&1 || echo "Ошибка чтения lxc conf" echo '```' echo "### Флаги автостарта ВМ и Контейнеров (onboot):" echo '```text' timeout 4s ${SSH_CMD} "grep -H -E '^onboot:' /etc/pve/qemu-server/*.conf /etc/pve/lxc/*.conf 2>/dev/null" 2>&1 || echo "Ошибка чтения onboot" echo '```' echo "### Виртуальные машины (QEMU) и Контейнеры (LXC):" echo '```text' timeout 4s ${SSH_CMD} "qm list; echo ''; pct list" 2>&1 || echo "Ошибка получения списка ВМ/LXC" echo '```' echo "---" #!/bin/bash set -uo pipefail SSH_CMD="ssh -n -o BatchMode=yes -o ConnectTimeout=4 fin21" echo "## 2. Периметр: Белый VPS (Host: fin21, IP: 153.76.194.24)" echo "### WireGuard wg0 на VPS:" echo '```text' timeout 4s ${SSH_CMD} "sudo wg show wg0" 2>&1 || echo "VPS или WireGuard недоступен" echo '```' echo "### Статус системных сервисов (Edge Stack):" echo '```text' timeout 4s ${SSH_CMD} "sudo systemctl is-active wg-quick@wg0 haproxy xray nginx | paste -d' ' -s - | awk '{print \"WireGuard:\", \$1, \"| HAProxy:\", \$2, \"| Xray:\", \$3, \"| Nginx:\", \$4}'" 2>&1 || echo "Ошибка проверки systemd" echo '```' echo "### Прослушиваемые сокеты (Ports 80, 443, 4443, 8443, 51820):" echo '```text' timeout 4s ${SSH_CMD} "sudo ss -tulpn | grep -E '80|443|4443|8443|51820'" 2>&1 || echo "Ошибка ss" echo '```' echo "### Тест аварийной заглушки Nginx (127.0.0.1:8443):" echo '```text' timeout 3s ${SSH_CMD} "curl -k -s https://127.0.0.1:8443" 2>&1 || echo "Nginx fallback не отвечает" echo '```' echo "### Конфигурация SSH-демона (sshd runtime):" echo '```text' timeout 4s ${SSH_CMD} "sudo sshd -T | grep -E 'passwordauthentication|permitrootlogin'" 2>&1 || echo "Ошибка проверки sshd" echo '```' echo "---" #!/bin/bash set -uo pipefail SSH_CMD="ssh -n -o BatchMode=yes -o ConnectTimeout=3 vyos" echo "## 3. Маршрутизатор VyOS (192.168.1.2)" echo "### Сетевые интерфейсы и L2-транк (VLANs 10, 20, 30):" echo '```text' timeout 4s ${SSH_CMD} "/opt/vyatta/bin/vyatta-op-cmd-wrapper show interfaces" 2>&1 || echo "Ошибка получения интерфейсов" echo '```' echo "### ARP-таблица K8s-интерфейса eth1 (проверка связности с нодами):" echo '```text' timeout 4s ${SSH_CMD} "ip neigh show dev eth1 2>/dev/null" 2>&1 || echo "Ошибка чтения ARP" echo '```' echo "### DHCP-сервер и выданные лизы (Options 3, 6):" echo '```text' timeout 4s ${SSH_CMD} "/opt/vyatta/bin/vyatta-op-cmd-wrapper show dhcp server leases" 2>&1 || echo "Ошибка получения DHCP лизов" echo '```' echo "### Перехват DNS через DNAT (Rule 53 -> 127.0.0.42:53):" echo '```text' timeout 4s ${SSH_CMD} "/opt/vyatta/bin/vyatta-op-cmd-wrapper show nat destination rules" 2>&1 || echo "Ошибка получения NAT правил" echo '```' echo "### Контейнеры маршрутизатора (Sing-Box & Zapret2):" echo '```text' timeout 4s ${SSH_CMD} "/opt/vyatta/bin/vyatta-op-cmd-wrapper show container" 2>&1 || echo "Ошибка получения контейнеров" echo '```' echo "### Наличие /dev/net/tun внутри контейнера sing-box:" echo '```text' timeout 4s ${SSH_CMD} "sudo podman exec sing-box ls -l /dev/net/tun 2>/dev/null" 2>&1 || echo "Контейнер sing-box не запущен или tun отсутствует" echo '```' echo "### Задержка VLESS-канала через Clash API (Main-1-out -> fin21):" echo '```text' timeout 4s ${SSH_CMD} "curl -s http://127.0.0.1:9090/proxies/Main-1-out 2>/dev/null" 2>&1 || echo "Clash API недоступен" echo '```' echo "### Статус таймера автосинхронизации Git (singbox-sync):" echo '```text' timeout 4s ${SSH_CMD} "sudo systemctl status singbox-sync.timer --no-pager; echo ''; sudo journalctl -u singbox-sync.service -n 5 --no-pager" 2>&1 || echo "Ошибка проверки таймера" echo '```' echo "### Статус WireGuard туннеля wg0 и пинг до VPS:" echo '```text' timeout 4s ${SSH_CMD} "sudo wg show wg0; echo ''; /opt/vyatta/bin/vyatta-op-cmd-wrapper ping 10.8.0.1 count 2" 2>&1 || echo "VyOS или туннель недоступен" echo '```' echo "### Таблица маршрутизации (show ip route):" echo '```text' timeout 4s ${SSH_CMD} "/opt/vyatta/bin/vyatta-op-cmd-wrapper show ip route" 2>&1 || echo "Ошибка получения маршрутов" echo '```' echo "---" #!/bin/bash set -uo pipefail SSH_VYOS="ssh -n -o BatchMode=yes -o ConnectTimeout=3 vyos" SSH_STORAGE="ssh -n -o BatchMode=yes -o ConnectTimeout=3 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -J vyos root@10.0.10.14" echo "## 4. Сервисы Tier-0 (Air-Gap фундамент)" echo "### Technitium DNS (10.0.10.11:53):" echo "* **Внутренний домен (*.svo88.space -> 10.0.30.200):** $(timeout 3s ${SSH_VYOS} "dig @10.0.10.11 vw.svo88.space +short" 2>&1 | tr '\n' ' ')" echo "* **Внешний резолв (google.com):** $(timeout 3s ${SSH_VYOS} "dig @10.0.10.11 google.com +short" 2>&1 | head -n1)" echo "### OpenBao Vault (10.0.10.12:8200):" echo '```json' timeout 3s ${SSH_VYOS} "curl -s http://10.0.10.12:8200/v1/sys/seal-status" 2>&1 || echo '{"error": "Vault недоступен"}' echo '```' echo "### Zot OCI Registry (10.0.10.15:5000):" echo '```json' timeout 3s ${SSH_VYOS} "curl -s http://10.0.10.15:5000/v2/_catalog" 2>&1 || echo '{"error": "Zot недоступен"}' echo '```' echo "### Forgejo GitOps Server (10.0.10.13:3000):" echo '```json' timeout 3s ${SSH_VYOS} "curl -s http://10.0.10.13:3000/api/v1/version" 2>&1 || echo '{"error": "Forgejo недоступен"}' echo '```' echo "### Ядерный NFS nfsd (storage0 - 10.0.10.14):" echo '```text' timeout 4s ${SSH_STORAGE} "echo '== Активные экспорты ядра (exportfs):'; exportfs -v; echo ''; echo '== Емкость смонтированных ZFS-датасетов:'; df -h /media /torrents /backups /models; echo ''; echo '== Права точки монтирования OpenCloud:'; ls -ld /backups/opencloud-users" 2>&1 || echo "NFS (storage0) недоступен" echo '```' echo "---" #!/bin/bash set -uo pipefail REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" TALOSCONFIG="${REPO_ROOT}/talos/clusterconfig/talosconfig" KUBECONFIG_PATH="${HOME}/.kube/config" echo "## 5. Kubernetes Платформа & Нагрузки" echo "### Участники кластера Talos (OS-level):" echo '```text' timeout 5s talosctl --talosconfig="${TALOSCONFIG}" -n 10.0.20.10 -e 10.0.20.10 get members 2>&1 || echo "Talos API недоступен" echo '```' echo "### Ноды кластера K8s:" echo '```text' timeout 5s kubectl --kubeconfig="${KUBECONFIG_PATH}" get nodes -o wide 2>&1 || echo "K8s API недоступен" echo '```' echo "### Топологические лейблы нод (Proxmox-CSI topology):" echo '```text' timeout 5s kubectl --kubeconfig="${KUBECONFIG_PATH}" get nodes -L topology.kubernetes.io/zone,topology.kubernetes.io/region 2>&1 || echo "Не удалось получить лейблы нод" echo '```' echo "### Статус ExternalSecrets (Синхронизация из Vault):" echo '```text' timeout 5s kubectl --kubeconfig="${KUBECONFIG_PATH}" get clustersecretstores,externalsecrets -A 2>&1 || echo "Не удалось получить ExternalSecrets" echo '```' echo "### Сетевой ingress, сертификаты TLS и L2 Fast-Path VIP:" echo '```text' timeout 5s kubectl --kubeconfig="${KUBECONFIG_PATH}" get certificates,ingresses -A 2>&1 || echo "Не удалось получить Ingress/TLS" echo '' timeout 5s kubectl --kubeconfig="${KUBECONFIG_PATH}" -n kube-system get ciliuml2announcementpolicies,ciliumloadbalancerippools 2>&1 || echo "Не удалось получить Cilium L2" echo '' timeout 3s curl -k -s -o /dev/null -w "Traefik VIP (10.0.30.200:443) HTTP Status: %{http_code}\n" https://10.0.30.200 2>&1 || echo "Traefik VIP недоступен" echo '```' echo "### Диски и тома (PVC / PV):" echo '```text' timeout 5s kubectl --kubeconfig="${KUBECONFIG_PATH}" get pvc,pv -A 2>&1 || echo "Не удалось получить PVC" echo '```' echo "### Статус DaemonSet Proxmox-CSI Node:" echo '```text' timeout 5s kubectl --kubeconfig="${KUBECONFIG_PATH}" -n kube-system get daemonset proxmox-csi-plugin-node 2>&1 || echo "Не удалось получить DaemonSet CSI" echo '```' echo "### Статус пространства мониторинга (VictoriaMetrics & Grafana):" echo '```text' timeout 5s kubectl --kubeconfig="${KUBECONFIG_PATH}" -n monitoring get statefulsets,pods,pvc 2>&1 || echo "Не удалось получить мониторинг" echo '```' echo "### Логи ошибок Proxmox CSI Plugin (последние строки):" echo '```text' timeout 5s kubectl --kubeconfig="${KUBECONFIG_PATH}" -n kube-system logs -l app.kubernetes.io/name=proxmox-csi-plugin --tail=15 --prefix=true 2>&1 || echo "Нет логов CSI" echo '```' echo "### Синхронизация GitOps (FluxCD):" echo '```text' timeout 5s kubectl --kubeconfig="${KUBECONFIG_PATH}" get gitrepositories,kustomizations,helmreleases -A 2>&1 || echo "Flux не установлен или недоступен" echo '```' echo "### Проблемные поды (Non-Running):" echo '```text' timeout 5s kubectl --kubeconfig="${KUBECONFIG_PATH}" get pods -A --field-selector=status.phase!=Running 2>&1 || echo "Все поды в статусе Running" echo '```' echo "### Последние события-предупреждения (Warning Events):" echo '```text' timeout 5s kubectl --kubeconfig="${KUBECONFIG_PATH}" get events -A --field-selector type=Warning --sort-by='.lastTimestamp' 2>&1 | tail -n 15 || echo "Нет предупреждений" echo '```' echo "### Реальный объем данных OpenCloud (/var/lib/opencloud-users):" echo '```text' timeout 10s kubectl --kubeconfig="${KUBECONFIG_PATH}" -n storage exec statefulset/opencloud -c opencloud -- du -sh /var/lib/opencloud-users 2>&1 || echo "Не удалось получить размер данных OpenCloud" echo '```' #!/bin/bash # Atlas C2 Configuration SSOT KDBX_PATH="${HOME}/Projects/atlas-secrets.kdbx" RAM_CACHE="/dev/shm/.atlas_secrets_cache" RAM_KEY="/dev/shm/.atlas_core" VAULT_ADDR="http://10.0.10.12:8200" VYOS_ROUTER_IP="192.168.1.2" NET_PREFIX="10.0.0.0/16" GIT_HOST="git.svo88.space" PVE_ENDPOINT="https://192.168.1.177:8006/" DEFAULT_SESSION_TTL=1