1

Я использую iptables v1.6.0 на Slackware 14.2. У меня есть некоторые правила фильтрации iptables, которые используют пользовательские цепочки. Пример вывода из iptables-save может выглядеть так

*filter
:INPUT DROP - [0:0]
:FORWARD DROP - [0:0]
:OUTPUT DROP - [0:0]
:custom_chain - [0:0]
-A INPUT -j custom_chain
-A OUTPUT -j ACCEPT
-A custom_chain -j ACCEPT
COMMIT

Согласно справочной странице iptables-restore опция -n должна оставить текущий набор правил без изменений и только добавить новые правила.

-n, --noflush
    don't flush the previous contents of the table.  If  not
    specified,both commands flush (delete) all previous contents
    of the respective table.

Тем не менее, если я пытаюсь добавить правила, такие как

# cat new_rules
*filter
:INPUT DROP - [0:0]
:FORWARD DROP - [0:0]
:OUTPUT DROP - [0:0]
:custom_chain - [0:0]
:new_chain - [0:0]
-A new_chain -j DROP
COMMIT

с помощью iptables-restore с параметром -n и проверьте набор правил с помощью iptables-save

# iptables-restore -n < new_rules
# iptables-save
*filter
:INPUT DROP - [0:0]
:FORWARD DROP - [0:0]
:OUTPUT DROP - [0:0]
:custom_chain - [0:0]
:new_chain - [0:0]
-A INPUT -j custom_chain
-A OUTPUT -j ACCEPT
-A new_chain -j DROP
COMMIT

тогда цепочки по умолчанию остаются неизменными, но пользовательская цепочка сбрасывается, несмотря на параметр -n . Есть ли способ сохранить старые пользовательские цепочки? Если это не ошибка, то в чем причина такого поведения?

ОБНОВИТЬ

Дальнейшие исследования показывают, что пользовательские цепочки сбрасываются только в том случае, если они явно упоминаются в файле new_rules . Однако это не решает проблему, поскольку все еще невозможно добавить правило в существующую пользовательскую цепочку. iptables-restore -n < new_rules прежнему сбрасывает и теряет все предыдущие правила в этой пользовательской цепочке, оставляя только одно правило, которое должно быть добавлено дополнительно.

2 ответа2

1

Я столкнулся с той же ошибкой. Просматривая https://git.netfilter.org/iptables/tree/iptables/ip6tables-restore.c?id=577b7e20c2af1e6ea2bbe72e0c01802334fa4069

Кажется, морское право

            if (ops->builtin(chain, handle) <= 0) {
            if (noflush && ops->is_chain(chain, handle)) {
                DEBUGP("Flushing existing user defined chain '%s'\n", chain);
                if (!ops->flush_entries(chain, handle))
                    xtables_error(PARAMETER_PROBLEM,
                           "error flushing chain "
                           "'%s':%s\n", chain,
                           strerror(errno));

Поскольку это не встроенная цепочка, а noflush равен 1, iptables-restore очистит пользовательскую таблицу.

-1

Во-первых: вы не должны использовать iptables - восстановите, как вы здесь пытаетесь, конечно, есть лучшее, более безопасное и элегантное решение. Возможно, с предложением grawity, используя ipset, или имея определенную цепочку, которую можно позволить удалить.

Я не вижу ошибки нигде.

Просто обратите внимание , : это "создание цепи" определение. При использовании -n эта цепочка не уничтожается, поэтому нет необходимости определять ее снова. Если он не переопределен, он не удаляется вместе со своим содержимым.

Итак, чтобы сохранить старый custom_chain, попробуйте это как файл new_rules:

*filter
:INPUT DROP - [0:0]
:FORWARD DROP - [0:0]
:OUTPUT DROP - [0:0]
:new_chain - [0:0]
-A new_chain -j DROP
-A custom_chain -j DROP
COMMIT

результат, когда у вас были начальные правила, а затем применить new_rules:

# iptables-restore -n < new_rules
# iptables-save
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
:custom_chain - [0:0]
:new_chain - [0:0]
-A INPUT -j custom_chain
-A OUTPUT -j ACCEPT
-A custom_chain -j ACCEPT
-A custom_chain -j DROP
-A new_chain -j DROP
COMMIT

В custom_chain добавлено больше контента, а предыдущий контент был сохранен: это то, что вы хотели.

Конечно, теперь вы не можете использовать файл new_rules один (без -n), вы получите ошибку, потому что custom_chain не определен.

Вы даже можете фрагментировать ваши правила, используемые с -n в файл с правилами, перезаписывающими существующие цепочки, а другой - нет, если он более управляем (но опять же ... нет).

new_rule1:

*filter
:new_chain - [0:0]
-A new_chain -j DROP
COMMIT

new_rule2:

*filter
-A custom_chain -j DROP
COMMIT

Применение обоих (используя -n с обоими) после предыдущего new_rules теперь даст:

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
:custom_chain - [0:0]
:new_chain - [0:0]
-A INPUT -j custom_chain
-A OUTPUT -j ACCEPT
-A custom_chain -j ACCEPT
-A custom_chain -j DROP
-A custom_chain -j DROP
-A new_chain -j DROP
COMMIT

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .