'iptables-restore' não preserva correntes personalizadas

0

Estou usando iptables v1.6.0 no Slackware 14.2. Eu tenho algumas regras de filtro iptables que usam cadeias personalizadas. Exemplo de saída de iptables-save pode parecer

*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

De acordo com a página man do iptables-restore , a opção -n deve deixar o conjunto de regras atual intacto e anexar apenas as novas regras.

-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.

No entanto, se eu tentar adicionar regras como

# 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

usando iptables-restore com a opção -n e verifique o conjunto de regras com 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

as cadeias padrão permanecem intactas, mas a cadeia personalizada é liberada apesar da opção -n . Existe uma maneira de preservar as antigas cadeias personalizadas? Se isso não é um bug, então qual é o raciocínio desse comportamento?

UPDATE

Outras investigações mostram que cadeias customizadas são apenas liberadas se forem explicitamente mencionadas no arquivo new_rules . No entanto, isso não resolve o problema, pois ainda é impossível anexar uma regra a uma cadeia personalizada preexistente. iptables-restore -n < new_rules ainda liberaria e perderia todas as regras anteriores nessa cadeia personalizada, deixando, assim, apenas a regra que deveria ser adicionada em acréscimo.

    
por nautical 17.09.2017 / 19:26

2 respostas

1

Eu encontrei o mesmo bug. Observando o link

Parece náutico estava certo

            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));

Como esta não é uma cadeia interna e o noflush é 1, o iptables-restore limpará a tabela personalizada.

    
por 09.04.2018 / 09:46
-1

Primeiro: você não deve usar o iptables - restaurar como você está tentando aqui, certamente há uma solução melhor, mais segura e elegante. Talvez com a sugestão do grawity usando ipset, ou por ter uma cadeia específica que pode se dar ao luxo de ser deletada.

Eu não vejo um bug em nenhum lugar.

Considere apenas que : são definições de "criação de cadeia". Usando -n esta cadeia não é destruída, então não há necessidade de defini-la novamente. Se não for redefinido, não será apagado junto com seu conteúdo.

Então, para preservar o antigo custom_chain, tente isso como arquivo 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

resultará quando você tiver as regras iniciais e aplicará 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 teve mais conteúdo adicionado e o conteúdo anterior foi preservado: é o que você queria.

Claro que agora você não pode usar o arquivo new_rules sozinho (sem -n ), você receberia um erro porque custom_chain não está definido.

Você pode até mesmo fragmentar suas regras usadas com -n em um arquivo com regras que realmente sobrescrevem correntes existentes, e a outra que não seria se fosse mais gerenciável (mas novamente ... não).

new_rule1:

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

new_rule2:

*filter
-A custom_chain -j DROP
COMMIT

Aplicando ambos (usando -n com ambos) depois que as novas regras anteriores passariam a dar:

*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

mas em vez de seguir este caminho, talvez seja preferível usar diretamente comandos antigos do iptables diretamente.

    
por 19.09.2017 / 20:29