Как настроить постоянные параметры брандмауэра в Ubuntu 22.04 LTS – запутался в ufw, nfw и iptables(-nfw/-legacy)

Вопрос или проблема

Кратко: как настроить правила брандмауэра так, чтобы они были постоянными? Я не использую UFW, я думаю, что использую iptables-nft.

Сначала я

  • начал с довольно свежей установки Ubuntu 22.04 LTS (добавлены некоторые случайные инструменты)
  • установил Docker с помощью пакетов apt (репозиторий https://download.docker.com/linux/ubuntu)
  • установил LXD с помощью snap

Существуют некоторые известные проблемы с брандмауэром при совместном использовании Docker и LXD, но я хочу использовать оба, и, насколько я знаю, это должно быть осуществимо, и это работало на моем предыдущем хосте (который был Ubuntu 18).

Из коробки сеть Docker работала, LXD – нет, и команды iptables показали такую конфигурацию брандмауэра:

sudo iptables -L
# Предупреждение: таблицы iptables-legacy присутствуют, используйте iptables-legacy для их просмотра
Цепочка INPUT (политика ACCEPT)
цель     протокол опция источник               назначение         
Цепочка FORWARD (политика DROP)
цель     протокол опция источник               назначение         
DOCKER-USER  все  --  откуда угодно             куда угодно            
DOCKER-ISOLATION-STAGE-1  все  --  откуда угодно             куда угодно            
ACCEPT     все  --  откуда угодно             куда угодно             ctstate RELATED,ESTABLISHED
DOCKER     все  --  откуда угодно             куда угодно            
ACCEPT     все  --  откуда угодно             куда угодно            
ACCEPT     все  --  откуда угодно             куда угодно            
Цепочка OUTPUT (политика ACCEPT)
цель     протокол опция источник               назначение         
Цепочка DOCKER (1 ссылка)
цель     протокол опция источник               назначение         
Цепочка DOCKER-ISOLATION-STAGE-1 (1 ссылка)
цель     протокол опция источник               назначение         
DOCKER-ISOLATION-STAGE-2  все  --  откуда угодно             куда угодно            
RETURN     все  --  откуда угодно             куда угодно            
Цепочка DOCKER-ISOLATION-STAGE-2 (1 ссылка)
цель     протокол опция источник               назначение         
DROP       все  --  откуда угодно             куда угодно            
RETURN     все  --  откуда угодно             куда угодно            
Цепочка DOCKER-USER (1 ссылка)
цель     протокол опция источник               назначение         
RETURN     все  --  откуда угодно             куда угодно 

и

sudo iptables-legacy -L
Цепочка INPUT (политика ACCEPT)
цель     протокол опция источник               назначение         
Цепочка FORWARD (политика ACCEPT)
цель     протокол опция источник               назначение         
Цепочка OUTPUT (политика ACCEPT)
цель     протокол опция источник               назначение  

Предупреждение “Таблицы iptables-legacy присутствуют” несколько беспокоило, но я не смог понять, является ли это проблемой, которую мне нужно исправить. На тот момент я сам не настраивал брандмауэр.

Я исправил LXD, добавив эти правила (последнее, чтобы сделать его менее открытым)

sudo iptables -I DOCKER-USER -o lxdbr0 -j ACCEPT
sudo iptables -I DOCKER-USER -i lxdbr0 -j ACCEPT
sudo iptables -I DOCKER-USER -i ext_if ! -s 192.168.1.0/24 -j DROP

Но теперь я не знаю, как сделать это постоянным.

Существует файл /etc/nftables.conf, но у него только такая пустая конфигурация

#!/usr/sbin/nft -f

flush ruleset

table inet filter {
    chain input {
        type filter hook input priority 0;
    }
    chain forward {
        type filter hook forward priority 0;
    }
    chain output {
        type filter hook output priority 0;
    }
}

Когда я выполняю nft list ruleset, там много конфигураций, связанных с Docker и LXD, которые очевидно не исходят из nftables.conf, и я не знаю, должно ли это быть динамичным и настраиваться чем-то другим, кроме как вручную редактируя файл nftables.conf.

Итак, теперь я создал скрипт setup-lxd-networking.sh, который выполняет эти команды iptables -I, которые я выполняю вручную, но это не очень удобно.

sudo nft list ruleset
...
table ip filter {
    chain DOCKER {
    }

    chain DOCKER-ISOLATION-STAGE-1 {
        iifname "docker0" oifname != "docker0" counter packets 18 bytes 1393 jump DOCKER-ISOLATION-STAGE-2
        counter packets 181 bytes 18684 return
    }

    chain DOCKER-ISOLATION-STAGE-2 {
        oifname "docker0" counter packets 0 bytes 0 drop
        counter packets 18 bytes 1393 return
    }

    chain FORWARD {
        type filter hook forward priority filter; policy drop;
        counter packets 209 bytes 35269 jump DOCKER-USER
        counter packets 181 bytes 18684 jump DOCKER-ISOLATION-STAGE-1
        oifname "docker0" ct state related,established counter packets 14 bytes 8351 accept
        oifname "docker0" counter packets 0 bytes 0 jump DOCKER
        iifname "docker0" oifname != "docker0" counter packets 18 bytes 1393 accept
        iifname "docker0" oifname "docker0" counter packets 0 bytes 0 accept
    }

    chain DOCKER-USER {
        iifname "ext_if" ip saddr != 192.168.1.0/24 counter packets 0 bytes 0 drop
        iifname "lxdbr0" counter packets 15 bytes 866 accept
        oifname "lxdbr0" counter packets 13 bytes 15719 accept
        counter packets 181 bytes 18684 return
    }
}
table inet lxd {
    chain pstrt.lxdbr0 {
        type nat hook postrouting priority srcnat; policy accept;
        ip saddr 10.5.62.0/24 ip daddr != 10.5.62.0/24 masquerade
        ip6 saddr fd42:dbed:893c:1f91::/64 ip6 daddr != fd42:dbed:893c:1f91::/64 masquerade
    }

    chain fwd.lxdbr0 {
        type filter hook forward priority filter; policy accept;
        ip version 4 oifname "lxdbr0" accept
        ip version 4 iifname "lxdbr0" accept
        ip6 version 6 oifname "lxdbr0" accept
        ip6 version 6 iifname "lxdbr0" accept
    }

    chain in.lxdbr0 {
        type filter hook input priority filter; policy accept;
        iifname "lxdbr0" tcp dport 53 accept
        iifname "lxdbr0" udp dport 53 accept
        iifname "lxdbr0" icmp type { destination-unreachable, time-exceeded, parameter-problem } accept
        iifname "lxdbr0" udp dport 67 accept
        iifname "lxdbr0" icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, nd-router-solicit, nd-neighbor-solicit, nd-neighbor-advert, mld2-listener-report } accept
        iifname "lxdbr0" udp dport 547 accept
    }

    chain out.lxdbr0 {
        type filter hook output priority filter; policy accept;
        oifname "lxdbr0" tcp sport 53 accept
        oifname "lxdbr0" udp sport 53 accept
        oifname "lxdbr0" icmp type { destination-unreachable, time-exceeded, parameter-problem } accept
        oifname "lxdbr0" udp sport 67 accept
        oifname "lxdbr0" icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, echo-request, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert, mld2-listener-report } accept
        oifname "lxdbr0" udp sport 547 accept
    }
}

