ฉันจะตรวจสอบว่ากฎ iptables มีอยู่แล้วได้อย่างไร


41

ฉันต้องเพิ่มกฎใน iptables เพื่อบล็อกการเชื่อมต่อกับพอร์ต tcp จากอินเทอร์เน็ต

เนื่องจากสคริปต์ของฉันอาจถูกเรียกหลายครั้งและไม่มีสคริปต์ที่จะลบกฎฉันต้องการตรวจสอบว่ากฎ iptables มีอยู่แล้วก่อนที่จะแทรกมัน - มิฉะนั้นจะมีกฎซ้ำซ้อนในห่วงโซ่ INPUT

ฉันจะตรวจสอบว่ากฎ iptables มีอยู่แล้วได้อย่างไร


อีกทางเลือกหนึ่งให้ใช้กระดาษหุ้มนี้ซึ่งให้การทำงานร่วมกับ iptables แบบ idempotent: xyne.archlinux.ca/projects/idemptables
sampablokuper

คำตอบ:


44

มี-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"

12

-Cตัวเลือกใหม่ไม่เป็นที่พอใจเนื่องจากเปิดให้เข้ากับสภาพการแข่งขันแบบเวลาเช็คอินต่อเวลา (TOCTTOU) หากทั้งสองกระบวนการพยายามที่จะเพิ่มกฎเดียวกันในเวลาเดียวกัน-Cจะไม่ปกป้องพวกเขาจากการเพิ่มสองครั้ง

ดังนั้นมันจึงไม่ดีไปกว่าการgrepแก้ปัญหา งานการประมวลผลข้อความที่แม่นยำบนเอาต์พุตiptables-saveสามารถทำงานได้อย่างน่าเชื่อถือ-Cเนื่องจากเอาต์พุตนั้นเป็นสแน็ปช็อตที่เชื่อถือได้ของสถานะของตาราง

สิ่งที่จำเป็นต้องมีคือ--ensureตัวเลือกที่จะตรวจสอบและเพิ่มกฎต่อเมื่อไม่มีกฎอยู่แล้ว ยิ่งไปกว่านั้นมันจะดีถ้ากฎถูกย้ายไปยังตำแหน่งที่ถูกต้องซึ่งจะมีการแทรกกฎใหม่หากไม่มีอยู่แล้ว ( --ensure-move) ตัวอย่างเช่นหากiptables -I 1ใช้เพื่อสร้างกฎที่ส่วนหัวของห่วงโซ่ แต่กฎนั้นมีอยู่แล้วในตำแหน่งที่เจ็ดจากนั้นกฎที่มีอยู่ควรย้ายไปยังตำแหน่งแรก

หากไม่มีคุณสมบัติเหล่านี้ฉันคิดว่าวิธีแก้ปัญหาที่เป็นไปได้คือการเขียน shell script loop โดยใช้โค้ดหลอกนี้:

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

รหัสนี้สามารถหมุนไปรอบ ๆ ; ไม่รับประกันว่าจะมีนักแข่งสองคนหรือมากกว่านั้นออกซ้ำภายในจำนวนครั้งที่แน่นอน สามารถเพิ่มการ backoff แบบเอ็กซ์โปเนนเชียลแบบสุ่มบางอย่างเพื่อช่วยในเรื่องนั้น


1
ฉันขอเพิ่มเติมว่าคำสั่งนี้ค่อนข้างไม่พอใจสำหรับเหตุผลง่ายๆที่คุณต้องระบุวิธีการเพิ่มกฎของคุณ ฉันทำการทดสอบด้วยการตั้งค่าของฉันและไม่สามารถหากฎได้เพราะฉันไม่ได้ระบุคำหลักและค่าที่แน่นอน ...
Fabien Haddadi

ถ้าคุณเอากฎชั่วคราวแล้วคุณอาจทำลายบางสิ่งบางอย่าง ...
Mehrdad

5

สิ่งนี้อาจดูค่อนข้างย้อนกลับ แต่มันใช้งานได้สำหรับฉัน - ลองลบกฎก่อน

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

