กฎ iptables เพื่ออนุญาตการรับส่งข้อมูล HTTP ไปยังโดเมนเดียวเท่านั้น


20

ฉันต้องกำหนดค่าเครื่องของฉันเพื่ออนุญาตการรับส่งข้อมูล HTTP ไปยัง / จาก serverfault.com เท่านั้น เว็บไซต์อื่น ๆ ทั้งหมดพอร์ตบริการไม่สามารถเข้าถึงได้ ฉันมากับกฎ iptables เหล่านี้:

#drop everything
iptables -P INPUT DROP
iptables -P OUTPUT DROP

#Now, allow connection to website serverfault.com on port 80
iptables -A OUTPUT -p tcp -d serverfault.com --dport 80 -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

#allow loopback
iptables -I INPUT 1 -i lo -j ACCEPT

มันใช้งานไม่ค่อยดี:

  • หลังจากฉันวางทุกอย่างแล้วไปยังกฎ 3:

    iptables -A เอาท์พุท -p tcp -d serverfault.com - พอร์ต 80 -j ยอมรับ

ฉันได้รับข้อผิดพลาดนี้:

iptables v1.4.4: host/network `serverfault.com' not found
Try `iptables -h' or 'iptables --help' for more information.

คุณคิดว่าเกี่ยวข้องกับ DNS หรือไม่ ฉันควรอนุญาตด้วยหรือไม่ หรือฉันควรจะใส่ที่อยู่ IP ในกฎ? คุณคิดว่าสิ่งที่ฉันพยายามทำสามารถทำได้ด้วยกฎที่ง่ายกว่า? อย่างไร?

ฉันขอขอบคุณความช่วยเหลือหรือคำแนะนำเกี่ยวกับเรื่องนี้ ขอบคุณมาก!


2
อย่าลืม sstatic.net และอื่น ๆ serverfault.com ไม่ได้มาจาก serverfault.com โดยสิ้นเชิง
Zoredache

คุณสามารถเรียกใช้พร็อกซีในระบบอื่นได้หรือไม่? นี่เป็นทางออกที่ดีที่สุด / ง่ายที่สุด: serverfault.com/questions/215134
mattdm

คำตอบ:


29

ด้วยกฎ IPTables เรื่องการสั่งซื้อ กฎจะถูกเพิ่มและนำไปใช้ตามลำดับ ยิ่งกว่านั้นเมื่อเพิ่มกฎด้วยตนเองพวกเขาจะถูกนำไปใช้ทันที ดังนั้นในตัวอย่างของคุณแพ็กเก็ตใด ๆ ก็ตามที่ผ่านเครือข่าย INPUT และ OUTPUT จะเริ่มลดลงทันทีที่มีการตั้งค่านโยบายเริ่มต้น นี่คือสาเหตุที่คุณได้รับข้อความแสดงข้อผิดพลาด สิ่งที่เกิดขึ้นคือ:

  1. นโยบาย DROP เริ่มต้นจะถูกนำไปใช้
  2. IPTables ได้รับชื่อโฮสต์เป็นปลายทาง
  3. IPTables พยายามค้นหา DNS ใน 'serverfault.com'
  4. การค้นหา DNS ถูกบล็อกโดยการกระทำ DROP

ในขณะที่ตัวเลือกแหล่งที่มา / ปลายทางจะยอมรับชื่อโฮสต์ แต่ก็ไม่แนะนำอย่างยิ่ง เพื่ออ้างถึงหน้าคน

ชื่อโฮสต์จะได้รับการแก้ไขเพียงครั้งเดียวเท่านั้นก่อนที่กฎจะถูกส่งไปยังเคอร์เนล โปรดทราบว่าการระบุชื่อที่จะแก้ไขด้วยแบบสอบถามระยะไกลเช่น DNS เป็นความคิดที่ไม่ดีจริงๆ

Slillibri ตะปูหัวซึ่งคำตอบของเขาคุณพลาดกฎการยอมรับ DNS ในกรณีของคุณมันจะไม่สำคัญ แต่โดยทั่วไปฉันจะกำหนดนโยบายเริ่มต้นในกระบวนการ สิ่งสุดท้ายที่คุณต้องการคือการทำงานจากระยะไกลและอนุญาตให้ SSH หลังจากเปิดการปฏิเสธเริ่มต้น

นอกจากนี้ขึ้นอยู่กับการกระจายของคุณคุณควรจะสามารถบันทึกกฎไฟร์วอลล์ของคุณเพื่อที่พวกเขาจะถูกนำไปใช้โดยอัตโนมัติเมื่อเริ่มต้น

รู้ทั้งหมดและจัดเรียงสคริปต์ของคุณใหม่นี่คือสิ่งที่ฉันอยากจะแนะนำ

# Allow loopback
iptables -I INPUT 1 -i lo -j ACCEPT

# Allow DNS
iptables -A OUTPUT -p udp --dport 53 -j ACCEPT

# Now, allow connection to website serverfault.com on port 80
iptables -A OUTPUT -p tcp -d serverfault.com --dport 80 -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# Drop everything
iptables -P INPUT DROP
iptables -P OUTPUT DROP

3
คำตอบที่สวยงาม
JakeRobinson

1
ฉันขอบคุณมันแม้ว่าคุณจะต้องพลาดความผิดพลาดไปเช่นกัน อุ่ย
Scott Pack

3
ที่จริงแล้วคุณสามารถวางiptables -Pงบของคุณได้ทุกที่ในสคริปต์ของคุณเนื่องจากนโยบายลูกโซ่จะใช้เฉพาะเมื่อแพ็กเก็ต "ตกลง" ปลายโซ่ ฉันมักจะวางงบนโยบาย (โดยทั่วไปคือDROPนโยบาย) ที่ด้านบนสุดของสคริปต์ iptables ของฉัน
Steven จันทร์

