Compare commits

...

16 commits

Author SHA1 Message Date
Киорогло Пётр Михайлович 6f0908b615 Документация: README, QUESTIONS, MANUAL, TROUBLESHOOT 2026-11-06 16:39:10 +05:00
Киорогло Пётр Михайлович 14b5b2ee95 Задание 3: скрипты настройки и проверки 2026-11-06 16:39:10 +05:00
Киорогло Пётр Михайлович d995ba80ab Задание 2: скрипты настройки и проверки 2026-11-06 16:39:10 +05:00
Киорогло Пётр Михайлович bbee2efaec Задание 1: скрипты настройки и проверки 2026-11-06 16:39:10 +05:00
Киорогло Пётр Михайлович 5e79be3862 Удалить README.md 2026-11-06 10:44:10 +05:00
Киорогло Пётр Михайлович 5d48f07b41 Синхронизация с удалённым репозиторием 2026-11-06 10:36:29 +05:00
Киорогло Пётр Михайлович b8d329156f Добавить задание КИМ (tasks.md) 2026-11-06 10:20:30 +05:00
Киорогло Пётр Михайлович 4b65da33d1 Удалить старые модульные скрипты 2026-11-06 10:18:18 +05:00
Киорогло Пётр Михайлович 35007d6c26 Удалить старые модульные скрипты 2026-11-06 10:18:06 +05:00
Киорогло Пётр Михайлович 985f3c19df Обновление базовых файлов стенда 2026-02-03 14:50:32 +05:00
Киорогло Пётр Михайлович 16a60f3fc7 Обновление базовых файлов стенда 2026-01-29 14:46:40 +05:00
Киорогло Пётр Михайлович 6297317449 Обновление базовых файлов стенда 2026-01-29 14:31:57 +05:00
root 6dd85b5219 Обновление базовых файлов стенда 2026-01-29 14:23:06 +05:00
root 8cb20b9302 Обновление базовых файлов стенда 2026-01-29 14:01:37 +05:00
user 7c2fd04d9b Обновление базовых файлов стенда 2026-01-21 17:14:21 +05:00
Киорогло Пётр Михайлович 536a74e26d Обновление базовых файлов стенда 2026-01-20 15:20:27 +05:00
42 changed files with 5178 additions and 70 deletions

114
MANUAL.md Normal file
View file

@ -0,0 +1,114 @@
# MANUAL.md — шаги, которые нельзя (или не нужно) автоматизировать
Пополняется по мере работы над заданиями 2 и 3.
## Задание 1
### BR-FW — если оказался НЕ Linux
1. Смотрим, какая система стоит на ВМ BR-FW (например EcoRouter или другой МСЭ).
2. Настраиваем по логике из zadanie1/br-fw.sh:
- имя br-fw.au-team.irpo;
- интерфейс к BR-RTR: адрес из сети /30 (адресация — из таблицы 2);
- маршрут по умолчанию через адрес BR-RTR (в сети /30);
- интерфейс к BR-SRV: адрес BR-FW в сети ≤16 адресов;
- OSPF: соседство с BR-RTR, рекламируем сети линка и сети BR-SRV;
- протокол OSPF разрешаем ТОЛЬКО на интерфейсе к BR-RTR;
- часовой пояс по месту экзамена.
3. Отчёт: заполняем раздел «коммутация/маршрутизация офиса BR».
### Таблица 2 и таблица 3
- Заполняются вручную из вывода tools/subnet-calc.sh и из ip -4 -br address
на машинах (см. README.md, порядок запуска).
## Задание 2
### HQ-CLI: ввод в домен samba-DC
Команде join нужен пароль администратора домена, нельзя автоматизировать
без секрета в файле. Делается вручную:
1. Проверить DNS: адрес BR-SRV должен резолвиться (DNS BR-SRV в /etc/resolv.conf).
Проверка: `realm discover au-team.irpo` (если используется realmd) либо
`smbclient -L //br-srv.au-team.irpo -U administrator`.
2. Ввести в домен одним из способов (уточнить на стенде, какой стек стоит
на HQ-CLI: realmd+sssd или winbind):
- realmd: `realm join au-team.irpo -U administrator` (пароль спросит);
- sssd/winbind вручную: настроить krb5.conf, затем
`net ads join -U administrator`.
3. Включить вход доменных пользователей: pam/winbind/sss настроить
(`/etc/nsswitch` и sssd.conf), перезапустить службы, проверить:
`getent passwd hquser1`.
4. Проверяем: `getent passwd hquser1`, затем `su - hquser1` — вход работает.
5. Проверить правило sudo (файл /etc/sudoers.d/hq_group от hq-cli.sh):
`su - hquser1 -c 'sudo cat /etc/hostname'` и убедиться, что другие команды
(например `sudo vim`) под пользователем группы hq НЕ работают.
## Задание 2: Ansible — ключи на машины
После br-srv.sh ключ сгенерирован, его надо раскидать вручную (пароль
запрашивается интерактивно, автоматизации по ТЗ нет):
```
ssh-copy-id sshuser@<адрес HQ-SRV>
ssh-copy-id sshuser@<адрес HQ-CLI>
ssh-copy-id net_admin@<адрес HQ-RTR>
ssh-copy-id net_admin@<адрес BR-RTR>
```
Затем на BR-SRV: `ansible all -m ping` — все четыре машины должны ответить
`pong`. Если машина отвечает, а модуль не находит python — установить
python3: `dnf install -y python3`.
### HQ-CLI: Яндекс Браузер
- Если пакет есть в репозитории РЕД ОС 8: `dnf install -y yandex-browser`
(уточнить точное имя пакета).
- Если нет — скачать rpm из Образца/Additional.iso/локальной сети и
`dnf localinstall`. Отметить в отчёте действие установки.
## Задание 3
### Кибер Бэкап (HQ-SRV и агент на HQ-CLI)
Графический продукт, автоматизации через конфиги нет:
1. Устанавливаем сервер управления на HQ-SRV (пакет с ISO/сети — уточнить
источник, где именно дистрибутив).
2. В веб-интерфейсе создаём подразделение `irpo`, пользователя
`irpoadmin` с паролем `P@ssw0rd` (значения берём из задания 3 п. 9).
3. На HQ-CLI ставим агент с функциями узла хранилища, подключаем к серверу.
4. На HQ-CLI создаём директорию /backup, выбираем её устройством хранения.
5. Создаём план «копирование /etc и всех поддиректорий» для HQ-SRV.
6. Запускаем план, показываем результат, снимаем скриншоты для отчёта.
## Задание 3
### HQ-SRV: HTTPS на реверс-прокси (доставка сертификатов)
Сертификаты выпущены hq-srv.sh (zadanie3) в /etc/CA. Их надо вручную доставить:
1. На ISP скопировать сертификат web/docker-домена и ключ:
`scp /etc/CA/веб_домен.crt root@<адрес ISP>:/etc/nginx/`
(аналогично ключ .key).
2. На ISP поправить пути в zadanie3/isp.sh (TLS_CERT_FILE/TLS_KEY_FILE)
и запустить скрипт повторно — он перенастроит прокси на 443.
3. На HQ-CLI скопировать root.crt и запустить zadanie3/hq-cli.sh
(укажите CA_ROOT_FILE) — доверие установится, браузер без предупреждений.
4. Проверить в браузере HQ-CLI (если GUI есть) либо curl: `curl -v https://...`
### HQ-SRV: Кибер Бэкап 18 (или аналог)
1. Установить сервер управления (источник — Additional.iso/локальный
репозиторий, точка задания 3 п. 9; ПрИл_6 содержит точные шаги).
2. В веб-интерфейсе создать подразделение «irpo», пользователя
«irpoadmin» с паролем P@ssw0rd.
3. На HQ-CLI установить агент с функциями узла хранилища, подключить
агент к серверу HQ-SRV.
4. На узел HQ-CLI выбрать/создать директорию /backup как устройство
хранения в консоли сервера.
5. Создать план резервного копирования: HQ-SRV, директория /etc со всеми
поддиректориями, целевой узел хранения — HQ-CLI /backup.
6. Запустить план, проверить архив в хранилище. Отметить шаги в отчёте.
### HQ-CLI: подключение pdf-принтера (если CLI без CUPS)
lpadmin/lpoptions из zadanie3/hq-cli.sh должны работать в консоли. Если
на стенде требуется GUI-подключение (GUI может отсутствовать) — сделать
через system-config-printer или настройки окружения, отметить в отчёте способ.
### Импорт пользователей через import.sh (задание 3, п. 1)
1. Монтируем Additional.iso в каталог (переменная ISO_DIR=/mnt/iso в
скриптах задания 3).
2. Запускаем файл с образа: `bash /mnt/iso/import.sh` — скрипт сам запросит
путь к источнику, вводим `/mnt/iso/users.csv`. Импорт идёт со всеми
атрибутами. Повторно допустимо (см. задание 3 п. 1).
3. Проверка: `samba-tool user list` на BR-SRV; пользователи должны
логиниться на HQ-CLI вручную (`su - имя_пользователя`). Результат в отчёт.

104
QUESTIONS.md Normal file
View file

