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

ลำดับกฎและสถานะการเชื่อมต่อเป็นความผิดพลาดคนละแบบ

เชนที่มีลำดับจะถูกประเมินจากบนลงล่าง และกฎแรกที่ถึงคำตัดสินสุดท้ายจะจบการไล่ผ่านเชนนั้น วางการอนุญาตกว้าง ๆ ไว้เหนือกฎล็อกที่เขียนอย่างระมัดระวัง แล้วกฎล็อกนั้นจะกลายเป็นเอกสารเท่านั้น คือมันอยู่ในชุดกฎ ตัวนับเป็นศูนย์ และจะไม่มีแพ็กเก็ตใดไปถึงมันเลย ข้อความเดียวกันที่ใช้กับเชนอื่นก็ไม่ได้พิสูจน์อะไร ใน 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 ที่มันอาศัยอยู่ ตำแหน่งที่มันต้องถือไว้เมื่อเทียบกับการอนุญาตที่กว้างกว่า และการทดสอบที่พิสูจน์สิ่งนั้น เมื่อมีคนแก้ชุดกฎโดยรอบในอีกหกเดือนต่อมา บันทึกนั้นคือคำเตือนเดียวว่าตำแหน่งนั้นตั้งใจไว้

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

บทความที่เกี่ยวข้อง