การเปลี่ยนกฎไฟร์วอลล์ไม่ทำงาน: ลำดับกฎและสถานะการเชื่อมต่อ
กฎที่แก้ไขอาจอยู่หลังการอนุญาตก่อนหน้าหรือถูกข้ามโดยการติดตามการเชื่อมต่อ แยกการทดสอบสองอย่าง ใช้โฟลว์ใหม่ และเก็บทางกลับไว้
คุณแก้ไขกฎ โหลดชุดกฎใหม่ แล้วอุโมงค์ก็ทำงานเหมือนเดิมทุกอย่าง ผลลัพธ์นี้มีสาเหตุที่พบบ่อยสองอย่าง และต้องใช้การทดสอบที่ต่างกัน ไม่ว่ากฎใหม่จะอยู่หลัง กฎก่อนหน้าที่อนุญาตแพ็กเก็ตไปแล้ว หรือการแลกเปลี่ยนที่คุณกำลังดูอยู่เป็นการเชื่อมต่อที่ถูกติดตามซึ่งการเปลี่ยนแปลงไม่เคยประเมินใหม่ กฎในไฟล์บอกเจตนา สิ่งที่ตัดสินแพ็กเก็ตคือเส้นทางที่ใช้งานจริงซึ่งแพ็กเก็ตพบ ทำการตรวจสอบด้านล่างตามลำดับ และระหว่างนั้นให้เก็บทางกลับไว้
ลำดับกฎและสถานะการเชื่อมต่อเป็นความผิดพลาดคนละแบบ
เชนที่มีลำดับจะถูกประเมินจากบนลงล่าง และกฎแรกที่ถึงคำตัดสินสุดท้ายจะจบการไล่ผ่านเชนนั้น วางการอนุญาตกว้าง ๆ ไว้เหนือกฎล็อกที่เขียนอย่างระมัดระวัง แล้วกฎล็อกนั้นจะกลายเป็นเอกสารเท่านั้น คือมันอยู่ในชุดกฎ ตัวนับเป็นศูนย์ และจะไม่มีแพ็กเก็ตใดไปถึงมันเลย ข้อความเดียวกันที่ใช้กับเชนอื่นก็ไม่ได้พิสูจน์อะไร ใน nftables เชนฐานผูกกับ hook ตามลำดับความสำคัญ ดังนั้นการอนุญาตในเชนหนึ่งไม่ได้ขัดขวางอีกเชนบน hook หรือลำดับความสำคัญอื่นไม่ให้เห็นแพ็กเก็ตเดียวกัน
การติดตามการเชื่อมต่อทำให้เกิดอาการที่สอง และจากภายนอกดูเหมือนกันทุกประการ เมื่อโฟลว์อยู่ในตารางสถานะ การอนุญาตสำหรับ established-or-related ใกล้ยอดเชนจะคืนค่าก่อนที่กฎใหม่ของคุณจะถูกพิจารณาด้วยซ้ำ การแมป NAT มีคุณสมบัติเดียวกัน คือการแปลถูกกำหนดไว้ตั้งแต่โฟลว์เริ่มต้น ดังนั้นกฎ postrouting ที่แก้ไขจะไม่เขียนเซสชันที่กำลังทำงานอยู่ใหม่ นี่คือเหตุผลที่การเปลี่ยนแปลงดูเหมือนได้ผลเมื่อเวลา 09:00 สำหรับการเชื่อมต่อใหม่ และดูเหมือนไม่ได้ทำอะไรเลยสำหรับเซสชันที่ใครบางคนเปิดไว้เมื่อเวลา 08:55
กลุ่มความปลอดภัยบนคลาวด์เพิ่มแบบจำลองที่สามซึ่งจับคนที่เรียนจาก iptables กฎขาเข้าเป็นรายการอนุญาตที่ประเมินเป็นเซตไม่ใช่การไล่ตามการจับคู่ครั้งแรก มีสถานะ และการลบกฎอนุญาตไม่ได้ยุติโฟลว์ที่ถูกติดตามอยู่แล้ว การสมมติความหมายแบบจับคู่ครั้งแรกบนแพลตฟอร์มที่ไม่มีสิ่งนั้นนำไปสู่ข้อสรุปที่มั่นใจแต่ผิด
อ่านชุดกฎที่ใช้งานอยู่ ไม่ใช่ไฟล์ที่คุณแก้ไข
เริ่มจากสิ่งที่เคอร์เนลบังคับใช้อยู่ตอนนี้ การกำหนดค่าที่บันทึกไว้แต่ไม่เคยถูกนำไปใช้ อธิบายพฤติกรรมที่ไม่เปลี่ยนไปได้อย่างน่าประหลาดใจ และการตัดออกใช้เพียงคำสั่งเดียว
nft list ruleset
iptables-saveจากนั้นถามว่ากฎของคุณถูกเข้าถึงหรือไม่ ตัวนับแพ็กเก็ตตอบเรื่องนี้โดยตรง และตอบได้ดีกว่าการใช้เหตุผลใด ๆ เกี่ยวกับเจตนา
iptables -L FORWARD -v -n --line-numbers
nft list chain inet filter forwardกฎล็อกที่มีแพ็กเก็ตเป็นศูนย์หลังการทดสอบจริงไม่ใช่ปัญหาเชิงนโยบาย แต่เป็นปัญหาเรื่องตำแหน่ง การย้ายมันเป็นการแก้ไขหนึ่งบรรทัด และไวยากรณ์คือสิ่งที่ทำให้เกิดบั๊กเดิม ด้วย iptables -I จะแทรกไว้ต้น และ -A จะต่อท้าย ส่วน nftables insert จะวางกฎไว้ต้นเชน ขณะที่ add จะต่อท้าย เมื่อกฎต้องชนะ จงบอกให้ชัดเจนแทนการเชื่อมโยงกับลำดับที่บังเอิญถูกโหลด
พิสูจน์ว่าโฟลว์ถูกติดตามอยู่หรือไม่
ก่อนจะโทษกฎ ให้ตรวจสอบว่าทราฟฟิกเป็นการเชื่อมต่อที่ถูกติดตามหรือไม่ ถามตารางสถานะเกี่ยวกับโฟลว์ที่เฉพาะเจาะจงแทนที่จะเทออกมาทั้งหมด
conntrack -L -p tcp --dport 1194
conntrack -E -p tcp --dport 1194รายการแสดงสถานะและเวลาที่เหลือ และนี่คือวิธีที่คุณแยกเซสชันที่สถาปนาแล้วออกจากความพยายามใหม่ โหมดเหตุการณ์พิมพ์การอัปเดตเมื่อเกิดขึ้น ซึ่งมีประโยชน์ขณะที่คุณเชื่อมต่อไคลเอนต์ใหม่ หากโฟลว์อยู่ในสถานะสถาปนาแล้วก่อนที่คุณจะแตะต้องสิ่งใด การแก้ไขกฎตัวกรองใด ๆ จะไม่เปลี่ยนชะตากรรมของมัน นี่ไม่ใช่บั๊กในไฟร์วอลล์ แต่เป็นสัญญาของการกรองที่มีสถานะ
จงต้านทานทางลัดในการล้างตารางทั้งหมดบนเกตเวย์โปรดักชัน conntrack -F ใช้งานได้ และมันยังทำลายทุกโฟลว์ที่ถูกติดตามบนเครื่อง รวมถึงเซสชันการจัดการที่คุณทำงานอยู่และอุโมงค์ที่บรรทุกเชลล์ของคุณ รายการเดี่ยว ๆ สามารถลบได้เมื่อจำเป็นจริง ๆ แต่โฟลว์ใหม่จากพอร์ตต้นทางใหม่มักเป็นการทดลองที่สะอาดกว่า
บางเส้นทางไม่ถูกติดตาม และมันทำงานตรงกันข้าม ทราฟฟิกที่ถูกทำเครื่องหมายเป็น notrack ในตาราง raw อุโมงค์บางส่วนที่เลี่ยง hook ปกติ และการกำหนดเส้นทางแบบอสมมาตรที่แยกโฟลว์ระหว่างเกตเวย์สองตัว ล้วนสร้างแพ็กเก็ตที่ถูกประเมินทีละตัว หรือสถานะที่ไม่เคยถูกสร้างที่ปลายทั้งสองข้าง หากตัวนับขยับทุกแพ็กเก็ต ให้สงสัยเส้นทางแบบนั้นก่อนสงสัยลำดับ
ทดสอบจากโฟลว์ใหม่พร้อมทางกลับ
ก่อนทดสอบกฎที่อาจตัดการเข้าถึงระยะไกล ให้สร้างเส้นทางกู้คืนก่อน คือคอนโซลของผู้ให้บริการ คอนโซลอนุกรม ที่อยู่การจัดการนอกแบนด์ หรืออินเทอร์เฟซที่สองที่กฎจับคู่ไม่ได้ ตัวจับเวลาย้อนกลับเป็นเพื่อนที่สมเหตุสมผล เพราะมันจะคืนชุดกฎก่อนหน้าแม้เซสชันของคุณจะตายกลางการทดสอบ
จากนั้นทดสอบด้วยการแลกเปลี่ยนที่สถานะยังไม่อาจครอบคลุม ตัดการเชื่อมต่อและเชื่อมต่อไคลเอนต์ใหม่เพื่อให้เกิดห้าองค์ประกอบใหม่ และเฝ้าดูปลายทั้งสองขณะที่มันเกิดขึ้น
tcpdump -ni eth0 'tcp port 1194'
journalctl -k -n 50 --no-pagerทำการทดสอบทั้งสองทิศทาง กฎที่บล็อกแฮนด์เชกขาเข้าใหม่ยังอาจอนุญาตเส้นทางตอบกลับ หรือกลับกัน และผลลัพธ์ทางเดียวคือสาเหตุปกติที่การล็อกทำงานได้เพียงครึ่งเดียว เชื่อมต่ออีกครั้งหลังการทดสอบเพื่อยืนยันสภาวะคงตัว และตรวจสอบว่าการเข้าถึงการจัดการที่ชอบด้วยกฎหมายยังอยู่ กฎที่เขียนสำหรับพอร์ตเดียวมักจับคู่กับช่วงที่กว้างกว่าที่ตั้งใจ
บันทึกวัตถุประสงค์และตำแหน่งไว้กับกฎ
กฎที่ไม่มีวัตถุประสงค์ที่บันทึกไว้คือกฎที่ไม่มีใครกล้าลบ ข้าง ๆ ทุกรายการล็อก ให้เก็บโฟลว์ที่มันปกป้อง เชนและ hook ที่มันอาศัยอยู่ ตำแหน่งที่มันต้องถือไว้เมื่อเทียบกับการอนุญาตที่กว้างกว่า และการทดสอบที่พิสูจน์สิ่งนั้น เมื่อมีคนแก้ชุดกฎโดยรอบในอีกหกเดือนต่อมา บันทึกนั้นคือคำเตือนเดียวว่าตำแหน่งนั้นตั้งใจไว้
ก่อนปิดการเปลี่ยนแปลง ให้ยืนยันสี่อย่าง คือชุดกฎที่ทำงานอยู่ตรงกับไฟล์ กฎใหม่มีตัวนับที่ไม่เป็นศูนย์หลังความพยายามใหม่ ทิศทางย้อนกลับและการเข้าถึงการจัดการยังทำงานอยู่ และคุณได้เชื่อมต่ออีกครั้งหนึ่งเพื่อพิสูจน์สภาวะคงตัว ไม่ใช่สถานะของเซสชันที่เก่ากว่าการเปลี่ยนแปลง หากสิ่งใดไม่ได้รับการตรวจสอบ การเปลี่ยนแปลงยังไม่เสร็จ ไม่ว่าอุโมงค์จะทำอะไรก็ตาม