Files
cyber-security/lab4/README.md
2026-04-04 10:21:42 +03:00

537 lines
20 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Сетевые адаптеры:
Adapter 1: NAT
для выхода в интернет (DNS, HTTP)
Adapter 2: Internal Network
имя: intnet
для связи с VM2
sudo vim /etc/netplan/01-netcfg.yaml
network:
version: 2
ethernets:
enp0s3: # NAT
dhcp4: true
enp0s8: # internal
addresses: [192.168.100.1/24]
network:
version: 2
ethernets:
enp0s3: # NAT
dhcp4: true
enp0s8: # internal
addresses: [192.168.100.2/24]
sudo chmod 600 /etc/netplan/01-netcfg.yaml
sudo netplan apply
sudo iptables -F
sudo iptables -X
sudo iptables -t nat -F
Ниже — учебная инструкция **только для настройки и проверки iptables**, без шагов про установку ОС, VirtualBox, netplan и утилит. Будем исходить из твоего текущего стенда:
* `firewall-host` — защищаемый хост, IP `192.168.100.1`
* `external-client` — внешний клиент, IP `192.168.100.2`
* у обеих машин есть NAT-интерфейс `enp0s3`
* внутренний интерфейс — `enp0s8`
* SSH к обеим машинам у тебя уже работает через проброс портов VirtualBox на `127.0.0.1:40001` и `127.0.0.1:40002`
Политика лабы: разрешить loopback, DNS, ping наружу, ping к защищаемому хосту только с одного IP, HTTP/HTTPS, а всё остальное запретить. Это прямо соответствует тексту задания.
---
# 2. Сначала разрешаем SSH, чтобы не отрезать себе доступ
Так как ты подключаешься к `firewall-host` по SSH, нужно **до включения блокировки** разрешить входящие SSH-подключения.
В твоём случае подключение приходит на саму Ubuntu-машину уже **после NAT VirtualBox**, то есть для Linux это обычный входящий TCP на порт `22`.
Выполни на `firewall-host`:
```bash
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
```
Пояснение:
* `-A INPUT` — добавить правило в конец цепочки `INPUT`, которая обрабатывает пакеты, входящие на этот хост.
* `-p tcp` — правило относится только к протоколу TCP.
* `--dport 22` — порт назначения 22, то есть SSH-сервер.
* `-j ACCEPT` — разрешить такой трафик.
Теперь разрешим ответы сервера по уже установленному SSH-соединению:
```bash
sudo iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
```
Пояснение:
* `-A OUTPUT` — добавить правило в цепочку `OUTPUT`, то есть для пакетов, исходящих с этого хоста.
* `-p tcp` — правило касается TCP.
* `--sport 22` — исходный порт 22; это ответы SSH-сервера клиенту.
* `-j ACCEPT` — разрешить.
Такой вариант рабочий, но в Linux обычно лучше использовать правило состояний соединений. Поэтому следующим шагом мы добавим его тоже.
---
# 3. Разрешаем уже установленные и связанные соединения
Это одно из самых важных правил. Оно позволяет не расписывать вручную каждый ответный пакет.
```bash
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
```
Пояснение:
* `-A INPUT` — правило для входящих пакетов.
* `-m conntrack` — подключить модуль отслеживания состояний соединений.
* `--ctstate ESTABLISHED,RELATED` — матчить пакеты:
* `ESTABLISHED` — относящиеся к уже установленному соединению;
* `RELATED` — связанные с уже существующим соединением.
* `-j ACCEPT` — разрешить.
И аналогично для исходящих:
```bash
sudo iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
```
Пояснение:
* здесь то же самое, но для исходящих пакетов.
Это правило особенно важно для:
* SSH-сессии, в которой ты уже сидишь;
* ответов от DNS-сервера;
* ответов от HTTP/HTTPS-серверов;
* ответов на исходящий ping (`echo-reply`).
**Порядок имеет значение.** Раз это правило стоит **раньше**, чем узкие правила вида «принять UDP/TCP с `--sport 53` или TCP с `--sport 80/443`» или «`echo-reply`», то **все ответные пакеты** по уже разрешённым исходящим запросам срабатывают здесь. Отдельные строки `INPUT` для `sport` DNS/HTTP(S) и для входящего `echo-reply` становятся **лишними**: до них очередь не дойдёт, а счётчики у таких правил останутся нулевыми.
На `INPUT` в учебной конфигурации **осмысленно оставить** явные разрешения только для **нового** входящего трафика, которое не описывается как `ESTABLISHED`/`RELATED`: SSH (если нужен), loopback и входящий `echo-request` только с разрешённого адреса (см. раздел 8).
---
# 4. Разрешаем loopback
Loopback — это локальное взаимодействие внутри самой ОС через интерфейс `lo`. По условию лабы его нужно разрешить.
```bash
sudo iptables -A INPUT -i lo -j ACCEPT
```
Пояснение:
* `-i lo` — входящий интерфейс `lo`, то есть loopback.
* `-j ACCEPT` — разрешить.
```bash
sudo iptables -A OUTPUT -o lo -j ACCEPT
```
Пояснение:
* `-o lo` — исходящий интерфейс `lo`.
* `-j ACCEPT` — разрешить.
---
# 5. Разрешаем DNS
По условию нужно разрешить взаимодействие с DNS-сервером. Обычно DNS-запросы идут по UDP на порт `53`. Иногда может использоваться и TCP 53, поэтому для учебной работы лучше разрешить оба варианта.
## UDP DNS
```bash
sudo iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
```
Пояснение:
* `-A OUTPUT` — правило для исходящих запросов.
* `-p udp` — DNS чаще всего использует UDP.
* `--dport 53` — порт назначения 53, стандартный порт DNS.
* `-j ACCEPT` — разрешить.
Входящие ответы DNS (UDP с `sport 53`) после этого правила пропускаются правилом `ESTABLISHED,RELATED` на `INPUT`; отдельная строка `INPUT --sport 53` не нужна и при типичном порядке правил всё равно не получила бы трафика.
## TCP DNS
```bash
sudo iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT
```
Пояснение:
* TCP используется реже, но может понадобиться для больших DNS-ответов или специальных случаев.
* входящие TCP-ответы от DNS идут через `ESTABLISHED,RELATED` на `INPUT`.
---
# 6. Разрешаем HTTP и HTTPS
По заданию нужно разрешить доступ к любым внешним серверам по HTTP/HTTPS.
## HTTP
```bash
sudo iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT
```
Пояснение:
* `-p tcp` — HTTP работает по TCP.
* `--dport 80` — порт назначения 80, стандартный HTTP.
* правило разрешает открывать веб-страницы по HTTP.
Входящие ответы HTTP (и далее HTTPS) принимаются правилом `ESTABLISHED,RELATED` на `INPUT`; отдельное `INPUT --sport 80` не требуется.
## HTTPS
```bash
sudo iptables -A OUTPUT -p tcp --dport 443 -j ACCEPT
```
Пояснение:
* порт 443 — стандартный HTTPS.
Входящие ответы HTTPS обрабатываются на `INPUT` через `ESTABLISHED,RELATED`.
---
# 7. Разрешаем ping наружу
По заданию нужно разрешить использование `ping` для проверки достижимости любых компьютеров во внешней сети. Для `ping` используется протокол ICMP. Конкретно запрос — это `echo-request`, ответ — `echo-reply`.
```bash
sudo iptables -A OUTPUT -p icmp --icmp-type echo-request -j ACCEPT
```
Пояснение:
* `-p icmp` — правило для протокола ICMP.
* `--icmp-type echo-request` — ICMP-пакеты типа “эхо-запрос”, то есть сам ping-запрос.
* `-j ACCEPT` — разрешить отправку.
Ответы `echo-reply` на этот исходящий ping ядро относит к той же «сессии»; на `INPUT` они проходят через `ESTABLISHED,RELATED`. Отдельное правило `INPUT -p icmp --icmp-type echo-reply` не обязательно и при раннем conntrack дублирует его бесполезно.
---
# 8. Разрешаем ping к защищаемому хосту только с одного адреса
По заданию защищаемый хост должен отвечать на ping только от одного конкретного внешнего адреса. В твоём стенде таким адресом будет `192.168.100.2`, то есть `external-client`.
```bash
sudo iptables -A INPUT -p icmp --icmp-type echo-request -s 192.168.100.2 -d 192.168.100.1 -j ACCEPT
```
Пояснение:
* `-p icmp` — ICMP.
* `--icmp-type echo-request` — входящий ping-запрос.
* `-s 192.168.100.2` — источник должен быть именно `192.168.100.2`.
* `-d 192.168.100.1` — адрес назначения — защищаемый хост.
* `-j ACCEPT` — разрешить.
```bash
sudo iptables -A OUTPUT -p icmp --icmp-type echo-reply -s 192.168.100.1 -d 192.168.100.2 -j ACCEPT
```
Пояснение:
* это правило разрешает отправку ответа ping именно этому клиенту.
* `-s 192.168.100.1` — источник ответа, сам firewall-host.
* `-d 192.168.100.2` — получатель ответа, только разрешённый клиент.
---
# 9. Только теперь включаем политику DROP по умолчанию
Когда все разрешающие правила уже стоят, можно включить запрет всего остального.
```bash
sudo iptables -P INPUT DROP
```
Пояснение:
* `-P` — установить политику по умолчанию для цепочки.
* `INPUT` — цепочка входящих пакетов.
* `DROP` — все пакеты, которые не подошли ни под одно разрешающее правило, будут отбрасываться.
```bash
sudo iptables -P OUTPUT DROP
```
Пояснение:
* то же самое для исходящих пакетов.
```bash
sudo iptables -P FORWARD DROP
```
Пояснение:
* цепочка `FORWARD` нужна для транзитных пакетов через хост.
* в этой лабораторной маршрутизатор делать не требуется, поэтому безопасно оставить `DROP`.
---
# 10. Проверяем, что SSH не отвалился
Сразу после установки политик выполни:
```bash
sudo iptables -L -n -v --line-numbers
```
Пояснение:
* убедись, что правила SSH, conntrack, loopback, исходящие DNS/HTTP(S)/ICMP и узкое правило входящего ping с `192.168.100.2` стоят в списке.
* на `INPUT` основной рост счётчиков у «ответного» трафика обычно виден у строки `ESTABLISHED,RELATED`, а не у отдельных `--sport` (если ты их вообще не добавляешь).
Открой **вторую SSH-сессию** к `firewall-host`:
```bash
ssh -p 40001 arity@127.0.0.1
```
Пояснение:
* это контрольная проверка.
* пока первая сессия ещё жива, ты проверяешь, что новое подключение тоже проходит.
* если вторая сессия открылась, значит SSH точно не заблокирован.
---
# 11. Проверка правил по заданию
## Проверка DNS
На `firewall-host`:
```bash
nslookup example.com
```
Пояснение:
* `nslookup` отправляет DNS-запрос серверу имён.
* если команда возвращает IP-адрес сайта, значит DNS разрешён.
## Проверка HTTP
```bash
curl http://example.com
```
Пояснение:
* `curl` делает HTTP-запрос к веб-серверу.
* если приходит HTML-ответ, правило HTTP работает.
## Проверка HTTPS
```bash
curl https://example.com
```
Пояснение:
* то же самое, но по HTTPS на порт 443.
## Проверка ping наружу
```bash
ping -c 4 8.8.8.8
```
Пояснение:
* `ping` — утилита проверки достижимости узла.
* `-c 4` — отправить только 4 запроса, а не бесконечно.
* `8.8.8.8` — внешний IP-адрес.
* если ответы приходят, исходящий ping разрешён.
## Проверка ping к защищаемому хосту с разрешённого адреса
На `external-client`:
```bash
ping -c 4 192.168.100.1
```
Пояснение:
* клиент `192.168.100.2` должен успешно пинговать `firewall-host`, потому что именно этот источник разрешён.
## Проверка блокировки лишнего трафика
Надёжный вариант — **TCP на порт, который не разрешён политикой**, на второй ВМ в `intnet` (у тебя это `external-client`).
На `external-client` подними слушатель на порт, например `8080`:
```bash
python3 -m http.server 8080
```
На `firewall-host` попробуй подключиться:
```bash
timeout 5 nc -vz 192.168.100.2 8080
```
Пояснение:
* исходящий TCP на `192.168.100.2:8080` не попадает под разрешённые `dport 53`/`80`/`443`, поэтому при политике `OUTPUT DROP` соединение не устанавливается (обычно таймаут).
* проверка к `example.com:22` для отчёта часто бессмысленна: порт 22 у публичных имён часто закрыт независимо от твоего МЭ.
---
# 12. Контроль трафика через tcpdump
По заданию нужно показать прохождение пакетов через `tcpdump`.
Общий просмотр трафика:
```bash
sudo tcpdump -i any -n
```
Пояснение:
* `tcpdump` — сниффер пакетов.
* `-i any` — слушать все интерфейсы сразу.
* `-n` — не преобразовывать адреса в имена.
Просмотр только ICMP:
```bash
sudo tcpdump -i any -n icmp
```
Пояснение:
* фильтр `icmp` покажет только ping-трафик.
Просмотр DNS:
```bash
sudo tcpdump -i any -n port 53
```
Пояснение:
* `port 53` — показать DNS-пакеты.
Просмотр HTTP/HTTPS:
```bash
sudo tcpdump -i any -n 'tcp port 80 or tcp port 443'
```
Пояснение:
* кавычки нужны, чтобы shell корректно передал выражение целиком.
* `or` — логическое “или”.
* выражение показывает трафик к HTTP и HTTPS.
Просмотр SSH:
```bash
sudo tcpdump -i any -n tcp port 22
```
Пояснение:
* поможет убедиться, что SSH-пакеты действительно проходят через фильтр.
---
# 13. Сохранение правил
Когда убедишься, что всё работает, сохрани конфигурацию:
```bash
sudo netfilter-persistent save
```
Пояснение:
* `netfilter-persistent` сохраняет текущие правила iptables, чтобы они восстановились после перезагрузки.
Можно дополнительно сохранить в файл:
```bash
sudo iptables-save > ~/iptables-lab4.rules
```
Пояснение:
* это текстовый дамп всех правил.
* удобно приложить к отчёту или использовать для восстановления.
---
# 14. Готовый набор команд в правильном порядке
Ниже — тот же порядок, но компактным блоком, чтобы ты мог выполнять по шагам:
```bash
sudo iptables-save > ~/iptables-before-lab.rules
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
sudo iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A OUTPUT -o lo -j ACCEPT
sudo iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
sudo iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT
sudo iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A OUTPUT -p tcp --dport 443 -j ACCEPT
sudo iptables -A OUTPUT -p icmp --icmp-type echo-request -j ACCEPT
sudo iptables -A INPUT -p icmp --icmp-type echo-request -s 192.168.100.2 -d 192.168.100.1 -j ACCEPT
sudo iptables -A OUTPUT -p icmp --icmp-type echo-reply -s 192.168.100.1 -d 192.168.100.2 -j ACCEPT
sudo iptables -P INPUT DROP
sudo iptables -P OUTPUT DROP
sudo iptables -P FORWARD DROP
```
---
# 16. Что написать в учебном смысле про SSH как “дополнение”
Можно формулировать так:
> В базовом задании SSH не входит в перечень разрешённого трафика, однако для сохранения удалённого доступа к стенду было добавлено дополнительное правило, разрешающее входящие TCP-соединения на порт 22 защищаемого хоста. Правило было установлено до включения политик DROP по умолчанию, чтобы не потерять административный доступ к системе.
Это хорошо звучит и по сути верно.