#!/bin/bash # ============================================================ # ПРОВЕРКА ЗАДАНИЯ 1 — HQ-RTR (только читает состояние!) # Пункты ssh/frr/iptables/DHCP требуют root — иначе ПРОПУЩЕНО. # ============================================================ NAME="hq-rtr" LOG="check_${NAME}_z1.txt" OK=0; FAIL=0; SKIP=0 ok() { echo "[OK] $1"; OK=$((OK+1)); } fail() { echo "[FAIL] $1 — $2"; FAIL=$((FAIL+1)); } skip() { echo "[ПРОПУЩЕНО] $1"; SKIP=$((SKIP+1)); } root_or_skip() { if [[ $EUID -ne 0 ]]; then skip "$1 (нужен root)"; return 1; fi; return 0; } check_var() { if [[ -z "${!2}" ]]; then skip "$1 — не задано $2"; return 1; fi; return 0; } expect_eq() { if [[ "$3" == "$2" ]]; then ok "$1"; else fail "$1" "ожидалось '$2', получено '$3'"; fi; } # ================= ПЕРЕМЕННЫЕ (заполните для проверки) ================= HOSTNAME_EXPECTED="hq-rtr.au-team.irpo" # таблица 3 NET_ADMIN_USER="net_admin" ISP_IF="" # интерфейс к ISP (для маршрута по умолчанию) VLAN100_IF="vlan100" # имя vlan-подинтерфейса VLAN 100 VLAN100_ADDR="" # адрес роутера в VLAN 100, адрес/префикс VLAN200_IF="vlan200" VLAN200_ADDR="" VLAN999_IF="vlan999" VLAN999_ADDR="" GRE_IF="gre1" # имя туннеля GRE_LOCAL="" # локальный конец туннеля, адрес/префикс GRE_REMOTE="" # адрес BR-RTR в сети ISP (пингуем через туннель) OSPF_PASSWORD="P@ssw0rd" # пароль OSPF по заданию DHCP_PORT_CHECK="67" # порт DHCP-сервера (изменять не нужно) EXAM_TZ="" main () { echo "=== Проверка задания 1: HQ-RTR ===" # --- 1. Имя хоста --- check_var "имя хоста" HOSTNAME_EXPECTED && expect_eq "имя хоста" "$HOSTNAME_EXPECTED" "$(hostname)" # --- 2. Пользователь net_admin --- check_var "пользователь net_admin" NET_ADMIN_USER && if id "$NET_ADMIN_USER" &>/dev/null; then ok "пользователь $NET_ADMIN_USER существует" else fail "пользователь $NET_ADMIN_USER" "нет такого пользователя"; fi check_var "sudo для net_admin" NET_ADMIN_USER && if root_or_skip "sudo для net_admin"; then if sudo -ln -U "$NET_ADMIN_USER" 2>/dev/null | grep -q "NOPASSWD: ALL"; then ok "net_admin — sudo без пароля (NOPASSWD: ALL)" else fail "sudo для net_admin" "нет NOPASSWD: ALL: $(sudo -l -U "$NET_ADMIN_USER" 2>&1 | tail -3)"; fi fi # --- 3. VLAN-подинтерфейсы на одном адаптере --- check_var "адрес в VLAN 100" VLAN100_ADDR && if grep -qF -- "$VLAN100_ADDR" <(ip -4 -o addr show "$VLAN100_IF" 2>/dev/null); then ok "адрес VLAN 100 ($VLAN100_IF) = $VLAN100_ADDR" else fail "адрес VLAN 100" "на $VLAN100_IF не нашёлся $VLAN100_ADDR"; fi check_var "адрес в VLAN 200" VLAN200_ADDR && if grep -qF -- "$VLAN200_ADDR" <(ip -4 -o addr show "$VLAN200_IF" 2>/dev/null); then ok "адрес VLAN 200 ($VLAN200_IF) = $VLAN200_ADDR" else fail "адрес VLAN 200" "на $VLAN200_IF не нашёлся $VLAN200_ADDR"; fi check_var "адрес в VLAN 999" VLAN999_ADDR && if grep -qF -- "$VLAN999_ADDR" <(ip -4 -o addr show "$VLAN999_IF" 2>/dev/null); then ok "адрес VLAN 999 ($VLAN999_IF) = $VLAN999_ADDR" else fail "адрес VLAN 999" "на $VLAN999_IF не нашёлся $VLAN999_ADDR"; fi # --- 4. GRE-туннель --- check_var "адрес туннеля" GRE_LOCAL && if grep -qF -- "$GRE_LOCAL" <(ip -4 -o addr show "$GRE_IF" 2>/dev/null); then ok "туннель $GRE_IF поднят с $GRE_LOCAL" else fail "туннель $GRE_IF" "не нашёлся адрес $GRE_LOCAL ($(ip -4 -o addr show "$GRE_IF" 2>/dev/null))"; fi # --- 5. OSPF: сосед через туннель и аутентификация MD5 --- if root_or_skip "OSPF (vtysh)"; then if ! command -v vtysh &>/dev/null; then skip "OSPF сосед — vtysh не найден (ПРОВЕРИТЬ: пакет/имя OSPF-демона на РЕД ОС 8)" else NEIGH_STATE=$(vtysh -c 'show ip ospf neighbor' 2>/dev/null | grep -c "Full") if [[ $NEIGH_STATE -ge 1 ]]; then ok "OSPF сосед в FULL (найдено $NEIGH_STATE)" else fail "OSPF сосед" "нет соседа в Full: $(vtysh -c 'show ip ospf neighbor' 2>&1)"; fi if vtysh -c 'show running-config' 2>/dev/null \ | grep -i "message-digest-key" | grep -qiF "$OSPF_PASSWORD"; then ok "OSPF MD5-аутентификация с паролем $OSPF_PASSWORD" else fail "OSPF MD5" "ключ/пароль не найдены в ospf-конфиге"; fi if vtysh -c 'show ip route ospf' 2>/dev/null | grep -q "O "; then ok "маршруты OSPF присутствуют" else fail "маршруты OSPF" "нет маршрутов от OSPF"; fi fi fi # --- 6. NAT на выход в сторону ISP --- if [[ -n "$ISP_IF" ]]; then if root_or_skip "NAT на ISP-интерфейс"; then COUNT=$(iptables -t nat -S POSTROUTING 2>/dev/null | grep -cF "$ISP_IF") if [[ $COUNT -ge 1 ]]; then ok "NAT правило MASQUERADE на $ISP_IF ($COUNT правил)" else fail "NAT" "нет MASQUERADE на $ISP_IF"; fi fi if ip route show default 2>/dev/null | grep -qF "$ISP_IF"; then ok "маршрут по умолчанию через $ISP_IF" else fail "маршрут по умолчанию" "через $ISP_IF нет"; fi else skip "NAT/маршрут по умолчанию — не задано ISP_IF" fi # --- 7. DHCP слушает на 67 --- if root_or_skip "DHCP-сервер слушает порт $DHCP_PORT_CHECK"; then if ss -ulnp 2>/dev/null | grep -q ":$DHCP_PORT_CHECK"; then ok "DHCP слушает порт $DHCP_PORT_CHECK (udp)" else fail "DHCP порт $DHCP_PORT_CHECK" "ничего не слушает udp/$DHCP_PORT_CHECK"; fi fi # --- 8. Связь через туннель (адрес BR-RTR в сети ISP) --- check_var "связь через туннель" GRE_REMOTE && if ping -c2 -W2 "$GRE_REMOTE" &>/dev/null; then ok "ping BR-RTR ($GRE_REMOTE)" else fail "ping BR-RTR ($GRE_REMOTE)" "недоступен (туннель/OSPF/NAT?)"; fi # --- 9. IP forwarding --- FWD=$(cat /proc/sys/net/ipv4/ip_forward 2>/dev/null) if [[ "$FWD" == "1" ]]; then ok "ip_forward включён" else fail "ip_forward" "ожидалось 1, получено '$FWD'"; fi # --- 10. Часовой пояс --- check_var "часовой пояс" EXAM_TZ && expect_eq "часовой пояс" "$EXAM_TZ" "$(timedatectl show -p Timezone --value)" echo "" echo "=== Проверить вручную ===" echo " — DHCP-лизинг на HQ-CLI (скрипт check/zadanie1/hq-cli.sh)" echo " — vtysh -c 'show ip ospf interface' (протокол только на $GRE_IF?)" echo "" echo "=== Итог: OK=$OK FAIL=$FAIL ПРОПУЩЕНО=$SKIP ===" [[ $FAIL -eq 0 ]] } main 2>&1 | tee "$LOG" STATUS=${PIPESTATUS[0]} echo "Лог сохранён: $LOG" exit $STATUS