Введение
iptables — это интерфейс командной строки для управления правилами фильтрации пакетов в Linux. Хотя во многих современных дистрибутивах эти правила реализуются через внутреннюю систему nftables, администраторам по-прежнему приходится работать с задачами и существующими системами, использующими синтаксис команды iptables.
Для начала удобно представить брандмауэр как упорядоченный список проверок. Пакет попадает в цепочку, каждое правило проверяет, соответствует ли он таким условиям, как интерфейс, протокол или порт, а цель, например ACCEPT или REJECT, определяет дальнейшее действие. Цепочка INPUT обрабатывает пакеты, адресованные локальному хосту. Поскольку правила проверяются сверху вниз, важны как их содержимое, так и положение в цепочке.
В этой лабораторной работе вы будете работать с одним локальным веб-сервисом и внесёте минимальные изменения только для его TCP-порта. Вы проверите текущее состояние брандмауэра, добавите правило для отклонения запросов, подтвердите его действие реальным трафиком, замените это правило явным разрешением, а затем удалите созданное в рамках лабораторной работы правило, не очищая и не переписывая остальные настройки брандмауэра.
Проверка брандмауэра и тестового сервиса
На этом этапе вы определите установленную реализацию iptables и убедитесь, что локальный тестовый сервис работает, прежде чем изменять правила брандмауэра.
Перейдите в каталог проекта, чтобы все последующие команды выполнялись из рабочего каталога курса.
cd /home/labex/project
Используйте command -v, чтобы определить исполняемый файл, который будет запускаться вашей оболочкой.
command -v iptables
Такая проверка надёжнее, чем предположение, что команда установлена: она показывает фактический путь к исполняемому файлу, обычно /usr/sbin/iptables, и возвращает ненулевой код завершения, если оболочка не может его найти.
Выведите сведения о версии и внутренней системе. На этом хосте Ubuntu в выводе обычно присутствует nf_tables; это означает, что привычный синтаксис iptables преобразуется в современную внутреннюю систему правил ядра.
sudo iptables --version
Вы должны увидеть вывод, похожий на следующий:
iptables v1.8... (nf_tables)
Название внутренней системы не меняет команды в этой лабораторной работе. Вы по-прежнему будете создавать и проверять правила с помощью iptables, а реализация сама отвечает за их представление в ядре.
Прежде чем фильтровать порт, обратитесь к конечной точке проверки состояния сервиса. Успешный ответ подтверждает готовность приложения, поэтому последующий сбой можно будет связать именно с правилом брандмауэра.
curl --noproxy '*' --fail --silent http://127.0.0.1:18086/health
Здесь 127.0.0.1 — IPv4-адрес обратной связи. Поэтому трафик выходит через локальный интерфейс lo и возвращается через него же, не попадая во внешнюю сеть. Параметр --noproxy '*' не позволяет настройкам прокси перенаправить запрос, --fail заставляет curl возвращать ошибку при HTTP-сбое, а --silent скрывает индикатор выполнения, чтобы ответ сервиса было проще прочитать.
Сервис возвращает:
iptables filter service ready
Проверка цепочки INPUT и добавление правила отклонения
На этом этапе вы изучите текущую цепочку INPUT и добавите одно точечное правило, отклоняющее TCP-трафик через обратный интерфейс к тестовому порту.
Параметр -S выводит правила в форме, похожей на команды. Указание INPUT ограничивает вывод пакетами, предназначенными для этого хоста.
sudo iptables -S INPUT
В первой строке обычно отображается политика цепочки, например -P INPUT ACCEPT. Политика используется как резервное действие только в том случае, если ни одно предыдущее правило не приняло окончательного решения. Следующие строки, начинающиеся с -A INPUT, содержат правила, добавленные в эту цепочку.
Для просмотра в эксплуатационном формате параметр -L выводит список правил цепочки, -n отключает медленное разрешение имён, а --line-numbers показывает позицию каждого правила. Порядок правил имеет значение: результат пакета определяется первой совпавшей завершающей целью.
Добавьте правило на позицию 1 с помощью -I INPUT 1. Оно соответствует интерфейсу обратной связи lo, протоколу TCP и порту назначения 18086. Цель REJECT с параметром tcp-reset немедленно отклоняет соединение, не заставляя клиент ждать истечения времени ожидания для отброшенного пакета.
sudo iptables -I INPUT 1 -i lo -p tcp --dport 18086 -j REJECT --reject-with tcp-reset
Читайте команду слева направо: -i lo ограничивает входящий интерфейс, -p tcp выбирает протокол, --dport 18086 задаёт сервис, а -j REJECT передаёт обработку цели отклонения. Параметр -I вставляет правило в указанную позицию; напротив, -A добавил бы его в конец цепочки, где более раннее совпадающее правило могло бы не позволить до него дойти. Такое точное сочетание условий не блокирует другие порты и внешние интерфейсы.
REJECT и DROP работают по-разному. REJECT отправляет ответ об ошибке, а DROP молча отбрасывает пакет. Сброс TCP позволяет этому локальному тесту завершиться быстро и предсказуемо, что удобнее для диагностики, чем ожидание тайм-аута.
Используйте -C, чтобы проверить наличие именно этого правила. При успешной проверке команда завершается с кодом 0. В данной системе реализация на базе nftables также выводит нормализованное правило; другие реализации могут завершать проверку без вывода.
sudo iptables -C INPUT -i lo -p tcp --dport 18086 -j REJECT --reject-with tcp-reset
Портативным результатом -C является код завершения, а не наличие текста на экране. Поэтому эту же команду удобно использовать в сценариях оболочки и автоматизированных проверках.
Снова выведите цепочку. Новое правило должно находиться на позиции 1 и содержать обозначение tcp dpt:18086.
sudo iptables -L INPUT -n --line-numbers
Проверка заблокированного трафика
На этом этапе вы повторите исходный запрос и проверите счётчики правила, чтобы доказать: трафик отклонил брандмауэр, а не приложение.
Выполните запрос внутри конструкции if. Поскольку запрос должен завершиться ошибкой, ветка else преобразует ожидаемый сбой в понятное сообщение и позволяет продолжить выполнение лабораторной работы.
if curl --noproxy '*' --fail --silent http://127.0.0.1:18086/health; then
echo "Unexpected: request succeeded"
else
echo "Expected: iptables rejected the request"
fi
Условия оболочки принимают решение по коду завершения команды: нулевой код выбирает ветку then, а ненулевой — else. Отправленный брандмауэром сброс заставляет curl завершиться с ненулевым кодом, поэтому переход в ветку else является ожидаемым результатом.
Ожидаемое сообщение:
Expected: iptables rejected the request
Теперь выведите цепочку с параметром -v, чтобы увидеть подробные счётчики. После запроса значения количества пакетов и байтов у правила для порта 18086 должны быть больше нуля.
sudo iptables -L INPUT -n -v --line-numbers
В выводе столбец pkts содержит количество совпавших пакетов, а bytes — их общий размер. Счётчики служат важным подтверждением: проверка с помощью -C доказывает наличие правила, а увеличение счётчика показывает, что реальный трафик достиг правила и совпал с ним. Если счётчик остался равен нулю, проверьте интерфейс, протокол, порт и положение правила, прежде чем искать причину в приложении.
Замена правила отклонения правилом разрешения
На этом этапе вы удалите точное правило отклонения, добавите явное правило разрешения для того же трафика и убедитесь, что доступ восстановился.
Приведённая ниже форма -D идентифицирует правило по полному набору условий и цели. Это безопаснее, чем очищать цепочку, поскольку удаляется только изменение, внесённое в рамках лабораторной работы.
sudo iptables -D INPUT -i lo -p tcp --dport 18086 -j REJECT --reject-with tcp-reset
Правила также можно удалять по номеру строки, однако номера меняются при добавлении и удалении правил. Удаление по точному описанию понятнее в повторяемой процедуре и снижает вероятность удаления соседнего правила. Не используйте здесь iptables -F: очистка удалит все правила выбранной цепочки, включая правила, не относящиеся к этой лабораторной работе.
Добавьте правило ACCEPT для того же интерфейса, протокола и порта.
sudo iptables -I INPUT 1 -i lo -p tcp --dport 18086 -j ACCEPT
ACCEPT разрешает совпавшему пакету продолжить обработку в сетевом стеке. Правило добавляется на позицию 1, чтобы его результат не перекрывался более ранним завершающим правилом. Обратите внимание: условия совпадения остались такими же точными, как и раньше; изменилась только цель.
Проверьте точное правило разрешения.
sudo iptables -C INPUT -i lo -p tcp --dport 18086 -j ACCEPT
Повторите исходный запрос к конечной точке состояния.
curl --noproxy '*' --fail --silent http://127.0.0.1:18086/health
Ответ снова доступен:
iptables filter service ready
Удаление правила, созданного в рамках лабораторной работы
На этом этапе вы удалите временное правило разрешения и убедитесь, что после упражнения не осталось созданных вами правил.
Удалите точное правило ACCEPT. Как и прежде, эта команда не очищает цепочку и не затрагивает правила, принадлежащие платформе или другому администратору.
sudo iptables -D INPUT -i lo -p tcp --dport 18086 -j ACCEPT
Удаление явного правила разрешения не означает автоматически, что сервис будет заблокирован. После удаления правила оставшиеся правила и, наконец, политика цепочки определяют судьбу пакета. В подготовленной среде исходный брандмауэр разрешает локальный запрос.
Снова проверьте наличие правила. На этот раз ошибка ожидаема, поэтому || выполнит сообщение справа только в том случае, если iptables -C вернёт ненулевой код завершения.
sudo iptables -C INPUT -i lo -p tcp --dport 18086 -j ACCEPT 2>/dev/null || echo "Lab allow rule removed"
Вы должны увидеть:
Lab allow rule removed
В завершение убедитесь, что удаление явного правила не остановило приложение. Доступ снова определяется исходной политикой и правилами цепочки.
curl --noproxy '*' --fail --silent http://127.0.0.1:18086/health
Итоги
Вы определили реализацию iptables и изучили цепочку INPUT, добавили и проверили точное правило отклонения, подтвердили его действие реальным трафиком и счётчиками, заменили его правилом разрешения и удалили только изменение, внесённое в рамках лабораторной работы. Эти операции дают необходимую практику управления фильтрацией пакетов на уровне команд и помогают безопасно работать с брандмауэром, не очищая несвязанные настройки.