1
@ สตีเว่น: คุณพูดถูก OP ดูเหมือนจะพิมพ์พวกเขาในแบบโต้ตอบ สมมติว่าคุณเชื่อมต่อกับโฮสต์ของคุณผ่าน SSH และกฎข้อแรกของคุณคือนโยบาย DROP การเชื่อมต่อ SSH ของคุณจะลดลงก่อนที่คุณจะสามารถพิมพ์กฎเพิ่มเติมได้ นี่เป็นปัญหาเรื่องเวลาเหมือนกันหากมีการแสดงออกที่แตกต่างจากที่เธอพบ
Scott Pack

ขอบคุณ กำลังลองสิ่งนี้ sudo iptables -I OUTPUT 1 -o lo -j ACCEPTแต่ไม่ได้ทำงานโดยไม่ต้องเพิ่ม ไม่ควรที่จะเพิ่ม?
Kiran


5

ความต้องการประเภทนี้อาจได้รับการจัดการที่ดีขึ้นด้วยเว็บพร็อกซีและ / หรือตัวกรอง Dansgaurdian สามารถกำหนดค่าให้ทำเช่นนี้ได้ คุณจะต้องใช้กฎ NAT เพื่อบังคับให้ทราฟฟิกของคุณผ่านตัวกรอง

การใช้ iptables เพื่อกรองจะช่วยให้ไซต์ใด ๆ ที่มีอยู่จากที่อยู่ IP ที่เกี่ยวข้อง โดยทั่วไปนี่เป็นส่วนย่อยเล็ก ๆ ของทั้งเว็บ


1
เห็นด้วยกับสิ่งนี้โดยสิ้นเชิง iptablesอาจเป็นเครื่องมือที่ผิดที่จะใช้ที่นี่เนื่องจากมันใช้งานไม่ได้ดีกับชื่อ DNS เว็บพร็อกซี่ที่มีการตั้งค่าตัวกรองที่เหมาะสมนั้นเหมาะสมกว่า
Steven จันทร์

2

ฉันเกรงว่า iptables จะไม่ทำงานในระดับนี้ แต่จะสนใจเฉพาะที่อยู่ ip ไม่ใช่ชื่อโฮสต์ หากคุณต้องการปิดกั้นการเข้าถึงโฮสต์เสมือนชื่ออื่น ๆ บน ip เดียวกันคุณจะต้องดูที่การวางไฟล์. htaccess


สิ่งนี้คือเมื่อฉันลองกฎข้อที่ 3 โดยไม่ต้อง "ทิ้งทุกอย่าง" มันใช้ได้ดีกับ iptables!
Zenet

2
อืมฉันอ่านคำถามผิด ใช่สิ่งที่เกิดขึ้นในพื้นหลังคือ iptables จะแก้ปัญหา serverfault.com เป็น 64.34.119.12 (ดูคำตอบจาก slillibri เพื่อทำความเข้าใจว่าทำไมการแก้ไขไม่ทำงาน) อย่างไรก็ตามเนื่องจาก iptables ไม่เข้าใจชื่อโฮสต์และเป็นเพียงการอนุญาตให้ ip คุณจะสามารถเชื่อมต่อกับเว็บไซต์ใด ๆ บน ip นั้นถ้ามันมีหลายเว็บไซต์
Niall Donegan

2
@ เอมิลี่มันอาจจะทำงานได้ดีในการที่กฎจะถูกเพิ่ม แต่ถ้า serverfault.com IP การเปลี่ยนแปลงการจราจรจะไม่ได้รับอนุญาต การอนุญาตไซต์เช่น google.com ซึ่งมีที่อยู่หลายร้อยแห่งซึ่งมีการเปลี่ยนแปลงบ่อยครั้งจะไม่ทำงานเลย
Zoredache

1

คุณต้องกำหนดค่านี้ที่เว็บเซิร์ฟเวอร์ของคุณ iptables เป็นตัวกรองแพ็คเก็ต ธุรกรรม HTTP ส่งชื่อไซต์ (เช่น stackoverflow) เป็นส่วนหนึ่งของเพย์โหลด TCP (เช่นไม่เป็นส่วนหนึ่งของส่วนหัว TCP ซึ่งเป็นสิ่งที่ iptables อ่านได้อย่างง่ายดาย)

เมื่อพิจารณาแล้วและความจริงที่ว่าธุรกรรม HTTP เกือบจะแพร่กระจายไปทั่วหลาย ๆ แพ็กเก็ต (เช่นคุณไม่สามารถจับคู่สตริงในส่วนหัว HTTP) ได้นี่เป็นการจัดการที่ดีกว่าโดยการกำหนดค่าเว็บเซิร์ฟเวอร์หรือพร็อกซีหน้า ของมัน

มันจะมีประโยชน์ที่จะทราบเหตุผลที่อยู่เบื้องหลังสิ่งนี้มีทางเลือกอื่นสองสามอย่าง:

  1. เปลี่ยนเส้นทางไปยัง URL ที่ถูกต้องหากพวกเขาป้อน URL ที่ไม่ถูกต้อง (เช่นเปลี่ยนเส้นทางไปที่ stackoverflow.com หากพวกเขาป้อน www.stackoverflow.com)
  2. บอกเว็บเซิร์ฟเวอร์ของคุณว่าไม่ให้บริการโฮสต์อื่นนอกเหนือจาก stackoverflow.com
  3. วางเว็บไซต์ไว้ใน IP แยกต่างหากที่ไม่มีสิ่งอื่นใดแก้ไขและให้เว็บเซิร์ฟเวอร์ของคุณฟังเท่านั้น

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