Como posso remover regras específicas do iptables?

334

Estou hospedando serviços HTTP e HTTPS especiais nas portas 8006 e 8007, respectivamente. Eu uso o iptables para "ativar" o servidor; ou seja, para rotear as portas HTTP e HTTPS de entrada:

iptables -A INPUT -i eth0 -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 8006 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 8007 -j ACCEPT
iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8006 
iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 443 -j REDIRECT --to-port 8007  
iptables -A OUTPUT -t nat -d 127.0.0.1 -p tcp --dport 80 -j REDIRECT --to-ports 8006
iptables -A OUTPUT -t nat -d 127.0.0.1 -p tcp --dport 443 -j REDIRECT --to-ports 8007 

Isso funciona como um encanto. No entanto, gostaria de criar outro script que desabilite meu servidor novamente; ou seja, restaure o iptables para o estado em que estava antes de executar as linhas acima. No entanto, estou tendo dificuldade em descobrir a sintaxe para remover essas regras. A única coisa que parece funcionar é uma descarga completa:

iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT

Mas isso também excluirá outras regras do iptables que são indesejadas.

Jeroen
fonte
2
Eu descobri que é melhor usar em -Ivez de -Apara ACCEPTlinhas. Isso ocorre porque, tipicamente, a última linha (por INPUTcadeia, por exemplo) é um DROPou REJECTe você deseja que sua regra venha antes disso. -Acoloca a nova regra após a última, enquanto -Icoloca no início.
Mark Lakata

Respostas:

471

Execute os mesmos comandos, mas substitua o "-A" por "-D". Por exemplo:

iptables -A ...

torna-se

iptables -D ...
Eli Rosencruft
fonte
7
Se você tiver várias regras de um tipo, elas não serão removidas.
ETech 27/03
4
tente executar esse comando -D várias vezes e ele excluirá todos eles.
Zhenyu Li
4
Eu executei o mesmo comando, mas com -D em vez de -I. Mas eu recebo REGRA BAD (não uma regra correspondente existe) ...
Ben
4
Se você adicionou uma regra com -Iou -R, ainda pode excluí-la com -D.
David Xia
Apenas uma nota. Crio uma regra com 'iptables -A ...' e a regra apareceu, mas não foi eficaz. Ao usar 'iptables -D ...', a resposta foi Má regra . Mesmo assim, a regra foi excluída. A regra estava visível com 'sudo iptables -nvL'. A corrente que usei foi 'INPUT'.
Ben Paz
446

Você também pode usar o número da regra ( --line-numbers ):

iptables -L INPUT --line-numbers

Exemplo de saída:

Chain INPUT (policy ACCEPT) 
    num  target prot opt source destination
    1    ACCEPT     udp  --  anywhere  anywhere             udp dpt:domain 
    2    ACCEPT     tcp  --  anywhere  anywhere             tcp dpt:domain 
    3    ACCEPT     udp  --  anywhere  anywhere             udp dpt:bootps 
    4    ACCEPT     tcp  --  anywhere  anywhere             tcp dpt:bootps

Portanto, se você deseja excluir a segunda regra:

iptables -D INPUT 2

Atualizar

Se você usar (d) uma tabela específica (por exemplo, nat), precisará adicioná-la ao comando delete (thx para @ThorSummoner para o comentário)

sudo iptables -t nat -D PREROUTING 1
domi27
fonte
4
Ambas as soluções são boas, mas essa não funcionará em uma configuração com script quando o número da linha for desconhecido. Portanto, a outra solução é mais geral e, portanto, mais correta, IMO.
Jeroen #
2
Bem, se você não sabe a linha que você pode usar um comentário (como resposta entre) ou fazer um grep para a regra:iptables -L INPUT --line-numbers | grep -oP "([0-9]{1,3}).*tcp.*domain" | cut -d" " -f1
domi27
6
Isso é bom apenas se a tabela não puder ter regras inseridas a qualquer momento. Caso contrário, os números de linha podem mudar entre observá-los e executar a regra de exclusão. Nesse caso, não é seguro supor que a janela de tempo seja tão curta que "é improvável que isso aconteça".
Nick
14
Lembre-se de que, se você excluir uma regra, os números de linha do restante serão alterados. Então, se você precisar excluir regra 5, 10, e 12 ... excluí-los 12, 10, em seguida, 5.
TomOnTime
2
Ao tentar excluir PREROUTING regras que eu tinha para especificar -t nat, por exemplo: sudo iptables -t nat --line-numbers -L, e excluí-los com -t natmuito, por exemplo: sudo iptables -t nat -D PREROUTING 1(Pode valer a pena acrescentar à resposta?)
ThorSummoner
31