У меня была такая же проблема. Как обсуждалось на форумах LXD здесь, решение, которое я нашел, заключалось в том, чтобы удалить Docker, установленный через apt, и заменить его на Docker из snap.

# apt purge docker.io
# apt autoremove
# snap install docker
# reboot

Причина в том, что lxd хочет использовать nftables, а docker от apt также хочет использовать nftables, но они не совместимы с lxd. Вы не можете заставить lxd использовать iptables-legacy. Но snap docker, похоже, использует iptables-legacy, так что они не мешают друг другу.

Ответ или решение

Настройка постоянных правил файрвола в Ubuntu 22.04 LTS с использованием iptables

Введение

Ваша ситуация с файрволом на Ubuntu 22.04 LTS подразумевает несколько компонентов, включая Docker, LXD и использование различных реализаций iptables (нфтовая и устаревшая версии). В этом руководстве мы подробно рассмотрим, как настроить постоянные правила файрвола с использованием iptables-nft, чтобы избежать необходимости запускать скрипт на каждом перезапуске системы.

Понимание структуры

Ваша текущая настройка использует iptables-nft, который является новой реализацией управления фильтрацией пакетов и интегрируется с nftables. Стоит отметить, что iptables-legacy также присутствует на системе и включает устаревшую архитектуру. Это объясняет предостережение о том, что на вашей системе имеются таблицы iptables-legacy. Оба могут сосуществовать, но при этом рекомендуется использовать один из них для избежания конфликтов.

