Как я могу удалить определенные правила из iptables?

334

Я размещаю специальные службы HTTP и HTTPS на портах 8006 и 8007 соответственно. Я использую iptables для «активации» сервера; т.е. для маршрутизации входящих портов HTTP и HTTPS:

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 

Это работает как шарм. Однако я хотел бы создать еще один скрипт, который снова отключает мой сервер; т.е. восстановить iptables в состояние, в котором он находился до запуска строк выше. Однако мне трудно разобраться в синтаксисе для удаления этих правил. Единственная вещь, которая, кажется, работает - это полный флеш:

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

Но это также удалит другие правила iptables, что нежелательно.

Йерун
источник
2
Я обнаружил , что лучше использовать -Iвместо -Aдля ACCEPTлиний. Это потому, что, как правило, последняя строка (например, для INPUTцепочки) - это DROPили, REJECTи вы хотите, чтобы ваше правило предшествовало этому. -Aставит новое правило после последнего правила, а -Iставит его в начале.
Марк Лаката

Ответы:

471

Выполните те же команды, но замените «-A» на «-D». Например:

iptables -A ...

становится

iptables -D ...
Эли Розенкруфт
источник
7
Если у вас есть несколько таких правил, они не будут удалены.
ETech
4
попробуйте выполнить эту команду -D несколько раз, и она удалит их все.
Женю Ли
4
я выполнил ту же команду, но с -D вместо -I. Но я получаю ПЛОХОЕ ПРАВИЛО (существует ли соответствующее правило) ...
Бен
4
Если вы добавили правило с помощью -Iили -R, вы можете удалить его с помощью -D.
Дэвид Ся
Просто записка. Я создал правило с помощью «iptables -A ...», и это правило появилось, но не вступило в силу. При использовании «iptables -D ...» ответ был « Плохое правило» . Несмотря на это правило было удалено. Правило было видно с помощью «sudo iptables -nvL». Цепочка, которую я использовал, была «INPUT».
Бен Пас
446

Вы также можете использовать номер правила ( --line-numbers ):

iptables -L INPUT --line-numbers

Пример вывода:

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

Итак, если вы хотите удалить второе правило:

iptables -D INPUT 2

Обновить

Если вы используете (d) определенную таблицу (например, nat), вы должны добавить ее в команду удаления (спасибо за комментарий @ThorSummoner)

sudo iptables -t nat -D PREROUTING 1
domi27
источник
4
Оба решения хороши, но это не будет работать в сценарии, когда номер строки неизвестен. Таким образом, другое решение является более общим и, следовательно, более правильным, IMO.
Йероен
2
Ну, если вы не знаете строку, вы можете использовать комментарий (например, ответ среди) или сделать grep для вашего правила:iptables -L INPUT --line-numbers | grep -oP "([0-9]{1,3}).*tcp.*domain" | cut -d" " -f1
domi27
6
Это хорошо, только если в таблицу не могут быть вставлены правила в любой момент времени. В противном случае номера строк могут измениться между их наблюдением и выполнением правила удаления. В таком случае небезопасно предполагать, что временное окно настолько короткое, что «это вряд ли когда-либо случится».
Ник
14
Помните, что если вы удалите одно правило, номера строк остатка изменятся. Итак, если вам нужно удалить правило 5, 10 и 12 ... удалите их 12, 10, а затем 5.
TomOnTime
2
При попытке удалить правила PREROUTING мне пришлось указать -t nat, например:, sudo iptables -t nat --line-numbers -Lи удалить их -t natтоже, например: sudo iptables -t nat -D PREROUTING 1(Может быть, стоит добавить к ответу?)
ThorSummoner
31

Лучшее решение, которое работает для меня без проблем, выглядит следующим образом:
1. Добавьте временное правило с некоторыми комментариями:

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

2. Когда правило добавлено и вы хотите удалить его (или все, что с этим комментарием), выполните:

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

Таким образом, вы на 100% удалите все правила, соответствующие $ comment, и оставите другие строки без изменений. Это решение работает в течение последних 2 месяцев с примерно 100 изменениями правил в день - никаких проблем. Надеюсь, это поможет

Etech
источник
2
Если у вас нет iptables-save / restore:iptables -S | grep "${comment}" | sed 's/^-A //' | while read rule; do iptables -D $rule; done
Мансур
Для реального использования: CRON 1) удалить старые spamhausзапреты iptables, 2) захватить spamhaus.org/drop , 3) grep для IP-адресов CIDR иiptables -A INPUT -s $ip_cidr -j -m comment --comment "spamhaus"
Xeoncross
2
@Mansour Или iptables -S | sed "/$comment/s/-A/iptables -D/e";) вот так
hek2mgl
@ hek2mgl sed не сдается, не так ли? =] Спасибо, я буду иметь в виду эту возможность (я забуду синтаксис через день).
Мансур
sed используется только для удаления "-" из uuid. В любом случае, если у вас есть синтаксис sed - он никогда не будет забыт. ))
ETech
11

Сначала перечислите все правила iptables с помощью этой команды:

iptables -S

это перечисляет как:

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

Затем скопируйте нужную строку, а просто заменить -Aс -Dудалить , что:

iptables -D XYZ -p ...
Владди Лопес
источник
2
Будь в курсе! Это неполный ответ. Из руководства о "-S": "Как и любая другая команда iptables, она применяется к указанной таблице (по умолчанию используется фильтр)." Таким образом, в случае использования этого параметра - следует повторить для всех таблиц: nat, mangle и т. Д.
pmod
1
В моем случае я получу iptables: Bad rule (does a matching rule exist in that chain?).Что сейчас?
Абдул
Ах, разобрался - в моей команде удаления отсутствовала спецификация таблицы. Таким образом, если вы перечислите все правила из таблицы natс помощью sudo iptables -S -t natи хотите удалить одно из возвращенных правил, копирования недостаточно. Вы должны добавить -t nat, например sudo iptables -D ... -t nat.
Абдул
Легко понять!
sknight
5

Используйте -Dкоманду, вот как manэто объясняет страница:

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

Реализуйте эту команду, как и все другие команды ( -A, -I), работающие с определенной таблицей. Если вы не работаете с таблицей по умолчанию ( filterтаблицей), используйте -t TABLENAMEдля указания этой целевой таблицы.

Удалить правило для соответствия

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

Примечание. При этом удаляется только первое найденное правило. Если у вас есть много совпавших правил (это может произойти в iptables), запустите это несколько раз.

Удалить правило, указанное как число

iptables -D INPUT 2

Помимо подсчета числа, вы можете перечислить номер строки с --line-numberпараметром, например:

iptables -t nat -nL --line-number
cizixs
источник
Я нашел этот с --line-номер является лучшим
Давуз
Да! Superb! Не хочу целогоiptables -F
Дев Ананд Садасивам
2

Предположим, что если вы хотите удалить правила NAT,

Перечислите добавленные IPtables, используя команду ниже,

# 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

Если вы хотите удалить правило nat из таблиц IP, просто выполните команду,

# sudo iptables -F -t nat -v

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

Затем вы можете проверить это,

# sudo iptables -L -t nat -v
lakshmikandan
источник