A melhor solução que funciona para mim sem problemas é a seguinte:
1. Adicione uma regra temporária com algum comentário:

comment=$(cat /proc/sys/kernel/random/uuid | sed 's/\-//g')
iptables -A ..... -m comment --comment "${comment}" -j REQUIRED_ACTION

2. Quando a regra foi adicionada e você deseja removê-la (ou tudo com este comentário), faça:

iptables-save | grep -v "${comment}" | iptables-restore

Portanto, você excluirá 100% de todas as regras que correspondem ao comentário $ e deixará outras linhas intocadas. Esta solução funciona nos últimos 2 meses com cerca de 100 alterações de regras por dia - sem problemas.

ETech
fonte
2
Caso você não tenha o iptables-save / restore:iptables -S | grep "${comment}" | sed 's/^-A //' | while read rule; do iptables -D $rule; done
Mansour
Para um uso da vida real: CRON 1) Excluir antigas spamhausiptables proibições, 2) grab spamhaus.org/drop , 3) grep para CIDR IP do eiptables -A INPUT -s $ip_cidr -j -m comment --comment "spamhaus"
Xeoncross
2
@Mansour Ou iptables -S | sed "/$comment/s/-A/iptables -D/e";) como este
hek2mgl
@ hek2mgl sed não desiste, não é? =] Obrigado, vou manter esse recurso em mente (esquecerei a sintaxe em um dia).
Mansour
sed é usado apenas para remover "-" do uuid. De qualquer forma, depois de obter a sintaxe sed - ela nunca será esquecida. ))
ETech
11

Primeiro, liste todas as regras do iptables com este comando:

iptables -S

lista como:

-A XYZ -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT

Em seguida, copie a linha desejada e substitua -Apor -Dpara excluir:

iptables -D XYZ -p ...
Wladdy Lopez
fonte
2
Estar ciente! Esta é uma resposta incompleta. Do manual sobre "-S": "Como todos os outros comandos do iptables, ele se aplica à tabela especificada (o filtro é o padrão).". Portanto, no caso de usar essa opção - deve ser repetida para todas as tabelas: nat, mangle, etc
pmod
1
No meu caso, recebo o iptables: Bad rule (does a matching rule exist in that chain?).que agora?
Abdull
Ah, descobri - meu comando delete estava faltando a especificação da tabela. Portanto, caso você listar todas as regras da tabela natcom sudo iptables -S -t nate que pretende eliminar uma das regras devolvidos, a cópia não é suficiente. Você precisa adicionar -t nat, por exemplo sudo iptables -D ... -t nat.
Abdull 16/02
Fácil de entender!
sknight
5

Use o -Dcomando, é assim que a manpágina explica:

-D, --delete chain rule-specification
-D, --delete chain rulenum
    Delete  one  or more rules from the selected chain.  
    There are two versions of this command: 
    the rule can be specified as a number in the chain (starting at 1 for the first rule) or a rule to match.

Realize esse comando, como todos os outros comandos ( -A, -I) funcionam em determinada tabela. Se você não estiver trabalhando na tabela padrão ( filtertabela), use -t TABLENAMEpara especificar essa tabela de destino.

Excluir uma regra para corresponder

iptables -D INPUT -i eth0 -p tcp --dport 443 -j ACCEPT

Nota: Isso exclui apenas a primeira regra correspondente. Se você tiver muitas regras correspondentes (isso pode acontecer no iptables), execute isso várias vezes.

Excluir uma regra especificada como um número

iptables -D INPUT 2

Além de contar o número, você pode listar o número da linha com o --line-numberparâmetro, por exemplo:

iptables -t nat -nL --line-number
cizixs
fonte
Achei isso um com --line-número é o melhor
Davuz
Sim! Soberbo! Não quero todoiptables -F
Dev Anand Sadasivam
2

Suponha que, se você deseja remover as regras NAT,

Liste as tabelas IP anexadas usando o comando abaixo,

# sudo iptables -L -t nat -v

Chain PREROUTING (policy ACCEPT 18 packets, 1382 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    7   420 DNAT       tcp  --  any    any     anywhere             saltmaster           tcp dpt:http to:172.31.5.207:80
    0     0 DNAT       tcp  --  eth0   any     anywhere             anywhere             tcp dpt:http to:172.31.5.207:8080

Se você deseja remover a regra nat das tabelas IP, basta executar o comando

# sudo iptables -F -t nat -v

Flushing chain `PREROUTING'
Flushing chain `INPUT'
Flushing chain `OUTPUT'
Flushing chain `POSTROUTING'

Então, você pode verificar se,

# sudo iptables -L -t nat -v
lakshmikandan
fonte