feat(zarya): declarative srv-init with ufw policies and verification gate

This commit is contained in:
v 2026-10-26 11:24:49 +03:00
parent 1d054935c4
commit 8259b80620
3 changed files with 198 additions and 3 deletions

View file

@ -26,6 +26,7 @@ case "${SUBCMD}" in
pack) exec "${ZARYA_DIR}/cmd/pack.sh" "$@" ;;
reset|nuke) exec "${ZARYA_DIR}/layers/reset.sh" "$@" ;;
gc) exec "${ZARYA_DIR}/layers/gc.sh" "$@" ;;
srv-init|vps-init) exec "${ZARYA_DIR}/cmd/vps-init.sh" "$@" ;;
help|--help|-h)
cat <<EOF
ZARYA Operator Interface (z)
@ -47,6 +48,7 @@ GitOps и оркестрация:
z up [layer] Макро-слои (host, net, tier0, talos, apps, all)
z run <selector> Плейбуки Ansible (01, 02)
z a [-auto-approve] OpenTofu apply в RAM-изоляции
z srv-init <IP> [ALIAS] [FLAGS] Day-0 удаленный бутстрап ноды .srv в 1 клик
Телеметрия и LLM:
z snap Снятие аудита в state/snapshots/
z pack [all|atlas|code|state] Сборка контекстов Repomix для LLM

182
cmd/vps-init.sh Executable file
View file