คุณควรได้รับข้อความที่คุ้นเคยกับ:

iptables: กฎไม่ถูกต้อง (มีกฎการจับคู่อยู่ในกลุ่มนั้นหรือไม่)

จากนั้นเพิ่มกฎของคุณตามปกติ:

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


1
การเปิดรูที่ไม่ต้องการในไฟร์วอลล์ของคุณเพียงเพื่อจำลองคำสั่ง idempotent อาจไม่ใช่ความคิดที่ดี แน่นอนว่ารูนั้นตั้งใจจะเป็นแบบชั่วคราว แต่ก็ยังเป็นการเพิ่มโอกาสของผู้โจมตี และหากมีสิ่งใดขัดจังหวะการเพิ่มกฎการเปลี่ยนหลุมอาจยังคงอยู่ต่อไปได้เรื่อย ๆ
sampablokuper

จุดดี @sampablokuper: กลยุทธ์นี้อาจเหมาะสำหรับกฎ ACCEPT เท่านั้นและไม่ใช่ DROP สำหรับเหตุผลด้านความปลอดภัย
lucaferrario

ในที่สุดฉันก็ลงมือทำสิ่งเดียวกัน!
warhansen

4

เพียงแค่รายการและค้นหามัน?

iptables --list | grep $ip

... หรืออย่างไรก็ตามคุณได้ระบุกฎไว้ หากคุณใช้grep -qมันจะไม่ส่งออกอะไรและคุณสามารถตรวจสอบค่าตอบแทนด้วย$?


3
ฉันขอแนะนำให้iptables-save|grep $ipแทนเพราะเป็นรูปแบบการแยกวิเคราะห์ได้ง่ายขึ้นโดยเฉพาะในสคริปต์ คุณสามารถตรวจสอบไวยากรณ์ที่แน่นอนของคำสั่งได้เช่นกันหากคุณต้องการ
Garrett

1
ไม่ตอบคำถามเหล่านี้จริง ๆ เพราะiptables-save|grep $ipสามารถจับคู่กฎหลายข้อได้ดีมาก อาจiptables-saveใช้เพื่อตรวจสอบข้อกำหนดของกฎที่สมบูรณ์แต่ก็ยังมีการแฮ็กอยู่เล็กน้อย: รูปแบบที่ส่งคืนโดยiptables-saveอาจไม่ตรงกับกฎในสคริปต์ทั้งหมด iptables-saveอาจสร้างตัวเลือกในลำดับที่แตกต่างเพิ่มสิ่งต่าง ๆ (เช่น-m tcp) และอื่น ๆ
larsks

จำไว้ว่าiptables --listจะพยายามแก้ไขพอร์ตที่รู้จักกันดี ดังนั้นตรวจสอบให้แน่ใจก่อนที่คุณจะ grep สำหรับพอร์ต
Fabien Haddadi

0

วิธีการเกี่ยวกับการเพิ่มครั้งแรกแล้วลบที่ซ้ำกันตามที่อธิบายในhttps://serverfault.com/questions/628590/duplicate-iptable-rules ง่ายที่สุด (สำหรับบรรทัดที่อยู่ติดกัน) น่าจะเป็น

iptables-save | uniq | iptables-restore

0

หากต้องการหลีกเลี่ยงกฎที่ซ้ำกันจากสคริปต์ของคุณให้เพิ่มบรรทัดด้านล่าง

iptables -C -INPUT -p tcp --dport 8080 --jump ACCEPT || iptables -A -INPUT -p tcp --dport 8080 --jump ACCEPT

ครั้งแรกเมื่อเรียกใช้คำสั่งด้านบนเราจะสังเกตข้อความด้านล่าง

iptables: กฎไม่ถูกต้อง (มีกฎการจับคู่อยู่ในกลุ่มนั้นหรือไม่)

นี่เป็นเพียงข้อมูล แต่ครึ่งหลังของคำสั่งจะช่วยให้มั่นใจได้ว่าจะเพิ่มกฎ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.