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