537 lines
20 KiB
Markdown
537 lines
20 KiB
Markdown
Сетевые адаптеры:
|
||
|
||
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 по умолчанию, чтобы не потерять административный доступ к системе.
|
||
|
||
Это хорошо звучит и по сути верно.
|