Введение

Представляю вашему вниманию продолжение своей предыдущей статьи. Здесь мы рассмотрим, как выпустить хосты в интернет через сервер с помощью утилиты iptables и как фильтровать входящие, исходящие или проходящие соединения.

Считаю важным сказать, что статья лишь демонстрирует, как могут работать некоторые сетевые технологии в Linux. Моральное и физическое устаревание описанных технологий никак не помешает вынести что-то полезное из приведенной информации.

Сеть, построенная в предыдущей статье
Сеть, построенная в предыдущей статье

В уже построенной сети настроим будем настраивать межсетевой экран, иногда его называют брандмауэр или файрвол.

Немного теории

Iptables - это, можно сказать, фильтр, через который проходят сетевые пакеты. Эти пакеты могут быть входящими (INPUT), исходящими (OUTPUT) или проходящими (FORWARD).

INPUT, OUTPUT и FORWARD - это три основные цепочки, есть еще две дополнительные цепочки POSTROUTING и PREROUTING. В первую пакет попадает тогда, когда он уже прошел через FORWARD, во вторую - когда еще неизвестно, куда из трех основных цепочек он попадет.

Также в iptables есть 4 таблицы: raw, mangle, nat, filter. Рассматривать их подробно сейчас не имеет смысла, так как будут использоваться только две из них: filter и nat. Таблица filter используется по умолчанию, а ее название говорит само за себя.

Самая наглядная информация - графическая, поэтому предлагаю ознакомиться с маршрутом прохождения пакетов с помощью следующей картинки:

Маршрут прохождения пакетов
Маршрут прохождения пакетов

Действия, которые можно совершать с пакетами:

  • ACCEPT - принять пакет

  • DROP - удалить пакет

  • REJECT - отклонить пакет с сообщением отправителю

  • LOG - сделать запись о пакете в лог-файл

  • QUEUE - отправить пакет пользовательскому приложению

При необходимости советую посетить следующую ссылку для получения более исчерпывающей информации: Настройка iptables для чайников.

Вывод хоста в интернет

Посмотрим, как по умолчанию выглядят цепочки iptables по умолчанию:

Цепочки iptables
Цепочки iptables

После Chain идет название цепочки, а в скобках - политика по умолчанию. Chain INPUT (policy ACCEPT) значит, что по умолчанию входящие пакеты принимаются, а Chain FORWARD (policy DROP) значило бы, что проходящие через сервер пакеты удалятся. Состояние файрвола можно смотреть несколькими способами (второй, на мой взгляд, нагляднее):

iptables-save
iptables -L -nv

Выводить хосты из локальных сетей в интернет будем через сервер. Для этого необходимо сделать так, чтобы пакеты шли в интернет от хоста через сервер, сервер заменял ip-адрес хоста на свой и отправлял в интернет как бы от своего имени. Для этого используется следующая команда:

iptables -t nat -j POSTROUTING -o eth0 -j MASQUERADE

Указывать при этом следует тот сетевой интерфейс, который на сервере уже смотрит в интернет (например, если eth0 - сетевой мост или NAT).

На хостах стоит проверить маршрутизацию командой route:

Маршрутизация
Маршрутизация

Если нет маршрута по умолчанию, то его следует добавить:

route add default gw 192.168.1.10 dev eth0

gw - адрес сервера, dev eth0 - интерфейс, связанный с сервером. Затем стоит пропинговать публичный DNS-сервер Google, чтобы убедиться, что выход в интернет есть. Обратите внимание, что на сервере должна быть разрешена пересылка пакетов в настройках ядра (echo 1 > /proc/sys/net/ipv4/ip_forward), а также политика цепочки FORWARD должна быть ACCEPT (на данном этапе).

Ограничение проходящих пакетов

Стоит сказать, что правила iptables иногда перекрывают друг друга. Например, если сначала вы затем запретили абсолютно все пакеты, а затем разрешили пакеты по протоколу HTTP, то по HTTP пакеты идти не будут. Происходит это потому, что когда пакет приходит в таблицу filter, в первую очередь он натыкается на первое прописанное правило (на то, которое запрещает абсолютно всё). По этому правилу пакет удаляется, и до разрешающего правила пакет уже не добирается.

Поэтому иногда легче установить политику по умолчанию, которая запретит проходить всем пакетам, а затем вручную прописать правила для отдельных типов пакетов.

iptables -P FORWARD DROP
iptables -A FORWARD -p tcp --dport 80 -j ACCEPT

В данном случае всё просто: первая команда - политика для цепочки FORWARD, вторая - разрешаем HTTP (80 порт) по tcp. Всё, теперь проходят только HTTP-пакеты

Более сложный пример

Сначала ограничим все проходящие пакеты, а затем постараемся пропинговать Яндекс по доменному имени ya.ru. В таком случае, необходимо вручную включить FORWARD icmp-пакетов и DNS-пакетов, а также определить, откуда брать доменные имена. Доменные имена будем брать с уже известного адреса 8.8.8.8, дописав параметры в файл /etc/hosts:

echo "8.8.8.8 nameserver" >> /etc/hosts

Разрешать пинг и DNS-пакеты будем следующими командами:

iptables -P FORWARD DROP
iptables -A FORWARD -p icmp -j ACCEPT
iptables -A FORWARD -p tcp --dport 53 -j ACCEPT
iptables -A FORWARD -p udp --dport 53 -j ACCEPT
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

