Як я можу видалити конкретні правила з 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.