@ -0,0 +1,104 @@
# QUESTIONS.md — что нужно уточнить на стенде / у экзаменатора
Список пополняется по мере работы с заданиями 2 и 3.
## HQ-SW (задание 1)
- По tasks.md HQ-SW — виртуальный коммутатор; кто и чем его настраивает (это
отдельная ВМ? EcoRouter? встроенный коммутатор гипервизора?) — уточнить.
- Что от него требуется по заданию 1 (что тренировать руками):
- порт в сторону HQ-SRV — access VLAN 100;
- порт в сторону HQ-CLI — access VLAN 200;
- порт в сторону HQ-RTR — trunk с VLAN 100, 200 и 999 (HQ-RTR маршрутизирует
все VLAN через ОДИН адаптер, п. 4 задания 1);
- управление в VLAN 999: IP управления HQ-SW должен быть из сети VLAN 999
(не более 8 адресов по заданию).
- Часовой пояс на HQ-SW НЕ настраивается (п. 11 задания 1).
## РЕД ОС 8 — менеджер сети и имена пакетов/служб (ПРОВЕРИТЬ на стенде)
- Сетевой менеджер: NetworkManager с keyfiles
(/etc/NetworkManager/system-connections/*.nmconnection)? Или
netplan/ifup? Все скрипты задания 1 написаны под NetworkManager.
- Пакет/служба для сохранения iptables: iptables (пакет iptables-services,
служба iptables)? Если используется firewalld или nftables — обсудить
с экзаменатором, поменять подход NAT.
- OSPF-демон: frr (пакет frr, конфиг /etc/frr/frr.conf, служба frr) или
quagga? В скриптах — frr, файл /etc/frr/daemons правится sed'ом
(zebra=yes, ospfd=yes) — проверить, что файл такой существует.
- Пакет DHCP-сервера: dhcp-server (служба dhcpd, конфиг /etc/dhcp/dhcpd.conf)?
Или kea/dnsmasq? В zadanie1/hq-rtr.sh — dhcp.
- DNS-сервер на HQ-SRV выбран dnsmasq (простой, A-записи через hosts-файл).
PTR-записи: dnsmasq должен отдавать обратные записи по записям hosts —
ПРОВЕРИТЬ на стенде (dig -x адрес). Если экзаменатор требует полноценный
bind — переделать hq-srv.sh.
- SELinux на РЕД ОС 8: если Enforcing, для порта SSH 2027 нужен
semanage (пакет policycoreutils-python-utils) — проверено в скриптах,
но имена пакетов ПРОВЕРИТЬ.
## BR-FW
- Тип системы неизвестен (УТОЧНИТЬ). zadanie1/br-fw.sh написан под Linux.
Если это не Linux (EcoRouter/другой МСЭ) — настройки OSPF-соседа и
интерфейсов делаются по-своему, взять логику из скрипта как чек-лист.
## HQ-CLI
- Графика: по предварительным данным HQ-CLI — только терминал. Пункты
задания 2 (Яндекс Браузер) и задания 3 (Кибер Бэкап GUI, принтер в GUI)
делаем через консоль где возможно, остальное — MANUAL.md/вручную.
- Установлен ли на РЕД ОС 8 репозиторий с Яндекс Браузером (dnf)? Если нет —
rpm-пакет с флешки/ISO — уточнить, откуда брать пакет.
## Задание 2 (уточнения по ходу)
- chrony: путь конфига (/etc/chrony.conf?) и имя службы (chronyd?) на РЕД ОС 8.
- NFS: имя пакета (nfs-utils) и службы (nfs-server) на РЕД ОС 8.
- mdadm: имя файла конфигурации (/etc/mdadm.conf по заданию; RHEL-вариант
/etc/mdadm.conf может дополняться переменными mdadm.conf.d).
- Веб-приложение: пользователь службы apache на РЕД ОС 8 (apache или httpd?),
также формат данных для подключения БД в index.php — смотреть файл из ISO.
- Samba: точное имя пакета samba-dc и путь samba-tool; команда для порога
блокировки (--lockout-attempt / --lockout-threshold, зависит от версии);
имя администратора домена (administrator?).
- Ansible: пакет ansible-core vs ansible; пользователи SSH для каждой машины
(из задания 1: sshuser на серверах, net_admin на роутерах).
- Docker: пакет (docker-engine / docker-ce / podman?), имена файлов образов
в Additional.iso (site_latest, mariadb_latest — тары или директории?),
содержимое compose.yaml (маппинг портов на 8080?).
- Autofs: пакет autofs, служба autofs на РЕД ОС 8.
- Ввод HQ-CLI в домен: realmd+sssd или winbind — заранее выяснить стек.
- Подтверждение «пользователи группы hq имеют право аутентифицироваться на
HQ-CLI»: как проверять (sssd getent / su - hquser1).
- Яндекс Браузер: имя пакета в репозитории РЕД ОС 8 (yandex-browser-stable?)
или источник rpm.
- Проброс 8080 наружу: на какую сеть идут DNAT-правила (интерфейс ISP), и что
разрешён прохождение пакетов в цепочке FORWARD (политика ACCEPT).
## Проверки (папка check/)
- chrony: имя службы (chronyd?), формат вывода `samba-tool domain passwordsettings show`
(точные строки "minimum password length" и "bad password count/lockout") —
если на стенде слова другие, поправить grep в check/zadanie2/br-srv.sh.
- Лизинг DHCP у NM: /var/lib/NetworkManager/*.lease — файлы есть на РЕД ОС 8?
(check/zadanie1/hq-cli.sh).
- `trust list` (p11-kit) доступен на РЕД ОС 8 для проверки CA (check/zadanie3/hq-cli.sh).
- atop: параметр интервала (INTERVAL/LOGINTERVAL) и путь конфига — в check/zadanie3/hq-srv.sh это переменная.
- Кибер Бэкап: имя service unit на стенде (переменная BACKUP_SERVICE_PATTERN).
- curl на ISP: если nginx уже в https-режиме, HTTP-запрос вернёт 301 (норма);
подробности в check/zadanie3/isp.sh.
## Задание 3 (уточнения по ходу)
- ЦС «отечественные алгоритмы»: обычный openssl RSA/EC — гост-подписи не умеет.
Уточнить у экзаменатора, оправдывает ли RSA критерий (или требуется
ГОСТ-пакет, например crypto-pro/ViPNet — что доступно на стенде?).
- nginx: пакет и наличие рестаров ok (ПРОВЕРИТЬ на РЕД ОС 8).
- Обратный прокси: HQ-SRV/BR-SRV резолвятся с ISP только через статические
маршруты (office nets за маршрутизаторами) — с ISP curl пробовать до запуска.
- atop: какой конфиг-файл читает служба на РЕД ОС 8 (/etc/sysconfig/atop?
/etc/atop/atop.conf?) и как называется параметр интервала.
- cups-pdf: есть ли пакет в репозитории РЕД ОС 8; имя pdf-принтера по умолчанию
(обычно pdf); доступность порта 631 извне (файрвол/SELinux).
- fail2ban: доступен ли пакет на РЕД ОС 8 (нужен EPEL?), формат порта в jail
(2027) и backend systemd.
- Кибер Бэкап 18: откуда брать дистрибутив на стенде (ISO/файл-сервер).
- Плейбук из Additional.iso/playbook: какие переменные/инвентарь ожидает,
где создаёт отчёты PC-INFO (path в плейбуке может отличаться).
- import.sh: точно интерактивен? Если использует свой механизм вопросов —
подготовить ответы заранее (cat answers | import.sh) — изучить на стенде.
- HQ-CLI: update-ca-trust на РЕД ОС 8; есть ли поддержка ipp-подключения
принтера без GUI (lpadmin/lpoptions).

156
README.md
View file

@ -1,93 +1,109 @@
# net # exam-net — скрипты подготовки к ДЭ 09.02.06 (Сетевое и системное администрирование)
Автоматизация настройки стенда по заданиям 1–3 (источник — `tasks.md`).
Скрипты запускаются на соответствующих машинах (ISP, HQ-RTR, BR-RTR, BR-FW,
HQ-SRV, BR-SRV, HQ-CLI), все решения по адресации вынесены в переменные
в начале каждого скрипта.
Структура:
## Getting started
To make it easy for you to get started with GitLab, here's a list of recommended next steps.
Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)!
## Add your files
- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files
- [ ] [Add files using the command line](https://docs.gitlab.com/topics/git/add_files/#add-files-to-a-git-repository) or push an existing Git repository with the following command:
``` ```
cd existing_repo tools/subnet-calc.sh калькулятор подсетей (python3)
git remote add origin http://192.168.0.185/kioroglop/net.git zadanie1/ скрипты задания 1 (сетевая инфраструктура)
git branch -M main zadanie2/ скрипты задания 2 (администрирование ОС)
git push -uf origin main zadanie3/ скрипты задания 3 (эксплуатация инфраструктуры)
QUESTIONS.md что проверить на стенде (имена пакетов/служб и т.д.)
MANUAL.md шаги, которые выполняются вручную
``` ```
## Integrate with your tools ## 1. Как скопировать репозиторий на машину
- [ ] [Set up project integrations](http://192.168.0.185/kioroglop/net/-/settings/integrations) На любой Linux-машине стенда (РЕД ОС 8):
```bash
dnf install -y git # если git ещё нет
git clone https://git.belmpk.ru/kioroglo2410/net.git
cd net
```
## Collaborate with your team ## 2. Калькулятор подсетей
- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/) ```bash
- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html) bash tools/subnet-calc.sh 172.16.0.0/16 hq_srv=32 hq_cli=16 mgmt=8 br_srv=16 br_link=2h tunnel=2h
- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically) ```
- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/)
- [ ] [Set auto-merge](https://docs.gitlab.com/user/project/merge_requests/auto_merge/)
## Test and Deploy - Числа — это АДРЕСА (включая адрес сети и broadcast). Суффикс `h` — число хостов
(`br_link=2h` → маска /30 для линка и туннеля).
- Вывод: минимальный префикс, адрес сети, маска, первый/последний адрес хоста,
broadcast — таблицей для отчёта и для заполнения переменных скриптов.
Use the built-in continuous integration in GitLab. ## 3. Порядок запуска скриптов
- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/) Задание 1:
- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing (SAST)](https://docs.gitlab.com/ee/user/application_security/sast/) ```
- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html) isp.sh -> HQ-RTR -> BR-RTR -> BR-FW -> HQ-SRV -> BR-SRV -> HQ-CLI
- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/) ```
- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html)
*** **Перед каждым запуском:**
1. Откройте скрипт (`vim zadanie1/isp.sh`) — заполните блок «ПЕРЕМЕННЫЕ»
в начале файла (адреса, интерфейсы, имена пакетов по заданиям).
2. Скрипт сам проверит заполнение и перечислит пустые переменные.
3. Запускайте от root: `sudo bash zadanie1/hq-rtr.sh` (или bash от root).
4. Все скрипты можно запускать повторно — конфиги перезаписываются,
строки не дублируются.
# Editing this README Порядок в заданиях 2 и 3 зависит от связей; ориентировочно:
- задание 2: `br-srv.sh` (samba/policy) -> `hq-srv.sh` (RAID/NFS/web) ->
`hq-cli.sh` (NFS/chrony) -> `isp.sh` (chrony-сервер) -> роутеры (DNAT).
Перед этим вручную — ввод HQ-CLI в домен (MANUAL.md) и ssh-copy-id для ansible.
- задание 3: `hq-srv.sh` (ЦС, atop, cups, fail2ban) -> доставка сертификатов
(MANUAL.md) -> `isp.sh` (реверс-прокси, HTTPS после доставки cert) ->
`hq-cli.sh` (доверие CA, принтер) -> `br-srv.sh` (import.sh, плейбук).
When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thanks to [makeareadme.com](https://www.makeareadme.com/) for this template. ## 4. Какие переменные обязательны
## Suggestions for a good README Каждый скрипт в начале содержит блок переменных с комментариями. Пустые
(`""`) при запуске приведут к сообщению «Заполните переменные...» и exit 1.
Универсальные, которые заполняются на почти всех машинах:
- `*_IF` — имя сетевого интерфейса (`ip -br link` чтобы посмотреть);
- `*_ADDR`, `*_NET` — адреса из вашего расчёта (формат `адрес/префикс`);
- `*_GW` — шлюзы (адреса соседних роутеров);
- в задании 3 в `isp.sh` — `TLS_CERT_FILE`/`TLS_KEY_FILE` после доставки
сертификатов (MANUAL.md).
Порядок заполнения адресов: сначала `tools/subnet-calc.sh`, потом скрипты
в порядке раздела 3.
Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information. ## 5. Скрипты проверки (check/)
## Name После каждого задания запускайте на соответствующей машине проверку:
Choose a self-explaining name for your project. ```
check/zadanie1/hq-rtr.sh # и т.п. — имя машины == машина, где запускаем
```
- Скрипт только читает состояние (искл. — временный файл в NFS в одной
проверке). Вывод `[OK]/[FAIL]/[ПРОПУЩЕНО]` сохраняется в
`check_<машина>_<задание>.txt` рядом — приложите к отчёту.
- Заполните переменные в начале (адреса/интерфейсы); пустая переменная →
пункт `[ПРОПУЩЕНО]`, скрипт не падает.
- Код возврата не 0, если есть FAIL.
- Отдельные пункты требуют root (sshd -T, iptables, vtysh, samba-tool) —
видят `[ПРОПУЩЕНО (нужен root)]` без него.
## Description ## 6. Что собой представляет ручной шаг
Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors.
## Badges Не всё автоматизируется честно (пароль админа домена, интерактивные установщики,
On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge. GUI). Такие места помечены в скриптах `ДЕЛАЕТСЯ ВРУЧНУЮ` и подробно описаны
в `MANUAL.md`. Порядок сохраняется вручную, а команды самопроверки — в конце
каждого скрипта.
## Visuals ## 7. Проверка результата
Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method.
## Installation - Каждый скрипт заканчивает блоком «=== Самопроверка ... ===» — там и в
Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection. интерактиве печатаются команды проверки (ping, dig, chronyc, lpstat,
fail2ban-client status, docker ps и т.д.).
- `bash -n <скрипт>` — проверка синтаксиса правок, которую вы делаете
при заполнении переменных.
## Usage ## 8. Проверить частые неточности
Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README.
## Support - РЕД ОС 8: имена пакетов/служб могут отличаться от указанных по умолчанию
Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc. (dnsmasq? frr? dhcp? nfs-utils?) — по пунктам смотри QUESTIONS.md;
соответствующие значения вынесены в переменные.
## Roadmap - Часовой пояс — везде переменная `EXAM_TZ`, поставь пояс места экзамена.
If you have ideas for releases in the future, it is a good idea to list them in the README.
## Contributing
State if you are open to contributions and what your requirements are for accepting them.
For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self.
You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser.
## Authors and acknowledgment
Show your appreciation to those who have contributed to the project.
## License
For open source projects, say how it is licensed.
## Project status
If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers.

135
TROUBLESHOOT.md Normal file
View file

@ -0,0 +1,135 @@
# TROUBLESHOOT.md — шпаргалка: частые проблемы и решения
Правило работы: сначала запустите check-скрипт своей машины (он скажет, ЧТО
сломано), затем откройте соответствующий раздел ниже. Все команды безопасны,
кроме отмеченных ОСТОРОЖНО.
## 0. Универсальная диагностика (всегда начинать с этого)
```
ip -4 -br a && ip route # адреса и маршруты
ping -c2 <адрес соседа> # линк жив?
ss -tlnp # что слушает по TCP (нужен root)
ss -ulnp # что слушает по UDP (нужен root)
systemctl status <служба> --no-pager # прямая сводка о службе
journalctl -eu <служба> --no-pager | tail -30 # почему служба упала
```
## 1. Сеть / NetworkManager
| Симптом | Причина | Решение |
|---|---|---|
| «Connection activation failed» | нет кабеля, пустой блок [connection], конфликт профилей | `nmcli con show`, `nmcli dev status`; перезаписать профиль и `nmcli con up <имя>` |
| NM не видит файл .nmconnection | права файла не 600 | `chmod 600 <файл>`, затем `nmcli con reload` |
| Адрес есть, пингов нет | не туда воткнуто; нет маршрута по умолчанию; VLAN-порт не в trunk | проверять `ip route`; на HQ-SW порт к роутеру должен быть trunk с VLAN 100/200/999 |
| Резолвинг не работает | пустой resolv.conf / недоступен DNS | `cat /etc/resolv.conf`, `ping <DNS>`; `systemctl restart NetworkManager` после смены |
## 2. GRE
| Симптом | Причина | Решение |
|---|---|---|
| Туннель есть, пинга нет | в remote указан не тот адрес (нужен адрес роутера в сети ISP) | на ОБЕИХ сторонах `ip tunnel show`; сверить remote/local |
| Пинг от роутера к роутеру есть, от сервера нет | нет маршрутов к офисным сетям | пропишите офисные сети в OSPF (network + passive-interface) или статикой |
| Не переживает перезагрузку | профиль без autoconnect | `nmcli con modify gre1 connection.autoconnect yes` |
## 3. OSPF (frr)
| Симптом | Причина | Решение |
|---|---|---|
| Сосед есть, но офиса не видны | забыли `network <офисная_сеть> area 0` | `vtysh -c 'show running-config'` — сравнить со списком сетей |
| Сосед в 2WAY, не Full | обычной broadcast-сети DR/BDR; в point-to-point туннеле | проще на gre: `ip ospf network point-to-point` на обеих сторонах |
| Соседей нет совсем | network-предложение не совпадает с реальной сетью; интерфейс в passive | проверить network-записи; `passive-interface default` НЕ должен включать туннель |
| MD5 не работает | другой пароль/номер ключа/нет ip ospf authentication | на обоих: `ip ospf authentication message-digest` и ОДИНАКОВЫЙ ключ+пароль |
| OSPF не слушает frr | не включены демоны | ПРОВЕРИТЬ /etc/frr/daemons: zebra=yes, ospfd=yes, `systemctl restart frr` |
## 4. NAT / Интернет
| Симптом | Причина | Решение |
|---|---|---|
| Пинг IP 77.88.8.7 не идёт из офиса | нет MASQUERADE; ip_forward=0 | `iptables -t nat -L POSTROUTING -nv`; `cat /proc/sys/net/ipv4/ip_forward` |
| После reboot правила NAT пропали | iptables не сохранён | `iptables-save > /etc/sysconfig/iptables`, `systemctl enable iptables` (ПРОВЕРИТЬ имя) |
| Пинг IP есть, имена не резолвятся | нет DNS / NAT-адресации | `ping ya.ru`; проверка DNS-конфигурации (раздел 7) |
## 5. DHCP
| Симптом | Причина | Решение |
|---|---|---|
| Клиент не получает адрес | служба dhcpd не активна; client не в нужной сети; range заполнен | `systemctl status dhcpd` (ПРОВЕРИТЬ имя), `nmcli con up <интерфейс>` снова |
| dhcpd не стартует | ошибка конфига (range вне сети, нет subnet) | `dhcpd -t`; `journalctl -eu dhcpd` |
## 6. SSH (порт 2027)
| Симптом | Причина | Решение |
|---|---|---|
| Connection refused | sshd не перезапущен после смены порта; SELinux; firewall | `ss -tlnp \| grep 2027`; `getenforce` → `semanage port -a -t ssh_port_t -p tcp 2027`; `firewall-cmd --add-port=2027/tcp --permanent && firewall-cmd --reload` |
| Permission denied | AllowUsers не содержит пользователя; MaxAuthTries? | `sudo sshd -T | grep -E 'port|allowusers|maxauthtries|banner'` |
| Баннер не показывается | баннер-файл не существует/путь другой | путь в `sshd -T` должен существовать с текстом |
## 7. DNS (dnsmasq)
| Симптом | Причина | Решение |
|---|---|---|
| dig пустой / REFUSED | служба/ports/listen-address | `systemctl status dnsmasq`; `ss -ulnp \| grep 53`; listen-address должен включать 127.0.0.1 и адрес сервера |
| A есть, PTR нет | dnsmasq не выдаёт reverse по hosts | `dig -x <IP>`; при необходимости добавить reverse-зону явно (см. QUESTIONS.md) |
| Внешние имена не резолвятся | нет `server=<адрес>` (форвардер) | `dig +short ya.ru @127.0.0.1`; добавить server-строку, рестарт |
## 8. RAID/mdadm
| Симптом | Причина | Решение |
|---|---|---|
| после reboot нет md0 | нет ARRAY-строки в /etc/mdadm.conf; initramfs старый | строка ARRAY по UUID, затем `dracut -f` |
| mdadm: device busy | диски смонтированы/грязные | размонтировать; `wipefs -a /dev/vdX` ОСТОРОЖНО (только array-диски!) |
| /raid не монтируется | неверный UUID в fstab | `blkid /dev/md0`; сверить с fstab; `mount -a` покажет ошибку |
## 9. NFS
| Симптом | Причина | Решение |
|---|---|---|
| mount: access denied | сеть клиента не в exports | `exportfs -v`; поправить строку; `exportfs -ra` |
| mount: connection refused | службы rpcbind/nfs-server не активны | `systemctl enable --now rpcbind nfs-server` (ПРОВЕРИТЬ имена); `ss -tlnp \| grep 2049` |
| Permission denied при записи | права ФС каталога | `ls -l /raid/nfs`, выставить владельца/права |
## 10. chrony
| Симптом | Причина | Решение |
|---|---|---|
| Stratum 10 | нет синхронизации с upstream | `chronyc sources -v`; доступен ли upstream; порт 123/udp |
| Клиенты не синхронизируются | нет allow <сеть> на сервере; firewall | добавить `allow <a.b.c.d/prefix>`, рестарт chronyd |
## 11. Docker
| Симптом | Причина | Решение |
|---|---|---|
| docker: command not found | пакет не установлен (или podman alias) | `dnf list installed \| grep -i dock`; соответствие пакету РЕД ОС 8 (ПРОВЕРИТЬ) |
| permission denied | docker требует root | `sudo docker ...` |
| compose: no such image | образ не загружен | `docker load -i <tar>`, затем `docker compose up -d` |
| 8080 не отвечает | контейнер упал | `docker ps -a`, `docker logs <id>`, `ss -tlnp | grep 8080` |
## 12. Nginx / apache / mariadb
| Симптом | Причина | Решение |
|---|---|---|
| nginx -t: [emerg] ... строка X | ошибка в exam-proxy.conf | поправить строку X; после правки `systemctl reload nginx` |
| 502 Bad Gateway | бэкенд недоступен с ISP (маршруты!) | `curl -v <бэкенд-IP:порт>` с ISP; если нет — статические маршруты или OSPF |
| 401 всё время | битый htpasswd | `printf "%s:%s\n" WEB "$(openssl passwd -apr1 'P@ssw0rd')" > файл` |
| виртуальный хост показывает дефолт | нет Host-маршрутизации | проверять server_name и какой блок ловит (nginx -t покажет; curl -H "Host: ...") |
| страница 500 | ошибки PHP/подключения к БД | `tail /var/log/httpd/error_log` (ПРОВЕРИТЬ путь на РЕД ОС 8); сверить учётные данные БД в index.php |
## 13. Samba DC
| Симптом | Причина | Решение |
|---|---|---|
| user create: password policy | пароль короче/проще политики | `samba-tool domain passwordsettings show`; ИСПОЛЬЗОВАТЬ пароль под политику |
| realm join fails | DNS BR-SRV не прописан на клиенте | `echo "nameserver <BR-SRV>" > /etc/resolv.conf`; тест `dig <домен>` |
| getent passwd hquser1 пусто | sssd/winbind не настроен/внизу | `systemctl status sssd`; логи; соглашение о формате имён группы ('hq' vs 'hq@домен') |
| sudo файл игнорируется | права не 440 / неверное имя группы | `chmod 440 /etc/sudoers.d/...`; имя группы сверить с getent |
## 14. fail2ban
| Симптом | Причина | Решение |
|---|---|---|
| не запускается | backend не видит журнал | в jail: `backend = systemd` (если используете journald) |
| IP не банится | maxretry/bantime не применились, jail не active | `sudo fail2ban-client status sshd`; проверьте порт 2027 в jail; `fail2ban-client reload` |
## 15. Сертификаты / https
| Симптом | Причина | Решение |
|---|---|---|
| certificate expired / not yet valid | уехало системное время | `timedatectl`; chrony должен тянуть время (задание 2) |
| unable to verify | клиент не доверяет корневому CA | root.crt в /etc/pki/ca-trust/source/anchors, `update-ca-trust` |
| браузер: CERT_AUTHORITY_INVALID | нет SAN или не доверие к CA | `openssl x509 -in cert -noout -ext subjectAltName`; домен ДОЛЖЕН быть в SAN |
## 16. Прочее
- Перезагрузка после большинства скриптов улучшает сходимость (особенно VLAN
и туннели). Ловить проблемы после reboot — пройтись check-скриптами.
- git clone падает по сертификату — на экзамене допустимо
`git config --global http.sslVerify false` (временно) или scp репозитория.
- Пустой DISPLAY? — всё по консоли, виртуальности GUI отсутствуют.
Если что-то сломалось не из этого списка: запустите check-скрипт машины,
посмотрите журналы (`journalctl -eu <служба> | tail -30`) и поиском по этому
файлу — похожие симптомы.

91
check/zadanie1/br-fw.sh Normal file
View file

@ -0,0 +1,91 @@
#!/bin/bash
# ============================================================
# ПРОВЕРКА ЗАДАНИЯ 1 — BR-FW (только читает состояние!)
# Пункты vtysh требуют root — иначе ПРОПУЩЕНО.
# Работает только если BR-FW — Linux (см. MANUAL.md про BR-FW).
# ============================================================
NAME="br-fw"
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="br-fw.au-team.irpo" # таблица 3
BR_RTR_IF="" # интерфейс к BR-RTR
BR_RTR_ADDR="" # адрес BR-FW в сети /30, адрес/префикс
BR_RTR_GW="" # адрес BR-RTR — маршрут по умолчанию
BR_SRV_IF="" # интерфейс к BR-SRV
BR_SRV_ADDR="" # адрес BR-FW в сети BR-SRV, адрес/префикс
BR_SRV_PING="" # адрес BR-SRV для проверки связи
EXAM_TZ=""
main () {
echo "=== Проверка задания 1: BR-FW ==="
# --- 1. Имя хоста ---
check_var "имя хоста" HOSTNAME_EXPECTED &&
expect_eq "имя хоста" "$HOSTNAME_EXPECTED" "$(hostname)"
# --- 2. Адреса интерфейсов ---
check_var "адрес линка к BR-RTR" BR_RTR_ADDR &&
if grep -qF -- "$BR_RTR_ADDR" <(ip -4 -o addr show "$BR_RTR_IF" 2>/dev/null); then
ok "адрес на $BR_RTR_IF = $BR_RTR_ADDR"
else fail "адрес линка к BR-RTR" "на $BR_RTR_IF нет $BR_RTR_ADDR"; fi
check_var "адрес в сети BR-SRV" BR_SRV_ADDR &&
if grep -qF -- "$BR_SRV_ADDR" <(ip -4 -o addr show "$BR_SRV_IF" 2>/dev/null); then
ok "адрес на $BR_SRV_IF = $BR_SRV_ADDR"
else fail "адрес в сети BR-SRV" "на $BR_SRV_IF нет $BR_SRV_ADDR"; fi
# --- 3. Шлюз по умолчанию через BR-RTR ---
check_var "шлюз по умолчанию" BR_RTR_GW &&
if ip route show default 2>/dev/null | grep -qF "$BR_RTR_GW"; then
ok "маршрут по умолчанию через $BR_RTR_GW"
else fail "маршрут по умолчанию" "ожидался via $BR_RTR_GW, получено: $(ip route show default)"; fi
# --- 4. OSPF-сосед BR-RTR (только по линку к BR-RTR) ---
if root_or_skip "OSPF (vtysh)"; then
if ! command -v vtysh &>/dev/null; then
skip "OSPF — vtysh не найден (ПРОВЕРИТЬ OSPF-демон на РЕД ОС 8 / что за система BR-FW)"
else
N_FULL=$(vtysh -c 'show ip ospf neighbor' 2>/dev/null | grep -c "Full")
if [[ $N_FULL -ge 1 ]]; then ok "OSPF сосед BR-RTR в FULL"
else fail "OSPF сосед" "нет соседа в Full: $(vtysh -c 'show ip ospf neighbor' 2>&1)"; fi
fi
fi
# --- 5. ip_forward ---
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
# --- 6. Связь с BR-SRV ---
check_var "связь с BR-SRV" BR_SRV_PING &&
if ping -c2 -W2 "$BR_SRV_PING" &>/dev/null; then ok "ping BR-SRV ($BR_SRV_PING)"
else fail "ping BR-SRV ($BR_SRV_PING)" "недоступен"; fi
# --- 7. Часовой пояс ---
check_var "часовой пояс" EXAM_TZ &&
expect_eq "часовой пояс" "$EXAM_TZ" "$(timedatectl show -p Timezone --value)"
echo ""
echo "=== Проверить вручную ==="
echo " — выход в Интернет из BR-SRV: ping 77.88.8.7 с BR-SRV"
echo " — таблицу 2 (адрес BR-FW, его шлюз) в отчёте"
echo ""
echo "=== Итог: OK=$OK FAIL=$FAIL ПРОПУЩЕНО=$SKIP ==="
[[ $FAIL -eq 0 ]]
}
main 2>&1 | tee "$LOG"
STATUS=${PIPESTATUS[0]}
echo "Лог сохранён: $LOG"
exit $STATUS

117
check/zadanie1/br-rtr.sh Normal file
View file

@ -0,0 +1,117 @@
#!/bin/bash
# ============================================================
# ПРОВЕРКА ЗАДАНИЯ 1 — BR-RTR (только читает состояние!)
# Пункты vtysh/iptables требуют root — иначе ПРОПУЩЕНО.
# ============================================================
NAME="br-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="br-rtr.au-team.irpo" # таблица 3
NET_ADMIN_USER="net_admin"
ISP_IF="" # интерфейс к ISP
BR_LINK_IF="" # интерфейс к BR-FW (сеть /30)
BR_LINK_ADDR="" # адрес BR-RTR на этом линке, адрес/префикс
GRE_IF="gre1"
GRE_LOCAL="" # локальный конец туннеля
GRE_REMOTE="" # адрес HQ-RTR в сети ISP (пингуем через туннель)
OSPF_PASSWORD="P@ssw0rd"
EXAM_TZ=""
main () {
echo "=== Проверка задания 1: BR-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"; fi
fi
# --- 3. Адeline в сторону BR-FW (сеть /30) ---
check_var "адрес линка к BR-FW" BR_LINK_ADDR &&
if grep -qF -- "$BR_LINK_ADDR" <(ip -4 -o addr show "$BR_LINK_IF" 2>/dev/null); then
ok "адрес на $BR_LINK_IF = $BR_LINK_ADDR"
else fail "адрес линка к BR-FW" "на $BR_LINK_IF нет $BR_LINK_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"; fi
# --- 5. OSPF: два соседа (HQ-RTR через туннель, BR-FW через линк) ---
if root_or_skip "OSPF (vtysh)"; then
if ! command -v vtysh &>/dev/null; then
skip "OSPF — vtysh не найден (ПРОВЕРИТЬ OSPF-демон на РЕД ОС 8)"
else
N_FULL=$(vtysh -c 'show ip ospf neighbor' 2>/dev/null | grep -c "Full")
if [[ $N_FULL -ge 2 ]]; then ok "OSPF соседи в FULL: $N_FULL"
else fail "OSPF соседи" "ожидалось 2 (HQ-RTR и BR-FW), найдено $N_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-аутентификация с паролем"
else fail "OSPF MD5" "ключ/пароль не найдены в конфиге"; 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 и маршрут по умолчанию ---
check_var "интерфейс ISP" ISP_IF &&
{ if root_or_skip "NAT"; 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; }
# --- 7. Связь через туннель ---
check_var "связь через туннель" GRE_REMOTE &&
if ping -c2 -W2 "$GRE_REMOTE" &>/dev/null; then ok "ping HQ-RTR через туннель ($GRE_REMOTE)"
else fail "ping HQ-RTR ($GRE_REMOTE)" "недоступен"; fi
# --- 8. ip_forward ---
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
# --- 9. Часовой пояс ---
check_var "часовой пояс" EXAM_TZ &&
expect_eq "часовой пояс" "$EXAM_TZ" "$(timedatectl show -p Timezone --value)"
echo ""
echo "=== Проверить вручную ==="
echo " — связь офис-к-офису: с HQ-SRV ping <адрес BR-SRV> и наоборот (сквозная маршрутизация)"
echo ""
echo "=== Итог: OK=$OK FAIL=$FAIL ПРОПУЩЕНО=$SKIP ==="
[[ $FAIL -eq 0 ]]
}
main 2>&1 | tee "$LOG"
STATUS=${PIPESTATUS[0]}
echo "Лог сохранён: $LOG"
exit $STATUS

87
check/zadanie1/br-srv.sh Normal file
View file

@ -0,0 +1,87 @@
#!/bin/bash
# ============================================================
# ПРОВЕРКА ЗАДАНИЯ 1 — BR-SRV (только читает состояние!)
# Пункты sshd -T и sudo требуют root.
# ============================================================
NAME="br-srv"
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="br-srv.au-team.irpo" # таблица 3
SRV_IF="" # интерфейс к BR-SRV
SRV_ADDR="" # адрес BR-SRV, адрес/префикс
SRV_GW="" # шлюз (адрес BR-FW)
SSH_PORT="2027"
SSH_USER="sshuser"
SSH_USER_UID="2027"
SSH_BANNER_TEXT="Authorized access only"
EXAM_TZ=""
main () {
echo "=== Проверка задания 1: BR-SRV ==="
# --- 1. Имя хоста ---
check_var "имя хоста" HOSTNAME_EXPECTED &&
expect_eq "имя хоста" "$HOSTNAME_EXPECTED" "$(hostname)"
# --- 2. Сеть ---
check_var "адрес" SRV_ADDR &&
if grep -qF -- "$SRV_ADDR" <(ip -4 -o addr show "$SRV_IF" 2>/dev/null); then
ok "адрес = $SRV_ADDR"
else fail "адрес" "не нашёлся $SRV_ADDR"; fi
check_var "шлюз" SRV_GW &&
expect_eq "шлюз по умолчанию" "$SRV_GW" "$(ip route show default 2>/dev/null | awk '{print $3}')"
# --- 3. Пользователь sshuser ---
check_var "пользователь sshuser" SSH_USER &&
if id "$SSH_USER" &>/dev/null; then
expect_eq "UID $SSH_USER" "$SSH_USER_UID" "$(id -u "$SSH_USER")"
else fail "пользователь $SSH_USER" "нет такого пользователя"; fi
check_var "sudo для sshuser" SSH_USER &&
if root_or_skip "sudo для sshuser"; then
if sudo -ln -U "$SSH_USER" 2>/dev/null | grep -q "NOPASSWD: ALL"; then
ok "sshuser — sudo без пароля"
else fail "sudo для sshuser" "нет NOPASSWD: ALL"; fi
fi
# --- 4. SSH: порт 2027, только sshuser, 2 попытки, баннер ---
if root_or_skip "sshd -T"; then
T=$(sshd -T 2>/dev/null)
expect_eq "SSH порт" "$SSH_PORT" "$(grep -E "^port " <<<"$T" | awk '{print $2}')"
if grep -E "^allowusers " <<<"$T" | grep -qw "$SSH_USER"; then
ok "SSH AllowUsers = $SSH_USER"
else fail "SSH AllowUsers" "$(grep -E '^allowusers' <<<"$T")"; fi
expect_eq "SSH MaxAuthTries" "2" "$(grep -E "^maxauthtries " <<<"$T" | awk '{print $2}')"
got_banner=$(grep -E "^banner " <<<"$T" | awk '{print $2}')
if [[ -n "$got_banner" ]] && grep -qF "$SSH_BANNER_TEXT" "$got_banner" 2>/dev/null; then
ok "SSH баннер '$SSH_BANNER_TEXT'"
else fail "SSH баннер" "banner=$got_banner"; fi
fi
# --- 5. Часовой пояс ---
check_var "часовой пояс" EXAM_TZ &&
expect_eq "часовой пояс" "$EXAM_TZ" "$(timedatectl show -p Timezone --value)"
echo ""
echo "=== Проверить вручную ==="
echo " — ssh -p 2027 sshuser@<адрес BR-SRV> с другой машины"
echo ""
echo "=== Итог: OK=$OK FAIL=$FAIL ПРОПУЩЕНО=$SKIP ==="
[[ $FAIL -eq 0 ]]
}
main 2>&1 | tee "$LOG"
STATUS=${PIPESTATUS[0]}
echo "Лог сохранён: $LOG"
exit $STATUS

80
check/zadanie1/hq-cli.sh Normal file
View file

@ -0,0 +1,80 @@
#!/bin/bash
# ============================================================
# ПРОВЕРКА ЗАДАНИЯ 1 — HQ-CLI (только читает состояние!)
# Клиент получает адрес по DHCP от HQ-RTR (VLAN 200): проверяем
# что адрес есть, шлюз и DNS правильные, суффикс домена — в resolv.
# ============================================================
NAME="hq-cli"
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-cli.au-team.irpo" # таблица 3
CLI_IF="" # интерфейс, подключённый к VLAN 200
HQ_RTR_ADDR="" # адрес HQ-RTR в VLAN 200 (ожидаемый шлюз)
HQ_SRV_ADDR="" # адрес HQ-SRV (ожидаемый DNS)
DNS_DOMAIN="au-team.irpo" # суффикс по заданию
EXAM_TZ=""
main () {
echo "=== Проверка задания 1: HQ-CLI ==="
# --- 1. Имя хоста ---
check_var "имя хоста" HOSTNAME_EXPECTED &&
expect_eq "имя хоста" "$HOSTNAME_EXPECTED" "$(hostname)"
# --- 2. Адрес по DHCP ---
if [[ -n "$CLI_IF" ]]; then
METHOD=$(nmcli -g ipv4.method con show "$CLI_IF" 2>/dev/null)
expect_eq "IPv4 ($CLI_IF) по DHCP" "auto" "$METHOD"
IP4=$(ip -4 -o addr show dev "$CLI_IF" 2>/dev/null | awk '{print $4}')
if [[ -n "$IP4" ]]; then ok "адрес получен по DHCP: $IP4"
else fail "адрес по DHCP" "адреса на $CLI_IF нет (DHCP-сервер на HQ-RTR работает?)"; fi
# DHCP-лизинг фактически выдан NetworkManager
if root_or_skip "файл DHCP-лизинга"; then
LEASE=$(grep -rls "ip_address=" /var/lib/NetworkManager/*.lease 2>/dev/null | head -1)
if [[ -n "$LEASE" ]]; then ok "лизинг DHCP сохранён в $LEASE"
else fail "DHCP-лизинг" "файл лизинга не найден в /var/lib/NetworkManager"; fi
fi
else
skip "адрес по DHCP — не задано CLI_IF"
fi
# --- 3. Шлюз и DNS из DHCP ---
check_var "шлюз = HQ-RTR" HQ_RTR_ADDR &&
expect_eq "шлюз по умолчанию" "$HQ_RTR_ADDR" "$(ip route show default 2>/dev/null | awk '{print $3}')"
check_var "DNS = HQ-SRV" HQ_SRV_ADDR &&
expect_eq "DNS-сервер в resolv.conf" "$HQ_SRV_ADDR" "$(grep -m1 nameserver /etc/resolv.conf | awk '{print $2}')"
# --- 4. Суффикс домена в resolv.conf ---
check_var "суффикс домена" DNS_DOMAIN &&
if grep -qE "(search|domain) .*$DNS_DOMAIN" /etc/resolv.conf 2>/dev/null; then
ok "суффикс $DNS_DOMAIN в resolv.conf"
else fail "суффикс домена" "нет $DNS_DOMAIN: $(cat /etc/resolv.conf 2>/dev/null)"; fi
# --- 5. Часовой пояс ---
check_var "часовой пояс" EXAM_TZ &&
expect_eq "часовой пояс" "$EXAM_TZ" "$(timedatectl show -p Timezone --value)"
echo ""
echo "=== Проверить вручную ==="
echo " — ping <адрес HQ-SRV> (маршрутизация VLAN 100/200)"
echo " — разрешение имён через новый DNS: dig hq-srv.$DNS_DOMAIN"
echo ""
echo "=== Итог: OK=$OK FAIL=$FAIL ПРОПУЩЕНО=$SKIP ==="
[[ $FAIL -eq 0 ]]
}
main 2>&1 | tee "$LOG"
STATUS=${PIPESTATUS[0]}
echo "Лог сохранён: $LOG"
exit $STATUS

141
check/zadanie1/hq-rtr.sh Normal file
View file

@ -0,0 +1,141 @@
#!/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

129
check/zadanie1/hq-srv.sh Normal file
View file

@ -0,0 +1,129 @@
#!/bin/bash
# ============================================================
# ПРОВЕРКА ЗАДАНИЯ 1 — HQ-SRV (только читает состояние!)
# Пункты sshd -T и sudo требуют root — иначе ПРОПУЩЕНО.
# Требует установленный dig (bind-utils): если его нет — DNS
# проверки получат [ПРОПУЩЕНО] с подсказкой.
# ============================================================
NAME="hq-srv"
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-srv.au-team.irpo" # таблица 3
SRV_IF="" # интерфейс к VLAN 100
SRV_ADDR="" # адрес HQ-SRV, адрес/префикс
SRV_GW="" # шлюз (адрес HQ-RTR в VLAN 100)
SSH_PORT="2027" # по заданию 1 п. 5
SSH_USER="sshuser"
SSH_USER_UID="2027" # по заданию 1 п. 3
SSH_BANNER_TEXT="Authorized access only"
# Адреса для DNS-записей (таблица 3)
HQ_RTR_IP="" BR_RTR_IP="" BR_FW_IP="" HQ_CLI_IP=""
BR_SRV_IP="" ISP_TO_HQ_IP="" ISP_TO_BR_IP=""
EXAM_TZ=""
main () {
echo "=== Проверка задания 1: HQ-SRV ==="
# --- 1. Имя хоста ---
check_var "имя хоста" HOSTNAME_EXPECTED &&
expect_eq "имя хоста" "$HOSTNAME_EXPECTED" "$(hostname)"
# --- 2. Сеть ---
check_var "адрес" SRV_ADDR &&
if grep -qF -- "$SRV_ADDR" <(ip -4 -o addr show "$SRV_IF" 2>/dev/null); then
ok "адрес = $SRV_ADDR"
else fail "адрес" "не нашёлся $SRV_ADDR ($(ip -4 -o addr show 2>/dev/null | grep inet))"; fi
check_var "шлюз" SRV_GW &&
expect_eq "шлюз по умолчанию" "$SRV_GW" "$(ip route show default 2>/dev/null | awk '{print $3}')"
# --- 3. Пользователь sshuser (UID 2027) и sudo ---
check_var "пользователь sshuser" SSH_USER &&
if id "$SSH_USER" &>/dev/null; then
got_uid=$(id -u "$SSH_USER")
expect_eq "UID $SSH_USER" "$SSH_USER_UID" "$got_uid"
else fail "пользователь $SSH_USER" "нет такого пользователя"; fi
check_var "sudo для sshuser" SSH_USER &&
if root_or_skip "sudo для sshuser"; then
if sudo -ln -U "$SSH_USER" 2>/dev/null | grep -q "NOPASSWD: ALL"; then
ok "sshuser — sudo без пароля"
else fail "sudo для sshuser" "нет NOPASSWD: ALL"; fi
fi
# --- 4. SSH: порт 2027, только sshuser, 2 попытки, баннер ---
if root_or_skip "sshd -T (эффективный конфиг)"; then
T=$(sshd -T 2>/dev/null)
if [[ -z "$T" ]]; then fail "sshd -T" "команда не отработала"
else
got_port=$(grep -E "^port " <<<"$T" | awk '{print $2}')
expect_eq "SSH порт" "$SSH_PORT" "$got_port"
if grep -E "^allowusers " <<<"$T" | grep -qw "$SSH_USER"; then
ok "SSH AllowUsers = $SSH_USER"
else fail "SSH AllowUsers" "$(grep -E '^allowusers' <<<"$T")"; fi
got_tries=$(grep -E "^maxauthtries " <<<"$T" | awk '{print $2}')
expect_eq "SSH MaxAuthTries" "2" "$got_tries"
got_banner=$(grep -E "^banner " <<<"$T" | awk '{print $2}')
if [[ -n "$got_banner" ]] && grep -qF "$SSH_BANNER_TEXT" "$got_banner" 2>/dev/null; then
ok "SSH баннер '$SSH_BANNER_TEXT'"
else fail "SSH баннер" "banner=$got_banner, текст не совпал"; fi
fi
fi
# --- 5. DNS: A- и PTR-записи по таблице 3 ---
if ! command -v dig &>/dev/null; then
skip "DNS-проверки — dig не установлен (dnf install bind-utils)"
else
check_dns_a () {
local RECORD="$1" EXPECT="$2"
local GOT; GOT=$(dig +short "$RECORD" @127.0.0.1 2>/dev/null)
if [[ "$GOT" == "$EXPECT" ]]; then ok "DNS A: $RECORD -> $EXPECT"
else fail "DNS A: $RECORD" "ожидалось '$EXPECT', получено '$GOT'"; fi
}
check_var "DNS hq-rtr" HQ_RTR_IP && check_dns_a "hq-rtr.au-team.irpo" "$HQ_RTR_IP"
check_var "DNS br-rtr" BR_RTR_IP && check_dns_a "br-rtr.au-team.irpo" "$BR_RTR_IP"
check_var "DNS br-fw" BR_FW_IP && check_dns_a "br-fw.au-team.irpo" "$BR_FW_IP"
# PTR для HQ-SRV (адрес = наш собственный, из переменной SRV_ADDR)
check_var "PTR HQ-SRV" SRV_ADDR &&
{ GOT_PTR=$(dig +short -x "${SRV_ADDR%/*}" @127.0.0.1 2>/dev/null)
if grep -q "hq-srv.au-team.irpo" <<<"$GOT_PTR"; then ok "PTR: ${SRV_ADDR%/*} -> hq-srv.au-team.irpo"
else fail "PTR HQ-SRV" "ожидалось 'hq-srv.au-team.irpo', получено '$GOT_PTR'"; fi; }
check_var "DNS hq-cli" HQ_CLI_IP && check_dns_a "hq-cli.au-team.irpo" "$HQ_CLI_IP"
check_var "DNS br-srv" BR_SRV_IP &&
{ check_dns_a "br-srv.au-team.irpo" "$BR_SRV_IP"
GOT_PTR=$(dig +short -x "$BR_SRV_IP" @127.0.0.1 2>/dev/null)
if grep -q "br-srv.au-team.irpo" <<<"$GOT_PTR"; then ok "PTR: $BR_SRV_IP -> br-srv.au-team.irpo"
else fail "PTR BR-SRV" "ожидалось 'br-srv.au-team.irpo', получено '$GOT_PTR'"; fi; }
check_var "DNS docker" ISP_TO_HQ_IP && check_dns_a "docker.au-team.irpo" "$ISP_TO_HQ_IP"
check_var "DNS web" ISP_TO_BR_IP && check_dns_a "web.au-team.irpo" "$ISP_TO_BR_IP"
fi
# --- 6. Часовой пояс ---
check_var "часовой пояс" EXAM_TZ &&
expect_eq "часовой пояс" "$EXAM_TZ" "$(timedatectl show -p Timezone --value)"
echo ""
echo "=== Проверить вручную ==="
echo " — ssh -p 2027 sshuser@<адрес HQ-SRV> с другой машины (подключение работает)"
echo " — fork wong вход под другими пользователями по ssh запрещён (MaxAuthTries/AllowUsers)"
echo ""
echo "=== Итог: OK=$OK FAIL=$FAIL ПРОПУЩЕНО=$SKIP ==="
[[ $FAIL -eq 0 ]]
}
main 2>&1 | tee "$LOG"
STATUS=${PIPESTATUS[0]}
echo "Лог сохранён: $LOG"
exit $STATUS

113
check/zadanie1/isp.sh Normal file
View file

@ -0,0 +1,113 @@
#!/bin/bash
# ============================================================
# ПРОВЕРКА ЗАДАНИЯ 1 — ISP (только читает состояние!)
# Ничего не настраивает и не перезапускает.
# Пункты с iptables требуют root — при запуске от обычного
# пользователя они получат [ПРОПУЩЕНО (нужен root)].
# ============================================================
NAME="isp"
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 (iptables и т.п.)
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="" # полное имя ISP (в таблице 3 записи нет — как задали)
WAN_IF="" # WAN-интерфейс (пример: enp0s3)
HQ_IF="" # интерфейс к HQ-RTR
HQ_NET="" # адрес ISP на этом интерфейсе, адрес/префикс
BR_IF="" # интерфейс к BR-RTR
BR_NET="" # адрес ISP на этом интерфейсе, адрес/префикс
HQ_RTR_ADDR="" # адрес HQ-RTR на линке (для пинга)
BR_RTR_ADDR="" # адрес BR-RTR на линке (для пинга)
EXAM_TZ="" # ожидаемый часовой пояс (например Europe/Moscow)
main () {
echo "=== Проверка задания 1: ISP ==="
# --- 1. Имя хоста ---
check_var "имя хоста (FQDN)" HOSTNAME_EXPECTED &&
expect_eq "имя хоста" "$HOSTNAME_EXPECTED" "$(hostname)"
# --- 2. WAN получает адрес по DHCP (method=auto) ---
if [[ -n "$WAN_IF" ]]; then
METHOD=$(nmcli -g ipv4.method con show "$WAN_IF" 2>/dev/null)
expect_eq "IPv4 WAN ($WAN_IF) по DHCP" "auto" "$METHOD"
IP4=$(ip -4 -o addr show dev "$WAN_IF" 2>/dev/null | awk '{print $4}')
if [[ -n "$IP4" ]]; then ok "WAN получил адрес: $IP4"
else fail "WAN получил адрес" "адреса на $WAN_IF нет"; fi
else
skip "WAN DHCP — не задано WAN_IF"
fi
# --- 3. Статические адреса на линках к роутерам ---
check_var "адрес на $HQ_IF (линк HQ)" HQ_NET &&
if grep -qF -- "$HQ_NET" <(ip -4 -o addr show dev "$HQ_IF" 2>/dev/null); then
ok "адрес на $HQ_IF = $HQ_NET"
else fail "адрес на $HQ_IF" "не нашёлся $HQ_NET в: $(ip -4 -o addr show dev "$HQ_IF" 2>/dev/null)"; fi
check_var "адрес на $BR_IF (линк BR)" BR_NET &&
if grep -qF -- "$BR_NET" <(ip -4 -o addr show dev "$BR_IF" 2>/dev/null); then
ok "адрес на $BR_IF = $BR_NET"
else fail "адрес на $BR_IF" "не нашёлся $BR_NET в: $(ip -4 -o addr show dev "$BR_IF" 2>/dev/null)"; fi
# --- 4. Маршрут по умолчанию через WAN ---
check_var "маршрут по умолчанию к WAN" WAN_IF &&
if ip route show default 2>/dev/null | grep -qF "$WAN_IF"; then
ok "маршрут по умолчанию через $WAN_IF: $(ip route show default)"
else fail "маршрут по умолчанию" "через $WAN_IF нет; маршруты: $(ip route show)"; fi
# --- 5. NAT (MASQUERADE) для сетей HQ-RTR и BR-RTR ---
if root_or_skip "NAT (iptables)"; then
check_var "NAT для сети HQ" HQ_NET && {
if grep -qF "$HQ_NET" <(iptables -t nat -S POSTROUTING 2>/dev/null); then
ok "NAT для $HQ_NET"
else fail "NAT для $HQ_NET" "нет правила MASQUERADE"; fi
}
check_var "NAT для сети BR" BR_NET && {
if grep -qF "$BR_NET" <(iptables -t nat -S POSTROUTING 2>/dev/null); then
ok "NAT для $BR_NET"
else fail "NAT для $BR_NET" "нет правила MASQUERADE"; fi
}
fi
# --- 6. 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
# --- 7. Связь с роутерами (по адресам из переменных) ---
check_var "связь с HQ-RTR" HQ_RTR_ADDR &&
if ping -c1 -W2 "$HQ_RTR_ADDR" &>/dev/null; then ok "ping HQ-RTR ($HQ_RTR_ADDR)"
else fail "ping HQ-RTR ($HQ_RTR_ADDR)" "недоступен"; fi
check_var "связь с BR-RTR" BR_RTR_ADDR &&
if ping -c1 -W2 "$BR_RTR_ADDR" &>/dev/null; then ok "ping BR-RTR ($BR_RTR_ADDR)"
else fail "ping BR-RTR ($BR_RTR_ADDR)" "недоступен"; fi
# --- 8. Часовой пояс ---
check_var "часовой пояс" EXAM_TZ &&
expect_eq "часовой пояс" "$EXAM_TZ" "$(timedatectl show -p Timezone --value)"
echo ""
echo "=== Проверить вручную: ==="
echo " — доступ в Интернет с ISP: ping -c2 77.88.8.7"
echo " — доступ в Интернет из офисов: с HQ-SRV/BR-SRV ping 77.88.8.7"
echo " — таблицу 2 в отчёте сверить с выводом ip -4 -br a на всех машинах"
echo ""
echo "=== Итог: OK=$OK FAIL=$FAIL ПРОПУЩЕНО=$SKIP ==="
[[ $FAIL -eq 0 ]]
}
main 2>&1 | tee "$LOG"
STATUS=${PIPESTATUS[0]}
echo "Лог сохранён: $LOG"
exit $STATUS

63
check/zadanie2/br-rtr.sh Normal file
View 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
View 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
View 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
View 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
View 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
View 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

73
check/zadanie3/br-srv.sh Normal file
View file

@ -0,0 +1,73 @@
#!/bin/bash
# ============================================================
# ПРОВЕРКА ЗАДАНИЕ 3 — BR-SRV: импорт пользователей, PC-INFO
# (только читает состояние; samba-tool требует root)
# Кибер Бэкап сервер — вручную (в конце список).
# ============================================================
NAME="br-srv"
LOG="check_${NAME}_z3.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; }
# ================= ПЕРЕМЕННЫЕ (заполните для проверки) =================
EXPECTED_USERS="" # список имён из users.csv через пробел (заполните после импорта)
# если пусто — пункт [ПРОПУЩЕНО], проверяем только факт import
ANSIBLE_DIR="/etc/ansible"
REPORT_DIR="$ANSIBLE_DIR/PC-INFO" # отчёты инвентаризации по заданию
EXPECTED_REPORTS="hq-srv hq-cli" # имена файлов-отчётов = имена ПК (коротные из hostname,
# без домена — уточните: с точками или подчёркиваниями?)
main () {
echo "=== Проверка задания 3: BR-SRV ==="
# --- 1. Импорт пользователей из users.csv ---
if root_or_skip "samba-tool (требует root)"; then
if ! command -v samba-tool &>/dev/null; then
skip "samba-tool — не найден"
elif [[ -n "$EXPECTED_USERS" ]]; then
USER_LIST=$(samba-tool user list 2>/dev/null)
for USER in $EXPECTED_USERS; do
if grep -qx "$USER" <<<"$USER_LIST"; then ok "импортирован $USER"
else fail "импорт $USER" "не найден в списке домена"; fi
done
else
N_TOTAL=$(samba-tool user list 2>/dev/null | wc -l)
if [[ $N_TOTAL -gt 5 ]]; then
ok "доменных пользователей больше 5 (сверх hquser1–5): $N_TOTAL"
else fail "импорт пользователей" "в домене только $N_TOTAL пользователей — import.sh не выполнен?"
fi
fi
fi
# --- 2. Отчёты PC-INFO (.yml, имя файла = имя ПК) ---
if [[ -d "$REPORT_DIR" ]]; then
YML_COUNT=$(ls "$REPORT_DIR"/*.yml 2>/dev/null | wc -l)
if [[ $YML_COUNT -ge 2 ]]; then ok "в $REPORT_DIR есть $YML_COUNT отчёт(ов) .yml"
else fail "отчёты $REPORT_DIR" "ожидалось ≥2 .yml файлов, найдено $YML_COUNT"; fi
for PC in $EXPECTED_REPORTS; do
if ls "$REPORT_DIR"/$PC*.yml &>/dev/null; then ok "отчёт для $PC присутствует ($(ls "$REPORT_DIR"/$PC*.yml 2>/dev/null | head -1))"
else fail "отчёт $PC" "файла вида $PC*.yml нет (имена могут отличаться — см. переменную EXPECTED_REPORTS)"; fi
done
else
fail "каталог $REPORT_DIR" "не существует"
fi
echo ""
echo "=== Проверить вручную ==="
echo " — открыть один .yml файл: там имя ПК и IP-адрес"
echo " — Кибер Бэкап сервер HQ-SRV работает (скриншот консоли/данные резервных проверок)"
echo ""
echo "=== Итог: OK=$OK FAIL=$FAIL ПРОПУЩЕНО=$SKIP ==="
[[ $FAIL -eq 0 ]]
}
main 2>&1 | tee "$LOG"
STATUS=${PIPESTATUS[0]}
echo "Лог сохранён: $LOG"
exit $STATUS

80
check/zadanie3/hq-cli.sh Normal file
View file

@ -0,0 +1,80 @@
#!/bin/bash
# ============================================================
# ПРОВЕРКА ЗАДАНИЯ 3 — HQ-CLI: доверие CA, https без -k,
# принтер по умолчанию, каталог /backup
# (только читает состояние!) Агент Кибер Бэкап — вручную.
# ============================================================
NAME="hq-cli"
LOG="check_${NAME}_z3.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)); }
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; }
# ================= ПЕРЕМЕННЫЕ (заполните для проверки) =================
CA_ANCHORS_DIR="/etc/pki/ca-trust/source/anchors" # ПРОВЕРИТЬ на РЕД ОС 8
CA_CN="au-team-CA" # CN корневого сертификата (переменная CA_SUBJECT)
WEB_DOMAIN="web.au-team.irpo"
DOCKER_DOMAIN="docker.au-team.irpo"
WEB_LOGIN="WEB" # по заданию 3 п. 3
WEB_PASS="P@ssw0rd"
CLIENT_PRINTER="pdf_printer" # локальное имя принтера на HQ-CLI
BACKUP_DIR="/backup" # каталог хранилища по заданию 3 п. 9
main () {
echo "=== Проверка задания 3: HQ-CLI ==="
# --- 1. Доверие корневому сертификату (установлен в хранилище) ---
if [[ -d "$CA_ANCHORS_DIR" ]] && ls "$CA_ANCHORS_DIR" | grep -q .; then
LISTED=$(ls "$CA_ANCHORS_DIR" | tr '\n' ' ')
echo "[ИНФО] в anchors: $LISTED"
SKIP=$((SKIP+1)) # ПРОВЕРИТЬ: имя файла бывает любым — критерий ниже через trust list
if command -v trust &>/dev/null; then
if trust list 2>/dev/null | grep -q "cn.*$CA_CN"; then ok "корневой сертификат ($CA_CN) в хранилище"
else fail "корневой CA" "$CA_CN не найден в trust list"; fi
else skip "trust list — команда trust не найдена (ПРОВЕРИТЬ на РЕД ОС 8)"
fi
else
fail "anchors $CA_ANCHORS_DIR" "каталог не найден или пуст — файл CA доставлен вручную?"
fi
# --- 2. https без предупреждений (curl без -k) ---
check_var "web-домен" WEB_DOMAIN &&
{ CODE=$(curl -s -o /dev/null -w "%{http_code}" -u "$WEB_LOGIN:$WEB_PASS" "https://$WEB_DOMAIN/" 2>/dev/null)
if grep -qE "^(200|301|302)$" <<<"$CODE"; then ok "https://$WEB_DOMAIN — соединение без ошибок сертификата (код $CODE)"
else fail "https $WEB_DOMAIN" "код '$CODE' (0 = ошибка соединения/сертификата)"; fi; }
check_var "docker-домен" DOCKER_DOMAIN &&
{ CODE=$(curl -s -o /dev/null -w "%{http_code}" "https://$DOCKER_DOMAIN/" 2>/dev/null)
if grep -qE "^(200|301|302)$" <<<"$CODE"; then ok "https://$DOCKER_DOMAIN — без ошибок сертификата ($CODE)"
else fail "https $DOCKER_DOMAIN" "код '$CODE'"; fi; }
# --- 3. Принтер по умолчанию ---
if command -v lpstat &>/dev/null; then
DEFAULT_P=$(lpstat -d 2>/dev/null | awk '{print $NF}')
expect_eq "принтер по умолчанию" "$CLIENT_PRINTER" "$DEFAULT_P"
if lpstat -p "$CLIENT_PRINTER" &>/dev/null; then ok "принтер $CLIENT_PRINTER зарегистрирован"
else fail "принтер $CLIENT_PRINTER" "не найден в lpstat -p"; fi
else skip "lpstat — утилита CUPS не найдена (dnf install cups)"; fi
# --- 4. Каталог /backup (узел хранилища) ---
if [[ -d "$BACKUP_DIR" ]]; then ok "каталог $BACKUP_DIR существует"
else fail "каталог $BACKUP_DIR" "не найден"; fi
echo ""
echo "=== Проверить вручную ==="
echo " — установка агента Кибер Бэкап на HQ-CLI (GUI), подключение к HQ-SRV"
echo " — предупреждения браузера (откройте страницу в Яндекс Браузере)"
echo " — печать: echo test | lp -d $CLIENT_PRINTER; проверьте появление pdf у принтера"
echo ""
echo "=== Итог: OK=$OK FAIL=$FAIL ПРОПУЩЕНО=$SKIP ==="
[[ $FAIL -eq 0 ]]
}
main 2>&1 | tee "$LOG"
STATUS=${PIPESTATUS[0]}
echo "Лог сохранён: $LOG"
exit $STATUS

116
check/zadanie3/hq-srv.sh Normal file
View file

@ -0,0 +1,116 @@
#!/bin/bash
# ============================================================
# ПРОВЕРКА ЗАДАНИЯ 3 — HQ-SRV: сертификаты, atop, CUPS, fail2ban
# (только читает состояние; openssl / lpstat / fail2ban-client
# могут требовать root — иначе ПРОПУЩЕНО)
# Кибер Бэкап — вручную (в конце список).
# ============================================================
NAME="hq-srv"
LOG="check_${NAME}_z3.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; }
# ================= ПЕРЕМЕННЫЕ (заполните для проверки) =================
CA_DIR="/etc/CA" # каталог ЦС из настройки
CERT_NAMES="web.au-team.irpo docker.au-team.irpo" # домены, которые выданы
ATOP_CONF="/etc/sysconfig/atop" # ПРОВЕРИТЬ путь на РЕД ОС 8
ATOP_INTERVAL="420" # интервал 7 минут (в секундах)
PDF_PRINTER="pdf" # принтер по заданию
F2B_SSH_PORT="2027" # порт ssh (fail2ban)
F2B_JAIL="/etc/fail2ban/jail.d/exam.local"
F2B_BANTIME="60" # бан 1 минута (в секундах)
F2B_MAXRETRY="3" # 3 попытки
BACKUP_SERVICE_PATTERN="cyber|backup" # ПРОВЕРИТЬ: как называется служба на стенде
main () {
echo "=== Проверка задания 3: HQ-SRV ==="
# --- 1. Сертификаты: срок (не менее ~29 дней) и цепочка ---
if command -v openssl &>/dev/null; then
KNOWN_DAYS_LEFT=$((29*24*3600)) # допустимая погрешность округления (выдан "на 30 дней")
check_var "каталог ЦС" CA_DIR &&
for NAME in $CERT_NAMES; do
CRT="$CA_DIR/$NAME.crt"
if [[ -f "$CRT" ]]; then
# проверка срока действия через -checkend
if openssl x509 -in "$CRT" -checkend "$KNOWN_DAYS_LEFT" &>/dev/null; then
ok "сертификат $NAME: срок действия ≥ 29 дней (выдан на 30)"
else fail "срок $NAME" "остаётся < 29 дней или сертификат не читается: $(openssl x509 -in "$CRT" -dates 2>&1)"; fi
# цепочка: подписан нашим CA
if openssl verify -CAfile "$CA_DIR/root.crt" "$CRT" 2>/dev/null | grep -q "OK"; then
ok "сертификат $NAME — подписан корневым $CA_DIR/root.crt"
else fail "цепочка $NAME" "verify: $(openssl verify -CAfile "$CA_DIR/root.crt" "$CRT" 2>&1)"; fi
# SAN
if openssl x509 -in "$CRT" -noout -ext subjectAltName 2>/dev/null | grep -qF "DNS:$NAME"; then
ok "SAN $NAME корректен"
else fail "SAN $NAME" "нет DNS:$NAME в subjectAltName"; fi
else
fail "сертификат $NAME" "файл $CRT не найден"; fi
done
else
skip "сертификаты — openssl не установлен"
fi
# --- 2. atop: интервал 420 c и служба ---
if [[ -f "$ATOP_CONF" ]]; then
GOT_INT=$(grep -E "^INTERVAL=|^LOGINTERVAL=" "$ATOP_CONF" | head -1)
if grep -qE "(=|=)$ATOP_INTERVAL" <<<"$GOT_INT"; then ok "atop: интервал $ATOP_INTERVAL с (7 минут)"
else fail "atop интервал" "ожидалось $ATOP_INTERVAL: $GOT_INT"; fi
else skip "atop конфиг — $ATOP_CONF не найден (ПРОВЕРИТЬ путь/имя параметров на РЕД ОС 8)"; fi
if systemctl is-active atop &>/dev/null; then ok "служба atop активна"
else fail "atop служба" "не активна (ПРОВЕРИТЬ имя службы)"; fi
# --- 3. CUPS: pdf-принтер, слушает 631 ---
if command -v lpstat &>/dev/null; then
PINFO=$(lpstat -p 2>/dev/null)
if grep -qw "$PDF_PRINTER" <<<"$PINFO" && ! grep -q "disabled" <<<"$PINFO"; then
ok "принтер $PDF_PRINTER опубликован и активен"
else fail "принтер $PDF_PRINTER" "не активен/отсутствует: $PINFO"; fi
if root_or_skip "проверка порта 631"; then
if ss -tln 2>/dev/null | grep -q ":631 "; then ok "CUPS слушает порт 631"
else fail "порт 631" "не слушает (сеть HQ-CLI не подключится к CUPS)"; fi
fi
else skip "CUPS — не установлен (ПРОВЕРИТЬ пакет cups)"; fi
# --- 4. fail2ban: порт 2027, попыток 3, ban 60 c ---
if command -v fail2ban-client &>/dev/null; then
if root_or_skip "fail2ban-client статус"; then
if fail2ban-client status sshd &>/dev/null; then ok "fail2ban: jail sshd активен"
else fail "fail2ban sshd" "статус не получен: $(fail2ban-client status sshd 2>&1)"; fi
BT=$(fail2ban-client get sshd bantime 2>/dev/null)
expect_eq "fail2ban bantime" "$F2B_BANTIME" "$BT"
MR=$(fail2ban-client get sshd maxretry 2>/dev/null)
expect_eq "fail2ban maxretry" "$F2B_MAXRETRY" "$MR"
fi
if grep -Eq "port.*$F2B_SSH_PORT" "$F2B_JAIL" 2>/dev/null; then ok "jail использует порт $F2B_SSH_PORT"
else fail "fail2ban порт" "нет $F2B_SSH_PORT в $F2B_JAIL"; fi
else skip "fail2ban — не установлен (ПРОВЕРИТЬ пакет/репозиторий на РЕД ОС 8)"; fi
# --- 5. Служба резервного копирования (Кибер Бэкап) ---
if systemctl list-unit-files 2>/dev/null | grep -qiE "$BACKUP_SERVICE_PATTERN"; then
echo "[ИНФО] найдены службы: $(systemctl list-unit-files 2>/dev/null | grep -iE "$BACKUP_SERVICE_PATTERN" | awk '{print $1}' | tr '\n' ' ')"
SKIP=$((SKIP+1))
else fail "служба резервного копирования" "ничего не найдено по шаблону '$BACKUP_SERVICE_PATTERN' (ПРОВЕРИТЬ имя службы в QUESTIONS.md)"; fi
echo ""
echo "=== Проверить вручную ==="
echo " — единица бэкапа настроена (GUI Кибер Бэкап на HQ-SRV)"
echo " — бэкап директории /etc выполняется на узел HQ-CLI (скриншоты)"
echo ""
echo "=== Итог: OK=$OK FAIL=$FAIL ПРОПУЩЕНО=$SKIP ==="
[[ $FAIL -eq 0 ]]
}
main 2>&1 | tee "$LOG"
STATUS=${PIPESTATUS[0]}
echo "Лог сохранён: $LOG"
exit $STATUS

73
check/zadanie3/isp.sh Normal file
View file

@ -0,0 +1,73 @@
# ПРОВЕРКА ЗАДАНИЕ 3 — ISP: реверс-прокси, web-аутентификация
# Проверяем через curl на самом ISP (nginx слушает 80/443 на всех
# интерфейсах; доменные имена подставляем HOST-заголовком, т.к.
# собственный DNS ISP про локальные записи не знает).
# ============================================================
NAME="isp"
LOG="check_${NAME}_z3.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)); }
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; }
# ================= ПЕРЕМЕННЫЕ (заполните для проверки) =================
WEB_DOMAIN="web.au-team.irpo" # таблица 3
DOCKER_DOMAIN="docker.au-team.irpo" # таблица 3
WEB_LOGIN="WEB" # по заданию
WEB_PASS="P@ssw0rd" # по заданию
TLS_MODE="" # "https" — если прокси уже на 443, иначе пусто
TLS_CERT_FILE="" # путь к сертификату на ISP (для пункта 4)
main () {
echo "=== Проверка задания 3: ISP (реверс-прокси) ==="
# --- 1. Служба прокси ---
if [[ "$TLS_MODE" == "https" ]]; then
EXPECT_PORT="443"
else
EXPECT_PORT="80"
fi
if ss -tln 2>/dev/null | grep -q "80 "; then ok "сервер слушает порт 80"
else fail "порт 80" "не слушает (nginx?)"; fi
if [[ "$TLS_MODE" == "https" ]]; then
if ss -tln 2>/dev/null | grep -q "443 "; then ok "сервер слушает порт 443 (TLS)"
else fail "порт 443" "не слушает — TLS не настроен"; fi
fi
# --- 2. docker.au-team.irpo — открывается testapp (без пароля) ---
check_var "docker-домен" DOCKER_DOMAIN &&
{ CODE=$(curl -s -o /dev/null -w "%{http_code}" -H "Host: $DOCKER_DOMAIN" "http://127.0.0.1/" 2>/dev/null)
if grep -qE "^(200|301|302)$" <<<"$CODE"; then ok "$DOCKER_DOMAIN: testapp отвечает ($CODE)"
else fail "$DOCKER_DOMAIN" "ожидалось 200/301/302, получено '$CODE'"; fi; }
# --- 3. web.au-team.irpo — аутентификация: 401 без пароля, 200 с паролем ---
check_var "web-домен" WEB_DOMAIN &&
{ CODE=$(curl -s -o /dev/null -w "%{http_code}" -H "Host: $WEB_DOMAIN" "http://127.0.0.1/" 2>/dev/null)
if [[ "$CODE" == "401" ]]; then ok "$WEB_DOMAIN без пароля: 401 (требует аутентификации)"
else fail "$WEB_DOMAIN без пароля" "ожидалось 401, получено '$CODE'"; fi
CODE=$(curl -s -o /dev/null -w "%{http_code}" -u "$WEB_LOGIN:$WEB_PASS" -H "Host: $WEB_DOMAIN" "http://127.0.0.1/" 2>/dev/null)
if grep -qE "^(200|301|302)$" <<<"$CODE"; then ok "$WEB_DOMAIN c $WEB_LOGIN:$WEB_PASS: $CODE"
else fail "$WEB_DOMAIN с паролем" "ожидалось 200/301/302, получено '$CODE'"; fi; }
# --- 4. TLS-сертификаты (для режима https) ---
check_var "сертификат TLS" TLS_CERT_FILE &&
{ if openssl x509 -in "$TLS_CERT_FILE" -noout 2>/dev/null; then ok "tls cert поднят: $TLS_CERT_FILE"
else fail "TLS сертификат" "файл не читается: $TLS_CERT_FILE"; fi; }
echo ""
echo "=== Проверить вручную ==="
echo " — браузер клиента: https://web.au-team.irpo (без предупреждений, ввод логина)"
echo " — https://docker.au-team.irpo без предупреждений (снято на HQ-CLI/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

160
example.sh Normal file
View file

@ -0,0 +1,160 @@
#!/bin/bash
# Скрипт настройки BR-RTR (Linux): имя хоста, интерфейсы, NAT, маршрутизация
# Интерфейсы:
# enp0s3 - в сторону ISP (статический адрес, шлюз, DNS)
# enp0s8 - в сторону BR-FW (локальная сеть)
# Проверяем, запущен ли скрипт от root
if [[ $EUID -ne 0 ]]; then
echo "Этот скрипт должен быть запущен с правами root"
exit 1
fi
echo "=== Настройка BR-RTR ==="
# 1. Установка имени хоста
read -p "Введите имя хоста (например: br-rtr.au-team.irpo): " hostname
if [[ -n "$hostname" ]]; then
echo "Устанавливаем имя хоста: $hostname"
hostnamectl set-hostname "$hostname"
else
echo "Имя хоста не было введено, пропускаем этот шаг"
fi
echo ""
echo "=== Настройка сетевых интерфейсов ==="
# 2. Настройка enp0s8 (в сторону BR-FW)
echo "Настройка интерфейса enp0s8 (сторона BR-FW)"
read -p "Введите IP адрес для enp0s8 в формате адрес/префикс: " ip_enp0s8
if [[ -n "$ip_enp0s8" ]]; then
echo "Настраиваем enp0s8 с адресом: $ip_enp0s8"
# Создаем файл конфигурации для enp0s8
cat > /etc/NetworkManager/system-connections/enp0s8.nmconnection << EOF
[connection]
id=enp0s8
uuid=$(uuidgen)
type=ethernet
autoconnect-priority=-999
interface-name=enp0s8
timestamp=$(date +%s)
[ethernet]
[ipv4]
address1=$ip_enp0s8
method=manual
[ipv6]
addr-gen-mode=eui64
method=disabled
[proxy]
EOF
# Права 600 обязательны, иначе NetworkManager проигнорирует файл
chmod 600 /etc/NetworkManager/system-connections/enp0s8.nmconnection
fi
# 3. Настройка enp0s3 (в сторону ISP)
echo "Настройка интерфейса enp0s3 (сторона ISP)"
read -p "Введите через запятую: адрес/префикс,шлюз,DNS: " ip_enp0s3
if [[ -n "$ip_enp0s3" ]]; then
echo "Настраиваем enp0s3 со статическим адресом"
# Разбираем ввод: адрес/префикс,шлюз,DNS
IFS=',' read -ra ADDR <<< "$ip_enp0s3"
ip_with_mask="${ADDR[0]}"
gateway="${ADDR[1]}"
dns="${ADDR[2]}"
cat > /etc/NetworkManager/system-connections/enp0s3.nmconnection << EOF
[connection]
id=enp0s3
uuid=$(uuidgen)
type=ethernet
autoconnect-priority=-999
interface-name=enp0s3
timestamp=$(date +%s)
[ethernet]
[ipv4]
address1=$ip_with_mask
gateway=$gateway
dns=$dns
method=manual
[ipv6]
addr-gen-mode=eui64
method=disabled
[proxy]
EOF
chmod 600 /etc/NetworkManager/system-connections/enp0s3.nmconnection
fi
echo ""
echo "=== Перезапуск NetworkManager ==="
systemctl restart NetworkManager
sleep 3
echo ""
echo "=== Настройка iptables и маршрутизации ==="
# 4. Включение и запуск iptables
systemctl enable --now iptables
echo "Статус iptables:"
systemctl status iptables --no-pager
# 5. Очистка правил iptables и настройка NAT
# NAT делаем на выходе в сторону ISP (enp0s3) для всего, что уходит из локальных сетей
iptables -F
iptables -t nat -F
iptables -t nat -A POSTROUTING -o enp0s3 -j MASQUERADE
echo "Добавлено правило NAT (MASQUERADE) на интерфейсе enp0s3"
# 6. Сохранение правил iptables
service iptables save
# 7. Включение IP forwarding
# Пишем в отдельный файл с перезаписью (>), чтобы при повторном запуске строки не дублировались
echo "Включаем IP forwarding..."
echo "net.ipv4.ip_forward = 1" > /etc/sysctl.d/99-forwarding.conf
sysctl -p /etc/sysctl.d/99-forwarding.conf
echo ""
echo "=== Проверка настроек ==="
echo "Текущие правила iptables NAT:"
iptables -t nat -L POSTROUTING -n -v
echo ""
echo "Текущее состояние IP forwarding:"
sysctl net.ipv4.ip_forward
echo ""
echo "=== Тестирование соединения ==="
echo "Для проверки можно выполнить следующие команды:"
if [[ -n "$ip_enp0s3" ]]; then
ip1=$(echo "$ip_with_mask" | cut -d'/' -f1)
echo "ping ya.ru -I $ip1"
fi
if [[ -n "$ip_enp0s8" ]]; then
ip2=$(echo "$ip_enp0s8" | cut -d'/' -f1)
echo "ping ya.ru -I $ip2"
fi
echo ""
read -p "Выполнить перезагрузку сейчас? (y/n): " reboot_now
if [[ "$reboot_now" == "y" || "$reboot_now" == "Y" ]]; then
echo "Перезагружаем систему..."
reboot
else
echo "Настройка завершена. Перезагрузите систему для применения всех изменений."
echo "Используйте команду: reboot"
fi

306
tasks.md Normal file
View file

@ -0,0 +1,306 @@
# КИМ 09.02.06-3-2027 — задания демонстрационного экзамена
Специальность 09.02.06 «Сетевое и системное администрирование», квалификация «Системный администратор (Эксплуатация объектов сетевой инфраструктуры)».
Источник: Спецификация КИМ ДЭ, Том 1 (инвариантная часть), образец заданий для ГИА ДЭ БУ. Образец задания 1 для ПА совпадает с заданием 1 ниже. Топология, таблица ВМ и требования к отчёту здесь опущены, остались только сами задания.
Время: задание 1 — 1 ч 00 мин, задание 2 — 1 ч 00 мин, задание 3 — 1 ч 30 мин. Всего 3 ч 30 мин.
---
# Задание 1. Настройка сетевой инфраструктуры
Необходимо разработать и настроить инфраструктуру информационно-коммуникационной системы согласно предложенной топологии (рисунок 1).
Задание включает базовую настройку устройств:
- присвоение имён устройствам;
- расчёт IP-адресации;
- настройку коммутации и маршрутизации.
В ходе проектирования и настройки сетевой инфраструктуры следует вести отчёт о своих действиях, включая таблицы и схемы, предусмотренные в задании.
## 1. Произведите базовую настройку устройств
- Настройте имена устройств согласно топологии. Используйте полное доменное имя, используйте таблицу 3, поле «Запись».
- На всех устройствах необходимо сконфигурировать IPv4:
- IP-адрес должен быть из приватного диапазона;
- локальная сеть в сторону HQ-SRV (VLAN 100): выделить сеть размером не более 32 адресов;
- локальная сеть в сторону HQ-CLI (VLAN 200): выделить сеть размером не более 16 адресов;
- локальная сеть для управления (VLAN 999): выделить сеть размером не более 8 адресов;
- между BR-FW и BR-RTR настройте сеть с минимально возможной маской подсети;
- в локальной сети в сторону BR-SRV необходимо выделить сеть из сети размером не более 16 адресов;
- сведения об адресах занесите в таблицу 2 (в качестве примера используйте Приложение 3).
## 2. Настройте доступ к сети Интернет на маршрутизаторе ISP
- Настройте адресацию на интерфейсах:
- интерфейс, подключённый к магистральному провайдеру, получает адрес по DHCP;
- настройте маршрут по умолчанию, DNS-сервер, если это необходимо;
- интерфейс в сторону HQ-RTR: подключён к сети 172.16.1.0/28;
- интерфейс в сторону BR-RTR: подключён к сети 172.16.2.0/28;
- на ISP настройте динамическую сетевую трансляцию портов для доступа к сети Интернет HQ-RTR и BR-RTR.
## 3. Создайте локальные учётные записи
На серверах HQ-SRV и BR-SRV создайте пользователя **sshuser**:
- пароль `P@ssw0rd`;
- идентификатор пользователя `2027`;
- пользователь sshuser должен иметь возможность запускать sudo без ввода пароля.
На маршрутизаторах HQ-RTR и BR-RTR создайте пользователя **net_admin**:
- пароль `P@ssw0rd`;
- при настройке ОС на базе Linux: запускать sudo без ввода пароля;
- при настройке ОС, отличных от Linux: пользователь должен обладать максимальными привилегиями.
## 4. Настройте коммутацию в сегменте HQ
- Трафик HQ-SRV должен принадлежать VLAN 100.
- Трафик HQ-CLI должен принадлежать VLAN 200.
- Предусмотреть возможность передачи трафика управления в VLAN 999.
- Реализовать на HQ-RTR маршрутизацию трафика всех указанных VLAN с использованием одного сетевого адаптера ВМ / физического порта.
- Сведения о настройке коммутации внесите в отчёт.
## 5. Настройте безопасный удалённый доступ на HQ-SRV и BR-SRV
- Для подключения используйте порт `2027`.
- Разрешите подключения исключительно пользователю sshuser.
- Ограничьте количество попыток входа до двух.
- Настройте баннер «Authorized access only».
## 6. IP-туннель между офисами HQ и BR
На маршрутизаторах HQ-RTR и BR-RTR сконфигурируйте IP-туннель:
- используйте протокол GRE;
- в качестве сетевого диапазона используйте сеть 10.10.10.0/24;
- для туннеля используйте минимально возможную маску подсети;
- сведения о туннеле занесите в отчёт.
## 7. Динамическая маршрутизация
Обеспечьте динамическую маршрутизацию на маршрутизаторах HQ-RTR и BR-RTR и межсетевом экране BR-FW. Сети одного офиса должны быть доступны из другого офиса и наоборот.
- Разрешите выбранный протокол только на интерфейсах туннеля на HQ-RTR и BR-RTR. На BR-FW используйте в OSPF только интерфейс в сторону BR-RTR.
- Используйте OSPF.
- Используйте аутентификацию в OSPF на маршрутизаторах HQ-RTR и BR-RTR:
- в качестве пароля используйте `P@ssw0rd`;
- пароль должен передаваться с использованием хешированного ключа MD5.
- Сведения о настройке и защите протокола занесите в отчёт.
## 8. Динамическая трансляция адресов на HQ-RTR и BR-RTR
Настройте динамическую трансляцию адресов для обоих офисов в сторону ISP. Все устройства в офисах должны иметь доступ к сети Интернет.
## 9. DHCP для сети в сторону HQ-CLI
- Настройте нужную подсеть.
- В качестве сервера DHCP выступает маршрутизатор HQ-RTR.
- Клиентом является машина HQ-CLI.
- Исключите из выдачи адрес маршрутизатора.
- Адрес шлюза по умолчанию: адрес маршрутизатора HQ-RTR.
- Адрес DNS-сервера для HQ-CLI: адрес сервера HQ-SRV.
- DNS-суффикс: `au-team.irpo`.
- Сведения о настройке протокола занесите в отчёт.
## 10. Инфраструктура разрешения доменных имён для офисов HQ и BR
- Основной DNS-сервер реализован на HQ-SRV.
- Сервер должен обеспечивать разрешение имён в сетевые адреса устройств и обратно в соответствии с таблицей 3.
- В качестве DNS-сервера пересылки используйте любой общедоступный DNS-сервер (77.88.8.7, 77.88.8.3 или другие).
## 11. Часовой пояс
Настройте часовой пояс на всех устройствах (за исключением виртуального коммутатора, в случае его использования) согласно месту проведения экзамена. На всех устройствах, кроме HQ-SW, выполните настройку часового пояса согласно месту проведения экзамена.
### Таблица 2 (заполняется участником)
| Имя устройства | IP-адрес | Шлюз по умолчанию |
|---|---|---|
| HQ-RTR | | |
| BR-RTR | | |
| HQ-SRV | | |
| HQ-CLI | | |
| BR-SRV | | |
| BR-FW | | |
### Таблица 3. DNS-записи
| Устройство | Запись | Тип |
|---|---|---|
| HQ-RTR | hq-rtr.au-team.irpo | A |
| BR-RTR | br-rtr.au-team.irpo | A |
| BR-FW | br-fw.au-team.irpo | A |
| HQ-SRV | hq-srv.au-team.irpo | A, PTR |
| HQ-CLI | hq-cli.au-team.irpo | A |
| BR-SRV | br-srv.au-team.irpo | A, PTR |
| ISP (интерфейс в сторону HQ-RTR) | docker.au-team.irpo | A |
| ISP (интерфейс в сторону BR-RTR) | web.au-team.irpo | A |
**Необходимые приложения:**
Прил_1_ОЗ_КИМ_09.02.06-3-2027.docx, Прил_2_ОЗ_КИМ_09.02.06-3-2027.docx, Прил_3_ОЗ_КИМ_09.02.06-3-2027.docx, Прил_4_ОЗ_КИМ_09.02.06-3-2027.docx
---
# Задание 2. Организация сетевого администрирования операционных систем
Необходимо разработать и настроить инфраструктуру информационно-коммуникационной системы согласно предложенной топологии (рисунок 2).
Для задания 2 используется **отдельный стенд**. Инструкция по настройке стенда для технических администраторов площадки находится в отдельном файле.
**В стенде преднастроены:**
- контроллер домена samba-dc на сервере BR-SRV. Контроллер домена установлен и функционирует, учётных записей компьютеров, подразделений, пользователей нет;
- IP-адреса, маски подсетей и шлюзы по умолчанию;
- сетевая трансляция адресов;
- IP-туннель;
- динамическая маршрутизация;
- созданы пользователи sshuser на серверах и net_admin на маршрутизаторах, им предоставлены административные привилегии;
- порты ssh на серверах;
- DHCP-сервер;
- DNS-сервер;
- сервер HQ-SRV имеет два дополнительных накопителя размером 1 ГБ.
## 1. Настройте контроллер домена Samba DC на BR-SRV
- Введите в созданный домен машину HQ-CLI.
- Создайте 5 пользователей для офиса HQ: имена формата hquser№ (hquser1, hquser2 и т.д.), политика паролей:
- минимальная длина пароля 8 символов;
- блокировка учётной записи после 5 неудачных попыток входа.
- Создайте группу hq, введите в группу созданных пользователей.
- Убедитесь, что пользователи группы hq имеют право аутентифицироваться на HQ-CLI.
- Пользователи группы hq должны иметь возможность повышать привилегии для выполнения ограниченного набора команд: `cat`, `grep`, `id`. Запускать другие команды с повышенными привилегиями пользователи группы права не имеют.
## 2. Файловое хранилище на HQ-SRV
- При помощи двух подключённых к серверу дополнительных дисков размером 1 Гб сконфигурируйте дисковый массив уровня 0.
- Имя устройства: `md0`. При необходимости конфигурация массива размещается в файле `/etc/mdadm.conf`.
- Создайте и отформатируйте раздел, в качестве файловой системы используйте ext4.
- Обеспечьте автоматическое монтирование в папку `/raid`.
## 3. Сервер сетевой файловой системы (NFS) на HQ-SRV
- В качестве папки общего доступа выберите `/raid/nfs`. Доступ для чтения и записи исключительно для сети в сторону HQ-CLI.
- На HQ-CLI настройте автомонтирование в папку `/mnt/nfs`.
- Основные параметры сервера отметьте в отчёте.
## 4. Служба сетевого времени chrony на маршрутизаторе ISP
- Вышестоящий NTP-сервер на ISP: на выбор участника.
- Стратум сервера: 5.
- В качестве клиентов NTP настройте: HQ-SRV, HQ-CLI, BR-RTR, BR-SRV.
## 5. Ansible на сервере BR-SRV
- Сформируйте файл инвентаря. В инвентарь должны входить HQ-SRV, HQ-CLI, HQ-RTR и BR-RTR.
- Рабочий каталог ansible должен располагаться в `/etc/ansible`.
- Все указанные машины должны без предупреждений и ошибок отвечать `pong` на команду ping в ansible, посланную с BR-SRV.
## 6. Веб-приложение в docker на BR-SRV
- Средствами docker должен создаваться стек контейнеров с веб-приложением и базой данных.
- Используйте образы `site_latest` и `mariadb_latest`, располагающиеся в директории `docker` в образе Additional.iso.
- В качестве docker-файла используйте файл `compose.yaml`, который располагается в образе Additional.iso.
- Приложение testapp, развёрнутое через docker, доступно для внешних подключений через порт 8080.
## 7. Веб-приложение на HQ-SRV
- Используйте веб-сервер apache.
- В качестве СУБД используйте mariadb.
- Файлы веб-приложения и дамп базы данных находятся в директории `web` образа Additional.iso.
- Выполните импорт схемы и данных из файла `dump.sql` в базу данных `webdb`.
- Создайте пользователя `web` с паролем `P@ssw0rd` и предоставьте ему права доступа к этой базе данных.
- Файлы `index.php` и `logo.png` скопируйте в корневой каталог сайта.
- В файле `index.php` укажите правильные учётные данные для подключения к БД.
- Запустите веб-сервер и убедитесь в работоспособности приложения.
- Основные параметры отметьте в отчёте.
## 8. Статическая трансляция портов на маршрутизаторах
- Пробросьте порт 8080 в порт приложения testapp BR-SRV на маршрутизаторе BR-RTR, для работы testapp извне.
- Пробросьте порт 8080 в порт веб-приложения на HQ-SRV на маршрутизаторе HQ-RTR, для работы веб-приложения извне.
- Пробросьте порт 2027 на HQ-RTR в порт 2027 сервера HQ-SRV, для подключения по ssh из внешних сетей.
- Пробросьте порт 2027 на BR-RTR в порт 2027 сервера BR-SRV, для подключения по ssh из внешних сетей.
## 9. Яндекс Браузер на HQ-CLI
Удобным способом установите приложение Яндекс Браузер на HQ-CLI. Установку браузера отметьте в отчёте.
**Необходимые приложения:** Прил_5_ОЗ_КИМ_09.02.06-3-2027.txt
---
# Задание 3. Эксплуатация объектов сетевой инфраструктуры
Необходимо разработать и настроить инфраструктуру информационно-коммуникационной системы согласно предложенной топологии (рисунок 3).
Задание 3 содержит: создание пользователей с помощью сценария, развёртывание и настройку центра сертификации, выдачу сертификатов веб-серверам для шифрования трафика, принт-сервер, сервер логирования и мониторинга, автоматизацию на основе инфраструктуры открытых ключей, защиту протокола ssh от перебора, настройку программного обеспечения для создания архивных копий.
В ходе проектирования и настройки сетевой инфраструктуры следует заносить записи в отчёт о своих действиях, когда это требуется в задании.
## 1. Импорт пользователей в домен au-team.irpo
- Скрипт `import.sh` располагается в корневой директории образа Additional.iso.
- В качестве файла-источника выберите файл `users.csv`, располагающийся в образе Additional.iso.
- Пользователи должны быть импортированы со своими паролями и другими атрибутами.
- Убедитесь, что импортированные пользователи могут войти на машину HQ-CLI.
## 2. Обратный прокси-сервер на маршрутизаторе ISP
- При обращении по доменному имени `web.au-team.irpo` у клиента должно открываться веб-приложение на HQ-SRV.
- При обращении по доменному имени `docker.au-team.irpo` у клиента должно открываться веб-приложение testapp.
## 3. Web-based аутентификация на маршрутизаторе ISP
При обращении к сайту `web.au-team.irpo` клиенту должно быть предложено ввести аутентификационные данные:
- в качестве логина выберите `WEB` с паролем `P@ssw0rd`;
- при успешной аутентификации клиент должен перейти на веб-сайт.
## 4. Центр сертификации на базе HQ-SRV
- Рекомендуется использовать отечественные алгоритмы шифрования.
- Сертификаты выдаются на 30 дней.
- Обеспечьте доверие сертификату для HQ-CLI.
- Выдайте сертификаты веб-серверам.
- Перенастройте ранее настроенный реверсивный прокси на протокол https.
- При обращении к `https://web.au-team.irpo` и `https://docker.au-team.irpo` у браузера клиента не должно возникать предупреждений.
## 5. atop на HQ-SRV
- Установите и настройте утилиту atop.
- Сервис должен вести непрерывный мониторинг состояния сервера (процессор, оперативная память, дисковые операции, сетевые подключения) с интервалом сбора данных **7 минут**.
## 6. Принт-сервер cups на HQ-SRV
- Опубликуйте виртуальный pdf-принтер.
- На клиенте HQ-CLI подключите виртуальный принтер как принтер по умолчанию.
## 7. Инвентаризация HQ-SRV и HQ-CLI через Ansible на BR-SRV
- Плейбук должен собирать информацию о рабочих местах:
- имя компьютера;
- IP-адрес компьютера.
- Плейбук должен быть размещён в директории `/etc/ansible`, отчёты в поддиректории `PC-INFO`, в формате `.yml`. Файлы должны называться именем компьютера, который был инвентаризирован.
- Файл плейбука располагается в образе Additional.iso в директории `playbook`.
## 8. fail2ban на HQ-SRV для защиты ssh
- Укажите порт ssh.
- При 3 неуспешных авторизациях адрес атакующего попадает в бан.
- Бан производится на 1 минуту.
## 9. Резервное копирование директории сервера HQ-SRV
- На HQ-SRV развернуть программное обеспечение для резервного копирования и восстановления данных с защитой от вирусов-шифровальщиков.
- Рекомендуется использовать Кибер Бэкап версии 18 или аналог, совпадающий по функционалу.
- Настройте подразделение `irpo`.
- Настройте пользователя с правами администратора: имя `irpoadmin`, пароль `P@ssw0rd`.
- Установите на HQ-CLI агент с функциями узла хранилища и подключите его к серверу управления.
- На узле хранилища HQ-CLI создайте директорию `/backup` и выберите её в качестве устройства хранения.
- Создайте план резервного копирования для сервера HQ-SRV: копирование директории `/etc` и всех её поддиректорий.
- Выполните резервное копирование директории `/etc` и всех её поддиректорий сервера HQ-SRV на узел хранения HQ-CLI.
**Необходимые приложения:** Прил_6_ОЗ_КИМ_09.02.06-3-2027.txt

110
tools/subnet-calc.sh Normal file
View file

@ -0,0 +1,110 @@
#!/bin/bash
# ============================================================
# Калькулятор подсетей для экзамена 09.02.06 (python3 + ipaddress)
#
# ЗАПУСК:
# bash tools/subnet-calc.sh <базовая_сеть> [имя=ЧИСЛО ...]
#
# ЧИСЛО — это АДРЕСА, а не хосты: считаются адрес сети и broadcast.
# Если нужен именно объём ХОСТОВ — добавьте суффикс h, например:
# srv=30 -> 30 адресов (включая сеть и broadcast)
# srv=28h -> 28 хостов + 2 спецадреса = 30 адресов
#
# ПРИМЕР (адреса подбираются последовательно из базовой сети):
# bash tools/subnet-calc.sh 10.0.0.0/24 hq_srv=32 hq_cli=16 mgmt=8 br_srv=16 br_link=2
#
# Для туннеля и линка BR-FW<->BR-RTR достаточно 2 адресов хостов:
# link=2 -> маска /30 (4 адреса: сеть, 2 хоста, broadcast)
#
# Пример вывода готовой таблицы — просто скопировать в отчёт (таблица 2).
# ============================================================
if ! command -v python3 >/dev/null 2>&1; then
echo "Нужен python3. Установите: dnf install -y python3"
exit 1
fi
python3 - "$@" <<'PY'
import sys
import ipaddress
def usage_and_exit():
print("Использование: subnet-calc.sh <базовая_сеть> [имя=число_адресов ...]")
print("Суффикс h означает число ХОСТОВ (например srv=28h -> 28 хостов).")
sys.exit(1)
def parse_size(value):
value = value.strip().lower()
hosts = value.endswith("h")
if hosts:
value = value[:-1]
try:
count = int(value)
except ValueError:
usage_and_exit()
if count < 1:
usage_and_exit()
need = count + 2 if hosts else count
return count, need
def main():
if len(sys.argv) < 2:
usage_and_exit()
try:
base = ipaddress.ip_network(sys.argv[1], strict=False)
except ValueError:
print("Некорректная базовая сеть:", sys.argv[1])
usage_and_exit()
print("Базовая сеть:", base, "| всего адресов:", base.num_addresses)
print()
cursor = int(base.network_address)
last = int(base.broadcast_address)
rows = []
overflow = False
for item in sys.argv[2:]:
name, sep, raw = item.partition("=")
if not sep:
print("Ошибка: параметр без '=' ->", item)
usage_and_exit()
count, need = parse_size(raw)
prefix = base.max_prefixlen - (need - 1).bit_length()
# Выравниваем начало подсети по границе новой маски
step = 1 << (base.max_prefixlen - prefix)
cursor = (cursor + step - 1) // step * step
net = ipaddress.ip_network((cursor, prefix), strict=False)
if int(net.broadcast_address) > last:
overflow = True
rows.append([
name,
str(net.network_address) + "/" + str(prefix),
str(net.netmask),
str(net.network_address + 1) if need > 2 else str(net.network_address),
str(net.broadcast_address - 1) if need > 2 else str(net.broadcast_address),
str(net.broadcast_address),
str(net.num_addresses),
])
cursor = int(net.broadcast_address) + 1
if overflow:
print("ВНИМАНИЕ: подсетей не хватило внутри базовой сети!")
print()
headers = ["Назначение", "Сеть", "Маска", "Первый хост", "Последний хост",
"Broadcast", "Адресов"]
widths = [max(len(headers[i]), max(len(r[i]) for r in rows)) for i in range(len(headers))]
line = "-+-".join("-" * w for w in widths)
print(" | ".join(h.ljust(w) for h, w in zip(headers, widths)))
print(line)
for row in rows:
print(" | ".join(c.ljust(w) for c, w in zip(row, widths)))
main()
PY

162
zadanie1/br-fw.sh Normal file
View file

@ -0,0 +1,162 @@
#!/bin/bash
# ============================================================
# ЗАДАНИЕ 1. Настройка BR-FW
# ------------------------------------------------------------
# ВНИМАНИЕ: СИСТЕМА BR-FW НЕИЗВЕСТНА (УТОЧНИТЬ, что за система).
# Скрипт написан В ПРЕДПОЛОЖЕНИИ Linux / РЕД ОС 8. Если на стенде
# BR-FW — не Linux, используйте MANUAL.md и настраивайте по-своему.
# ------------------------------------------------------------
# Имя, интерфейсы (к BR-RTR: сеть /30, к BR-SRV: сеть <=16 адресов),
# маршрут по умолчанию через BR-RTR, OSPF (только интерфейс к BR-RTR),
# IP forwarding, часовой пояс.
# NAT для офиса BR НЕ настраивается — NAT делает BR-RTR.
# ============================================================
# --- Проверка прав root ---
if [[ $EUID -ne 0 ]]; then
echo "Запустите скрипт с правами root (sudo bash br-fw.sh)"
exit 1
fi
# ================= ПЕРЕМЕННЫЕ (заполните перед запуском) =================
HOSTNAME_FQDN="br-fw.au-team.irpo" # таблица 3, запись br-fw.au-team.irpo
# --- Интерфейс в сторону BR-RTR (сеть с минимально возможной маской /30) ---
BR_RTR_IF="" # интерфейс к BR-RTR
BR_RTR_ADDR="" # адрес BR-FW в этой сети, формат адрес/префикс (/30)
BR_RTR_GW="" # адрес BR-RTR в этой же сети — маршрут по умолчанию
# --- Интерфейс в сторону BR-SRV (сеть не более 16 адресов) ---
BR_SRV_IF="" # интерфейс к BR-SRV
BR_SRV_ADDR="" # адрес BR-FW в этой сети, формат адрес/префикс
# --- OSPF (протокол разрешён ТОЛЬКО на интерфейсе к BR-RTR; пароля нет —
# аутентификация по заданию требуется только на туннеле HQ<->BR) ---
OSPF_AREA="0.0.0.0"
# ПРОВЕРИТЬ на РЕД ОС 8: пакет, конфиг и службу OSPF (frr / quagga)
FRR_PACKAGE="frr"
FRR_CONF="/etc/frr/frr.conf"
FRR_DAEMONS="/etc/frr/daemons"
DNS_FW="" # внешний DNS для BR-FW (необязательно, например 77.88.8.7)
# --- Прочее ---
EXAM_TZ="Europe/Moscow" # проверить на экзамене
FORWARD_CONF="/etc/sysctl.d/99-ip-forward.conf" # перезаписывается целиком
NM_CONF_DIR="/etc/NetworkManager/system-connections"
# ============ Проверка заполнения переменных ============
MISSING=()
for NAME in HOSTNAME_FQDN BR_RTR_IF BR_RTR_ADDR BR_RTR_GW BR_SRV_IF \
BR_SRV_ADDR EXAM_TZ; do
[[ -z "${!NAME}" ]] && MISSING+=("$NAME")
done
if [[ ${#MISSING[@]} -gt 0 ]]; then
echo "Заполните переменные в начале скрипта: ${MISSING[*]}"
exit 1
fi
echo "=== Настройка BR-FW (предположение: Linux / РЕД ОС 8) ==="
# --- 1. Имя хоста ---
hostnamectl set-hostname "$HOSTNAME_FQDN"
echo "Имя хоста: $(hostname)"
# --- 2. Интерфейс в сторону BR-RTR (+ маршрут по умолчанию) ---
echo "--- Профиль $BR_RTR_IF (статика, шлюз $BR_RTR_GW) ---"
cat > "$NM_CONF_DIR/$BR_RTR_IF.nmconnection" <<EOF
[connection]
id=$BR_RTR_IF
type=ethernet
autoconnect=yes
interface-name=$BR_RTR_IF
[ethernet]
[ipv4]
address1=$BR_RTR_ADDR
gateway=$BR_RTR_GW
method=manual
[ipv6]
method=disabled
[proxy]
EOF
chmod 600 "$NM_CONF_DIR/$BR_RTR_IF.nmconnection"
# --- 3. Интерфейс в сторону BR-SRV ---
echo "--- Профиль $BR_SRV_IF (статика) ---"
cat > "$NM_CONF_DIR/$BR_SRV_IF.nmconnection" <<EOF
[connection]
id=$BR_SRV_IF
type=ethernet
autoconnect=yes
interface-name=$BR_SRV_IF
[ethernet]
[ipv4]
address1=$BR_SRV_ADDR
method=manual
[ipv6]
method=disabled
[proxy]
EOF
chmod 600 "$NM_CONF_DIR/$BR_SRV_IF.nmconnection"
nmcli connection reload
nmcli connection up "$BR_RTR_IF" || echo "ВНИМАНИЕ: не поднялся $BR_RTR_IF"
nmcli connection up "$BR_SRV_IF" || echo "ВНИМАНИЕ: не поднялся $BR_SRV_IF"
# --- 4. IP forwarding (BR-FW пересылает трафик BR-SRV в сторону BR-RTR) ---
echo "net.ipv4.ip_forward = 1" > "$FORWARD_CONF"
sysctl -p "$FORWARD_CONF"
# --- 5. OSPF: рекламируем обе сети BR, но HELLO только на линке к BR-RTR ---
echo "--- OSPF (${FRR_PACKAGE}) ---"
dnf install -y "$FRR_PACKAGE" || echo "ПРОВЕРИТЬ: пакет $FRR_PACKAGE не установился"
LINK_NET=$(python3 -c "import ipaddress,sys; print(ipaddress.ip_network(sys.argv[1], strict=False))" "$BR_RTR_ADDR")
SRV_NET=$(python3 -c "import ipaddress,sys; print(ipaddress.ip_network(sys.argv[1], strict=False))" "$BR_SRV_ADDR")
cat > "$FRR_CONF" <<EOF
frr version 8
frr defaults traditional
hostname $(hostname -s)
service integrated-vtysh-config
!
router ospf
passive-interface default
no passive-interface $BR_RTR_IF
network $LINK_NET area $OSPF_AREA
network $SRV_NET area $OSPF_AREA
!
EOF
if [[ -f "$FRR_DAEMONS" ]]; then
sed -ri 's/^zebra=.*/zebra=yes/; s/^ospfd=.*/ospfd=yes/' "$FRR_DAEMONS"
fi
systemctl enable --now "$FRR_PACKAGE" || echo "ПРОВЕРИТЬ: служба $FRR_PACKAGE не запустилась"
# --- 6. DNS (если нужно BR-FW) ---
if [[ -n "$DNS_FW" ]]; then
if grep -q "^nameserver" /etc/resolv.conf 2>/dev/null; then
echo "DNS уже прописан: $(grep '^nameserver' /etc/resolv.conf)"
else
echo "nameserver $DNS_FW" > /etc/resolv.conf
fi
fi
# --- 7. Часовой пояс ---
timedatectl set-timezone "$EXAM_TZ"
echo ""
echo "=== Самопроверка для BR-FW ==="
ip -4 -br address show
echo ""
echo "Маршруты:"
ip route show
echo ""
echo "Дополнительные проверки вручную:"
echo " vtysh -c 'show ip ospf neighbor' (сосед BR-RTR в FULL?)"
echo " ping -c2 $BR_RTR_GW (BR-RTR доступен?)"
echo " ping -c2 77.88.8.7 (Интернет через BR-RTR, у BR-RTR NAT)"

217
zadanie1/br-rtr.sh Normal file
View file

@ -0,0 +1,217 @@
#!/bin/bash
# ============================================================
# ЗАДАНИЕ 1. Настройка BR-RTR (Linux / РЕД ОС 8)
# Имя, net_admin, интерфейсы (к ISP и к BR-FW: сеть /30),
# GRE-туннель до HQ-RTR, OSPF (MD5), NAT, часовой пояс.
# ============================================================
# --- Проверка прав root ---
if [[ $EUID -ne 0 ]]; then
echo "Запустите скрипт с правами root (sudo bash br-rtr.sh)"
exit 1
fi
# ================= ПЕРЕМЕННЫЕ (заполните перед запуском) =================
HOSTNAME_FQDN="br-rtr.au-team.irpo" # таблица 3, запись br-rtr.au-team.irpo
# --- Пользователь net_admin (значения из задания) ---
NET_ADMIN_USER="net_admin"
NET_ADMIN_PASS="P@ssw0rd"
# --- Интерфейс в сторону ISP ---
ISP_IF="" # интерфейс к ISP (пример: enp0s3)
ISP_NET="" # адрес BR-RTR в этой сети, формат адрес/префикс
# (по заданию сеть 172.16.2.0/28)
ISP_GW="" # шлюз по умолчанию — адрес ISP в этой же сети
DNS_ROUTER="" # внешний DNS для роутера (необязательно, например 77.88.8.7)
# --- Интерфейс в сторону BR-FW (сеть с минимально возможной маской) ---
BR_LINK_IF="" # интерфейс к BR-FW (пример: enp0s8)
BR_LINK_ADDR="" # адрес BR-RTR в этой сети, адрес/префикс (маска /30 — см. калькулятор)
# --- Локальная сеть в сторону BR-SRV (через BR-FW; не более 16 адресов) ---
# Нужна только для правил NAT — адрес BR-RTR здесь назначает BR-FW.
NAT_NETS="" # через пробел, например: "<сеть к BR-FW/префикс> <сеть BR-SRV/префикс>"
# --- GRE-туннель до HQ-RTR (сеть 10.10.10.0/24, минимальная маска -> /30) ---
GRE_IF="gre1"
GRE_LOCAL="" # локальный конец туннеля, адрес/префикс (из калькулятора, /30)
GRE_REMOTE="" # удалённый конец — адрес HQ-RTR в сети ISP (без префикса)
# --- OSPF (значения из задания) ---
OSPF_PASSWORD="P@ssw0rd"
OSPF_AREA="0.0.0.0"
# ПРОВЕРИТЬ на РЕД ОС 8: пакет, конфиг и службу OSPF (frr / quagga)
FRR_PACKAGE="frr"
FRR_CONF="/etc/frr/frr.conf"
FRR_DAEMONS="/etc/frr/daemons"
# --- Прочее ---
EXAM_TZ="Europe/Moscow" # проверить на экзамене
FORWARD_CONF="/etc/sysctl.d/99-ip-forward.conf" # перезаписывается целиком
NM_CONF_DIR="/etc/NetworkManager/system-connections"
IPTABLES_SERVICE="iptables" # ПРОВЕРИТЬ
# ============ Проверка заполнения переменных ============
MISSING=()
for NAME in HOSTNAME_FQDN ISP_IF ISP_NET ISP_GW BR_LINK_IF BR_LINK_ADDR \
NAT_NETS GRE_LOCAL GRE_REMOTE EXAM_TZ; do
[[ -z "${!NAME}" ]] && MISSING+=("$NAME")
done
if [[ ${#MISSING[@]} -gt 0 ]]; then
echo "Заполните переменные в начале скрипта: ${MISSING[*]}"
exit 1
fi
echo "=== Настройка BR-RTR ==="
# --- 1. Имя хоста ---
hostnamectl set-hostname "$HOSTNAME_FQDN"
echo "Имя хоста: $(hostname)"
# --- 2. Пользователь net_admin с sudo без пароля ---
echo "--- Пользователь $NET_ADMIN_USER ---"
if id "$NET_ADMIN_USER" &>/dev/null; then
echo "Пользователь уже существует"
else
useradd -m "$NET_ADMIN_USER"
fi
echo "$NET_ADMIN_USER:$NET_ADMIN_PASS" | chpasswd
echo "$NET_ADMIN_USER ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/net_admin
chmod 440 /etc/sudoers.d/net_admin
# --- 3. Интерфейс в сторону ISP ---
echo "--- Профиль $ISP_IF (статика, шлюз $ISP_GW) ---"
cat > "$NM_CONF_DIR/$ISP_IF.nmconnection" <<EOF
[connection]
id=$ISP_IF
type=ethernet
autoconnect=yes
interface-name=$ISP_IF
[ethernet]
[ipv4]
address1=$ISP_NET
gateway=$ISP_GW
method=manual
[ipv6]
method=disabled
[proxy]
EOF
chmod 600 "$NM_CONF_DIR/$ISP_IF.nmconnection"
# --- 4. Интерфейс в сторону BR-FW ---
echo "--- Профиль $BR_LINK_IF (статика, /30) ---"
cat > "$NM_CONF_DIR/$BR_LINK_IF.nmconnection" <<EOF
[connection]
id=$BR_LINK_IF
type=ethernet
autoconnect=yes
interface-name=$BR_LINK_IF
[ethernet]
[ipv4]
address1=$BR_LINK_ADDR
method=manual
[ipv6]
method=disabled
[proxy]
EOF
chmod 600 "$NM_CONF_DIR/$BR_LINK_IF.nmconnection"
# --- 5. GRE-туннель до HQ-RTR ---
echo "--- Туннель $GRE_IF ---"
cat > "$NM_CONF_DIR/$GRE_IF.nmconnection" <<EOF
[connection]
id=$GRE_IF
type=ip-tunnel
autoconnect=yes
interface-name=$GRE_IF
[ip-tunnel]
mode=gre
remote=$GRE_REMOTE
[ipv4]
address1=$GRE_LOCAL
method=manual
[ipv6]
method=disabled
[proxy]
EOF
chmod 600 "$NM_CONF_DIR/$GRE_IF.nmconnection"
nmcli connection reload
for C in "$ISP_IF" "$BR_LINK_IF" "$GRE_IF"; do
nmcli connection up "$C" || echo "ВНИМАНИЕ: не поднялся профиль $C"
done
# --- 6. IP forwarding ---
echo "net.ipv4.ip_forward = 1" > "$FORWARD_CONF"
sysctl -p "$FORWARD_CONF"
# --- 7. NAT в сторону ISP ---
echo "--- NAT (MASQUERADE) ---"
for SRC_NET in $NAT_NETS; do
if iptables -t nat -C POSTROUTING -s "$SRC_NET" -o "$ISP_IF" -j MASQUERADE 2>/dev/null; then
echo "Правило для $SRC_NET уже есть"
else
iptables -t nat -A POSTROUTING -s "$SRC_NET" -o "$ISP_IF" -j MASQUERADE
echo "Добавлено MASQUERADE для $SRC_NET"
fi
done
iptables-save > /etc/sysconfig/iptables
systemctl enable --now "$IPTABLES_SERVICE" 2>/dev/null \
|| echo "ПРОВЕРИТЬ: служба $IPTABLES_SERVICE не запустилась"
# --- 8. OSPF: туннель (MD5) + интерфейс к BR-FW (сосед BR-FW) ---
echo "--- OSPF (${FRR_PACKAGE}) ---"
dnf install -y "$FRR_PACKAGE" || echo "ПРОВЕРИТЬ: пакет $FRR_PACKAGE не установился"
TUN_NET=$(python3 -c "import ipaddress,sys; print(ipaddress.ip_network(sys.argv[1], strict=False))" "$GRE_LOCAL")
LINK_NET=$(python3 -c "import ipaddress,sys; print(ipaddress.ip_network(sys.argv[1], strict=False))" "$BR_LINK_ADDR")
cat > "$FRR_CONF" <<EOF
frr version 8
frr defaults traditional
hostname $(hostname -s)
service integrated-vtysh-config
!
router ospf
passive-interface default
no passive-interface $GRE_IF
no passive-interface $BR_LINK_IF_SHORT
network $TUN_NET area $OSPF_AREA
network $LINK_NET area $OSPF_AREA
!
interface $GRE_IF
ip ospf authentication message-digest
ip ospf message-digest-key 1 md5 $OSPF_PASSWORD
!
EOF
if [[ -f "$FRR_DAEMONS" ]]; then
sed -ri 's/^zebra=.*/zebra=yes/; s/^ospfd=.*/ospfd=yes/' "$FRR_DAEMONS"
fi
systemctl enable --now "$FRR_PACKAGE" || echo "ПРОВЕРИТЬ: служба $FRR_PACKAGE не запустилась"
# --- 9. Часовой пояс ---
timedatectl set-timezone "$EXAM_TZ"
echo ""
echo "=== Самопроверка для BR-RTR ==="
ip -4 -br address show
echo ""
echo "Правила NAT:"
iptables -t nat -L POSTROUTING -n -v
echo ""
echo "Дополнительные проверки вручную:"
echo " nmcli connection show (все профили активны?)"
echo " ip -4 addr show $GRE_IF (туннель поднят?)"
echo " vtysh -c 'show ip ospf neighbor' (соседи HQ-RTR и BR-FW в FULL?)"
echo " ping -c2 $ISP_GW (шлюз ISP доступен?)"

131
zadanie1/br-srv.sh Normal file
View file

@ -0,0 +1,131 @@
#!/bin/bash
# ============================================================
# ЗАДАНИЕ 1. Настройка BR-SRV (Linux / РЕД ОС 8)
# Имя, адрес в сети BR (через BR-FW), пользователь sshuser
# (UID 2027, sudo без пароля), SSH: порт 2027, только sshuser,
# 2 попытки, баннер, часовой пояс.
# ============================================================
# --- Проверка прав root ---
if [[ $EUID -ne 0 ]]; then
echo "Запустите скрипт с правами root (sudo bash br-srv.sh)"
exit 1
fi
# ================= ПЕРЕМЕННЫЕ (заполните перед запуском) =================
HOSTNAME_FQDN="br-srv.au-team.irpo" # таблица 3, запись br-srv.au-team.irpo
# --- Сеть ---
SRV_IF="" # интерфейс в сторону BR-FW
SRV_ADDR="" # адрес BR-SRV в сети BR (сеть не более 16 адресов), адрес/префикс
SRV_GW="" # шлюз — адрес BR-FW в этой же сети
DNS_SRV="" # DNS для сервера — адрес HQ-SRV (основной DNS по заданию)
# либо внешний, например 77.88.8.7 — уточните у экзаменатора
# --- Пользователь sshuser (значения из задания) ---
SSH_USER="sshuser"
SSH_USER_PASS="P@ssw0rd"
SSH_USER_UID="2027"
# --- SSH (значения из задания) ---
SSH_PORT="2027"
SSH_BANNER_TEXT="Authorized access only"
SSH_BANNER_FILE="/etc/ssh/exam-banner"
SSHD_CONF="/etc/ssh/sshd_config"
# --- Прочее ---
EXAM_TZ="Europe/Moscow" # проверить на экзамене
NM_CONF_DIR="/etc/NetworkManager/system-connections"
# ============ Проверка заполнения переменных ============
MISSING=()
for NAME in HOSTNAME_FQDN SRV_IF SRV_ADDR SRV_GW SSH_USER SSH_USER_PASS \
SSH_USER_UID SSH_PORT EXAM_TZ; do
[[ -z "${!NAME}" ]] && MISSING+=("$NAME")
done
if [[ ${#MISSING[@]} -gt 0 ]]; then
echo "Заполните переменные в начале скрипта: ${MISSING[*]}"
exit 1
fi
echo "=== Настройка BR-SRV ==="
# --- 1. Имя хоста ---
hostnamectl set-hostname "$HOSTNAME_FQDN"
echo "Имя хоста: $(hostname)"
# --- 2. Сеть ---
echo "--- Профиль $SRV_IF ---"
cat > "$NM_CONF_DIR/$SRV_IF.nmconnection" <<EOF
[connection]
id=$SRV_IF
type=ethernet
autoconnect=yes
interface-name=$SRV_IF
[ethernet]
[ipv4]
address1=$SRV_ADDR
gateway=$SRV_GW
method=manual
[ipv6]
method=disabled
[proxy]
EOF
chmod 600 "$NM_CONF_DIR/$SRV_IF.nmconnection"
nmcli connection reload
nmcli connection up "$SRV_IF" || echo "ВНИМАНИЕ: не поднялся $SRV_IF"
if [[ -n "$DNS_SRV" ]]; then
if grep -q "^nameserver" /etc/resolv.conf 2>/dev/null; then
echo "DNS уже прописан: $(grep '^nameserver' /etc/resolv.conf)"
else
echo "nameserver $DNS_SRV" > /etc/resolv.conf
fi
fi
# --- 3. Пользователь sshuser: UID 2027, пароль, sudo без пароля ---
if id "$SSH_USER" &>/dev/null; then
echo "Пользователь уже существует"
else
useradd -u "$SSH_USER_UID" -m "$SSH_USER"
fi
echo "$SSH_USER:$SSH_USER_PASS" | chpasswd
echo "$SSH_USER ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/sshuser
chmod 440 /etc/sudoers.d/sshuser
echo "Проверка UID: id $SSH_USER"
# --- 4. SSH: порт 2027, только sshuser, MaxAuthTries 2, баннер ---
echo "--- Настройка SSH (порт $SSH_PORT) ---"
echo "$SSH_BANNER_TEXT" > "$SSH_BANNER_FILE"
for KEY in Port AllowUsers MaxAuthTries Banner; do
sed -riE "s/^[[:space:]]*[#]*[[:space:]]*${KEY}[[:space:]].*$//" "$SSHD_CONF"
done
cat >> "$SSHD_CONF" <<EOF
Port $SSH_PORT
AllowUsers $SSH_USER
MaxAuthTries 2
Banner $SSH_BANNER_FILE
EOF
if command -v getenforce >/dev/null 2>&1 && [[ $(getenforce) == "Enforcing" ]]; then
if ! semanage port -l | grep -qw "$SSH_PORT" 2>/dev/null; then
semanage port -a -t ssh_port_t -p tcp "$SSH_PORT" 2>/dev/null \
|| echo "ПРОВЕРИТЬ: не удалось добавить SELinux-порт $SSH_PORT"
fi
fi
sshd -t && echo "Конфиг sshd корректен" || echo "ПРОВЕРИТЬ: sshd -t вернул ошибку"
systemctl restart sshd || systemctl restart ssh
echo "Проверка: ss -tlnp | grep ':$SSH_PORT'"
# --- 5. Часовой пояс ---
timedatectl set-timezone "$EXAM_TZ"
echo ""
echo "=== Самопроверка для BR-SRV ==="
ip -4 -br address show
echo ""
echo "Дополнительные проверки вручную:"
echo " ss -tlnp | grep ':$SSH_PORT' (SSH на порту 2027?)"
echo " ping -c2 $SRV_GW (BR-FW доступен?)"

73
zadanie1/hq-cli.sh Normal file
View file

@ -0,0 +1,73 @@
#!/bin/bash
# ============================================================
# ЗАДАНИЕ 1. Настройка HQ-CLI (Linux / РЕД ОС 8, только консоль)
# Имя, адрес по DHCP от HQ-RTR (VLAN 200), часовой пояс.
# DHCP-сервер находится на HQ-RTR: выдаёт адрес, шлюз (HQ-RTR),
# DNS (HQ-SRV) и суффикс au-team.irpo.
# ============================================================
# --- Проверка прав root ---
if [[ $EUID -ne 0 ]]; then
echo "Запустите скрипт с правами root (sudo bash hq-cli.sh)"
exit 1
fi
# ================= ПЕРЕМЕННЫЕ (заполните перед запуском) =================
HOSTNAME_FQDN="hq-cli.au-team.irpo" # таблица 3, запись hq-cli.au-team.irpo
CLI_IF="" # интерфейс к HQ-SW (access-порт VLAN 200; тег ставит только HQ-SW)
EXAM_TZ="Europe/Moscow" # проверить на экзамене
NM_CONF_DIR="/etc/NetworkManager/system-connections"
# ============ Проверка заполнения переменных ============
MISSING=()
for NAME in HOSTNAME_FQDN CLI_IF EXAM_TZ; do
[[ -z "${!NAME}" ]] && MISSING+=("$NAME")
done
if [[ ${#MISSING[@]} -gt 0 ]]; then
echo "Заполните переменные в начале скрипта: ${MISSING[*]}"
exit 1
fi
echo "=== Настройка HQ-CLI ==="
# --- 1. Имя хоста ---
hostnamectl set-hostname "$HOSTNAME_FQDN"
echo "Имя хоста: $(hostname)"
# --- 2. Интерфейс: адрес по DHCP ---
echo "--- Профиль $CLI_IF (DHCP) ---"
cat > "$NM_CONF_DIR/$CLI_IF.nmconnection" <<EOF
[connection]
id=$CLI_IF
type=ethernet
autoconnect=yes
interface-name=$CLI_IF
[ethernet]
[ipv4]
method=auto
[ipv6]
method=disabled
[proxy]
EOF
chmod 600 "$NM_CONF_DIR/$CLI_IF.nmconnection"
nmcli connection reload
nmcli connection up "$CLI_IF" || echo "ВНИМАНИЕ: не поднялся $CLI_IF (DHCP на HQ-RTR запущен?)"
# --- 3. Часовой пояс ---
timedatectl set-timezone "$EXAM_TZ"
echo ""
echo "=== Самопроверка для HQ-CLI ==="
ip -4 -br address show
echo ""
echo "Дополнительные проверки вручную (после получения адреса по DHCP):"
echo " hostnamectl (имя и часовой пояс?)"
echo " cat /etc/resolv.conf (DNS = адрес HQ-SRV, суффикс au-team.irpo?)"
echo " ip route (шлюз по умолчанию = адрес HQ-RTR?)"
echo " ping -c2 <адрес HQ-SRV>"

254
zadanie1/hq-rtr.sh Normal file
View file

@ -0,0 +1,254 @@
#!/bin/bash
# ============================================================
# ЗАДАНИЕ 1. Настройка HQ-RTR (Linux / РЕД ОС 8)
# Имя, net_admin, интерфейс к ISP, VLAN 100/200/999 на ОДНОМ адаптере,
# GRE-туннель до BR-RTR, OSPF (MD5) в туннеле, NAT, DHCP для VLAN 200,
# часовой пояс.
# ============================================================
# --- Проверка прав root ---
if [[ $EUID -ne 0 ]]; then
echo "Запустите скрипт с правами root (sudo bash hq-rtr.sh)"
exit 1
fi
# ================= ПЕРЕМЕННЫЕ (заполните перед запуском) =================
HOSTNAME_FQDN="hq-rtr.au-team.irpo" # таблица 3, запись hq-rtr.au-team.irpo
# --- Пользователь net_admin (значения из задания) ---
NET_ADMIN_USER="net_admin"
NET_ADMIN_PASS="P@ssw0rd"
# --- Интерфейс в сторону ISP ---
ISP_IF="" # интерфейс к ISP (пример: enp0s3)
ISP_NET="" # адрес HQ-RTR в этой сети, формат адрес/префикс
# (по заданию сеть 172.16.1.0/28)
ISP_GW="" # шлюз по умолчанию — адрес ISP в этой же сети
DNS_ROUTER="" # внешний DNS для роутера (необязательно, например 77.88.8.7)
# --- Локальные VLAN на ОДНОМ физическом адаптере ---
LAN_IF="" # физический адаптер в сторону HQ-SW (пример: enp0s8)
VLAN100_ADDR="" # адрес HQ-RTR в VLAN 100 (сеть не более 32 адресов), адрес/префикс
VLAN200_ADDR="" # адрес HQ-RTR в VLAN 200 (сеть не более 16 адресов), адрес/префикс
VLAN999_ADDR="" # адрес HQ-RTR в VLAN 999 (сеть не более 8 адресов), адрес/префикс
# --- GRE-туннель до BR-RTR (сеть 10.10.10.0/24, минимальная маска -> /30) ---
GRE_IF="gre1"
GRE_LOCAL="" # локальный конец туннеля, адрес/префикс (из calculator, /30)
GRE_REMOTE="" # удалённый конец туннеля — адрес BR-RTR в сети ISP (без префикса)
# --- OSPF (значения из задания) ---
OSPF_PASSWORD="P@ssw0rd"
OSPF_AREA="0.0.0.0"
# ПРОВЕРИТЬ на РЕД ОС 8: пакет, конфиг и службу OSPF (frr / quagga)
FRR_PACKAGE="frr"
FRR_CONF="/etc/frr/frr.conf"
FRR_DAEMONS="/etc/frr/daemons"
# --- NAT в сторону ISP (адресации не содержит) ---
# Список сетей офиса для NAT — адреса сетей с префиксом (для правил iptables).
NAT_NETS="" # через пробел, например: "<сеть VLAN100/префикс> <сеть VLAN200/префикс> <сеть VLAN999/префикс>"
# --- DHCP для VLAN 200 (клиент — HQ-CLI) ---
DHCP_PACKAGE="dhcp-server" # ПРОВЕРИТЬ: пакет DHCP-сервера в РЕД ОС 8
DHCPD_SERVICE="dhcpd" # ПРОВЕРИТЬ: имя службы
DHCPD_CONF="/etc/dhcp/dhcpd.conf"
DHCP_SUBNET="" # адрес сети VLAN 200 (без префикса)
DHCP_NETMASK="" # маска этой сети (255.255.255.x)
DHCP_RANGE_FIRST="" # первый адрес выдачи (АДРЕС HQ-RTR ВЫПАДАЕТ: он вне range)
DHCP_RANGE_LAST="" # последний адрес выдачи
DHCP_DOMAIN="au-team.irpo"
HQ_SRV_IP="" # адрес HQ-SRV (VLAN 100) — DNS-сервер для HQ-CLI
# --- Прочее ---
EXAM_TZ="Europe/Moscow" # проверить на экзамене
FORWARD_CONF="/etc/sysctl.d/99-ip-forward.conf" # перезаписывается целиком
NM_CONF_DIR="/etc/NetworkManager/system-connections"
IPTABLES_SERVICE="iptables" # ПРОВЕРИТЬ
# ============ Проверка заполнения переменных ============
MISSING=()
for NAME in HOSTNAME_FQDN ISP_IF ISP_NET ISP_GW LAN_IF VLAN100_ADDR VLAN200_ADDR \
VLAN999_ADDR GRE_LOCAL GRE_REMOTE NAT_NETS DHCP_SUBNET DHCP_NETMASK \
DHCP_RANGE_FIRST DHCP_RANGE_LAST HQ_SRV_IP EXAM_TZ; do
[[ -z "${!NAME}" ]] && MISSING+=("$NAME")
done
if [[ ${#MISSING[@]} -gt 0 ]]; then
echo "Заполните переменные в начале скрипта: ${MISSING[*]}"
exit 1
fi
echo "=== Настройка HQ-RTR ==="
# --- 1. Имя хоста ---
hostnamectl set-hostname "$HOSTNAME_FQDN"
echo "Имя хоста: $(hostname)"
# --- 2. Пользователь net_admin с sudo без пароля ---
echo "--- Пользователь $NET_ADMIN_USER ---"
if id "$NET_ADMIN_USER" &>/dev/null; then
echo "Пользователь уже существует"
else
useradd -m "$NET_ADMIN_USER"
fi
echo "$NET_ADMIN_USER:$NET_ADMIN_PASS" | chpasswd
# Файл в sudoers.d перезаписывается целиком — дублей нет
echo "$NET_ADMIN_USER ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/net_admin
chmod 440 /etc/sudoers.d/net_admin
echo "Проверка: su - $NET_ADMIN_USER -c 'sudo -n true && echo sudo OK'"
# --- 3. Интерфейс в сторону ISP ---
echo "--- Профиль $ISP_IF (статика, шлюз $ISP_GW) ---"
cat > "$NM_CONF_DIR/$ISP_IF.nmconnection" <<EOF
[connection]
id=$ISP_IF
type=ethernet
autoconnect=yes
interface-name=$ISP_IF
[ethernet]
[ipv4]
address1=$ISP_NET
gateway=$ISP_GW
method=manual
[ipv6]
method=disabled
[proxy]
EOF
chmod 600 "$NM_CONF_DIR/$ISP_IF.nmconnection"
# --- 4. VLAN-интерфейсы (100/200/999) на одном физическом адаптере ---
make_vlan_profile () {
printf '%s\n' \
"[connection]
id=$1
type=vlan
autoconnect=yes
interface-name=$1
[vlan]
parent=$LAN_IF
id=$2
[ipv4]
address1=$3
method=manual
[ipv6]
method=disabled
[proxy]" > "$NM_CONF_DIR/$1.nmconnection"
chmod 600 "$NM_CONF_DIR/$1.nmconnection"
}
echo "--- VLAN 100 ---"; make_vlan_profile vlan100 100 "$VLAN100_ADDR"
echo "--- VLAN 200 ---"; make_vlan_profile vlan200 200 "$VLAN200_ADDR"
echo "--- VLAN 999 ---"; make_vlan_profile vlan999 999 "$VLAN999_ADDR"
# --- 5. GRE-туннель ---
echo "--- Туннель $GRE_IF ---"
cat > "$NM_CONF_DIR/$GRE_IF.nmconnection" <<EOF
[connection]
id=$GRE_IF
type=ip-tunnel
autoconnect=yes
interface-name=$GRE_IF
[ip-tunnel]
mode=gre
remote=$GRE_REMOTE
[ipv4]
address1=$GRE_LOCAL
method=manual
[ipv6]
method=disabled
[proxy]
EOF
chmod 600 "$NM_CONF_DIR/$GRE_IF.nmconnection"
nmcli connection reload
for C in "$ISP_IF" vlan100 vlan200 vlan999 "$GRE_IF"; do
nmcli connection up "$C" || echo "ВНИМАНИЕ: не поднялся профиль $C"
done
# --- 6. IP forwarding ---
echo "net.ipv4.ip_forward = 1" > "$FORWARD_CONF"
sysctl -p "$FORWARD_CONF"
# --- 7. NAT в сторону ISP ---
echo "--- NAT (MASQUERADE) ---"
for SRC_NET in $NAT_NETS; do
if iptables -t nat -C POSTROUTING -s "$SRC_NET" -o "$ISP_IF" -j MASQUERADE 2>/dev/null; then
echo "Правило для $SRC_NET уже есть"
else
iptables -t nat -A POSTROUTING -s "$SRC_NET" -o "$ISP_IF" -j MASQUERADE
echo "Добавлено MASQUERADE для $SRC_NET"
fi
done
iptables-save > /etc/sysconfig/iptables
systemctl enable --now "$IPTABLES_SERVICE" 2>/dev/null \
|| echo "ПРОВЕРИТЬ: служба $IPTABLES_SERVICE не запустилась"
# --- 8. OSPF в туннеле с аутентификацией MD5 ---
echo "--- OSPF (${FRR_PACKAGE}) ---"
dnf install -y "$FRR_PACKAGE" || echo "ПРОВЕРИТЬ: пакет $FRR_PACKAGE не установился"
# Сеть туннеля вычисляем из адреса туннеля (нужен python3)
TUN_NET=$(python3 -c "import ipaddress,sys; print(ipaddress.ip_network(sys.argv[1], strict=False))" "$GRE_LOCAL")
cat > "$FRR_CONF" <<EOF
frr version 8
frr defaults traditional
hostname $(hostname -s)
service integrated-vtysh-config
!
router ospf
passive-interface default
no passive-interface $GRE_IF
network $TUN_NET area $OSPF_AREA
!
interface $GRE_IF
ip ospf authentication message-digest
ip ospf message-digest-key 1 md5 $OSPF_PASSWORD
!
EOF
# Включаем нужные демоны frr (zebra + ospfd) — файл правим точечно, без дублей
if [[ -f "$FRR_DAEMONS" ]]; then
sed -ri 's/^zebra=.*/zebra=yes/; s/^ospfd=.*/ospfd=yes/' "$FRR_DAEMONS"
fi
systemctl enable --now "$FRR_PACKAGE" || echo "ПРОВЕРИТЬ: служба $FRR_PACKAGE не запустилась"
# --- 9. DHCP для VLAN 200 ---
echo "--- DHCP ($DHCP_PACKAGE) ---"
dnf install -y "$DHCP_PACKAGE" || echo "ПРОВЕРИТЬ: пакет $DHCP_PACKAGE не установился"
cat > "$DHCPD_CONF" <<EOF
# Клиент HQ-CLI получает адрес из указанного range.
# Адрес HQ-RTR в выдачу не попадает (он вне range) — это и есть исключение.
subnet $DHCP_SUBNET netmask $DHCP_NETMASK {
range $DHCP_RANGE_FIRST $DHCP_RANGE_LAST;
option routers $VLAN200_ADDR; # шлюз — HQ-RTR (его адрес в VLAN 200)
option domain-name-servers $HQ_SRV_IP;
option domain-name "$DHCP_DOMAIN";
}
EOF
systemctl enable --now "$DHCPD_SERVICE" || echo "ПРОВЕРИТЬ: служба $DHCPD_SERVICE не запустилась"
# --- 10. Часовой пояс ---
timedatectl set-timezone "$EXAM_TZ"
echo ""
echo "=== Самопроверка для HQ-RTR ==="
ip -4 -br address show
echo ""
echo "Правила NAT:"
iptables -t nat -L POSTROUTING -n -v
echo ""
echo "Дополнительные проверки вручную:"
echo " nmcli connection show (все профили активны?)"
echo " ip -4 addr show $GRE_IF (туннель поднят?)"
echo " vtysh -c 'show ip ospf neighbor' (сосед BR-RTR в состоянии FULL?)"
echo " ss -clip -n | grep 67 (DHCP слушает?)"
echo " ping -c2 $ISP_GW (шлюз ISP доступен?)"

186
zadanie1/hq-srv.sh Normal file
View file

@ -0,0 +1,186 @@
#!/bin/bash
# ============================================================
# ЗАДАНИЕ 1. Настройка HQ-SRV (Linux / РЕД ОС 8)
# Имя, адрес в VLAN 100, пользователь sshuser (UID 2027, sudo без пароля),
# SSH: порт 2027, только sshuser, 2 попытки, баннер,
# DNS-сервер (dnsmasq): зона au-team.irpo по таблице 3, forwarder,
# часовой пояс.
# ============================================================
# --- Проверка прав root ---
if [[ $EUID -ne 0 ]]; then
echo "Запустите скрипт с правами root (sudo bash hq-srv.sh)"
exit 1
fi
# ================= ПЕРЕМЕННЫЕ (заполните перед запуском) =================
HOSTNAME_FQDN="hq-srv.au-team.irpo" # таблица 3, запись hq-srv.au-team.irpo
# --- Сеть ---
SRV_IF="" # интерфейс к HQ-SW (access-порт VLAN 100; на HQ-SRV тег не ставится)
SRV_ADDR="" # адрес HQ-SRV в VLAN 100, формат адрес/префикс
SRV_GW="" # шлюз — адрес HQ-RTR в VLAN 100
DNS_SRV="" # внешний DNS для самого сервера (необязательно, напр. 77.88.8.7)
# --- Пользователь sshuser (значения из задания) ---
SSH_USER="sshuser"
SSH_USER_PASS="P@ssw0rd"
SSH_USER_UID="2027"
# --- SSH (значения из задания) ---
SSH_PORT="2027" # порт подключения
SSH_BANNER_TEXT="Authorized access only"
SSH_BANNER_FILE="/etc/ssh/exam-banner"
SSHD_CONF="/etc/ssh/sshd_config"
# --- DNS-сервер (dnsmasq; ПРОВЕРИТЬ: пакет/служба на РЕД ОС 8) ---
DNS_PACKAGE="dnsmasq"
DNS_SERVICE="dnsmasq"
DNS_HOSTS_FILE="/etc/exam.hosts" # наши записи A/PTR, перезаписывается целиком
DNS_EXTRA_CONF="/etc/dnsmasq.d/exam.conf"
DNS_DOMAIN="au-team.irpo"
DNS_UPSTREAM="" # forwarder по заданию: любой общий DNS (77.88.8.7 / 77.88.8.3 / др.)
DNS_LISTEN="" # адрес, на котором слушать DNS (адрес HQ-SRV в VLAN 100)
# --- Адреса для записей таблицы 3 (все без префикса) ---
HQ_RTR_IP="" # hq-rtr.au-team.irpo
BR_RTR_IP="" # br-rtr.au-team.irpo
BR_FW_IP="" # br-fw.au-team.irpo
HQ_CLI_IP="" # hq-cli.au-team.irpo
BR_SRV_IP="" # br-srv.au-team.irpo
ISP_TO_HQ_IP="" # docker.au-team.irpo — ISP со стороны HQ-RTR
ISP_TO_BR_IP="" # web.au-team.irpo — ISP со стороны BR-RTR
# --- Прочее ---
EXAM_TZ="Europe/Moscow" # проверить на экзамене
NM_CONF_DIR="/etc/NetworkManager/system-connections"
# ============ Проверка заполнения переменных ============
MISSING=()
for NAME in HOSTNAME_FQDN SRV_IF SRV_ADDR SRV_GW SSH_USER SSH_USER_PASS SSH_USER_UID \
SSH_PORT DNS_UPSTREAM DNS_LISTEN HQ_RTR_IP BR_RTR_IP BR_FW_IP HQ_CLI_IP \
BR_SRV_IP ISP_TO_HQ_IP ISP_TO_BR_IP EXAM_TZ; do
[[ -z "${!NAME}" ]] && MISSING+=("$NAME")
done
if [[ ${#MISSING[@]} -gt 0 ]]; then
echo "Заполните переменные в начале скрипта: ${MISSING[*]}"
exit 1
fi
# Адрес HQ-SRV без префикса — для записи A/PTR на себя
SRV_ADDR_HOST="${SRV_ADDR%/*}"
echo "=== Настройка HQ-SRV ==="
# --- 1. Имя хоста ---
hostnamectl set-hostname "$HOSTNAME_FQDN"
echo "Имя хоста: $(hostname)"
# --- 2. Сеть ---
echo "--- Профиль $SRV_IF ---"
cat > "$NM_CONF_DIR/$SRV_IF.nmconnection" <<EOF
[connection]
id=$SRV_IF
type=ethernet
autoconnect=yes
interface-name=$SRV_IF
[ethernet]
[ipv4]
address1=$SRV_ADDR
gateway=$SRV_GW
method=manual
[ipv6]
method=disabled
[proxy]
EOF
chmod 600 "$NM_CONF_DIR/$SRV_IF.nmconnection"
nmcli connection reload
nmcli connection up "$SRV_IF" || echo "ВНИМАНИЕ: не поднялся $SRV_IF"
if [[ -n "$DNS_SRV" ]]; then
if grep -q "^nameserver" /etc/resolv.conf 2>/dev/null; then
echo "DNS уже прописан: $(grep '^nameserver' /etc/resolv.conf)"
else
echo "nameserver $DNS_SRV" > /etc/resolv.conf
fi
fi
# --- 3. Пользователь sshuser: UID 2027, пароль, sudo без пароля ---
if id "$SSH_USER" &>/dev/null; then
echo "Пользователь уже существует"
else
useradd -u "$SSH_USER_UID" -m "$SSH_USER"
fi
echo "$SSH_USER:$SSH_USER_PASS" | chpasswd
echo "$SSH_USER ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/sshuser
chmod 440 /etc/sudoers.d/sshuser
echo "Проверка UID: id $SSH_USER"
# --- 4. SSH: порт 2027, только sshuser, MaxAuthTries 2, баннер ---
echo "--- Настройка SSH (порт $SSH_PORT) ---"
echo "$SSH_BANNER_TEXT" > "$SSH_BANNER_FILE"
# Удаляем старые значения (в т.ч. закомментированные), затем дописываем новые.
# Повторный запуск не создаёт дублей: сначала чистим, потом пишем.
for KEY in Port AllowUsers MaxAuthTries Banner; do
sed -riE "s/^[[:space:]]*[#]*[[:space:]]*${KEY}[[:space:]].*$//" "$SSHD_CONF"
done
cat >> "$SSHD_CONF" <<EOF
Port $SSH_PORT
AllowUsers $SSH_USER
MaxAuthTries 2
Banner $SSH_BANNER_FILE
EOF
# Если включён SELinux, порт 2027 нужно разрешить политике sshd
# (ПРОВЕРИТЬ на РЕД ОС 8; для semanage может понадобиться пакет
# policycoreutils-python-utils)
if command -v getenforce >/dev/null 2>&1 && [[ $(getenforce) == "Enforcing" ]]; then
if ! semanage port -l | grep -qw "$SSH_PORT" 2>/dev/null; then
semanage port -a -t ssh_port_t -p tcp "$SSH_PORT" 2>/dev/null \
|| echo "ПРОВЕРИТЬ: не удалось добавить SELinux-порт $SSH_PORT"
fi
fi
sshd -t && echo "Конфиг sshd корректен" || echo "ПРОВЕРИТЬ: sshd -t вернул ошибку"
systemctl restart sshd || systemctl restart ssh
echo "Проверка: ss -tlnp | grep ':$SSH_PORT'"
# --- 5. DNS-сервер (dnsmasq): зона au-team.irpo по таблице 3 ---
echo "--- DNS ($DNS_PACKAGE) ---"
dnf install -y "$DNS_PACKAGE" || echo "ПРОВЕРИТЬ: пакет $DNS_PACKAGE не установился"
# Записи A и PTR (PTR появляется автоматически по записям hosts —
# убедитесь на стенде, что обратные зоны отвечают)
cat > "$DNS_HOSTS_FILE" <<EOF
$HQ_RTR_IP hq-rtr.au-team.irpo hq-rtr
$BR_RTR_IP br-rtr.au-team.irpo br-rtr
$BR_FW_IP br-fw.au-team.irpo br-fw
$SRV_ADDR_HOST hq-srv.au-team.irpo hq-srv
$HQ_CLI_IP hq-cli.au-team.irpo hq-cli
$BR_SRV_IP br-srv.au-team.irpo br-srv
$ISP_TO_HQ_IP docker.au-team.irpo docker
$ISP_TO_BR_IP web.au-team.irpo web
EOF
cat > "$DNS_EXTRA_CONF" <<EOF
domain=$DNS_DOMAIN
local=/$DNS_DOMAIN/
listen-address=127.0.0.1,$DNS_LISTEN
server=$DNS_UPSTREAM
addn-hosts=$DNS_HOSTS_FILE
EOF
systemctl enable --now "$DNS_SERVICE" \
|| { echo "ПРОВЕРИТЬ: служба $DNS_SERVICE не запустилась"; systemctl status "$DNS_SERVICE" --no-pager; }
# --- 6. Часовой пояс ---
timedatectl set-timezone "$EXAM_TZ"
echo ""
echo "=== Самопроверка для HQ-SRV ==="
ip -4 -br address show
echo ""
echo "Дополнительные проверки вручную:"
echo " ss -tlnp | grep ':$SSH_PORT' (SSH на порту 2027?)"
echo " ss -uln | grep ':53' (DNS слушает?)"
echo " dig +short hq-rtr.$DNS_DOMAIN @127.0.0.1"
echo " dig +short -x $SRV_ADDR_HOST @127.0.0.1 (проверка PTR HQ-SRV)"
echo " ping -c2 $SRV_GW (шлюз HQ-RTR доступен?)"

132
zadanie1/hq-sw.sh Normal file
View file

@ -0,0 +1,132 @@
#!/bin/bash
# ============================================================
# ЗАДАНИЕ 1. Настройка HQ-SW как Linux-ВМ (вариант 1)
# Bridge с vlan_filtering на трёх адаптерах:
# - к HQ-RTR: trunk VLAN 100, 200, 999;
# - к HQ-SRV: access VLAN 100 (untagged) — тегов сервер не видит;
# - к HQ-CLI: access VLAN 200 (untagged) — тегов клиент не видит.
# Управление коммутатором — адрес в VLAN 999 (подынтерфейс bridge).
# Часовой пояс на HQ-SW НЕ настраивается (по п. 11 задания 1).
# ПРОВЕРИТЬ на стенде: имена интерфейсов и persistence-подход.
# ============================================================
# --- Проверка прав root ---
if [[ $EUID -ne 0 ]]; then
echo "Запустите скрипт с правами root (sudo bash hq-sw.sh)"
exit 1
fi
# ================= ПЕРЕМЕННЫЕ (заполните перед запуском) =================
HOSTNAME_FQDN="hq-sw.au-team.irpo" # записи в таблице 3 нет — уточнить имя
BRIDGE="br0" # имя создаваемого моста
RTR_IF="" # интерфейс к HQ-RTR (trunk) (пример: enp0s3)
SRV_IF="" # интерфейс к HQ-SRV (access) (пример: enp0s8)
CLI_IF="" # интерфейс к HQ-CLI (access) (пример: enp0s9)
VLAN_SRV="100" # VLAN трафика HQ-SRV (по заданию)
VLAN_CLI="200" # VLAN трафика HQ-CLI (по заданию)
VLAN_MGMT="999" # VLAN управления (по заданию)
MGMT_ADDR="" # адрес HQ-SW в VLAN 999, формат адрес/префикс
# (сеть управления не более 8 адресов)
MGMT_GW="" # адрес HQ-RTR в VLAN 999 (необязательно — шлюз управления)
UNIT_FILE="/etc/systemd/system/hq-sw-bridge.service" # перезапуск моста после reboot
SELF_COPY="/usr/local/sbin/hq-sw-bridge"
# ============ Проверка заполнения переменных ============
MISSING=()
for NAME in HOSTNAME_FQDN RTR_IF SRV_IF CLI_IF MGMT_ADDR; do
[[ -z "${!NAME}" ]] && MISSING+=("$NAME")
done
if [[ ${#MISSING[@]} -gt 0 ]]; then
echo "Заполните переменные в начале скрипта: ${MISSING[*]}"
exit 1
fi
echo "=== Настройка HQ-SW (bridge + VLAN filtering) ==="
# --- 1. Имя хоста ---
hostnamectl set-hostname "$HOSTNAME_FQDN"
echo "Имя хоста: $(hostname)"
# --- 2. Мост с фильтрацией VLAN (повторный запуск безопасен: не падает, если мост есть) ---
echo "--- Мост $BRIDGE ---"
ip link add "$BRIDGE" type bridge vlan_filtering 1 2>/dev/null \
|| echo "Мост $BRIDGE уже существует — продолжаем"
ip link set dev "$BRIDGE" up
# --- 3. Порты в мост ---
echo "--- Порты в мост ---"
for IF in "$RTR_IF" "$SRV_IF" "$CLI_IF"; do
ip link set dev "$IF" nomaster 2>/dev/null || true
ip link set dev "$IF" master "$BRIDGE" || echo "ВНИМАНИЕ: $IF не вошёл в мост"
ip link set dev "$IF" up
done
# --- 4. VLAN-конфигурация портов ---
# ВАЖНО: сначала убираем дефолтный untagged vid 1, иначе трафик уйдёт в VLAN 1.
echo "--- VLAN-порты ---"
# Порт к HQ-RTR: trunk (все VLAN тегированными, без untagged)
bridge vlan del dev "$RTR_IF" vid 1 2>/dev/null || true
for VID in $VLAN_SRV $VLAN_CLI $VLAN_MGMT; do
bridge vlan add dev "$RTR_IF" vid "$VID"
done
# Порты к HQ-SRV и HQ-CLI: access — VLAN уходит наружу без тега
bridge vlan del dev "$SRV_IF" vid 1 2>/dev/null || true
bridge vlan add dev "$SRV_IF" vid "$VLAN_SRV" pvid untagged
bridge vlan del dev "$CLI_IF" vid 1 2>/dev/null || true
bridge vlan add dev "$CLI_IF" vid "$VLAN_CLI" pvid untagged
# --- 5. Управление коммутатором: адрес в VLAN 999 на подынтерфейсе моста ---
VLAN_IF="$BRIDGE.$VLAN_MGMT"
ip link add link "$BRIDGE" name "$VLAN_IF" type vlan id "$VLAN_MGMT" 2>/dev/null \
|| true
ip addr replace "$MGMT_ADDR" dev "$VLAN_IF"
ip link set dev "$VLAN_IF" up
if [[ -n "$MGMT_GW" ]]; then
ip route replace default via "$MGMT_GW" dev "$VLAN_IF"
fi
echo "Управление: $VLAN_IF = $MGMT_ADDR"
# --- 6. Сохраняем после reboot: копия скрипта + systemd-юнит ---
# (скрипт идемпотентен, повторный запуск безопасен)
install -m 755 "$0" "$SELF_COPY" \
|| echo "ПРОВЕРИТЬ: не удалось скопировать $0 в $SELF_COPY"
cat > "$UNIT_FILE" <<'EOF'
[Unit]
Description=HQ-SW: bridge с VLAN filtering и управлением в VLAN 999
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/hq-sw-bridge
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable hq-sw-bridge \
&& echo "После reboot мост восстановится автоматически" \
|| echo "ПРОВЕРИТЬ: не включился автозапуск hq-sw-bridge.service"
echo ""
echo "=== Самопроверка для HQ-SW ==="
echo "Порты и мост:"
ip -br link show
echo ""
echo "VLAN-конфигурация портов:"
bridge vlan show
echo ""
echo "Управление:"
ip -4 addr show "$VLAN_IF" 2>/dev/null
[[ -n "$MGMT_GW" ]] && ip route show default
echo ""
echo "Дополнительные проверки вручную:"
echo " bridge -d link show (порты в состоянии forward?)"
echo " ping -c2 <адрес HQ-RTR в VLAN 999>"
echo " После reboot: systemctl status hq-sw-bridge"

182
zadanie1/isp.sh Normal file
View file

@ -0,0 +1,182 @@
#!/bin/bash
# ============================================================
# ЗАДАНИЕ 1. Настройка ISP (Linux / РЕД ОС 8)
# Имя, интерфейсы (WAN по DHCP, линки к HQ-RTR и BR-RTR),
# NAT для сетей HQ-RTR и BR-RTR, часовой пояс.
# ============================================================
# --- Проверка прав root ---
if [[ $EUID -ne 0 ]]; then
echo "Запустите скрипт с правами root (sudo bash isp.sh)"
exit 1
fi
# ================= ПЕРЕМЕННЫЕ (заполните перед запуском) =================
# Полное доменное имя ISP. В таблице 3 задания записи ISP нет — уточните имя.
HOSTNAME_FQDN=""
# Администрирование ниже настраивается без запросов — только переменные.
WAN_IF="" # интерфейс к провайдеру (пример: enp0s3), получит адрес по DHCP
HQ_IF="" # интерфейс в сторону HQ-RTR
HQ_NET="" # адрес ISP на этом интерфейсе, формат адрес/префикс
# (по заданию сеть 172.16.1.0/28 — вписать свой адрес/префикс)
BR_IF="" # интерфейс в сторону BR-RTR
BR_NET="" # адрес ISP здесь, формат адрес/префикс
# (по заданию сеть 172.16.2.0/28)
DNS_ISP="" # внешний DNS-сервер, если DHCP провайдера его не выдаёт
# (необязательно, например 77.88.8.7)
# Часовой пояс — поставьте пояс места проведения экзамена
EXAM_TZ="Europe/Moscow" # проверить на экзамене
# Служба сохранения iptables на РЕД ОС 8 — проверить на стенде (ПРОВЕРИТЬ:
# пакет iptables-services и имя службы)
IPTABLES_SERVICE="iptables"
NM_CONF_DIR="/etc/NetworkManager/system-connections"
FORWARD_CONF="/etc/sysctl.d/99-ip-forward.conf" # перезаписывается целиком
# ============ Проверка заполнения переменных ============
MISSING=()
for NAME in HOSTNAME_FQDN WAN_IF HQ_IF HQ_NET BR_IF BR_NET EXAM_TZ; do
[[ -z "${!NAME}" ]] && MISSING+=("$NAME")
done
if [[ ${#MISSING[@]} -gt 0 ]]; then
echo "Заполните переменные в начале скрипта: ${MISSING[*]}"
exit 1
fi
echo "=== Настройка ISP ==="
# --- 1. Имя хоста ---
echo "Имя хоста: $HOSTNAME_FQDN"
hostnamectl set-hostname "$HOSTNAME_FQDN"
echo "Проверка: hostnamectl"
# --- 2. WAN-интерфейс: адрес по DHCP ---
echo "--- Профиль $WAN_IF (DHCP) ---"
cat > "$NM_CONF_DIR/$WAN_IF.nmconnection" <<EOF
[connection]
id=$WAN_IF
type=ethernet
autoconnect=yes
interface-name=$WAN_IF
[ethernet]
[ipv4]
method=auto
[ipv6]
method=disabled
[proxy]
EOF
chmod 600 "$NM_CONF_DIR/$WAN_IF.nmconnection"
echo "Записан $NM_CONF_DIR/$WAN_IF.nmconnection"
# --- 3. Интерфейс в сторону HQ-RTR ---
echo "--- Профиль $HQ_IF (статика) ---"
cat > "$NM_CONF_DIR/$HQ_IF.nmconnection" <<EOF
[connection]
id=$HQ_IF
type=ethernet
autoconnect=yes
interface-name=$HQ_IF
[ethernet]
[ipv4]
address1=$HQ_NET
method=manual
[ipv6]
method=disabled
[proxy]
EOF
chmod 600 "$NM_CONF_DIR/$HQ_IF.nmconnection"
# --- 4. Интерфейс в сторону BR-RTR ---
echo "--- Профиль $BR_IF (статика) ---"
cat > "$NM_CONF_DIR/$BR_IF.nmconnection" <<EOF
[connection]
id=$BR_IF
type=ethernet
autoconnect=yes
interface-name=$BR_IF
[ethernet]
[ipv4]
address1=$BR_NET
method=manual
[ipv6]
method=disabled
[proxy]
EOF
chmod 600 "$NM_CONF_DIR/$BR_IF.nmconnection"
# --- 5. Применяем профили ---
nmcli connection reload
nmcli connection up "$WAN_IF" || echo "ВНИМАНИЕ: не поднялся $WAN_IF (DHCP? кабель?)"
nmcli connection up "$HQ_IF"
nmcli connection up "$BR_IF"
# --- 6. IP forwarding (файл перезаписывается целиком — дублей не будет) ---
echo "--- Включаем маршрутизацию пакетов ---"
echo "net.ipv4.ip_forward = 1" > "$FORWARD_CONF"
sysctl -p "$FORWARD_CONF"
# --- 7. NAT для сетей HQ-RTR и BR-RTR ---
# Динамическая трансляция (MASQUERADE) на выходе в Интернет только для
# адресов сетей HQ-RTR и BR-RTR. Правила добавляются, только если их нет.
echo "--- NAT (MASQUERADE) ---"
for SRC_NET in "$HQ_NET" "$BR_NET"; do
if iptables -t nat -C POSTROUTING -s "$SRC_NET" -o "$WAN_IF" -j MASQUERADE 2>/dev/null; then
echo "Правило для $SRC_NET уже есть"
else
iptables -t nat -A POSTROUTING -s "$SRC_NET" -o "$WAN_IF" -j MASQUERADE
echo "Добавлено MASQUERADE для $SRC_NET"
fi
done
# --- 8. Сохраняем правила iptables и включаем службу ---
echo "--- Сохранение правил iptables ---"
if command -v iptables-save >/dev/null 2>&1; then
iptables-save > /etc/sysconfig/iptables
systemctl enable --now "$IPTABLES_SERVICE" 2>/dev/null \
|| echo "ПРОВЕРИТЬ: служба $IPTABLES_SERVICE не запустилась"
else
echo "ПРОВЕРИТЬ: iptables-save недоступен — как сохранить правила на РЕД ОС 8?"
fi
# --- 9. DNS (если DHCP провайдера не выдал) ---
if [[ -n "$DNS_ISP" ]]; then
echo "ПРОВЕРИТЬ: DNS-сервер для ISP задаётся здесь ($DNS_ISP)."
echo "Если resolv.conf пустой — впишите DNS через nmcli или вручную."
fi
# --- 10. Часовой пояс ---
timedatectl set-timezone "$EXAM_TZ"
echo "Часовой пояс: $(timedatectl show -p Timezone --value)"
echo ""
echo "=== Самопроверка для ISP ==="
echo "Адреса интерфейсов:"
ip -4 -br address show
echo ""
echo "Маршруты (маршрут по умолчанию должен идти через $WAN_IF):"
ip route show
echo ""
echo "Правила NAT:"
iptables -t nat -L POSTROUTING -n -v
echo ""
echo "Дополнительные проверки вручную:"
echo " ping -c2 77.88.8.7 (доступ в Интернет от ISP)"
echo " ping -c2 <адрес HQ-RTR> (линк к HQ-RTR)"
echo " ping -c2 <адрес BR-RTR> (линк к BR-RTR)"

90
zadanie2/br-rtr.sh Normal file
View 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
View 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
View 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
View 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
View 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
View 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)"

95
zadanie3/br-srv.sh Normal file
View file

@ -0,0 +1,95 @@
#!/bin/bash
# ============================================================
# ЗАДАНИЕ 3. Настройка BR-SRV (Linux / РЕД ОС 8)
# 1. Импорт пользователей: import.sh + users.csv из Additional.iso
# (import.sh сам запрашивает путь к файлу-источнику)
# 7. Инвентаризация через Ansible: плейбук из образа, отчёты в
# /etc/ansible/PC-INFO в формате .yml (имя файла = имя ПК)
# ============================================================
# --- Проверка прав 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
# --- 1. Импорт пользователей ---
IMPORT_SCRIPT="$ISO_DIR/import.sh" # по заданию — в корне образа
USERS_CSV="$ISO_DIR/users.csv" # файл-источник по заданию
# --- 7. Плейбук для инвентаризации ---
ANSIBLE_DIR="/etc/ansible"
PLAYBOOK_SRC="$ISO_DIR/playbook" # директория плейбука в образе
PLAYBOOK_DST="$ANSIBLE_DIR/playbook" # куда копируем на BR-SRV
REPORT_DIR="$ANSIBLE_DIR/PC-INFO" # отчёты .yml по имени ПК
# ============ Проверка заполнения переменных ============
MISSING=()
for NAME in EXAM_TZ; do
[[ -z "${!NAME}" ]] && MISSING+=("$NAME")
done
if [[ ${#MISSING[@]} -gt 0 ]]; then
echo "Заполните переменные в начале скрипта: ${MISSING[*]}"
exit 1
fi
echo "=== Настройка BR-SRV, задание 3 ==="
# --- 1. Импорт пользователей (import.sh сам спрашивает путь) ---
echo "--- Импорт пользователей из $USERS_CSV ---"
if [[ -x "$IMPORT_SCRIPT" || -f "$IMPORT_SCRIPT" ]]; then
echo "Скрипт найден: $IMPORT_SCRIPT"
echo "Он интерактивно запрашивает файл-источник — запустите вручную:"
echo " bash $IMPORT_SCRIPT и в ответ на вопрос укажите $USERS_CSV"
echo "После импорта проверьте: samba-tool user list"
# Проверку запускаем только если обе вещи на месте:
bash "$IMPORT_SCRIPT" || echo "ЗАПУСТИТЕ ВРУЧНУЮ с указанием $USERS_CSV (см. выше)"
else
echo "ДЕЛАЕТСЯ ВРУЧНУЮ: $IMPORT_SCRIPT не найден — смонтируйте Additional.iso в $ISO_DIR"
fi
# --- 2. Плейбук для инвентаризации машин HQ-SRV и HQ-CLI ---
echo "--- Плейбук инвентаризации ---"
if [[ -d "$PLAYBOOK_SRC" ]]; then
mkdir -p "$PLAYBOOK_DST"
cp -f "$PLAYBOOK_SRC"/* "$PLAYBOOK_DST/" 2>/dev/null \
|| echo "ПРОВЕРИТЬ: в $PLAYBOOK_SRC нет файлов?"
ls -l "$PLAYBOOK_DST"
else
echo "ДЕЛАЕТСЯ ВРУЧНУЮ: нет $PLAYBOOK_SRC — смонтируйте Additional.iso в $ISO_DIR"
fi
mkdir -p "$REPORT_DIR"
echo "Плейбуки в $PLAYBOOK_DST. Запуск (с BR-SRV, из задания 2 настроен ansible):"
# Запускаем первый найденный .yml (имя файла в образе нам неизвестно заранее)
PLAYBOOK_YML=""
shopt -s nullglob
for F in "$PLAYBOOK_DST"/*.yml "$PLAYBOOK_DST"/*.yaml; do
PLAYBOOK_YML="$F"
break
done
shopt -u nullglob
if [[ -n "$PLAYBOOK_YML" ]]; then
echo " ansible-playbook $PLAYBOOK_YML"
ansible-playbook "$PLAYBOOK_YML" \
|| echo "ПРОВЕРИТЬ: плейбук не отработал — посмотрите его содержимое и ошибки"
else
echo "ДЕЛАЕТСЯ ВРУЧНУЮ: .yml не найден в $PLAYBOOK_DST"
fi
echo ""
echo "Отчёты должны появиться в $REPORT_DIR (имя файла = имя ПК):"
ls -l "$REPORT_DIR" || true
timedatectl set-timezone "$EXAM_TZ"
echo ""
echo "=== Самопроверка на BR-SRV ==="
echo "Импортированные пользователи (должны появиться из users.csv):"
samba-tool user list
echo ""
echo "Отчёты инвентаризации:"
ls -l "$REPORT_DIR"

87
zadanie3/hq-cli.sh Normal file
View file

@ -0,0 +1,87 @@
#!/bin/bash
# ============================================================
# ЗАДАНИЕ 3. Настройка HQ-CLI (Linux / РЕД ОС 8)
# 4. Доверие корневому сертификату ЦС (HQ-SRV)
# 6. Подключение виртуального pdf-принтера как принтера по умолчанию
# 9. Агент Кибер Бэкап — ДЕЛАЕТСЯ ВРУЧНУЮ (MANUAL.md)
# ============================================================
# --- Проверка прав root ---
if [[ $EUID -ne 0 ]]; then
echo "Запустите скрипт с правами root (sudo bash hq-cli.sh)"
exit 1
fi
# ================= ПЕРЕМЕННЫЕ (заполните перед запуском) =================
EXAM_TZ="Europe/Moscow" # проверить на экзамене
# --- 4. Доверие корневому сертификату ---
CA_ROOT_FILE="" # путь к скопированному корневому сертификату
# (root.crt копируется с HQ-SRV вручную — MANUAL.md)
CA_ANCHORS_DIR="/etc/pki/ca-trust/source/anchors" # ПРОВЕРИТЬ на РЕД ОС 8
CA_TRUST_CMD="update-ca-trust" # ПРОВЕРИТЬ команду обновления хранилища
# --- 6. Принтер по умолчанию (виртуальный pdf с HQ-SRV) ---
CUPS_SERVER="" # адрес HQ-SRV (без префикса)
PRINTER_NAME="pdf" # имя принтера, как он опубликован на HQ-SRV
CLIENT_PRINTER="pdf_printer" # локальное имя подключения на HQ-CLI
CUPS_PACKAGE="cups" # клиенту нужны утилиты lpadmin/lpstat
# ============ Проверка заполнения переменных ============
MISSING=()
for NAME in CA_ROOT_FILE CUPS_SERVER EXAM_TZ; do
[[ -z "${!NAME}" ]] && MISSING+=("$NAME")
done
if [[ ${#MISSING[@]} -gt 0 ]]; then
echo "Заполните переменные в начале скрипта: ${MISSING[*]}"
exit 1
fi
echo "=== Настройка HQ-CLI, задание 3 ==="
# --- 1. Доверие корневому сертификату ЦС ---
echo "--- Доверие CA ---"
if [[ ! -f "$CA_ROOT_FILE" ]]; then
echo "ДЕЛАЕТСЯ ВРУЧНУЮ: файла $CA_ROOT_FILE нет — скопируйте root.crt с HQ-SRV"
echo " scp root@<адрес HQ-SRV>:$CA_ROOT_FILE "
exit 1
fi
cp "$CA_ROOT_FILE" "$CA_ANCHORS_DIR/"
"$CA_TRUST_CMD" && echo "Хранилище сертификатов обновлено" \
|| echo "ПРОВЕРИТЬ: $CA_TRUST_CMD не выполнился"
echo "Проверка: curl -I https://web.au-team.irpo (не должен писать про сертификат)"
# --- 2. Принтер по умолчанию ---
echo "--- Подключение принтера — $CLIENT_PRINTER <- $CUPS_SERVER:$PRINTER_NAME ---"
dnf install -y "$CUPS_PACKAGE" || echo "ПРОВЕРИТЬ: пакет $CUPS_PACKAGE не установился"
if lpstat -p 2>/dev/null | grep -qw "$CLIENT_PRINTER"; then
echo "Принтер $CLIENT_PRINTER уже подключён"
else
lpadmin -p "$CLIENT_PRINTER" \
-v "ipp://$CUPS_SERVER:631/printers/$PRINTER_NAME" -E \
&& echo "Принтер добавлен" \
|| echo "ПРОВЕРИТЬ: lpadmin не смог добавить принтер (CUPS на HQ-SRV слушает 631?)"
fi
# Назначить принтер по умолчанию (повторно безопасно)
lpoptions -d "$CLIENT_PRINTER" >/dev/null && echo "Принтер по умолчанию: $CLIENT_PRINTER"
lpstat -p -d
# --- 3. Агент Кибер Бэкап — вручную ---
echo ""
echo "ДЕЛАЕТСЯ ВРУЧНУЮ (MANUAL.md): установить агент с функциями узла"
echo "хранилища, подключить к серверу HQ-SRV, создать /backup и выбрать"
echo "её как устройство хранения. Директорию /backup можно создать сейчас:"
mkdir -p /backup && echo " Директория /backup создана"
# --- 4. Часовой пояс ---
timedatectl set-timezone "$EXAM_TZ"
echo ""
echo "=== Самопроверка на HQ-CLI ==="
lpstat -p -d
echo ""
echo "Дополнительные проверки вручную:"
echo " curl -I https://web.au-team.irpo (без предупреждений о сертификате)"
echo " curl -I https://docker.au-team.irpo (без предупреждений + логин WEB/P@ssw0rd на web)"
echo " echo test | lp -d $CLIENT_PRINTER (печать в pdf-принтер)"
echo " ls /var/spool/cups-pdf на HQ-SRV (pdf появился у принтера?)"

182
zadanie3/hq-srv.sh Normal file
View file

@ -0,0 +1,182 @@
#!/bin/bash
# ============================================================
# ЗАДАНИЕ 3. Настройка HQ-SRV (Linux / РЕД ОС 8)
# 4. Центр сертификации: root-CA, сертификаты веб-серверам на 30 дней
# (поставка на ISP и HQ-CLI — вручную, MANUAL.md)
# 5. atop: мониторинг с интервалом 7 минут (420 секунд)
# 6. Спринт-сервер cups: публикация виртуального pdf-принтера
# 8. fail2ban для ssh: порт 2027, 3 попытки, бан 1 минута
# 9. Кибер Бэкап — ДЕЛАЕТСЯ ВРУЧНУЮ (MANUAL.md)
# ============================================================
# --- Проверка прав root ---
if [[ $EUID -ne 0 ]]; then
echo "Запустите скрипт с правами root (sudo bash hq-srv.sh)"
exit 1
fi
# ================= ПЕРЕМЕННЫЕ (заполните перед запуском) =================
EXAM_TZ="Europe/Moscow" # проверить на экзамене
# --- 4. Центр сертификации (openssl; ПРОВЕРИТЬ: по заданию рекомендуются
# отечественные алгоритмы — стандартный openssl гост-подписи не умеет,
# обсудите требования и инструменты с экзаменатором, см. QUESTIONS.md) ---
CA_DIR="/etc/CA" # каталог ЦС (создаётся)
CA_CERT="root.crt" # публичный корневой сертификат
CA_KEY="root.key" # ключ корневого CA
CA_DAYS="3650" # срок корневого сертификата (срок выдачи задан ниже)
CA_SUBJECT="/CN=au-team-CA/O=AU-TEAM" # изменить при желании
CERT_DAYS="30" # срок сертификатов веб-серверов ПО ЗАДАНИЮ
CERT_NAMES="web.au-team.irpo docker.au-team.irpo" # домены по таблице 3
# --- 5. atop ---
ATOP_PACKAGE="atop" # ПРОВЕРИТЬ: пакет atop на РЕД ОС 8
ATOP_SERVICE="atop"
ATOP_CONF="/etc/sysconfig/atop" # ПРОВЕРИТЬ путь конфига atop на РЕД ОС 8
ATOP_INTERVAL="420" # 7 минут по заданию (в секундах)
# --- 6. cups + pdf-принтер ---
CUPS_PACKAGE="cups" # ПРОВЕРИТЬ: пакет/служба CUPS на РЕД ОС 8
CUPS_SERVICE="cups"
CUPS_PDF_PACKAGE="cups-pdf" # ПРОВЕРИТЬ: наличие пакета cups-pdf
PDF_PRINTER="pdf" # имя виртуального pdf-принтера
# --- 8. fail2ban ---
F2B_PACKAGE="fail2ban" # ПРОВЕРИТЬ: пакет и репозиторий fail2ban на РЕД ОС 8
F2B_SERVICE="fail2ban"
F2B_JAIL="/etc/fail2ban/jail.d/exam.local" # перезаписывается целиком
F2B_SSH_PORT="2027" # порт ssh (задание 1, п. 5)
F2B_MAXRETRY="3" # 3 неуспешные попытки по заданию
F2B_BANTIME="60" # бан 1 минута (60 с) по заданию
# ============ Проверка заполнения переменных ============
MISSING=()
for NAME in CA_DIR CA_CERT CA_KEY CA_SUBJECT CERT_NAMES EXAM_TZ; do
[[ -z "${!NAME}" ]] && MISSING+=("$NAME")
done
if [[ ${#MISSING[@]} -gt 0 ]]; then
echo "Заполните переменные в начале скрипта: ${MISSING[*]}"
exit 1
fi
echo "=== Настройка HQ-SRV, задание 3 ==="
# --- 1. Центр сертификации ---
echo "--- ЦС (openssl) ---"
mkdir -p "$CA_DIR" || exit 1
cd "$CA_DIR" || exit 1
if [[ ! -f "$CA_CERT" ]]; then
openssl req -x509 -newkey rsa:2048 -nodes \
-keyout "$CA_KEY" -out "$CA_CERT" -days "$CA_DAYS" \
-subj "${CA_SUBJECT}" \
&& echo "Создан корневой сертификат: $CA_CERT"
else
echo "Корневой сертификат уже существует"
fi
# Сертификаты веб-серверам (для каждого домена: ключ + сертификат со SAN)
for NAME in $CERT_NAMES; do
if [[ -f "$NAME.crt" ]]; then
echo "Сертификат $NAME.crt уже существует"
continue
fi
openssl req -newkey rsa:2048 -nodes -keyout "$NAME.key" \
-out "$NAME.csr" -subj "/CN=$NAME/O=AU-TEAM" \
-addext "subjectAltName=DNS:$NAME"
# Подписываем корневым CA на CERT_DAYS
if openssl x509 -req -in "$NAME.csr" \
-CA "$CA_CERT" -CAkey "$CA_KEY" -CAcreateserial \
-out "$NAME.crt" -days "$CERT_DAYS" \
-extfile <(printf "subjectAltName=DNS:%s" "$NAME"); then
echo "Сертификат выдан: $NAME.crt (на $CERT_DAYS дней)"
else
echo "ПРОВЕРИТЬ: не удалось подписать сертификат $NAME"
fi
done
openssl x509 -in "$CA_CERT" -noout -subject -dates
echo ""
echo "ПРОВЕРИТЬ SAN и срок каждого сертификата:"
for NAME in $CERT_NAMES; do
openssl x509 -in "$NAME.crt" -noout -subject -ext subjectAltName -dates 2>/dev/null
done
# --- 2. atop: интервал 420 с ---
echo "--- atop (интервал $ATOP_INTERVAL c) ---"
dnf install -y "$ATOP_PACKAGE" || echo "ПРОВЕРИТЬ: пакет $ATOP_PACKAGE не установился"
if [[ -f "$ATOP_CONF" ]]; then
if grep -qE "^(LOG)?INTERVAL=" "$ATOP_CONF"; then
sed -ri "s/^(LOG)?INTERVAL=[0-9]+/INTERVAL=$ATOP_INTERVAL/" "$ATOP_CONF"
else
echo "INTERVAL=$ATOP_INTERVAL" >> "$ATOP_CONF"
fi
echo "Интервал задан в $ATOP_CONF"
else
echo "INTERVAL=$ATOP_INTERVAL" > "$ATOP_CONF"
echo "Создан $ATOP_CONF (ПРОВЕРИТЬ, подхватывается ли конфиг службой)"
fi
systemctl enable --now "$ATOP_SERVICE" \
|| { echo "ПРОВЕРИТЬ: служба $ATOP_SERVICE не запустилась"; systemctl status "$ATOP_SERVICE" --no-pager; }
# --- 3. cups + виртуальный pdf-принтер ---
echo "--- cups / pdf-принтер ---"
dnf install -y "$CUPS_PACKAGE" || echo "ПРОВЕРИТЬ: пакет $CUPS_PACKAGE не установился"
dnf install -y "$CUPS_PDF_PACKAGE" || echo "ПРОВЕРИТЬ: пакет $CUPS_PDF_PACKAGE не установился (нет ли аналога в репозитории?)"
systemctl enable --now "$CUPS_SERVICE" \
|| { echo "ПРОВЕРИТЬ: служба $CUPS_SERVICE не запустилась"; systemctl status "$CUPS_SERVICE" --no-pager; }
# Публикация принтера (создание + включение как общий) — без дублей
if lpstat -p 2>/dev/null | grep -qw "$PDF_PRINTER"; then
echo "Принтер $PDF_PRINTER уже есть"
else
lpadmin -p "$PDF_PRINTER" -v cups-pdf:/ -E -o printer-is-shared=true \
&& echo "Публикуем принтер $PDF_PRINTER" \
|| echo "ПРОВЕРИТЬ: не удалось опубликовать принтер — сделать через веб-интерфейс CUPS вручную"
fi
# Слушать на всех интерфейсах, чтобы HQ-CLI подключился по сети (ПРОВЕРИТЬ)
if ! grep -qE "^Port 631|^Listen [^[:space:]]*:631" /etc/cups/cupsd.conf 2>/dev/null \
|| grep -qE "^Listen localhost:631" /etc/cups/cupsd.conf 2>/dev/null; then
sed -i "s/^Listen localhost:631/Port 631/" /etc/cups/cupsd.conf
if ! grep -qE "^Port 631|^Listen [^[:space:]]*:631" /etc/cups/cupsd.conf; then
echo "Port 631" >> /etc/cups/cupsd.conf
fi
systemctl restart "$CUPS_SERVICE"
fi
lpstat -p
# --- 4. fail2ban для ssh ---
echo "--- fail2ban (порт $F2B_SSH_PORT, $F2B_MAXRETRY попыток, $F2B_BANTIME c) ---"
dnf install -y "$F2B_PACKAGE" || echo "ПРОВЕРИТЬ: пакет $F2B_PACKAGE не установился (репозиторий EPEL?)"
mkdir -p /etc/fail2ban/jail.d
cat > "$F2B_JAIL" <<EOF
[DEFAULT]
bantime = $F2B_BANTIME
maxretry = $F2B_MAXRETRY
[sshd]
enabled = true
port = $F2B_SSH_PORT
EOF
mkdir -p /var/run/fail2ban
systemctl enable --now "$F2B_SERVICE" \
|| { echo "ПРОВЕРИТЬ: служба $F2B_SERVICE не запустилась"; systemctl status "$F2B_SERVICE" --no-pager; }
# --- 5. Кибер Бэкап — вручную ---
echo ""
echo "ДЕЛАЕТСЯ ВРУЧНУЮ (MANUAL.md): развёртывание Кибер Бэкап, подразделение"
echo "ирпо, пользователь irpoadmin / P@ssw0rd, план копирования /etc на узел HQ-CLI."
# --- 6. Часовой пояс ---
timedatectl set-timezone "$EXAM_TZ"
echo ""
echo "=== Самопроверка на HQ-SRV ==="
echo "Корневой сертификат и сертификаты:"
ls -l "$CA_DIR"
echo ""
echo "fail2ban статус:"
fail2ban-client status sshd 2>/dev/null || echo "ПРОВЕРИТЬ: fail2ban-client status sshd"
echo ""
echo "Дополнительные проверки вручную:"
echo " systemd-analyze verify atop 2>/dev/null; journalctl -u $ATOP_SERVICE --since -5min"
echo " cat $ATOP_CONF (INTERVAL=420?)"
echo " lpstat -p (принтер $PDF_PRINTER и активен?)"
echo " ssh -p $F2B_SSH_PORT wronguser@localhost (3 раза с неверным паролем -> fail2ban-client status sshd => banned)"

155
zadanie3/isp.sh Normal file
View file

@ -0,0 +1,155 @@
#!/bin/bash
# ============================================================
# ЗАДАНИЕ 3. Обратный прокси-сервер на ISP (Linux / РЕД ОС 8)
# 2. Реверс-прокси на nginx:
# web.au-team.irpo -> веб-приложение на HQ-SRV
# docker.au-team.irpo -> testapp на BR-SRV
# 3. Web-based аутентификация на web.au-team.irpo (WEB / P@ssw0rd)
# 4. HTTPS: сертификаты выдаёт ЦС на HQ-SRV (zadanie3/hq-srv.sh) и
# доставляются вручную (MANUAL.md) — после этого задайте
# TLS_CERT_FILE/TLS_KEY_FILE и запустите скрипт повторно.
# ВНИМАНИЕ: проброс 8080 с роутеров (задание 2) больше не основной
# путь — клиенты заходят через ISP по доменному имени на 80/443.
# ============================================================
# --- Проверка прав root ---
if [[ $EUID -ne 0 ]]; then
echo "Запустите скрипт с правами root (sudo bash isp.sh)"
exit 1
fi
# ================= ПЕРЕМЕННЫЕ (заполните перед запуском) =================
NGINX_PACKAGE="nginx" # ПРОВЕРИТЬ: пакет reverse-proxy на РЕД ОС 8
NGINX_SERVICE="nginx"
PROXY_CONF="/etc/nginx/conf.d/exam-proxy.conf" # перезаписывается целиком
WEB_DOMAIN="web.au-team.irpo" # из таблицы 3
DOCKER_DOMAIN="docker.au-team.irpo" # из таблицы 3
HQ_SRV_WEB="" # адрес:порт веб-приложения HQ-SRV, формат IP:порт (apache:80)
BR_SRV_APP="" # адрес:порт testapp на BR-SRV, формат IP:порт (8080)
WEB_LOGIN="WEB" # логин web-аутентификации по заданию
WEB_PASS="P@ssw0rd" # пароль web-аутентификации по заданию
HTPASSWD_FILE="/etc/nginx/exam-web.htpasswd"
# --- HTTPS (п. 4 задания 3): после ручной доставки сертификатов — заполнить ---
TLS_CERT_FILE="" # путь к сертификату на этом ISP (web/docker domain, SAN)
TLS_KEY_FILE="" # путь к связанному ключу
EXAM_TZ="Europe/Moscow" # проверить на экзамене
# ============ Проверка заполнения переменных ============
MISSING=()
for NAME in HQ_SRV_WEB BR_SRV_APP EXAM_TZ; do
[[ -z "${!NAME}" ]] && MISSING+=("$NAME")
done
if [[ ${#MISSING[@]} -gt 0 ]]; then
echo "Заполните переменные в начале скрипта: ${MISSING[*]}"
exit 1
fi
echo "=== Обратный прокси на ISP ==="
dnf install -y "$NGINX_PACKAGE" || echo "ПРОВЕРИТЬ: пакет $NGINX_PACKAGE не установился"
# --- 1. Файл с паролем web-аутентификации (htpasswd через openssl) ---
echo "--- Базовая аутентификация ($WEB_DOMAIN) ---"
PASS_HASH=$(openssl passwd -apr1 "$WEB_PASS")
printf "%s:%s\n" "$WEB_LOGIN" "$PASS_HASH" > "$HTPASSWD_FILE"
chmod 640 "$HTPASSWD_FILE"
echo "Записан $HTPASSWD_FILE (логин $WEB_LOGIN)"
# --- 2. Конфигурация прокси ---
echo "--- Конфиг прокси ---"
if [[ -n "$TLS_CERT_FILE" && -n "$TLS_KEY_FILE" ]]; then
if [[ ! -f "$TLS_CERT_FILE" || ! -f "$TLS_KEY_FILE" ]]; then
echo "Ошибка: TLS_CERT_FILE/TLS_KEY_FILE указаны, но файлов нет!"
exit 1
fi
cat > "$PROXY_CONF" <<EOF
server {
listen 80;
server_name $WEB_DOMAIN;
return 301 https://\$host\$request_uri;
}
server {
listen 443 ssl;
server_name $WEB_DOMAIN;
ssl_certificate $TLS_CERT_FILE;
ssl_certificate_key $TLS_KEY_FILE;
auth_basic "Authorized access only";
auth_basic_user_file $HTPASSWD_FILE;
location / {
proxy_pass http://$HQ_SRV_WEB;
proxy_set_header Host \$host;
}
}
server {
listen 80;
server_name $DOCKER_DOMAIN;
return 301 https://\$host\$request_uri;
}
server {
listen 443 ssl;
server_name $DOCKER_DOMAIN;
ssl_certificate $TLS_CERT_FILE;
ssl_certificate_key $TLS_KEY_FILE;
location / {
proxy_pass http://$BR_SRV_APP;
proxy_set_header Host \$host;
}
}
EOF
echo "Режим: HTTPS (443) + редирект с 80"
else
# Временный вариант до доставки сертификатов: чистый HTTP
cat > "$PROXY_CONF" <<EOF
server {
listen 80;
server_name $WEB_DOMAIN;
auth_basic "Authorized access only";
auth_basic_user_file $HTPASSWD_FILE;
location / {
proxy_pass http://$HQ_SRV_WEB;
proxy_set_header Host \$host;
}
}
server {
listen 80;
server_name $DOCKER_DOMAIN;
location / {
proxy_pass http://$BR_SRV_APP;
proxy_set_header Host \$host;
}
}
EOF
echo "Обходный режим: HTTP. После выдачи сертификата (hq-srv.sh) и копирования"
echo " cert/key вручную задайте TLS_CERT_FILE/TLS_KEY_FILE и ПОВТОРИТЕ скрипт."
fi
nginx -t && echo "Конфиг nginx корректен" || { echo "ОШИБКА nginx -t"; exit 1; }
systemctl enable --now "$NGINX_SERVICE" \
|| { echo "ПРОВЕРИТЬ: служба $NGINX_SERVICE не запустилась"; systemctl status "$NGINX_SERVICE" --no-pager; }
# --- 3. Доступность серверов из ISP ---
# ISP напрямую знает только сети линков /28 к маршрутизаторам. До
# HQ-SRV/BR-SRV трафик идёт через офисы — если curl с ISP не работает,
# добавьте статические маршруты вручную:
echo "Если curl не работает от ISP до HQ-SRV/BR-SRV — добавьте маршруты вручную:"
echo " ip route add <сеть офиса HQ а/п> via <адрес HQ-RTR на линке>"
echo " ip route add <сеть офиса BR а/п> via <адрес BR-RTR на линке>"
# --- 4. Часовой пояс ---
timedatectl set-timezone "$EXAM_TZ"
echo ""
echo "=== Самопроверка на ISP ==="
echo "curl для проверки прокси (HTTP-режим, с аутентификацией):"
echo " curl -u $WEB_LOGIN:$WEB_PASS http://$WEB_DOMAIN -I"
echo " curl http://$DOCKER_DOMAIN -I"
echo "curl для режима HTTPS: замените http на https"