banaction เดียว สองการขนส่ง: ซ่อม jail ของ fail2ban สำหรับ VPN
ban กว้างเท่ากับโปรโตคอลในแอ็กชันของมันเท่านั้น เปรียบเทียบตัวนับของเชนกับตัวฟัง แล้วครอบคลุมทั้งสองการขนส่งใน jail เอง
ไม่มีอะไรใน fail2ban ที่ทิ้งแพ็กเก็ตได้ด้วยตัวเอง: มันเรียกใช้แอ็กชัน และแอ็กชันนั้นเองที่เป็นตัวระบุโปรโตคอลและพอร์ต เมื่อ jail รายงานว่ามี ban ขณะที่ดีมอนยังคงรับการเข้าสู่ระบบอยู่ ban นั้นมักเป็นของจริงและแคบกว่าที่บันทึกบ่งชี้ ไคลเอนต์ที่เชื่อมต่อใหม่ผ่านการขนส่งอีกทางจะไม่พบกฎที่ติดตั้งไว้เลย ก่อนจะเปลี่ยนอะไร ให้เปรียบเทียบสิ่งที่แอ็กชันติดตั้งกับสิ่งที่ดีมอนฟังอยู่ เพราะหลักฐานอยู่ในเชนไฟร์วอลล์ที่แอ็กชันเขียนไว้ ไม่ใช่ในรายการของ jail
อ่านเชน ไม่ใช่อ่านสรุปของ jail
fail2ban แทรกเชนของตัวเองไว้หน้าเชนของบริการ ดังนั้นรายการตัวนับจะแสดงสิ่งที่มียู่อย่างตรงไปตรงมา ถ้าเชนที่ตั้งชื่อตาม jail มีกฎเดียวและคอลัมน์โปรโตคอลอ่านว่า udp นั่นก็อธิบายการเข้าสู่ระบบ TCP ที่ยังคงมาถึงได้ครบถ้วน มีเพียงแพ็กเก็ต UDP จากต้นทางที่ถูกบล็อกเท่านั้นที่ถูกปฏิเสธ บริการมีตัวฟัง TCP และไม่มีอะไรในเชนนั้นแตะต้องมัน
ระวังผลของ jail ข้างเคียงด้วย โฮสต์หนึ่งอาจดูเหมือนกำหนดค่าไว้สมบูรณ์เพียงเพราะ jail อื่นส่งครึ่งที่ขาดไปให้ และบิลด์เดียวกันก็ไม่ทำอะไรในที่ที่ jail นั้นไม่ได้ติดตั้ง
แอ็กชันระบุโปรโตคอลเดียว และนั่นคือจุดที่มันพัง
banaction แต่ละตัวคือเทมเพลตคำสั่งไฟร์วอลล์ และโปรโตคอลอยู่ในช่องว่างช่องหนึ่งของมัน ความแคบนี้เป็นเจตนา เพราะ jail ของเว็บกับ jail ของ DNS ไม่มีธุระอะไรกับการบล็อกพอร์ตเดียวกัน กลายเป็นกับดักเมื่อบริการฟังมากกว่าหนึ่งการขนส่ง ซึ่งดีมอน VPN ทำเป็นปกติ ตัวกรองอาจเฝ้าดูการเข้าสู่ระบบที่ล้มเหลวจากทั้งสองการขนส่ง ขณะที่แอ็กชันครอบคลุมเพียงทางเดียว
การติดตั้ง SoftEther และ OpenVPN มักฟังทั้ง UDP และ TCP พร้อมกัน และเพราะบรรทัดบันทึกดูเหมือนกันทั้งสองกรณี ตัวกรองจึงเฝ้าดูทั้งคู่ ความไม่สมมาตรไม่เคยปรากฏในรายงานของ jail เอง fail2ban นับความล้มเหลวได้ถูกต้องแล้วจึงติดตั้งกฎที่ใช้กับครึ่งหนึ่งของทราฟฟิกที่ความล้มเหลวนั้นมาถึง
ทำให้ ban ครอบคลุมทั้งสองการขนส่ง
แก้ที่นิยามของ jail แทน กฎที่เขียนด้วยมือจะถูกสลับที่ในการโหลดครั้งถัดไป เขียนแอ็กชันสองรายการ รายการละโปรโตคอล:
action = %(banaction)s[name=%(__name__)s-tcp, actionname=%(__name__)s-tcp, protocol="tcp", port="%(port)s", chain="%(chain)s"]
%(banaction)s[name=%(__name__)s-udp, actionname=%(__name__)s-udp, protocol="udp", port="%(port)s", chain="%(chain)s"]
อย่าพยายามย่อด้วย protocol = all banaction ค่าเริ่มต้นคือแอ็กชัน multiport และขยายเป็น -p <protocol> -m multiport --dports <port> เมื่อไม่มีโปรโตคอล L4 ก็ไม่มีอะไรให้การจับคู่พอร์ตทดสอบ ดังนั้น iptables จะปฏิเสธกฎ ขณะที่ jail ยังรายงานว่า ban สำเร็จ แอ็กชันทุกพอร์ตอย่าง iptables-allports หรือ nftables-allports ยอมรับรายการเดียวได้ แต่บล็อกทุกพอร์ตบนต้นทางนั้น ซึ่งเป็นการตัดสินใจอีกแบบและต้องมีเหตุผลของตัวเอง ปล่อย protocol ไว้ที่ tcp หรือ udp แล้วยอมรับสองรายการ
พิสูจน์ว่ากฎมีอยู่จริงแทนที่จะเชื่อการตั้งค่า เพราะการตั้งค่าเป็นเพียงความตั้งใจจนกว่าเชนจะยึดไว้:
iptables -S f2b-vpn-tcp
iptables -S f2b-vpn-udp
แต่ละเชนควรมีกฎเดียว โดย -p tcp อยู่ในเชนแรกและ -p udp อยู่ในเชนที่สอง ทั้งคู่ระบุที่อยู่ที่ถูกบล็อก จากนั้นยืนยันว่าที่อยู่เดียวกันถูกปฏิเสธทั้งสองการขนส่ง ban ที่คุณไม่เห็นในเชนคือความหวัง และรายงานครั้งถัดไปของอาการเดิมจะทำให้เสียเวลาชั่วโมงเดิมอีกครั้ง
สิ่งที่ ban ยังพลาด และกรณีถัดไป
สิ่งที่แอ็กชันทำคือปฏิเสธต้นทางเดียว และเฉพาะบนพอร์ตที่ระบุไว้ในนั้นเท่านั้น มันไม่ได้ทำอะไรกับผู้โจมตีที่หมุนเวียนที่อยู่ และไม่สามารถแยกเครื่องที่เป็นปฏิปักษ์ออกจากทางออก NAT ระดับผู้ให้บริการที่ผู้ใช้หลายร้อยคนใช้ร่วมกัน ซึ่งการ ban ครั้งเดียวจะกีดกันคนที่ไม่ได้ทำอะไรเลย ตรวจสอบให้แน่ใจว่าตัวกรองอ่าน ที่อยู่ที่ไคลเอนต์มีอยู่จริง ไม่ใช่เฮดเดอร์ที่ถูกส่งต่อหรือที่อยู่พร็อกซี รักษาหน้าต่างให้สั้นพอที่ความผิดพลาดจะหมดอายุไปเอง
ไม่มีข้อใดในนี้ที่สนับสนุนให้ข้ามการแก้โปรโตคอล มันสนับสนุนให้ถือสองความคิดไว้พร้อมกัน ban แคบกว่าที่สรุปของ jail บ่งชี้ และแม้ ban ที่สมบูรณ์ก็ยังแคบกว่าภัยคุกคาม วางเชนไฟร์วอลล์ไว้ข้างรายการตัวฟังของดีมอนแล้วเปรียบเทียบทีละโปรโตคอล เพราะสองรายการนั้นเป็นตัวตัดสินว่า ban จะไปถึงบริการได้หรือไม่
เก็บคำสั่งโหลดซ้ำและรายการเชนไว้ในรันบุ๊กข้าง jail คนถัดไปจะต้องใช้ทั้งสองอย่าง และสรุปของ jail จะไม่บอกเขาเลย