Важно разрешить пересылку пакетов по 53 порту не только по tcp, но и по udp. Я не до конца уверен, с чем именно это связано, но если сделать иначе, то пинг по доменному имени не сработает. Последнее же правило нужно, чтобы разрешить перенаправление пакетов, которые являются частью установленных соединений или связаны с ними. Это важно для поддержания работоспособности уже установленных соединений, а также для обработки ответных пакетов или пакетов, проходящих через систему и перенаправляемых между сетями.

Стоит быть особенно внимательным при настройке iptables, ведь, например, можно забыть открыть 21 порт при тестировании соединений утилитой telnet. Также не стоит забывать об использовании iptables-save и iptables-restore, чтобы сохранять текущее состоянии файрвола в текстовый файл и в любой удобный момент восстанавливать предыдущее состояние.

iptables-save > firewall_ver1.txt
iptables-restore firewall_ver1.txt

Заключение

Это лишь малая часть из того, что можно рассказать про iptables, сетевые технологии и Linux. Некоторым представленным инструментам давно пора на пенсию, но для обучения на простых примерах они еще используются. При желании можно копнуть глубже и найти более грамотные и лаконичные решения для представленных мной задач, я лишь показал возможные варианты, знание которых мне бы сильно помогло на начальных этапах.

Комментарии (16)


  1. biff_33
    10.07.2023 23:57
    +10

    Если нет адреса по умолчанию, то его следует добавить:
    route add default gw 192.168.1.10 dev eth0

    инструкция из 90-х?


    $: route
    command not found: route

    Давайте придерживаться инструкций таки-не-десятилетней давности.
    ip route add default via 192.168.1.10 dev eth0


    echo "8.8.8.8 nameserver" >> /etc/hosts

    Именно в hosts? а не в resolv.conf, причем слова наоборот?


  1. Vilgelm
    10.07.2023 23:57
    +1

    Я не до конца уверен, с чем именно это связано, но если сделать иначе, то пинг по доменному имени не сработает

    С тем, что DNS по-умолчанию работает по UDP? Если по какой-то причине ничего кроме TCP на выходе нет (например, клиенты ходят в сеть через гейт, который все заворачивает HTTP прокси), то можно поднять на клиенте DoH и тогда будет работать. А вот "классический" DNS без UDP неработоспособен.


    И зачем пихать nameserver в hosts?


    1. max31ru12 Автор
      10.07.2023 23:57
      -1

      Спасибо за информацию, nameserver пихаю в hosts, потому что он у меня пустой, и хосты в подсетях не знают, что такое ya.ru


      1. Vilgelm
        10.07.2023 23:57
        +2

        Все равно не понимаю зачем в hosts. Такое ощущение, что у вас просто где-то в конфигурации стоит шаблон по-умолчанию, в котором нужно nameserver заменить на адрес DNS сервера. А вместо этого вы прописываете в hosts что nameserver — это восьмерки. Работать оно, конечно, будет, но это как-то странно.


  1. yds
    10.07.2023 23:57

    Вроде бы iptables-save используется для сохранения правил. А не для просмотра. 


    1. max31ru12 Автор
      10.07.2023 23:57

      Нет, все примененные правила сразу же вступают в силу, а результат команды iptables-save - это текстовое описание примененных правил, которое можно зафиксировать в файле


  1. iig
    10.07.2023 23:57
    +2

    Вроде как iptables уже deprecated, пора изучать nftables?


    1. mpa4b
      10.07.2023 23:57
      -3

      Вроде как iptables уже deprecated, пора изучать nftables?

      https://www.opennet.ru/opennews/art.shtml?num=59409 что-то я не уверен.


    1. mayorovp
      10.07.2023 23:57
      +1

      Так в ядре его и нет уже, но это не мешает консольным командам работать.


      1. mpa4b
        10.07.2023 23:57

        С чего вы взяли, что netfilter нет в ядре?


        1. dlinyj
          10.07.2023 23:57

          В ядре у комментатора выше может и не быть, а в исходниках есть.


          1. mpa4b
            10.07.2023 23:57
            -2

            Ну так надо уточнять, в каком именно дистрибутиве нет iptables и не включен netfilter в ядре. Пока что всегда оказывалось, что и классический iptables есть (достаточно его лишь установить пакетным менеджером) и netfilter тоже никуда не девается.


        1. mayorovp
          10.07.2023 23:57
          +1

          (комментарий был удалён)


  1. dlinyj
    10.07.2023 23:57
    +2

    Всё тоже самое бы, но для современных дистрибутивов с утилитой ip, nftables и т.п.


  1. aim
    10.07.2023 23:57

    iptables? а чего не ipchains из 2.2 ядра или ipfwadm, который Кокс сделал на базе бсдшного ipfw?!


  1. buratino
    10.07.2023 23:57
    +1

    В заголовке упоминается VirtualBox, в тексте статьи он даже не упоминается.

    Насчет виртуальных сетей тоже берут смутные сомнения - сетевая маска и настройка таблицы маршрутизации - это еще не сеть.

    С какой стороны VirtualBox стоит заявляемый в заголовке линукс сервер - тоже как-то неясно.

    Если бы, например, на линукс-сервере, стояло с десяток запущенных виртуальных машин с зоопарком осей , и между ними хотя бы пинги бегали, то тогда можно было бы заявлять, что этот текст - туториал, а так он больше на сдачу какого-то зачета похож