@ -0,0 +1,182 @@
#!/bin/bash
set -euo pipefail
ZARYA_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
source "${ZARYA_DIR}/lib/common.sh"
TARGET_IP=""
ALIAS=""
PORT="${SRV_DEFAULT_PORT:-1488}"
USER_NAME="${SRV_DEFAULT_USER:-atlas}"
TCP_PORTS="${SRV_DEFAULT_TCP_PORTS:-1488 80 443}"
UDP_PORTS="${SRV_DEFAULT_UDP_PORTS:-51820}"
UFW_IN="${SRV_UFW_INCOMING:-deny}"
UFW_OUT="${SRV_UFW_OUTGOING:-allow}"
UFW_FWD="${SRV_UFW_FORWARD:-deny}"
UFW_APP="${SRV_UFW_APPLICATION:-skip}"
ENABLE_BBR="${SRV_ENABLE_BBR:-true}"
DISABLE_IPV6="${SRV_DISABLE_IPV6:-true}"
DISABLE_ICMP="${SRV_DISABLE_ICMP:-false}"
VERIFY_GATE="false"
PUBKEY="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGY8TEByHoDFNsy18VG6BJALc8HUYeoKZz2PeKMyKMND atlas@core"
while [[ $# -gt 0 ]]; do
case "$1" in
--verify|--test|-v)
VERIFY_GATE="true"
shift
;;
--port)
PORT="$2"
shift 2
;;
--user)
USER_NAME="$2"
shift 2
;;
--tcp)
TCP_PORTS="$2"
shift 2
;;
--udp)
UDP_PORTS="$2"
shift 2
;;
--disable-icmp)
DISABLE_ICMP="true"
shift
;;
--enable-icmp)
DISABLE_ICMP="false"
shift
;;
--disable-ipv6)
DISABLE_IPV6="true"
shift
;;
--enable-ipv6)
DISABLE_IPV6="false"
shift
;;
--no-bbr)
ENABLE_BBR="false"
shift
;;
--help|-h)
echo "Использование: z srv-init <IP> [ALIAS] [--verify] [--port N] [--user NAME] [--tcp 'PORTS'] [--udp 'PORTS'] [--disable-icmp] [--disable-ipv6] [--no-bbr]"
exit 0
;;
*)
if [[ -z "${TARGET_IP}" ]]; then
TARGET_IP="$1"
elif [[ -z "${ALIAS}" ]]; then
ALIAS="$1"
fi
shift
;;
esac
done
if [[ -z "${TARGET_IP}" ]]; then
log_err "IP-адрес целевого сервера обязателен. Введите 'z srv-init --help'."
exit 1
fi
if [[ -z "${ALIAS}" ]]; then
LAST_OCTET="${TARGET_IP##*.}"
ALIAS="n${LAST_OCTET}.srv"
fi
log_info "Инициализация ноды ${ALIAS} (${TARGET_IP}:${PORT})..."
ssh -o StrictHostKeyChecking=accept-new -p 22 "root@${TARGET_IP}" "bash -s" << REMOTE_EOF
set -euo pipefail
id -u "${USER_NAME}" &>/dev/null || useradd -m -s /bin/bash -G sudo "${USER_NAME}"
mkdir -p "/home/${USER_NAME}/.ssh"
echo "${PUBKEY}" > "/home/${USER_NAME}/.ssh/authorized_keys"
chmod 700 "/home/${USER_NAME}/.ssh"
chmod 600 "/home/${USER_NAME}/.ssh/authorized_keys"
chown -R "${USER_NAME}:${USER_NAME}" "/home/${USER_NAME}/.ssh"
echo "${USER_NAME} ALL=(ALL) NOPASSWD:ALL" > "/etc/sudoers.d/${USER_NAME}"
chmod 440 "/etc/sudoers.d/${USER_NAME}"
if systemctl is-active --quiet ssh.socket 2>/dev/null; then
systemctl disable --now ssh.socket
fi
rm -rf /etc/ssh/sshd_config.d/*.conf
cat << SSHEOF > /etc/ssh/sshd_config
Port ${PORT}
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin prohibit-password
PubkeyAuthentication yes
X11Forwarding no
AcceptEnv LANG LC_*
Subsystem sftp /usr/lib/openssh/sftp-server
SSHEOF
systemctl enable --now ssh.service
systemctl restart ssh.service
which ufw >/dev/null 2>&1 || (DEBIAN_FRONTEND=noninteractive apt-get update -y && DEBIAN_FRONTEND=noninteractive apt-get install -y ufw)
ufw --force reset
ufw default ${UFW_IN} incoming
ufw default ${UFW_OUT} outgoing
ufw default ${UFW_FWD} forward
sed -i -E 's/^DEFAULT_APPLICATION_POLICY=.*/DEFAULT_APPLICATION_POLICY="'${UFW_APP}'"/' /etc/default/ufw || true
if [[ "${DISABLE_IPV6}" == "true" ]]; then
sed -i -E 's/^IPV6=.*/IPV6=no/' /etc/default/ufw || true
fi
for p in ${TCP_PORTS}; do
ufw allow "\${p}/tcp"
done
for p in ${UDP_PORTS}; do
ufw allow "\${p}/udp"
done
ufw --force enable
rm -f /etc/sysctl.d/99-atlas.conf
touch /etc/sysctl.d/99-atlas.conf
if [[ "${ENABLE_BBR}" == "true" ]]; then
printf "net.core.default_qdisc = fq\nnet.ipv4.tcp_congestion_control = bbr\n" >> /etc/sysctl.d/99-atlas.conf
fi
if [[ "${DISABLE_IPV6}" == "true" ]]; then
printf "net.ipv6.conf.all.disable_ipv6 = 1\nnet.ipv6.conf.default.disable_ipv6 = 1\nnet.ipv6.conf.lo.disable_ipv6 = 1\n" >> /etc/sysctl.d/99-atlas.conf
fi
if [[ "${DISABLE_ICMP}" == "true" ]]; then
printf "net.ipv4.icmp_echo_ignore_all = 1\n" >> /etc/sysctl.d/99-atlas.conf
fi
sysctl --system >/dev/null 2>&1 || true
REMOTE_EOF
SSH_CONFIG="${HOME}/.ssh/config"
if ! grep -q "Host.*${ALIAS}" "${SSH_CONFIG}" 2>/dev/null; then
printf "\nHost %s\n Hostname %s\n" "${ALIAS}" "${TARGET_IP}" >> "${SSH_CONFIG}"
fi
if [[ "${VERIFY_GATE}" == "true" ]]; then
log_warn "Включен режим ручного подтверждения."
echo "Откройте соседний терминал и выполните: ssh ${ALIAS}"
read -r -p "Подключение успешно? [y/N]: " CONFIRM
if [[ "${CONFIRM}" != "y" && "${CONFIRM}" != "Y" ]]; then
log_err "Подтверждение отклонено оператором. Откат конфигурации..."
ssh -o ConnectTimeout=10 -p "${PORT}" -i "${RAM_KEY}" "${USER_NAME}@${TARGET_IP}" "sudo ufw disable && sudo sed -i -E 's/^Port .*/Port 22/' /etc/ssh/sshd_config && sudo systemctl restart ssh.service" || true
log_warn "Откат завершен: порт 22 возвращен, UFW выключен."
exit 1
fi
fi
log_info "Автоматическая валидация ноды ${ALIAS}..."
ssh -o ConnectTimeout=5 "${ALIAS}" "hostname"
log_ok "Сервер ${ALIAS} успешно инициализирован и верифицирован."

View file

@ -1,6 +1,3 @@
#!/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"
@ -12,3 +9,17 @@ GIT_HOST="git.svo88.space"
PVE_ENDPOINT="https://192.168.1.177:8006/"
DEFAULT_SESSION_TTL=1
SRV_DEFAULT_PORT=1488
SRV_DEFAULT_USER="atlas"
SRV_DEFAULT_TCP_PORTS="1488 80 443"
SRV_DEFAULT_UDP_PORTS="51820"
SRV_UFW_INCOMING="deny"
SRV_UFW_OUTGOING="allow"
SRV_UFW_FORWARD="deny"
SRV_UFW_APPLICATION="skip"
SRV_ENABLE_BBR="true"
SRV_DISABLE_IPV6="true"
SRV_DISABLE_ICMP="false"