題 如何檢查iptables規則是否已存在?


我需要在iptables中添加一條規則來阻止從Internet連接到tcp端口。

由於我的腳本可能被多次調用而且沒有刪除規則的腳本,我想在插入之前檢查iptables規則是否已經存在 - 否則INPUT鏈中會有很多重複規則。

如何檢查iptables規則是否已存在?


35
2017-11-22 03:04


起源


或者,使用此包裝器,它提供冪等的iptables交互: xyne.archlinux.ca/projects/idemptables - sampablokuper


答案:


有一個新的 -C --check 最近的iptables版本中的選項。

# iptables -C INPUT -p tcp --dport 8080 --jump ACCEPT
iptables: Bad rule (does a matching rule exist in that chain?).
# echo $?
1

# iptables -A INPUT -p tcp --dport 8080 --jump ACCEPT

# iptables -C INPUT -p tcp --dport 8080 --jump ACCEPT
# echo $?
0

對於較舊的iptables版本,我會使用Garrett的建議:

# iptables-save | grep -- "-A INPUT -p tcp -m tcp --dport 8080 -j ACCEPT"

39
2017-09-20 08:33





新的 -C 選項不令人滿意,因為它對使用時間(TOCTTOU)競賽條件開放。如果兩個進程嘗試在同一時間添加相同的規則, -C 不會保護他們不要添加兩次。

所以,它真的沒有比 grep 解。對輸出的準確文本處理作業 iptables-save 可以像...一樣可靠地工作 -C,因為該輸出是表的狀態的可靠快照。

我們需要的是一個 --ensure 只有當規則尚不存在時才會自動檢查並添加規則的選項。此外,如果規則被移動到正確的位置,如果它已經不存在則插入新規則將是很好的(--ensure-move)。例如,如果 iptables -I 1 用於在鏈的頭部創建規則,但該規則已存在於第七個位置,則現有規則應移至 第一個位置。

沒有這些功能,我認為一個可行的解決方法是基於這個偽代碼編寫一個shell腳本循環:

while true ; do
  # delete all copies of the rule first

  while copies_of_rule_exist ; do
    iptables -D $RULE
  done

  # now try to add the rule

  iptables -A $RULE # or -I 

  # At this point there may be duplicates due to races.
  # Bail out of loop if there is exactly one, otherwise
  # start again.
  if exactly_one_copy_of_rule_exists ; then
    break;
  fi
done

這段代碼可以旋轉;它不能保證兩個或更多的參賽者將在固定的迭代次數內出局。可以添加一些隨機指數退避睡眠來幫助解決這個問題。


9
2017-07-02 19:26



我可以補充一點,這個命令並不令人滿意,原因很簡單,你必須查明添加規則的確切方式。我使用我的設置進行了測試,但找不到規則,因為我沒有指定確切的關鍵字和值... - Fabien Haddadi


這可能看起來有些倒退,但它適用於我 - 請先嘗試刪除規則。

iptables -D INPUT -s xxx.xxx.xxx.xxx -j DROP;

您應該收到類似的消息:

iptables:錯誤的規則(該鏈中是否存在匹配規則?)

然後只需正常添加您的規則:

iptables -A INPUT -s xxx.xxx.xxx.xxx -j DROP;


5
2017-11-27 15:21



在防火牆中打開一個不需要的洞,只是為了模擬一個冪等命令,可能不是一個好主意。當然,這個洞是暫時的,但它仍然可以提高攻擊者的機會。如果某些事情中斷了替換規則的添加,則該漏洞可能會無限期地持續存在。 - sampablokuper
好點@sampablokuper:出於安全考慮,這個策略可能只適用於ACCEPT規則而不適用於DROP規則 - lucaferrario
我最終做了同樣的事情! - warhansen


只需列出並蒐索它?

iptables --list | grep $ip

......或者你有規定的規則。如果你使用 grep -q 它不會輸出任何內容,您只需檢查返回值即可 $?


3
2017-11-22 03:06



我會建議 iptables-save|grep $ip 相反,因為它是一種更容易解析的格式,尤其是在腳本中。如果需要,您也可以檢查命令的確切語法。 - Garrett
這些都沒有實際回答這個問題,因為 iptables-save|grep $ip 非常匹配 多 規則。或者 iptables-save 可以用來檢查 完成 規則規範,但這仍然是一個黑客:返回的格式 iptables-save 可能與腳本中的規則不完全匹配。 iptables-save 可以按不同的順序生成選項,添加內容(如 -m tcp),等等。 - larsks
請記住 iptables --list 將嘗試解決知名港口。因此,在grep一個端口之前確保這一點。 - Fabien Haddadi