Як я можу видалити конкретні правила з 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. Але я отримую BAD RULE (чи існує відповідне правило) ...
Бен

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), ви повинні додати її до команди delete (thx до @ThorSummoner для коментаря)

sudo iptables -t nat -D PREROUTING 1

4
Обидва рішення хороші, але це не працюватиме в сценарії, коли номер рядка невідомий. Тож інше рішення є більш загальним, а отже, більш правильним, ІМО.
Єроен

2
Добре, якщо ви не знаєте рядка, ви можете використовувати коментар (наприклад, відповідь серед) або зробити iptables -L INPUT --line-numbers | grep -oP "([0-9]{1,3}).*tcp.*domain" | cut -d" " -f1
похвалу

6
Це добре лише в тому випадку, якщо до таблиці не можуть бути вставлені правила в будь-який момент часу. Інакше номери рядків можуть змінюватися між спостереженням за ними та виконанням правила видалення. У такому випадку небезпечно вважати, що часове вікно настільки коротке, що "навряд чи колись трапиться".
Нік

14
Пам'ятайте, що якщо ви видалите одне правило, номери рядків, що залишилися, змінюються. Отже, якщо вам потрібно видалити правила 5, 10 і 12 ... видаліть їх 12, 10, то 5.
TomOnTime

2
При спробі видалити правила ПЕРЕДАЧАННЯ, я повинен був вказати -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% видалите всі правила, що відповідають $ коментарю, а інші рядки залишиться недоторканими. Це рішення працює протягом останніх 2 місяців із приблизно 100 змінами правил на день - жодних питань. Сподіваюся, це допомагає


2
Якщо у вас немає iptables-save / recovery:iptables -S | grep "${comment}" | sed 's/^-A //' | while read rule; do iptables -D $rule; done
Mansour

Для використання в реальному житті: 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.
Абдул

Легко зрозуміти!
скин

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

Я знайшов цей із --line-number є найкращим
Davuz

Так! Чудово! Не хочу цілогоiptables -F
Dev Anand Sadasivam

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 з IPtables, просто виконайте команду,

# sudo iptables -F -t nat -v

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

Потім ви можете перевірити це,

# sudo iptables -L -t nat -v
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.