Задание 2: скрипты настройки и проверки
This commit is contained in:
parent
bbee2efaec
commit
d995ba80ab
63
check/zadanie2/br-rtr.sh
Normal file
63
check/zadanie2/br-rtr.sh
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
#!/bin/bash
|
||||
# ============================================================
|
||||
# ПРОВЕРКА ЗАДАНИЯ 2 — BR-RTR: DNAT (8080/2027 -> BR-SRV),
|
||||
# chrony-клиент (сервер = ISP)
|
||||
# (только читает состояние; iptables требует root)
|
||||
# ============================================================
|
||||
|
||||
NAME="br-rtr"
|
||||
LOG="check_${NAME}_z2.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; }
|
||||
|
||||
# ================= ПЕРЕМЕННЫЕ (заполните для проверки) =================
|
||||
BR_SRV_IP="" # адрес BR-SRV
|
||||
TESTAPP_PORT="8080" # порт testapp
|
||||
SSH_PORT="2027"
|
||||
NTP_ADDR="" # адрес ISP (источник NTP)
|
||||
|
||||
main () {
|
||||
echo "=== Проверка задания 2: BR-RTR (DNAT + chrony-клиент) ==="
|
||||
|
||||
if root_or_skip "правила DNAT (iptables)"; then
|
||||
NAT=$(iptables -t nat -S PREROUTING 2>/dev/null)
|
||||
check_var "адрес BR-SRV" BR_SRV_IP && {
|
||||
if grep -qF "DNAT --to-destination $BR_SRV_IP:$TESTAPP_PORT" <<<"$NAT" \
|
||||
|| grep -qF "DNAT --to $BR_SRV_IP:$TESTAPP_PORT" <<<"$NAT"; then
|
||||
ok "проброс 8080 -> $BR_SRV_IP:$TESTAPP_PORT"
|
||||
else fail "проброс 8080" "нет DNAT строки в: $NAT"; fi
|
||||
}
|
||||
check_var "адрес BR-SRV" BR_SRV_IP && {
|
||||
if grep -qF "DNAT --to-destination $BR_SRV_IP:$SSH_PORT" <<<"$NAT" \
|
||||
|| grep -qF "DNAT --to $BR_SRV_IP:$SSH_PORT" <<<"$NAT"; then
|
||||
ok "проброс 2027 -> $BR_SRV_IP:$SSH_PORT"
|
||||
else fail "проброс 2027" "нет DNAT строки в: $NAT"; fi
|
||||
}
|
||||
fi
|
||||
|
||||
# --- chrony-клиент: источник = адрес ISP ---
|
||||
check_var "источник NTP" NTP_ADDR &&
|
||||
if command -v chronyc &>/dev/null; then
|
||||
if chronyc sources 2>/dev/null | grep -qF "$NTP_ADDR"; then
|
||||
ok "NTP источник = $NTP_ADDR"
|
||||
else fail "NTP источник" "адрес $NTP_ADDR не найден в chronyc sources: $(chronyc sources 2>&1)"; fi
|
||||
else skip "NTP источник — chronyc не найден (ПРОВЕРИТЬ пакет chrony)"; fi
|
||||
|
||||
echo ""
|
||||
echo "=== Проверить вручную ==="
|
||||
echo " — chronyc tracking (синхронизировано?)"
|
||||
echo " — с ISP: nc -zv <адрес BR-RTR на линке> 2027 и 8080"
|
||||
|
||||
echo ""
|
||||
echo "=== Итог: OK=$OK FAIL=$FAIL ПРОПУЩЕНО=$SKIP ==="
|
||||
[[ $FAIL -eq 0 ]]
|
||||
}
|
||||
main 2>&1 | tee "$LOG"
|
||||
STATUS=${PIPESTATUS[0]}
|
||||
echo "Лог сохранён: $LOG"
|
||||
exit $STATUS
|
||||
98
check/zadanie2/br-srv.sh
Normal file
98
check/zadanie2/br-srv.sh
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
#!/bin/bash
|
||||
# ============================================================
|
||||
# ПРОВЕРКА ЗАДАНИЯ 2 — BR-SRV: Samba DC, Ansible, Docker
|
||||
# (только читает состояние; samba-tool/docker/ansible требуют root)
|
||||
# ЕДИНСТВЕННАЯ запись — нет: все команды только для чтения
|
||||
# (docker ps, samba-tool user list, ansible ping — информационный модуль).
|
||||
# ============================================================
|
||||
|
||||
NAME="br-srv"
|
||||
LOG="check_${NAME}_z2.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; }
|
||||
|
||||
# ================= ПЕРЕМЕННЫЕ (заполните для проверки) =================
|
||||
HQ_USERS_COUNT="5" # по заданию hquser1..5
|
||||
HQ_GROUP="hq"
|
||||
MIN_PWD_LENGTH="8" # политика по заданию
|
||||
LOCKOUT_ATTEMPTS="5" # блокировка по заданию
|
||||
# sudo-проверка группы hq выполняется на HQ-CLI (check/zadanie2/hq-cli.sh)
|
||||
|
||||
main () {
|
||||
echo "=== Проверка задания 2: BR-SRV (Samba/Ansible/Docker) ==="
|
||||
|
||||
# --- 1. Пользователи hquser1..5 ---
|
||||
if root_or_skip "samba-tool (требует root)"; then
|
||||
if ! command -v samba-tool &>/dev/null; then
|
||||
skip "Samba — samba-tool не найден (ПРОВЕРИТЬ установку samba-dc)"
|
||||
else
|
||||
USER_LIST=$(samba-tool user list 2>/dev/null)
|
||||
COUNT_OK=0
|
||||
for i in $(seq 1 "$HQ_USERS_COUNT"); do
|
||||
if grep -qx "hquser${i}" <<<"$USER_LIST"; then COUNT_OK=$((COUNT_OK+1));
|
||||
else fail "пользователь hquser${i}" "не найден в списке домена"; fi
|
||||
done
|
||||
[[ $COUNT_OK -eq $HQ_USERS_COUNT ]] && ok "пользователи hquser1..$HQ_USERS_COUNT созданы ($COUNT_OK)"
|
||||
# --- группа hq ---
|
||||
if samba-tool group list 2>/dev/null | grep -qx "$HQ_GROUP"; then
|
||||
ok "группа $HQ_GROUP существует"
|
||||
MEMBERS=$(samba-tool group listmembers "$HQ_GROUP" 2>/dev/null | grep -c "^hquser")
|
||||
if [[ $MEMBERS -eq $HQ_USERS_COUNT ]]; then ok "в группе $HQ_GROUP все $HQ_USERS_COUNT пользователей"
|
||||
else fail "состав группы $HQ_GROUP" "ожидалось $HQ_USERS_COUNT hquser*, найдено $MEMBERS: $(samba-tool group listmembers "$HQ_GROUP" 2>&1)"; fi
|
||||
else fail "группа $HQ_GROUP" "группа не найдена"; fi
|
||||
# --- политика паролей ---
|
||||
POLICY=$(samba-tool domain passwordsettings show 2>/dev/null)
|
||||
if grep -Eqi "minimum password length.*$MIN_PWD_LENGTH" <<<"$POLICY"; then
|
||||
ok "минимальная длина пароля = $MIN_PWD_LENGTH"
|
||||
else fail "длина пароля" "ожидалось $MIN_PWD_LENGTH: $(echo "$POLICY" | grep -i length)"; fi
|
||||
if grep -Eqi "bad password count.*$LOCKOUT_ATTEMPTS|lockout.*$LOCKOUT_ATTEMPTS" <<<"$POLICY"; then
|
||||
ok "блокировка после $LOCKOUT_ATTEMPTS неудачных попыток"
|
||||
else fail "блокировка учётной записи" "ожидалось $LOCKOUT_ATTEMPTS: $(echo "$POLICY" | grep -Ei 'lockout|attempt')"; fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# --- 2. Ansible: ansible all -m ping (все pong) ---
|
||||
if command -v ansible &>/dev/null; then
|
||||
PING_OUT=$(ansible all -m ping 2>&1)
|
||||
N_OK=$(grep -c "SUCCESS" <<<"$PING_OUT")
|
||||
N_FAILS=$(grep -c "UNREACHABLE\|failed" <<<"$PING_OUT")
|
||||
if [[ $N_OK -ge 4 && $N_FAILS -eq 0 ]]; then ok "ansible all -m ping: $N_OK машин ответили"
|
||||
else fail "ansible ping" "успешных $N_OK (ожидалось ≥4), проблем $N_FAILS"; fi
|
||||
else
|
||||
skip "ansible — не установлен/не в PATH (инвентарь в /etc/ansible)"
|
||||
fi
|
||||
|
||||
# --- 3. Docker: контейнеры и порт 8080 ---
|
||||
if root_or_skip "docker ps / сетевая проверка порта"; then
|
||||
if command -v docker &>/dev/null; then
|
||||
CWEB=$(docker ps 2>/dev/null | grep -ciE "site|web|app")
|
||||
CDB=$(docker ps 2>/dev/null | grep -ciE "mariadb|db")
|
||||
if [[ $CWEB -ge 1 && $CDB -ge 1 ]]; then
|
||||
ok "docker: найдено $CWEB контейнер(ов) приложения, $CDB — БД"
|
||||
else fail "docker контейнеры" "ожидалось приложение + mariadb: $(docker ps 2>&1)"; fi
|
||||
if curl -s -o /dev/null -w "%{http_code}" "http://127.0.0.1:8080/" 2>/dev/null | grep -q "200\|301\|302\|401"; then
|
||||
ok "testapp отвечает на порт 8080 (curl)"
|
||||
else fail "testapp порт 8080" "нет ответа от локального порта 8080"; fi
|
||||
else
|
||||
skip "docker — команда не найдена (ПРОВЕРИТЬ пакет docker на РЕД ОС 8)"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== Проверить вручную ==="
|
||||
echo " — testapp доступен на 8080 извне: с ISP curl http://<линк к BR-RTR>:8080"
|
||||
echo " — вход пользователей группы hq на HQ-CLI (см. check/zadanie2/hq-cli.sh)"
|
||||
|
||||
echo ""
|
||||
echo "=== Итог: OK=$OK FAIL=$FAIL ПРОПУЩЕНО=$SKIP ==="
|
||||
[[ $FAIL -eq 0 ]]
|
||||
}
|
||||
main 2>&1 | tee "$LOG"
|
||||
STATUS=${PIPESTATUS[0]}
|
||||
echo "Лог сохранён: $LOG"
|
||||
exit $STATUS
|
||||
100
check/zadanie2/hq-cli.sh
Normal file
100
check/zadanie2/hq-cli.sh
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
#!/bin/bash
|
||||
# ============================================================
|
||||
# ПРОВЕРКА ЗАДАНИЕ 2 — HQ-CLI: automount NFS, chrony, домен, sudo
|
||||
# для группы hq (только cat/grep/id), Яндекс Браузер
|
||||
# ЕДИНСТВЕННЫЕ попытка записи — временный файл в NFS (см. пункт 2,
|
||||
# создаётся и сразу удаляется).
|
||||
# ============================================================
|
||||
|
||||
NAME="hq-cli"
|
||||
LOG="check_${NAME}_z2.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; }
|
||||
|
||||
# ================= ПЕРЕМЕННЫЕ (заполните для проверки) =================
|
||||
NFS_MOUNT="/mnt/nfs" # точка автомонтирования по заданию
|
||||
NFS_SERVER="" # адрес HQ-SRV (проверка записи в auto.nfs)
|
||||
HQ_USER_TEST="hquser1" # пользователь домена для проверки входа
|
||||
SUDO_CMDS="/usr/bin/cat /usr/bin/grep /usr/bin/id" # разрешённый список
|
||||
NTP_ADDR="" # адрес ISP (источник NTP)
|
||||
BROWSER_PATTERN="yandex" # ищемся через dnf list installed
|
||||
|
||||
main () {
|
||||
echo "=== Проверка задания 2: HQ-CLI ==="
|
||||
|
||||
# --- 1. Автомонтирование NFS в /mnt/nfs ---
|
||||
if root_or_skip "конфиг autofs"; then
|
||||
if grep -Eq "[[:space:]]*/mnt[[:space:]]+" /etc/auto.master 2>/dev/null; then
|
||||
ok "auto.master: карта для /mnt присутствует"
|
||||
else fail "auto.master" "нет записи для /mnt"; fi
|
||||
if grep -Eq "^[[:space:]]*[a-zA-Z0-9_-]+[[:space:]]+-rw[[:space:]]+.*$NFS_SERVER" /etc/auto.nfs 2>/dev/null; then
|
||||
echo "[ИНФО] $(cat /etc/auto.nfs 2>/dev/null)"
|
||||
SKIP=$((SKIP+1))
|
||||
fi
|
||||
fi
|
||||
# смонтированную директорию NFS проверяем её содержимым
|
||||
# (cat вызывает automount триггер — чистое чтение)
|
||||
# доступный каталог NFS проверяем чтением (оно же триггерит automount)
|
||||
if [[ -d "$NFS_MOUNT" ]]; then
|
||||
ok "каталог $NFS_MOUNT доступен (autofs активен)"
|
||||
else fail "каталог $NFS_MOUNT" "не открылся (autofs/сервер недоступен)"; fi
|
||||
|
||||
# --- 2. ЕДИНСТВЕННЫЙ временный файл в NFS (создаём и сразу удаляем) ---
|
||||
if [[ -d "$NFS_MOUNT" && -w "$NFS_MOUNT" ]]; then
|
||||
printf 'tmp %s\n' "$(date +%s)" > "$NFS_MOUNT/.delete-nfs-write-test"
|
||||
if [[ -f "$NFS_MOUNT/.delete-nfs-write-test" ]]; then
|
||||
ok "запись в NFS работает (временный файл создан)"
|
||||
fi
|
||||
rm -f "$NFS_MOUNT/.delete-nfs-write-test" && ok "временный файл удалён"
|
||||
else
|
||||
skip "запись в NFS (не смонтирован $NFS_MOUNT)"
|
||||
fi
|
||||
|
||||
# --- 3. chrony-клиент: источник = ISP ---
|
||||
check_var "источник NTP" NTP_ADDR &&
|
||||
if command -v chronyc &>/dev/null; then
|
||||
if chronyc sources 2>/dev/null | grep -qF "$NTP_ADDR"; then ok "NTP источник = $NTP_ADDR"
|
||||
else fail "NTP источник" "нет $NTP_ADDR в chronyc sources"; fi
|
||||
else skip "NTP источник — chronyc не найден"; fi
|
||||
|
||||
# --- 4. Пользователь домена доступен (getent) ---
|
||||
if getent passwd "$HQ_USER_TEST" &>/dev/null; then
|
||||
ok "пользователь домена $HQ_USER_TEST доступен на машине (getent)"
|
||||
else fail "пользователь домена $HQ_USER_TEST" "getent не вернул запись (ввод в домен вручную — MANUAL.md)"; fi
|
||||
|
||||
# --- 5. Sudo для группы hq (только cat/grep/id) ---
|
||||
if root_or_skip "sudo -l -U $HQ_USER_TEST"; then
|
||||
SUDO_OUT=$(sudo -l -U "$HQ_USER_TEST" 2>/dev/null)
|
||||
CMDS_OK=1
|
||||
for c in $SUDO_CMDS; do
|
||||
grep -qw "$(basename "$c")" <<<"$SUDO_OUT" || CMDS_OK=0
|
||||
done
|
||||
if [[ $CMDS_OK -eq 1 ]] && ! grep -q "NOPASSWD: ALL" <<<"$SUDO_OUT"; then
|
||||
ok "sudo для $HQ_USER_TEST: только $(echo "$SUDO_CMDS" | tr ' ' ',')"
|
||||
else fail "sudo для $HQ_USER_TEST" "список не совпал (есть ALL или нет всех команд): $(echo "$SUDO_OUT" | grep NOPASSWD)"; fi
|
||||
fi
|
||||
|
||||
# --- 6. Яндекс Браузер ---
|
||||
if dnf list installed 2>/dev/null | grep -qiF "$BROWSER_PATTERN"; then
|
||||
ok "Яндекс Браузер установлен ($(dnf list installed 2>/dev/null | grep -iF "$BROWSER_PATTERN"))"
|
||||
else fail "Яндекс Браузер" "пакет не найден в dnf list installed"; fi
|
||||
|
||||
echo ""
|
||||
echo "=== Проверить вручную ==="
|
||||
echo " — запуск Яндекс Браузера с рабочего стола (если GUI есть)"
|
||||
echo " — реальные входы доменных пользователей в систему (экран входа/GUI или su -)"
|
||||
|
||||
echo ""
|
||||
echo "=== Итог: OK=$OK FAIL=$FAIL ПРОПУЩЕНО=$SKIP ==="
|
||||
[[ $FAIL -eq 0 ]]
|
||||
}
|
||||
main 2>&1 | tee "$LOG"
|
||||
STATUS=${PIPESTATUS[0]}
|
||||
echo "Лог сохранён: $LOG"
|
||||
exit $STATUS
|
||||
59
check/zadanie2/hq-rtr.sh
Normal file
59
check/zadanie2/hq-rtr.sh
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
#!/bin/bash
|
||||
# ============================================================
|
||||
# ПРОВЕРКА ЗАДАНИЯ 2 — HQ-RTR: статический проброс портов (DNAT)
|
||||
# 8080 -> веб-приложение на HQ-SRV, 2027 -> SSH HQ-SRV
|
||||
# (только читает состояние; iptables требует root)
|
||||
# ============================================================
|
||||
|
||||
NAME="hq-rtr"
|
||||
LOG="check_${NAME}_z2.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; }
|
||||
|
||||
# ================= ПЕРЕМЕННЫЕ (заполните для проверки) =================
|
||||
HQ_SRV_IP="" # адрес HQ-SRV (без префикса)
|
||||
WEB_APP_PORT="80" # порт apache на HQ-SRV (как в настройке)
|
||||
SSH_PORT="2027" # порт ssh на HQ-SRV
|
||||
|
||||
main () {
|
||||
echo "=== Проверка задания 2: HQ-RTR (DNAT) ==="
|
||||
|
||||
if root_or_skip "правила DNAT (iptables)"; then
|
||||
NAT=$(iptables -t nat -S PREROUTING 2>/dev/null)
|
||||
check_var "адрес HQ-SRV" HQ_SRV_IP && {
|
||||
if grep -qF "DNAT --to-destination $HQ_SRV_IP:$WEB_APP_PORT" <<<"$NAT" \
|
||||
|| grep -qF "DNAT --to $HQ_SRV_IP:$WEB_APP_PORT" <<<"$NAT"; then
|
||||
ok "проброс 8080 -> $HQ_SRV_IP:$WEB_APP_PORT"
|
||||
else fail "проброс 8080" "нет DNAT строки в: $NAT"; fi
|
||||
}
|
||||
check_var "адрес HQ-SRV" HQ_SRV_IP && {
|
||||
if grep -qF "DNAT --to-destination $HQ_SRV_IP:$SSH_PORT" <<<"$NAT" \
|
||||
|| grep -qF "DNAT --to $HQ_SRV_IP:$SSH_PORT" <<<"$NAT"; then
|
||||
ok "проброс 2027 -> $HQ_SRV_IP:$SSH_PORT"
|
||||
else fail "проброс 2027" "нет DNAT строки в: $NAT"; fi
|
||||
}
|
||||
POLICY=$(iptables -S FORWARD 2>/dev/null | head -1)
|
||||
if grep -q "policy" <<<"$POLICY"; then
|
||||
echo "[ИНФО] $POLICY"
|
||||
SKIP=$((SKIP+1))
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== Проверить вручную ==="
|
||||
echo " — с ISP: curl -I http://<адрес HQ-RTR на линке>:8080 (доступ к веб-приложению извне)"
|
||||
echo " — с ISP: nc -zv <адрес HQ-RTR на линке> 2027"
|
||||
|
||||
echo ""
|
||||
echo "=== Итог: OK=$OK FAIL=$FAIL ПРОПУЩЕНО=$SKIP ==="
|
||||
[[ $FAIL -eq 0 ]]
|
||||
}
|
||||
main 2>&1 | tee "$LOG"
|
||||
STATUS=${PIPESTATUS[0]}
|
||||
echo "Лог сохранён: $LOG"
|
||||
exit $STATUS
|
||||
104
check/zadanie2/hq-srv.sh
Normal file
104
check/zadanie2/hq-srv.sh
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
#!/bin/bash
|
||||
# ============================================================
|
||||
# ПРОВЕРКА ЗАДАНИЯ 2 — HQ-SRV: RAID0, NFS, chrony, apache+mariadb
|
||||
# (только читает состояние; exportfs/mdadm-детали требуют root)
|
||||
# ============================================================
|
||||
|
||||
NAME="hq-srv"
|
||||
LOG="check_${NAME}_z2.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; }
|
||||
|
||||
# ================= ПЕРЕМЕННЫЕ (заполните для проверки) =================
|
||||
RAID_NAME="md0" # имя массива по заданию
|
||||
RAID_MOUNT="/raid" # точка монтирования по заданию
|
||||
NFS_EXPORT="/raid/nfs" # директория экспорта по заданию
|
||||
NFS_NET="" # сеть HQ-CLI (как в exports)
|
||||
APACHE_PORT="80" # порт apache
|
||||
WEB_DB_NAME="webdb" # БД по заданию
|
||||
WEB_DB_USER="web" # пользователь БД по заданию
|
||||
WEB_DB_PASS="P@ssw0rd" # пароль пользователя БД по заданию
|
||||
ISO_WEB_DIR="/mnt/iso/web" # откуда копировались файлы (для справки)
|
||||
NTP_ADDR="" # адрес ISP (chrony)
|
||||
|
||||
main () {
|
||||
echo "=== Проверка задания 2: HQ-SRV ==="
|
||||
|
||||
# --- 1. RAID0 (md0) ---
|
||||
if [[ -e /dev/$RAID_NAME ]] || grep -q "$RAID_NAME" /proc/mdstat 2>/dev/null; then
|
||||
if grep -A1 "$RAID_NAME" /proc/mdstat 2>/dev/null | grep -q "raid0"; then
|
||||
ok "массив $RAID_NAME собран уровнем 0"
|
||||
else fail "уровень $RAID_NAME" "не raid0 в /proc/mdstat: $(grep -A1 "$RAID_NAME" /proc/mdstat 2>/dev/null)"; fi
|
||||
DISKS=$(grep -A1 "$RAID_NAME" /proc/mdstat 2>/dev/null | head -1 | grep -o "\[2/2\]")
|
||||
if [[ -n "$DISKS" ]]; then ok "в массиве 2 диска ($DISKS)"
|
||||
else fail "диски массива" "ожидалось [2/2]: $(grep -A1 "$RAID_NAME" /proc/mdstat)"; fi
|
||||
else
|
||||
fail "массив $RAID_NAME" "не существует"; fi
|
||||
|
||||
# --- 2. ФС ext4 и монтирование /raid ---
|
||||
FSTYP=$(lsblk -no FSTYPE /dev/$RAID_NAME 2>/dev/null)
|
||||
expect_eq "файловая система $RAID_NAME" "ext4" "$FSTYP"
|
||||
if mountpoint -q "$RAID_MOUNT" 2>/dev/null; then
|
||||
ok "$RAID_MOUNT смонтирована"
|
||||
else fail "$RAID_MOUNT" "не точка монтирования"; fi
|
||||
if grep -qE " .*$RAID_MOUNT " /etc/fstab 2>/dev/null \
|
||||
&& grep -E " .*$RAID_MOUNT .*ext4" /etc/fstab &>/dev/null; then
|
||||
ok "/raid прописан в /etc/fstab"
|
||||
else fail "/raid в fstab" "нет строки с $RAID_MOUNT (ext4): $(grep -E "raid" /etc/fstab)"; fi
|
||||
|
||||
# --- 3. NFS ---
|
||||
if grep -qF "$NFS_EXPORT" /etc/exports 2>/dev/null; then
|
||||
EXPORT_LINE=$(grep -F "$NFS_EXPORT" /etc/exports)
|
||||
if check_var "сеть HQ-CLI для NFS" NFS_NET && grep -qF "$NFS_NET" <<<"$EXPORT_LINE" \
|
||||
&& grep -qw "rw" <<<"$EXPORT_LINE"; then
|
||||
ok "NFS экспорт: $EXPORT_LINE"
|
||||
else fail "NFS экспорт" "нет rw для $NFS_NET: '$EXPORT_LINE'"; fi
|
||||
else fail "NFS экспорт $NFS_EXPORT" "нет строки в /etc/exports"; fi
|
||||
if root_or_skip "exportfs (текущее состояние NFS)"; then
|
||||
if exportfs -v 2>/dev/null | grep -qF "$NFS_EXPORT"; then
|
||||
ok "NFS экспорт активен (exportfs)"
|
||||
else fail "NFS экспорт активен" "нет в exportfs -v"; fi
|
||||
fi
|
||||
|
||||
# --- 4. chrony-клиент ---
|
||||
check_var "источник NTP" NTP_ADDR &&
|
||||
if command -v chronyc &>/dev/null; then
|
||||
if chronyc sources 2>/dev/null | grep -qF "$NTP_ADDR"; then ok "NTP источник = $NTP_ADDR"
|
||||
else fail "NTP источник" "нет $NTP_ADDR в chronyc sources"; fi
|
||||
else skip "NTP источник — chronyc не найден (ПРОВЕРИТЬ пакет chrony)"; fi
|
||||
|
||||
# --- 5. apache + mariadb + приложение ---
|
||||
if systemctl is-active httpd &>/dev/null || systemctl is-active apache2 &>/dev/null; then
|
||||
ok "веб-сервер apache активен"
|
||||
else fail "apache" "служба не активна (ПРОВЕРИТЬ имя службы на РЕД ОС 8)"; fi
|
||||
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" "http://127.0.0.1:$APACHE_PORT/" 2>/dev/null)
|
||||
if [[ "$HTTP_CODE" == "200" ]]; then ok "apache отвечает 200 на порт $APACHE_PORT"
|
||||
else fail "ответ apache" "ожидалось 200, получено '$HTTP_CODE'"; fi
|
||||
if [[ -f /var/www/html/index.php && -f /var/www/html/logo.png ]]; then
|
||||
ok "index.php и logo.png в корне сайта"
|
||||
else fail "файлы сайта" "нет index.php/logo.png в /var/www/html"; fi
|
||||
|
||||
MYSQL_OUT=$(mysql -u"$WEB_DB_USER" -p"$WEB_DB_PASS" -e "SHOW TABLES;" "$WEB_DB_NAME" 2>&1)
|
||||
if grep -q "Tables_in" <<<"$MYSQL_OUT"; then
|
||||
ok "доступ к БД $WEB_DB_NAME под $WEB_DB_USER (таблицы есть)"
|
||||
else fail "БД $WEB_DB_NAME" "нет таблиц или ошибка подключения: $MYSQL_OUT"; fi
|
||||
|
||||
echo ""
|
||||
echo "=== Проверить вручную ==="
|
||||
echo " — страница приложения в браузере (функционал, картинка logo.png)"
|
||||
echo " — содержимое index.php (учётные данные БД указаны правильно)"
|
||||
echo " — скриншоты для отчёта: exportfs -v, mdadm --D dev/md0, df -h /raid"
|
||||
|
||||
echo ""
|
||||
echo "=== Итог: OK=$OK FAIL=$FAIL ПРОПУЩЕНО=$SKIP ==="
|
||||
[[ $FAIL -eq 0 ]]
|
||||
}
|
||||
main 2>&1 | tee "$LOG"
|
||||
STATUS=${PIPESTATUS[0]}
|
||||
echo "Лог сохранён: $LOG"
|
||||
exit $STATUS
|
||||
67
check/zadanie2/isp.sh
Normal file
67
check/zadanie2/isp.sh
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
#!/bin/bash
|
||||
# ============================================================
|
||||
# ПРОВЕРКА ЗАДАНИЯ 2 — ISP: chrony-сервер, стратум 5
|
||||
# (только читает состояние)
|
||||
# ============================================================
|
||||
|
||||
NAME="isp"
|
||||
LOG="check_${NAME}_z2.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; }
|
||||
|
||||
# ================= ПЕРЕМЕННЫЕ (заполните для проверки) =================
|
||||
CHRONY_CONF="/etc/chrony.conf" # ПРОВЕРИТЬ путь на РЕД ОС 8
|
||||
STRATUM_EXPECTED="5" # по заданию 2 п. 4
|
||||
ALLOW_NETS="" # сети клиентов, через пробел (как в isp.sh настройки)
|
||||
|
||||
main () {
|
||||
echo "=== Проверка задания 2: ISP (chrony) ==="
|
||||
|
||||
# --- 1. Стратум 5 ---
|
||||
if command -v chronyc &>/dev/null; then
|
||||
GOT_STRATUM=$(chronyc tracking 2>/dev/null | awk '/^Stratum/ {print $2}')
|
||||
if [[ "$GOT_STRATUM" == "$STRATUM_EXPECTED" ]]; then ok "стратум = $GOT_STRATUM"
|
||||
else fail "стратум" "ожидалось $STRATUM_EXPECTED, получено '$GOT_STRATUM'"; fi
|
||||
# служба активна
|
||||
if systemctl is-active chronyd &>/dev/null; then ok "служба chronyd активна"
|
||||
else fail "служба chronyd" "не активна (ПРОВЕРИТЬ имя службы на РЕД ОС 8)"; fi
|
||||
else
|
||||
skip "chronyc — не найден (ПРОВЕРИТЬ пакет chrony)"
|
||||
fi
|
||||
|
||||
# --- 2. Разрешено доступ для клиентских сетей (allow) ---
|
||||
NETS_OK=0; NETS_TOTAL=0
|
||||
for NET in $ALLOW_NETS; do
|
||||
NETS_TOTAL=$((NETS_TOTAL+1))
|
||||
if grep -qE "^allow[[:space:]]+$NET" "$CHRONY_CONF" 2>/dev/null; then
|
||||
NETS_OK=$((NETS_OK+1))
|
||||
else fail "allow $NET" "нет строки в $CHRONY_CONF"; fi
|
||||
done
|
||||
if [[ $NETS_TOTAL -eq 0 ]]; then skip "allow-сети — не задано ALLOW_NETS"
|
||||
elif [[ $NETS_OK -eq $NETS_TOTAL ]]; then ok "allow для всех $NETS_TOTAL сетей клиентов"
|
||||
fi
|
||||
|
||||
# --- 3. Сервер NTP слушает 123/udp ---
|
||||
if root_or_skip "порт NTP (ss)"; then
|
||||
if ss -uln 2>/dev/null | grep -q ":123 "; then ok "NTP слушает udp/123"
|
||||
else fail "NTP порт 123" "не слушает (chronyd: allow без локального статуса?)"; fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== Проверить вручную ==="
|
||||
echo " — chronyc clients (кто реально опрашивает)"
|
||||
echo " — chronyc sources точно сообщает о вышестоящем сервере"
|
||||
|
||||
echo ""
|
||||
echo "=== Итог: OK=$OK FAIL=$FAIL ПРОПУЩЕНО=$SKIP ==="
|
||||
[[ $FAIL -eq 0 ]]
|
||||
}
|
||||
main 2>&1 | tee "$LOG"
|
||||
STATUS=${PIPESTATUS[0]}
|
||||
echo "Лог сохранён: $LOG"
|
||||
exit $STATUS
|
||||
90
zadanie2/br-rtr.sh
Normal file
90
zadanie2/br-rtr.sh
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
#!/bin/bash
|
||||
# ============================================================
|
||||
# ЗАДАНИЕ 2. Настройка BR-RTR (Linux / РЕД ОС 8)
|
||||
# Статическая трансляция портов (DNAT):
|
||||
# 8080 -> приложение testapp на BR-SRV (порт 8080)
|
||||
# 2027 -> SSH на BR-SRV (порт 2027)
|
||||
# Клиент NTP: chrony -> сервер ISP.
|
||||
# ============================================================
|
||||
|
||||
# --- Проверка прав root ---
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo "Запустите скрипт с правами root (sudo bash br-rtr.sh)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ================= ПЕРЕМЕННЫЕ (заполните перед запуском) =================
|
||||
ISP_IF="" # интерфейс в сторону ISP (куда входят подключения извне)
|
||||
BR_SRV_IP="" # адрес BR-SRV (без префикса)
|
||||
TESTAPP_PORT="8080" # порт testapp на BR-SRV по заданию
|
||||
SSH_PORT="2027" # порт SSH на BR-SRV по заданию
|
||||
IPTABLES_SERVICE="iptables" # ПРОВЕРИТЬ
|
||||
|
||||
# --- chrony-клиент ---
|
||||
CHRONY_CONF="/etc/chrony.conf" # ПРОВЕРИТЬ путь конфига chrony на РЕД ОС 8
|
||||
CHRONY_PACKAGE="chrony"
|
||||
CHRONY_SERVICE="chronyd"
|
||||
NTP_SERVER="" # адрес ISP по которому до него достучаться (без префикса)
|
||||
|
||||
EXAM_TZ="Europe/Moscow" # проверить на экзамене
|
||||
|
||||
# ============ Проверка заполнения переменных ============
|
||||
MISSING=()
|
||||
for NAME in ISP_IF BR_SRV_IP NTP_SERVER EXAM_TZ; do
|
||||
[[ -z "${!NAME}" ]] && MISSING+=("$NAME")
|
||||
done
|
||||
if [[ ${#MISSING[@]} -gt 0 ]]; then
|
||||
echo "Заполните переменные в начале скрипта: ${MISSING[*]}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "=== Настройка DNAT (проброс портов) на BR-RTR ==="
|
||||
|
||||
add_dnat () {
|
||||
if iptables -t nat -C PREROUTING -i "$ISP_IF" -p tcp --dport "$2" \
|
||||
-j DNAT --to-destination "$3" 2>/dev/null; then
|
||||
echo "Правило $4 уже есть"
|
||||
else
|
||||
iptables -t nat -A PREROUTING -i "$ISP_IF" -p tcp --dport "$2" \
|
||||
-j DNAT --to-destination "$3"
|
||||
echo "Добавлено DNAT: $4"
|
||||
fi
|
||||
}
|
||||
|
||||
# --- 1. Проброс порта testapp ---
|
||||
add_dnat "$ISP_IF" "$TESTAPP_PORT" "$BR_SRV_IP:$TESTAPP_PORT" \
|
||||
"$TESTAPP_PORT -> $BR_SRV_IP:$TESTAPP_PORT"
|
||||
|
||||
# --- 2. Проброс порта SSH ---
|
||||
add_dnat "$ISP_IF" "$SSH_PORT" "$BR_SRV_IP:$SSH_PORT" "$SSH_PORT -> $BR_SRV_IP:$SSH_PORT"
|
||||
|
||||
# --- 3. Сохранение правил ---
|
||||
iptables-save > /etc/sysconfig/iptables
|
||||
systemctl enable --now "$IPTABLES_SERVICE" 2>/dev/null \
|
||||
|| echo "ПРОВЕРИТЬ: служба $IPTABLES_SERVICE не запустилась"
|
||||
|
||||
# --- 4. chrony-клиент: сервер = ISP ---
|
||||
echo "--- chrony-клиент (server = $NTP_SERVER) ---"
|
||||
dnf install -y "$CHRONY_PACKAGE" || echo "ПРОВЕРИТЬ: пакет $CHRONY_PACKAGE не установился"
|
||||
if ! grep -qE "^server[[:space:]]+$NTP_SERVER\\b" "$CHRONY_CONF" 2>/dev/null; then
|
||||
sed -i "1i server $NTP_SERVER iburst" "$CHRONY_CONF"
|
||||
echo "Добавлено: server $NTP_SERVER iburst"
|
||||
else
|
||||
echo "Строка server уже есть"
|
||||
fi
|
||||
systemctl enable --now "$CHRONY_SERVICE" \
|
||||
|| { echo "ПРОВЕРИТЬ: служба $CHRONY_SERVICE не запустилась"; systemctl status "$CHRONY_SERVICE" --no-pager; }
|
||||
|
||||
timedatectl set-timezone "$EXAM_TZ"
|
||||
|
||||
echo ""
|
||||
echo "=== Самопроверка на BR-RTR ==="
|
||||
echo "Правила DNAT:"
|
||||
iptables -t nat -L PREROUTING -n -v
|
||||
echo ""
|
||||
echo "chronyc sources"
|
||||
chronyc sources 2>/dev/null
|
||||
echo ""
|
||||
echo "Дополнительные проверки вручную:"
|
||||
echo " chronyc tracking (Stratum 6 и источник == адрес ISP)"
|
||||
echo " с ISP: nc -zv <адрес BR-RTR на линке> 8080 и 2027"
|
||||
173
zadanie2/br-srv.sh
Normal file
173
zadanie2/br-srv.sh
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
#!/bin/bash
|
||||
# ============================================================
|
||||
# ЗАДАНИЕ 2. Настройка BR-SRV (Linux / РЕД ОС 8)
|
||||
# DC samba уже установлен на стенде — настраиваем домен дальше:
|
||||
# 1. Пользователи hquser1..5, политика паролей, группа hq
|
||||
# 5. Ansible: инвентарь (HQ-SRV, HQ-CLI, HQ-RTR, BR-RTR), каталог /etc/ansible
|
||||
# 6. Docker: стек testapp из Additional.iso (порт 8080 наружу)
|
||||
# ============================================================
|
||||
|
||||
# --- Проверка прав root ---
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo "Запустите скрипт с правами root (sudo bash br-srv.sh)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ================= ПЕРЕМЕННЫЕ (заполните перед запуском) =================
|
||||
EXAM_TZ="Europe/Moscow" # проверить на экзамене
|
||||
ISO_DIR="/mnt/iso" # точка монтирования Additional.iso
|
||||
DOMAN="au-team.irpo"
|
||||
|
||||
# --- 1. Samba DC (утилита samba-tool; ПРОВЕРИТЬ путь на РЕД ОС 8) ---
|
||||
SMB_DOMAIN="au-team.irpo"
|
||||
SMB_DB_USER="administrator" # ПРОВЕРИТЬ как называется админ DC на стенде
|
||||
DOMAIN_USER_PASS="P@ssw0rd" # пароль пользователей hquser1..5 (по желанию)
|
||||
NUM_HQ_USERS="5" # количество пользователей по заданию
|
||||
MIN_PWD_LENGTH="8" # минимальная длина пароля по заданию
|
||||
LOCKOUT_ATTEMPTS="5" # блокировка после N неудачных попыток
|
||||
# Команда для lockout зависит от версии samba — ПРОВЕРИТЬ на стенде:
|
||||
# samba-tool domain settings set --lockout-attempt=5 (новые версии)
|
||||
# samba-tool domain passwordsettings set --lockout-threshold=5 (старые)
|
||||
LOCKOUT_CMD="samba-tool domain settings set --lockout-attempt=$LOCKOUT_ATTEMPTS"
|
||||
|
||||
# --- 5. Ansible ---
|
||||
ANSIBLE_PACKAGE="ansible-core" # ПРОВЕРИТЬ: пакет ansible на РЕД ОС 8
|
||||
ANSIBLE_DIR="/etc/ansible"
|
||||
INVENTORY="$ANSIBLE_DIR/inventory"
|
||||
ANSIBLE_CFG="$ANSIBLE_DIR/ansible.cfg"
|
||||
|
||||
# --- Адреса и учётные данные для инвентаря (без префиксов) ---
|
||||
HQ_SRV_IP=""
|
||||
HQ_CLI_IP=""
|
||||
HQ_RTR_IP=""
|
||||
BR_RTR_IP=""
|
||||
HQ_SRV_USER="sshuser" # пользователь из задания 1 на HQ-SRV
|
||||
HQ_CLI_USER="sshuser"
|
||||
HQ_RTR_USER="net_admin"
|
||||
BR_RTR_USER="net_admin"
|
||||
|
||||
# SSH-ключ для ansible: ключ генерим, но copy-id на каждый хост требует
|
||||
# пароль — это РУЧНОЙ шаг (MANUAL.md)
|
||||
ANSIBLE_KEY="/root/.ssh/id_ed25519"
|
||||
|
||||
# --- 6. Docker ---
|
||||
DOCKER_PACKAGE="docker-engine" # ПРОВЕРИТЬ: пакет docker на РЕД ОС 8 (docker-ce?)
|
||||
DOCKER_SERVICE="docker"
|
||||
APP_DIR="/opt/testapp" # рабочий каталог стека
|
||||
ISO_DOCKER_DIR="$ISO_DIR/docker" # образы site_latest, mariadb_latest (ПРОВЕРИТЬ имена файлов)
|
||||
COMPOSE_FILE="compose.yaml" # файл compose из Additional.iso
|
||||
APP_EXTERNAL_PORT="8080" # наружу приложение доступно через этот порт
|
||||
|
||||
# ============ Проверка заполнения переменных ============
|
||||
MISSING=()
|
||||
for NAME in HQ_SRV_IP HQ_CLI_IP HQ_RTR_IP BR_RTR_IP EXAM_TZ; do
|
||||
[[ -z "${!NAME}" ]] && MISSING+=("$NAME")
|
||||
done
|
||||
if [[ ${#MISSING[@]} -gt 0 ]]; then
|
||||
echo "Заполните переменные в начале скрипта: ${MISSING[*]}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "=== Настройка BR-SRV, задание 2 ==="
|
||||
|
||||
# --- 1. Пользователи hquser1..5, политика, группа hq ---
|
||||
echo "--- Samba: доменные пользователи и группа ---"
|
||||
samba-tool domain passwordsettings set --min-pwd-length="$MIN_PWD_LENGTH" \
|
||||
|| echo "ПРОВЕРИТЬ: не установилась min-pwd-length"
|
||||
$LOCKOUT_CMD \
|
||||
|| echo "ПРОВЕРИТЬ: не сработала установка lockout (см. комментарий в переменных выше)"
|
||||
for i in $(seq 1 "$NUM_HQ_USERS"); do
|
||||
if samba-tool user list | grep -qw "hquser${i}"; then
|
||||
echo "hquser${i} уже существует"
|
||||
else
|
||||
samba-tool user create "hquser${i}" "$DOMAIN_USER_PASS" \
|
||||
|| echo "ПРОВЕРИТЬ: не создан hquser${i}"
|
||||
fi
|
||||
done
|
||||
if samba-tool group list | grep -qw "hq"; then
|
||||
echo "Группа hq уже существует"
|
||||
else
|
||||
samba-tool group create hq
|
||||
fi
|
||||
samba-tool group addmembers hq "hquser1,hquser2,hquser3,hquser4,hquser5" 2>/dev/null \
|
||||
|| echo "ПРОВЕРИТЬ: члены не добавлены — вручную: samba-tool group addmembers hq hquser1,hquser2,..."
|
||||
samba-tool group listmembers hq
|
||||
|
||||
# --- 5. Ansible ---
|
||||
echo "--- Ansible (каталог /etc/ansible) ---"
|
||||
dnf install -y "$ANSIBLE_PACKAGE" || echo "ПРОВЕРИТЬ: пакет $ANSIBLE_PACKAGE не установился"
|
||||
mkdir -p "$ANSIBLE_DIR"
|
||||
cat > "$ANSIBLE_CFG" <<EOF
|
||||
[defaults]
|
||||
inventory = $INVENTORY
|
||||
host_key_checking = False
|
||||
EOF
|
||||
cat > "$INVENTORY" <<EOF
|
||||
[hq_srv]
|
||||
hq_srv ansible_host=$HQ_SRV_IP ansible_user=$HQ_SRV_USER
|
||||
|
||||
[hq_cli]
|
||||
hq_cli ansible_host=$HQ_CLI_IP ansible_user=$HQ_CLI_USER
|
||||
|
||||
[hq_rtr]
|
||||
hq_rtr ansible_host=$HQ_RTR_IP ansible_user=$HQ_RTR_USER
|
||||
|
||||
[br_rtr]
|
||||
br_rtr ansible_host=$BR_RTR_IP ansible_user=$BR_RTR_USER
|
||||
EOF
|
||||
chmod 600 "$INVENTORY"
|
||||
# Ключ для входа по SSH (копирование на хосты — вручную, см. MANUAL.md)
|
||||
if [[ ! -f "$ANSIBLE_KEY" ]]; then
|
||||
ssh-keygen -t ed25519 -N "" -f "$ANSIBLE_KEY"
|
||||
fi
|
||||
echo ""
|
||||
echo "=== РУЧНОЙ ШАГ: скопировать ключ на все машины инвентаря ==="
|
||||
echo " ssh-copy-id ${HQ_SRV_USER}@${HQ_SRV_IP}"
|
||||
echo " ssh-copy-id ${HQ_CLI_USER}@${HQ_CLI_IP}"
|
||||
echo " ssh-copy-id ${HQ_RTR_USER}@${HQ_RTR_IP}"
|
||||
echo " ssh-copy-id ${BR_RTR_USER}@${BR_RTR_IP}"
|
||||
echo "=== После этого проверить: ansible all -m ping ==="
|
||||
|
||||
# --- 6. Docker: стек из Additional.iso ---
|
||||
echo "--- Docker (стек testapp из $ISO_DOCKER_DIR) ---"
|
||||
dnf install -y "$DOCKER_PACKAGE" || echo "ПРОВЕРИТЬ: пакет $DOCKER_PACKAGE не установился"
|
||||
systemctl enable --now "$DOCKER_SERVICE" \
|
||||
|| { echo "ПРОВЕРИТЬ: служба $DOCKER_SERVICE не запустилась"; systemctl status "$DOCKER_SERVICE" --no-pager; }
|
||||
mkdir -p "$APP_DIR" || exit 1
|
||||
if [[ ! -d "$ISO_DOCKER_DIR" ]]; then
|
||||
echo "ДЕЛАЕТСЯ ВРУЧНУЮ: нет $ISO_DOCKER_DIR — смонтируйте Additional.iso в $ISO_DIR"
|
||||
else
|
||||
# Образы могут быть в .tar — загружаем любые найденные тары
|
||||
shopt -s nullglob
|
||||
for TAR in "$ISO_DOCKER_DIR"/*.tar; do
|
||||
docker load -i "$TAR" && echo "Образ загружен: $TAR"
|
||||
done
|
||||
if [[ -f "$ISO_DOCKER_DIR/$COMPOSE_FILE" ]]; then
|
||||
cp "$ISO_DOCKER_DIR/$COMPOSE_FILE" "$APP_DIR/"
|
||||
echo "compose скопирован в $APP_DIR"
|
||||
else
|
||||
echo "ДЕЛАЕТСЯ ВРУЧНУЮ: $COMPOSE_FILE не найден в $ISO_DOCKER_DIR"
|
||||
fi
|
||||
shopt -u nullglob
|
||||
fi
|
||||
echo "ПРОВЕРИТЬ вручную в $APP_DIR:"
|
||||
echo " cat $APP_DIR/$COMPOSE_FILE (что там по портам? наружу нужен $APP_EXTERNAL_PORT)"
|
||||
echo " docker compose -f $APP_DIR/$COMPOSE_FILE up -d (или docker-compose командой)"
|
||||
echo " docker ps; curl -I http://localhost:$APP_EXTERNAL_PORT"
|
||||
|
||||
timedatectl set-timezone "$EXAM_TZ"
|
||||
|
||||
echo ""
|
||||
echo "=== Самопроверка на BR-SRV ==="
|
||||
echo "samba-tool user list | grep hquser"
|
||||
samba-tool user list | grep hquser
|
||||
echo ""
|
||||
echo "ansible --version"
|
||||
ansible --version 2>/dev/null || echo "ПРОВЕРИТЬ: ansible не установился"
|
||||
echo ""
|
||||
echo "ansible all -m ping (после ручного ssh-copy-id, см. выше)"
|
||||
echo "docker ps (контейнеры testapp и mariadb?)"
|
||||
echo ""
|
||||
echo "Связность через задание 1 (без неё ansible/docker не заработают):"
|
||||
echo " ping -c2 $HQ_RTR_IP (маршрутизация через туннель)"
|
||||
echo " ping -c2 $HQ_SRV_IP"
|
||||
117
zadanie2/hq-cli.sh
Normal file
117
zadanie2/hq-cli.sh
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
#!/bin/bash
|
||||
# ============================================================
|
||||
# ЗАДАНИЕ 2. Настройка HQ-CLI (Linux / РЕД ОС 8)
|
||||
# 1. Ввод в домен — ДЕЛАЕТСЯ ВРУЧНУЮ (нужен пароль админа, MANUAL.md)
|
||||
# 3. Автомонтирование NFS (/mnt/nfs через autofs)
|
||||
# 4. chrony-клиент (сервер ISP)
|
||||
# 1 (п.1). Sudo для группы hq: только cat, grep, id
|
||||
# 9. Яндекс Браузер — попытка через dnf, иначе вручную (MANUAL.md)
|
||||
# ============================================================
|
||||
|
||||
# --- Проверка прав root ---
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo "Запустите скрипт с правами root (sudo bash hq-cli.sh)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ================= ПЕРЕМЕННЫЕ (заполните перед запуском) =================
|
||||
EXAM_TZ="Europe/Moscow" # проверить на экзамене
|
||||
DOMAN="au-team.irpo"
|
||||
|
||||
# --- 3. NFS (автомонтирование в /mnt/nfs) ---
|
||||
NFS_SERVER="" # адрес HQ-SRV (без префикса)
|
||||
AUTO_MASTER="/etc/auto.master"
|
||||
AUTO_FILE="/etc/auto.nfs"
|
||||
AUTOFS_PACKAGE="autofs" # ПРОВЕРИТЬ: пакет autofs на РЕД ОС 8
|
||||
AUTOFS_SERVICE="autofs"
|
||||
|
||||
# --- 4. chrony-клиент ---
|
||||
CHRONY_CONF="/etc/chrony.conf" # ПРОВЕРИТЬ путь конфига chrony
|
||||
CHRONY_PACKAGE="chrony"
|
||||
CHRONY_SERVICE="chronyd"
|
||||
NTP_SERVER="" # адрес ISP (без префикса)
|
||||
|
||||
# --- 1 (п.1). Sudo для доменной группы hq: только cat, grep, id ---
|
||||
HQ_GROUP_NAME="hq"
|
||||
SUDO_COMMANDS="/usr/bin/cat, /usr/bin/grep, /usr/bin/id"
|
||||
SUDO_FILE="/etc/sudoers.d/hq_group"
|
||||
|
||||
# --- 9. Яндекс Браузер ---
|
||||
BROWSER_PACKAGE="yandex-browser" # ПРОВЕРИТЬ: имя пакета и наличие в репозитории РЕД ОС 8
|
||||
|
||||
# ============ Проверка заполнения переменных ============
|
||||
MISSING=()
|
||||
for NAME in NFS_SERVER NTP_SERVER EXAM_TZ; do
|
||||
[[ -z "${!NAME}" ]] && MISSING+=("$NAME")
|
||||
done
|
||||
if [[ ${#MISSING[@]} -gt 0 ]]; then
|
||||
echo "Заполните переменные в начале скрипта: ${MISSING[*]}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "=== Настройка HQ-CLI, задание 2 ==="
|
||||
|
||||
# --- 1. Ввод в домен — вручную ---
|
||||
echo "ДЕЛАЕТСЯ ВРУЧНУЮ: ввод в домен $DOMAN (пароль администратора запрашивается)"
|
||||
echo " Пошаговая инструкция: MANUAL.md, раздел 'HQ-CLI: ввод в домен samba-DC'"
|
||||
|
||||
# --- 3. Автомонтирование NFS через autofs ---
|
||||
echo "--- autofs (/mnt/nfs) ---"
|
||||
dnf install -y "$AUTOFS_PACKAGE" || echo "ПРОВЕРИТЬ: пакет $AUTOFS_PACKAGE не установился"
|
||||
if ! grep -qE "^[[:space:]]*/mnt[[:space:]]+$AUTO_FILE" "$AUTO_MASTER" 2>/dev/null; then
|
||||
echo "/mnt $AUTO_FILE" >> "$AUTO_MASTER"
|
||||
echo "auto.master: добавлена строка /mnt $AUTO_FILE"
|
||||
fi
|
||||
# Файл перезаписывается целиком — дублей нет
|
||||
cat > "$AUTO_FILE" <<EOF
|
||||
nfs -rw $NFS_SERVER:/raid/nfs
|
||||
EOF
|
||||
chmod 644 "$AUTO_FILE"
|
||||
systemctl enable --now "$AUTOFS_SERVICE" \
|
||||
|| { echo "ПРОВЕРИТЬ: служба $AUTOFS_SERVICE не запустилась"; systemctl status "$AUTOFS_SERVICE" --no-pager; }
|
||||
|
||||
# --- 4. chrony-клиент ---
|
||||
echo "--- chrony-клиент ($NTP_SERVER) ---"
|
||||
dnf install -y "$CHRONY_PACKAGE" || echo "ПРОВЕРИТЬ: пакет $CHRONY_PACKAGE не установился"
|
||||
if ! grep -qE "^server[[:space:]]+$NTP_SERVER\\b" "$CHRONY_CONF" 2>/dev/null; then
|
||||
sed -i "1i server $NTP_SERVER iburst" "$CHRONY_CONF"
|
||||
echo "Добавлено: server $NTP_SERVER iburst"
|
||||
fi
|
||||
systemctl enable --now "$CHRONY_SERVICE" \
|
||||
|| { echo "ПРОВЕРИТЬ: служба $CHRONY_SERVICE не запустилась"; systemctl status "$CHRONY_SERVICE" --no-pager; }
|
||||
|
||||
# --- 1 (п.1). Sudo для группы hq: только cat, grep, id ---
|
||||
echo "--- sudo для группы $HQ_GROUP_NAME ---"
|
||||
# Файл перезаписывается целиком — дублей нет
|
||||
# ПРОВЕРИТЬ формат имени группы после ввода в домен:
|
||||
# getent group hq
|
||||
# если имя группы с суффиксом домена — заменить строку ниже на %hq@$DOMAN
|
||||
cat > "$SUDO_FILE" <<EOF
|
||||
%$HQ_GROUP_NAME ALL=(ALL) NOPASSWD: $SUDO_COMMANDS
|
||||
EOF
|
||||
chmod 440 "$SUDO_FILE"
|
||||
echo "Файл $SUDO_FILE записан: группа может повышать привилегии только для cat/grep/id"
|
||||
|
||||
# --- 9. Яндекс Браузер (попытка через dnf; иначе вручную) ---
|
||||
echo "--- Яндекс Браузер ---"
|
||||
if dnf install -y "$BROWSER_PACKAGE" 2>/dev/null; then
|
||||
echo "Браузер установлен"
|
||||
else
|
||||
echo "ДЕЛАЕТСЯ ВРУЧНУЮ: пакет $BROWSER_PACKAGE не нашёлся в репозитории."
|
||||
echo " Возьмите rpm из Additional.iso / локального источника и установите:"
|
||||
echo " dnf localinstall /путь/к/пакету.rpm (шаг отметить в отчёте)"
|
||||
fi
|
||||
|
||||
# --- Часовой пояс ---
|
||||
timedatectl set-timezone "$EXAM_TZ"
|
||||
|
||||
echo ""
|
||||
echo "=== Самопроверка на HQ-CLI ==="
|
||||
echo "NFS: cd /mnt/nfs && df -h ."
|
||||
echo "NTP:"
|
||||
chronyc sources 2>/dev/null
|
||||
echo ""
|
||||
echo "Дополнительные проверки вручную:"
|
||||
echo " sudo -l (после ввода в домен: только cat/grep/id?)"
|
||||
echo " chronyc tracking (источник = адрес ISP)"
|
||||
echo " dnf list installed | grep -i yandex"
|
||||
66
zadanie2/hq-rtr.sh
Normal file
66
zadanie2/hq-rtr.sh
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
#!/bin/bash
|
||||
# ============================================================
|
||||
# ЗАДАНИЕ 2. Настройка HQ-RTR (Linux / РЕД ОС 8)
|
||||
# Статическая трансляция портов (DNAT):
|
||||
# 8080 -> веб-приложение на HQ-SRV (порт приложения)
|
||||
# 2027 -> SSH на HQ-SRV (порт 2027)
|
||||
# ============================================================
|
||||
|
||||
# --- Проверка прав root ---
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo "Запустите скрипт с правами root (sudo bash hq-rtr.sh)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ================= ПЕРЕМЕННЫЕ (заполните перед запуском) =================
|
||||
ISP_IF="" # интерфейс в сторону ISP (куда входят подключения извне)
|
||||
HQ_SRV_IP="" # адрес HQ-SRV в VLAN 100 (без префикса)
|
||||
WEB_APP_PORT="80" # порт, где слушает веб-приложение (apache) на HQ-SRV
|
||||
SSH_PORT="2027" # порт SSH на HQ-SRV по заданию
|
||||
IPTABLES_SERVICE="iptables" # ПРОВЕРИТЬ
|
||||
|
||||
# ============ Проверка заполнения переменных ============
|
||||
MISSING=()
|
||||
for NAME in ISP_IF HQ_SRV_IP WEB_APP_PORT SSH_PORT; do
|
||||
[[ -z "${!NAME}" ]] && MISSING+=("$NAME")
|
||||
done
|
||||
if [[ ${#MISSING[@]} -gt 0 ]]; then
|
||||
echo "Заполните переменные в начале скрипта: ${MISSING[*]}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "=== Настройка DNAT (проброс портов) на HQ-RTR ==="
|
||||
|
||||
add_dnat () {
|
||||
if iptables -t nat -C PREROUTING -i "$ISP_IF" -p tcp --dport "$2" \
|
||||
-j DNAT --to-destination "$3" 2>/dev/null; then
|
||||
echo "Правило $4 уже есть"
|
||||
else
|
||||
iptables -t nat -A PREROUTING -i "$ISP_IF" -p tcp --dport "$2" \
|
||||
-j DNAT --to-destination "$3"
|
||||
echo "Добавлено DNAT: $4"
|
||||
fi
|
||||
}
|
||||
|
||||
# --- 1. Проброс порта веб-приложения ---
|
||||
add_dnat "$ISP_IF" 8080 "$HQ_SRV_IP:$WEB_APP_PORT" "8080 -> $HQ_SRV_IP:$WEB_APP_PORT"
|
||||
|
||||
# --- 2. Проброс порта SSH ---
|
||||
add_dnat "$ISP_IF" "$SSH_PORT" "$HQ_SRV_IP:$SSH_PORT" "$SSH_PORT -> $HQ_SRV_IP:$SSH_PORT"
|
||||
|
||||
# --- 3. Сохранение правил ---
|
||||
iptables-save > /etc/sysconfig/iptables
|
||||
systemctl enable --now "$IPTABLES_SERVICE" 2>/dev/null \
|
||||
|| echo "ПРОВЕРИТЬ: служба $IPTABLES_SERVICE не запустилась"
|
||||
|
||||
echo ""
|
||||
echo "=== Самопроверка на HQ-RTR ==="
|
||||
echo "Правила DNAT:"
|
||||
iptables -t nat -L PREROUTING -n -v
|
||||
echo ""
|
||||
echo "Дополнительные проверки вручную:"
|
||||
echo " с ISP: curl -I http://<адрес HQ-RTR на линке>:8080 (ответ apache?)"
|
||||
echo " с ISP: nc -zv <адрес HQ-RTR на линке> 2027"
|
||||
echo ""
|
||||
echo "Если цепочка FORWARD закрыта политикой DROP, добавьте разрешение"
|
||||
echo "или убедитесь, что политика ACCEPT: iptables -L FORWARD -n // policy"
|
||||
193
zadanie2/hq-srv.sh
Normal file
193
zadanie2/hq-srv.sh
Normal file
|
|
@ -0,0 +1,193 @@
|
|||
#!/bin/bash
|
||||
# ============================================================
|
||||
# ЗАДАНИЕ 2. Настройка HQ-SRV (Linux / РЕД ОС 8)
|
||||
# 2. RAID0 из двух дисков по 1 ГБ: md0, ext4, авто-монтирование /raid
|
||||
# 3. NFS: /raid/nfs, rw только для сети HQ-CLI; отчёт
|
||||
# 4. chrony-клиент (сервер ISP)
|
||||
# 7. Веб-приложение: apache + mariadb, файлы из Additional.iso
|
||||
# ============================================================
|
||||
|
||||
# --- Проверка прав root ---
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo "Запустите скрипт с правами root (sudo bash hq-srv.sh)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ================= ПЕРЕМЕННЫЕ (заполните перед запуском) =================
|
||||
EXAM_TZ="Europe/Moscow" # проверить на экзамене
|
||||
ISO_DIR="/mnt/iso" # точка монтирования Additional.iso
|
||||
|
||||
# --- 2. RAID0 ---
|
||||
RAID_DEV1="" # первый диск 1 ГБ (пример: /dev/vdb)
|
||||
RAID_DEV2="" # второй диск 1 ГБ (пример: /dev/vdc)
|
||||
RAID_NAME="md0" # имя устройства по заданию
|
||||
MDADM_CONF="/etc/mdadm.conf" # по заданию; ПРОВЕРИТЬ имя файла на РЕД ОС 8
|
||||
RAID_MOUNT="/raid"
|
||||
FSTAB="/etc/fstab"
|
||||
|
||||
# --- 3. NFS ---
|
||||
NFS_PACKAGE="nfs-utils" # ПРОВЕРИТЬ: пакет NFS-сервера на РЕД ОС 8
|
||||
NFS_SERVICE="nfs-server"
|
||||
NFS_EXPORT="/raid/nfs"
|
||||
NFS_NET="" # сеть HQ-CLI, формат адрес/префикс — доступ только ей
|
||||
|
||||
# --- 4. chrony-клиент ---
|
||||
CHRONY_CONF="/etc/chrony.conf" # ПРОВЕРИТЬ путь конфига chrony
|
||||
CHRONY_PACKAGE="chrony"
|
||||
CHRONY_SERVICE="chronyd"
|
||||
NTP_SERVER="" # адрес ISP (без префикса)
|
||||
|
||||
# --- 7. Веб-приложение ---
|
||||
APACHE_PACKAGE="httpd" # ПРОВЕРИТЬ: пакет apache на РЕД ОС 8
|
||||
APACHE_SERVICE="httpd"
|
||||
MARIADB_PACKAGE="mariadb-server"
|
||||
MARIADB_SERVICE="mariadb"
|
||||
WEB_ROOT="/var/www/html" # корневой каталог сайта
|
||||
WEB_DB_NAME="webdb" # название БД по заданию
|
||||
WEB_DB_USER="web" # пользователь БД по заданию
|
||||
WEB_DB_PASS="P@ssw0rd" # пароль пользователя БД по заданию
|
||||
ISO_WEB_DIR="$ISO_DIR/web" # директория приложения в образе (файлы: dump.sql,
|
||||
# index.php, logo.png — содержание НЕ известно заранее)
|
||||
WEB_DB_HOST="localhost" # хост подключения для index.php (уточнить по файлам задания)
|
||||
APACHE_EXTERNAL_PORT="80" # порт apache по заданию (наружу пробрасывается 8080)
|
||||
|
||||
# ============ Проверка заполнения переменных ============
|
||||
MISSING=()
|
||||
for NAME in RAID_DEV1 RAID_DEV2 NFS_NET NTP_SERVER EXAM_TZ; do
|
||||
[[ -z "${!NAME}" ]] && MISSING+=("$NAME")
|
||||
done
|
||||
if [[ ${#MISSING[@]} -gt 0 ]]; then
|
||||
echo "Заполните переменные в начале скрипта: ${MISSING[*]}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "=== Настройка HQ-SRV, задание 2 ==="
|
||||
|
||||
# --- 1. RAID0 (md0) из двух дисков ---
|
||||
echo "--- RAID0 (mdadm) ---"
|
||||
dnf install -y mdadm || echo "ПРОВЕРИТЬ: пакет mdadm не установился"
|
||||
if mdadm --detail /dev/$RAID_NAME >/dev/null 2>&1; then
|
||||
echo "Массив /dev/$RAID_NAME уже существует"
|
||||
else
|
||||
mdadm --create /dev/$RAID_NAME --level=0 --raid-devices=2 \
|
||||
"$RAID_DEV1" "$RAID_DEV2" --run
|
||||
fi
|
||||
mdadm --detail /dev/$RAID_NAME || echo "ПРОВЕРИТЬ: массив не собрался"
|
||||
# Конфигурация массива в файл (строку ARRAY добавляем только если её нет)
|
||||
if ! grep -q "^ARRAY /dev/$RAID_NAME" "$MDADM_CONF" 2>/dev/null; then
|
||||
mdadm --detail /dev/$RAID_NAME | grep -E "^(UUID)" >> "$MDADM_CONF"
|
||||
echo "ARRAY /dev/$RAID_NAME UUID=$(mdadm -D /dev/$RAID_NAME | awk '/^UUID/ {print $3}')" >> "$MDADM_CONF"
|
||||
chmod 644 "$MDADM_CONF"
|
||||
fi
|
||||
if command -v dracut >/dev/null 2>&1; then
|
||||
dracut -f || echo "ПРОВЕРИТЬ: не удалось собрать initramfs"
|
||||
fi
|
||||
|
||||
# --- 2. ext4 и автопримонтирование /raid ---
|
||||
echo "--- Файловая система и монтирование $RAID_MOUNT ---"
|
||||
# Повторный запуск не должен перезаписывать ext4: проверяем по blkid
|
||||
if blkid /dev/$RAID_NAME | grep -q "TYPE=\"ext4\""; then
|
||||
echo "Файловая система ext4 уже создана"
|
||||
else
|
||||
mkfs.ext4 /dev/$RAID_NAME
|
||||
fi
|
||||
mkdir -p "$RAID_MOUNT"
|
||||
RAID_UUID=$(blkid -s UUID -o value /dev/$RAID_NAME)
|
||||
if mountpoint -q "$RAID_MOUNT"; then
|
||||
echo "Монтируется: $RAID_MOUNT уже смонтирована"
|
||||
else
|
||||
if ! grep -q "^UUID=$RAID_UUID $RAID_MOUNT" "$FSTAB"; then
|
||||
echo "UUID=$RAID_UUID $RAID_MOUNT ext4 defaults 0 0" >> "$FSTAB"
|
||||
fi
|
||||
mount -a
|
||||
fi
|
||||
df -h "$RAID_MOUNT"
|
||||
|
||||
# --- 3. NFS: экспорт /raid/nfs только для сети HQ-CLI ---
|
||||
echo "--- NFS ---"
|
||||
dnf install -y "$NFS_PACKAGE" || echo "ПРОВЕРИТЬ: пакет $NFS_PACKAGE не установился"
|
||||
mkdir -p "$NFS_EXPORT"
|
||||
# Доступ всё равно ограничен в exports только сетью HQ-CLI
|
||||
if ! grep -E "^$NFS_EXPORT " /etc/exports 2>/dev/null | grep -q "$NFS_NET"; then
|
||||
echo "$NFS_EXPORT $NFS_NET(rw,sync,subtree_check)" >> /etc/exports
|
||||
echo "Добавлен экспорт: $NFS_EXPORT для $NFS_NET"
|
||||
fi
|
||||
exportfs -ra || { echo "Ошибка exportfs:"; exportfs -v; }
|
||||
systemctl enable --now "$NFS_SERVICE" \
|
||||
|| { echo "ПРОВЕРИТЬ: служба $NFS_SERVICE не запустилась"; systemctl status "$NFS_SERVICE" --no-pager; }
|
||||
echo "Основные параметры сервера для отчёта:"
|
||||
exportfs -v
|
||||
|
||||
# --- 4. chrony-клиент (сервер = ISP) ---
|
||||
echo "--- chrony-клиент ($NTP_SERVER) ---"
|
||||
dnf install -y "$CHRONY_PACKAGE" || echo "ПРОВЕРИТЬ: пакет $CHRONY_PACKAGE не установился"
|
||||
if ! grep -qE "^server[[:space:]]+$NTP_SERVER\\b" "$CHRONY_CONF" 2>/dev/null; then
|
||||
sed -i "1i server $NTP_SERVER iburst" "$CHRONY_CONF"
|
||||
echo "Добавлено: server $NTP_SERVER iburst"
|
||||
fi
|
||||
systemctl enable --now "$CHRONY_SERVICE" \
|
||||
|| { echo "ПРОВЕРИТЬ: служба $CHRONY_SERVICE не запустилась"; systemctl status "$CHRONY_SERVICE" --no-pager; }
|
||||
|
||||
# --- 5. Веб-приложение: apache + mariadb + файлы из Additional.iso ---
|
||||
echo "--- Веб-приложение (apache + mariadb) ---"
|
||||
if [[ ! -d "$ISO_WEB_DIR" ]]; then
|
||||
echo "ДЕЛАЕТСЯ ВРУЧНУЮ: директории $ISO_WEB_DIR нет — смонтируйте Additional.iso в $ISO_DIR"
|
||||
echo " mount -o loop /путь/к/образу/Additional.iso $ISO_DIR"
|
||||
else
|
||||
ls -l "$ISO_WEB_DIR"
|
||||
fi
|
||||
dnf install -y "$APACHE_PACKAGE" "$MARIADB_PACKAGE" || echo "ПРОВЕРИТЬ: пакеты apache/mariadb не установились"
|
||||
systemctl enable --now "$MARIADB_SERVICE" "$APACHE_SERVICE" \
|
||||
|| echo "ПРОВЕРИТЬ: службы $MARIADB_SERVICE/$APACHE_SERVICE не запустились"
|
||||
|
||||
# Импорт дампа в webdb и создание пользователя web (права на webdb)
|
||||
mysql -e "CREATE DATABASE IF NOT EXISTS $WEB_DB_NAME CHARACTER SET utf8;"
|
||||
mysql -e "CREATE USER IF NOT EXISTS '$WEB_DB_USER'@'$WEB_DB_HOST' IDENTIFIED BY '$WEB_DB_PASS';"
|
||||
mysql -e "GRANT ALL PRIVILEGES ON $WEB_DB_NAME.* TO '$WEB_DB_USER'@'$WEB_DB_HOST'; FLUSH PRIVILEGES;"
|
||||
if [[ -f "$ISO_WEB_DIR/dump.sql" ]]; then
|
||||
mysql "$WEB_DB_NAME" < "$ISO_WEB_DIR/dump.sql"
|
||||
echo "Дамп импортирован: $ISO_WEB_DIR/dump.sql -> $WEB_DB_NAME"
|
||||
else
|
||||
echo "ДЕЛАЕТСЯ ВРУЧНУЮ: dump.sql не найден в $ISO_WEB_DIR"
|
||||
fi
|
||||
mysql -e "SHOW TABLES FROM $WEB_DB_NAME; SELECT User,Host FROM mysql.user WHERE User='$WEB_DB_USER';"
|
||||
|
||||
# Копируем файлы приложения в корневой каталог сайта
|
||||
if [[ -f "$ISO_WEB_DIR/index.php" ]]; then
|
||||
cp -f "$ISO_WEB_DIR/index.php" "$WEB_ROOT/"
|
||||
else
|
||||
echo "ДЕЛАЕТСЯ ВРУЧНУЮ: index.php не найден в $ISO_WEB_DIR"
|
||||
fi
|
||||
if [[ -f "$ISO_WEB_DIR/logo.png" ]]; then
|
||||
cp -f "$ISO_WEB_DIR/logo.png" "$WEB_ROOT/"
|
||||
else
|
||||
echo "ДЕЛАЕТСЯ ВРУЧНУЮ: logo.png не найден в $ISO_WEB_DIR"
|
||||
fi
|
||||
chown -R apache:apache "$WEB_ROOT" 2>/dev/null \
|
||||
|| echo "ПРОВЕРИТЬ: пользователь службы apache на РЕД ОС 8 (может быть httpd)"
|
||||
|
||||
# Данные для подключения БД в index.php — проверить как выглядит файл,
|
||||
# поправить вручную при необходимости (пример для sed):
|
||||
# sed -i "s/DB_HOST.*/'${WEB_DB_HOST}',/" $WEB_ROOT/index.php (формат может отличаться)
|
||||
echo "ПРОВЕРИТЬ: в $WEB_ROOT/index.php укажите вручную учётные данные БД:"
|
||||
echo " хост $WEB_DB_HOST, база $WEB_DB_NAME, пользователь $WEB_DB_USER, пароль $WEB_DB_PASS"
|
||||
|
||||
# --- 6. Часовой пояс ---
|
||||
timedatectl set-timezone "$EXAM_TZ"
|
||||
|
||||
echo ""
|
||||
echo "=== Самопроверка на HQ-SRV ==="
|
||||
echo "Массив и смонтированный RAID:"
|
||||
lsblk /dev/$RAID_DEV1 /dev/$RAID_DEV2 /dev/$RAID_NAME 2>/dev/null
|
||||
df -h "$RAID_MOUNT"
|
||||
echo ""
|
||||
echo "Экспорт NFS:"
|
||||
exportfs -v
|
||||
echo ""
|
||||
echo " chronyc sources"
|
||||
chronyc sources 2>/dev/null
|
||||
echo ""
|
||||
echo "Дополнительные проверки вручную:"
|
||||
echo " mysql -u$WEB_DB_USER -p$WEB_DB_PASS -e 'USE $WEB_DB_NAME; SHOW TABLES;'"
|
||||
echo " curl -I http://127.0.0.1:$APACHE_EXTERNAL_PORT (страница веб-приложения?)"
|
||||
echo " с HQ-CLI: showmount -e <адрес HQ-SRV> (список экспортов NFS)"
|
||||
77
zadanie2/isp.sh
Normal file
77
zadanie2/isp.sh
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
#!/bin/bash
|
||||
# ============================================================
|
||||
# ЗАДАНИЕ 2. Настройка ISP (Linux / РЕД ОС 8)
|
||||
# Служба сетевого времени chrony: сервер, стратум 5.
|
||||
# Клиенты по заданию: HQ-SRV, HQ-CLI, BR-RTR, BR-SRV (их сети
|
||||
# разрешаем командой allow). Учитывается: сети HQ-RTR и BR-RTR
|
||||
# за NAT у ISP не видны как адреса клиентов — клиент подключается
|
||||
# с адреса маршрутизатора после SNAT, разрешаем обе сети линков.
|
||||
# ============================================================
|
||||
|
||||
# --- Проверка прав root ---
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo "Запустите скрипт с правами root (sudo bash isp.sh)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ================= ПЕРЕМЕННЫЕ (заполните перед запуском) =================
|
||||
# ПРОВЕРИТЬ на РЕД ОС 8: имя конфига chrony и имя службы
|
||||
CHRONY_CONF="/etc/chrony.conf"
|
||||
CHRONY_PACKAGE="chrony"
|
||||
CHRONY_SERVICE="chronyd"
|
||||
|
||||
ISO_UPSTREAM="ru.pool.ntp.org" # вышестоящий NTP-сервер (на выбор по заданию;
|
||||
# здесь имя, а не адрес — не адресация стенда)
|
||||
STRATUM="5" # стратум сервера по заданию
|
||||
|
||||
ALLOW_NETS="" # сети клиентов NTP, через пробел, адрес/префикс:
|
||||
# сеть к HQ-RTR (по заданию 172.16.1.0/28)
|
||||
# сеть к BR-RTR (по заданию 172.16.2.0/28)
|
||||
|
||||
EXAM_TZ="Europe/Moscow" # проверить на экзамене
|
||||
|
||||
# ============ Проверка заполнения переменных ============
|
||||
MISSING=()
|
||||
for NAME in ALLOW_NETS EXAM_TZ; do
|
||||
[[ -z "${!NAME}" ]] && MISSING+=("$NAME")
|
||||
done
|
||||
if [[ ${#MISSING[@]} -gt 0 ]]; then
|
||||
echo "Заполните переменные в начале скрипта: ${MISSING[*]}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "=== Настройка chrony-сервера на ISP (стратум $STRATUM) ==="
|
||||
|
||||
dnf install -y "$CHRONY_PACKAGE" || echo "ПРОВЕРИТЬ: пакет $CHRONY_PACKAGE не установился"
|
||||
|
||||
# Добавляем только отсутствующие строки — повторный запуск не дублирует.
|
||||
add_line_once () {
|
||||
if ! grep -qx "$1" "$CHRONY_CONF" 2>/dev/null; then
|
||||
echo "$1" >> "$CHRONY_CONF"
|
||||
echo "Добавлено: $1"
|
||||
else
|
||||
echo "Уже есть: $1"
|
||||
fi
|
||||
}
|
||||
|
||||
add_line_once "local stratum $STRATUM"
|
||||
for NET in $ALLOW_NETS; do
|
||||
add_line_once "allow $NET"
|
||||
done
|
||||
|
||||
systemctl enable --now "$CHRONY_SERVICE" \
|
||||
|| { echo "ПРОВЕРИТЬ: служба $CHRONY_SERVICE не запустилась"; systemctl status "$CHRONY_SERVICE" --no-pager; }
|
||||
|
||||
timedatectl set-timezone "$EXAM_TZ"
|
||||
|
||||
echo ""
|
||||
echo "=== Самопроверка на ISP ==="
|
||||
echo "chronyc tracking (стролбик Stratum)"
|
||||
chronyc tracking 2>/dev/null || echo "(проверить chronyc tracking)"
|
||||
echo ""
|
||||
echo "sudo tail -5 $CHRONY_CONF"
|
||||
echo ""
|
||||
echo "Дополнительные проверки вручную:"
|
||||
echo " ss -uln | grep ':123' (NTP слушает?)"
|
||||
echo " chronyc sources (смотрим на upstream)"
|
||||
echo " с HQ-SRV/HQ-CLI/BR-RTR/BR-SRV: chronyc sources (source = адрес ISP)"
|
||||
Loading…
Reference in a new issue