Параметры docker и lxd

Docker и LXD требуют определенных настроек для совместной работы, особенно при использовании nftables. Если оба проекта не следуют одним и тем же правилам управления сетевым трафиком, могут возникнуть проблемы, как у вас. Ваше решение добавить правила iptables для разрешения трафика между Docker и LXD – это правильный шаг, но эти изменения, как вы уже заметили, не сохраняются при перезагрузке.

Постоянные правила iptables-nft

Если использование nftables для управления правилами вам удобнее, вот шаги, которые помогут в создании и сохранении постоянных правил:

  1. Создание конфигурационного файла nftables:

    • Вы можете использовать файл /etc/nftables.conf для сохранения правил.
    • Откройте файл /etc/nftables.conf в текстовом редакторе с правами администратора:
      sudo nano /etc/nftables.conf

    Пример конфигурации с вашими текущими правилами может выглядеть так:

    #!/usr/sbin/nft -f
    
    flush ruleset
    
    table ip filter {
       chain DOCKER-USER {
           type filter hook forward priority filter; policy accept;
           iifname "ext_if" ip saddr != 192.168.1.0/24 drop
           iifname "lxdbr0" accept
           oifname "lxdbr0" accept
       }
    }
  2. Сохранение и использование правил:

    • Сохраните изменения и выйдите, нажав CTRL+X, затем Y, и Enter.
    • После этого запустите nft для применения конфигурации:
      sudo nft -f /etc/nftables.conf
  3. Автозагрузка правил при загрузке системы:

    • Для запуска nftables при загрузке необходимо активировать службу:
      sudo systemctl enable nftables.service

Альтернативный подход: использование iptables-persistent

Если вы предпочитаете продолжать использовать iptables, вы можете сделать правила постоянными с помощью пакета iptables-persistent. Вот как это сделать:

  1. Установите iptables-persistent:

    sudo apt install iptables-persistent
  2. Сохраните текущие правила:
    После установки вас попросят сохранить текущие правила iptables. Вы можете выбрать "Yes".

  3. Куририрование правил:
    Существует специальный процесс для редактирования текущих правил, которые могут быть загружены при каждой перезагрузке. Вы можете использовать для этого команды:

    sudo iptables-save > /etc/iptables/rules.v4
    sudo iptables-legacy-save > /etc/iptables/rules.v6

Заключение

В заключение, несмотря на наличие различных реализаций и подходов к управления трафиком в вашей системе, вы можете выбрать тот, который для вас более удобен. Ваши текущие правила iptables могут быть сохранены с помощью nftables, если вы решите использовать его в качестве основного инструмента, или через iptables-persistent, чтобы обеспечить применение правил при каждой загрузке. Правильная настройка файрвола обеспечит стабильную работу Docker и LXD на вашей системе, минимизируя проблемы с совместимостью.

Оцените материал
Добавить комментарий

Капча загружается...