“ SYN ท่วมได้ที่เป็นไปได้” ในบันทึกแม้จะมีการเชื่อมต่อ SYN_RECV จำนวนน้อย


30

เมื่อเร็ว ๆ นี้เรามีเซิร์ฟเวอร์ apache ที่ตอบสนองช้ามากเนื่องจากการเกิดน้ำท่วม SYN วิธีแก้ปัญหาสำหรับสิ่งนี้คือการเปิดใช้งาน tcp_syncookies ( net.ipv4.tcp_syncookies=1 in /etc/sysctl.conf)

ฉันโพสต์คำถามเกี่ยวกับเรื่องนี้ที่นี่ถ้าคุณต้องการพื้นหลังเพิ่มเติม

หลังจากเปิดใช้งาน syncookies เราเริ่มเห็นข้อความต่อไปนี้ใน / var / log / ข้อความประมาณทุก 60 วินาที:

[84440.731929] possible SYN flooding on port 80. Sending cookies.

Vinko Vrsalovic แจ้งผมว่านี้หมายถึงค้าง SYN จะได้รับเต็มรูปแบบเพื่อผมยก tcp_max_syn_backlog เพื่อ 4096 ในบางจุดที่ผม tcp_synack_retries ยังลดลงถึง 3 (ลดลงจากเริ่มต้นของ 5) sysctl -w net.ipv4.tcp_synack_retries=3โดยการออกและเสนอขาย หลังจากทำสิ่งนี้แล้วความถี่จะลดลงเมื่อช่วงเวลาของข้อความแตกต่างกันไปประมาณ 60 ถึง 180 วินาที

ต่อไปฉันออกsysctl -w net.ipv4.tcp_max_syn_backlog=65536แต่ยังได้รับข้อความในบันทึก

ตลอดทั้งหมดนี้ฉันได้ดูจำนวนการเชื่อมต่อในสถานะ SYN_RECV (โดยเรียกใช้watch --interval=5 'netstat -tuna |grep "SYN_RECV"|wc -l') และมันไม่เคยสูงกว่าประมาณ 240 ซึ่งต่ำกว่าขนาดของงานในมือมาก แต่ฉันมีเซิร์ฟเวอร์ Red Hat ที่วนรอบ 512 (ขีด จำกัด บนเซิร์ฟเวอร์นี้คือค่าเริ่มต้นของ 1024)

มีการตั้งค่า tcp อื่น ๆ ที่จะ จำกัด ขนาดของ backlog หรือฉันเห่าต้นไม้ผิด? จำนวนการเชื่อมต่อ SYN_RECV ควรnetstat -tunaสัมพันธ์กับขนาดของงานในมือหรือไม่?


ปรับปรุง

อย่างดีที่สุดที่ฉันสามารถบอกได้ว่าฉันกำลังเผชิญกับการเชื่อมต่อที่ถูกต้องที่นี่netstat -tuna|wc -lวนเวียนอยู่รอบ ๆ 5,000 ฉันได้ทำการวิจัยในวันนี้และพบโพสต์นี้จากพนักงาน last.fm ซึ่งค่อนข้างมีประโยชน์

ฉันได้ค้นพบว่า tcp_max_syn_backlog ไม่มีผลเมื่อเปิดใช้งาน syncookies (ตามลิงค์นี้ )

ดังนั้นในขั้นตอนต่อไปฉันตั้งค่าต่อไปนี้ใน sysctl.conf:

net.ipv4.tcp_syn_retries = 3
        # default=5
net.ipv4.tcp_synack_retries = 3
        # default=5
net.ipv4.tcp_max_syn_backlog = 65536
        # default=1024
net.core.wmem_max = 8388608
        # default=124928
net.core.rmem_max = 8388608
        # default=131071
net.core.somaxconn = 512
        # default = 128
net.core.optmem_max = 81920
        # default = 20480

จากนั้นผมก็ตั้งค่าของฉันทดสอบเวลาตอบสนองวิ่งและผู้พิการโดยsysctl -p syncookiessysctl -w net.ipv4.tcp_syncookies=0

หลังจากทำเช่นนี้จำนวนการเชื่อมต่อในสถานะ SYN_RECV ยังคงอยู่ประมาณ 220-250 แต่การเชื่อมต่อเริ่มล่าช้าอีกครั้ง เมื่อฉันสังเกตเห็นความล่าช้าเหล่านี้ฉันเปิดใช้งาน syncookies อีกครั้งและความล่าช้าหยุดลง

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

แต่การซิงค์ที่ค้างไว้นั้นไม่เต็มไปด้วยการเชื่อมต่อเพียง 250 การเชื่อมต่อในสถานะ SYN_RECV! เป็นไปได้หรือไม่ที่ข้อความการท่วม SYN เป็นปลาเฮอริ่งแดงและเป็นสิ่งอื่นที่ไม่ใช่ syn_backlog ที่กำลังเติม?

หากใครมีตัวเลือกการปรับแต่งอื่น ๆ ที่ฉันยังไม่ได้ลองฉันก็ยินดีที่จะลองพวกเขา แต่ฉันเริ่มสงสัยว่าการตั้งค่า syn_backlog ไม่ได้ถูกนำไปใช้อย่างเหมาะสมด้วยเหตุผลบางประการ


คำตอบ:


27

ดังนั้นนี่เป็นคำถามที่เรียบร้อย

เริ่มแรกฉันรู้สึกประหลาดใจที่คุณเห็นการเชื่อมต่อใด ๆในสถานะ SYN_RECV ที่เปิดใช้งานคุกกี้ SYN ความสวยงามของคุกกี้ SYN คือคุณสามารถมีส่วนร่วมในการจับมือ TCP 3-way ในฐานะเซิร์ฟเวอร์โดยใช้การเข้ารหัสดังนั้นฉันคาดหวังว่าเซิร์ฟเวอร์จะไม่แสดงการเชื่อมต่อครึ่งเปิดเลยเพราะนั่นจะเป็นสถานะเดียวกันกับที่ ไม่ถูกเก็บไว้

อันที่จริงแล้วการแอบดูอย่างรวดเร็วที่แหล่งที่มา (tcp_ipv4.c) แสดงข้อมูลที่น่าสนใจเกี่ยวกับวิธีที่เคอร์เนลใช้คุกกี้ SYN โดยพื้นฐานแล้วแม้จะเปิดใช้งานเคอร์เนลจะทำงานเหมือนปกติจนกว่าคิวของการเชื่อมต่อที่ค้างอยู่จะเต็ม สิ่งนี้จะอธิบายรายการการเชื่อมต่อที่มีอยู่ของคุณในสถานะ SYN_RECV

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

อีกวิธีหนึ่งหากคุณปิดคุกกี้ SYN ข้อความจะหายไป นั่นเป็นเพียงการทำงานให้กับคุณถ้าคุณไม่ถูกน้ำท่วม SYN อีกต่อไป

ในการพูดถึงสิ่งอื่น ๆ ที่คุณทำ:

  • net.ipv4.tcp_synack_retries:
    • การเพิ่มสิ่งนี้จะไม่มีผลในเชิงบวกใด ๆ สำหรับการเชื่อมต่อขาเข้าที่ถูกปลอมแปลงหรือสำหรับการรับคุกกี้ SYN แทนที่จะเป็นสถานะฝั่งเซิร์ฟเวอร์ (ไม่ลองอีกครั้ง)
    • สำหรับการเชื่อมต่อที่ปลอมแปลงขาเข้าการเพิ่มสิ่งนี้จะเพิ่มจำนวนของแพ็คเก็ตที่คุณส่งไปยังที่อยู่ปลอมและอาจเป็นระยะเวลาที่ที่อยู่ที่ปลอมแปลงอยู่ในตารางการเชื่อมต่อของคุณ
    • ภายใต้การโหลดปกติ / จำนวนการเชื่อมต่อที่เข้ามายิ่งมีโอกาสมากขึ้นที่คุณจะทำการเชื่อมต่อผ่านลิงค์ที่วางแพ็กเก็ตได้อย่างรวดเร็ว / สำเร็จ มีผลตอบแทนลดลงสำหรับการเพิ่มนี้
  • net.ipv4.tcp_syn_retries: การเปลี่ยนแปลงนี้จะไม่มีผลต่อการเชื่อมต่อขาเข้า (จะมีผลเฉพาะการเชื่อมต่อขาออก)

ตัวแปรอื่น ๆ ที่คุณพูดถึงฉันยังไม่ได้ค้นคว้า แต่ฉันสงสัยว่าคำตอบสำหรับคำถามของคุณนั้นค่อนข้างที่นี่

หากคุณไม่ได้รับน้ำท่วม SYN และเครื่องตอบสนองต่อการเชื่อมต่อที่ไม่ใช่ HTTP (เช่น SSH) ฉันคิดว่าอาจมีปัญหาเครือข่ายและคุณควรมีวิศวกรเครือข่ายช่วยให้คุณดูได้ หากเครื่องไม่ตอบสนองโดยทั่วไปแม้ว่าคุณจะไม่ได้รับน้ำท่วม SYN ดูเหมือนว่าจะเกิดปัญหาในการโหลดอย่างรุนแรงหากมีผลต่อการสร้างการเชื่อมต่อ TCP (ระดับค่อนข้างต่ำและไม่ต้องใช้ทรัพยากรมาก)


ขอบคุณ - นี่คือคำตอบที่น่าสนใจและให้ข้อมูล แน่นอนตอบคำถามของฉันเกี่ยวกับความสัมพันธ์ระหว่างการเชื่อมต่อในสถานะ SYN_RECV และการส่งคุกกี้ เครื่องตอบสนองต่อ HTTP ที่ไม่ใช่รวมถึง SSH และ HTTPS ซึ่งรับปริมาณการรับส่งข้อมูลน้อยกว่า HTTP มาก ดังนั้นเราจึงตัดสินใจว่าการลดทราฟฟิกเป็นวิธีที่จะไป
Alex Forbes

สำหรับการหาวิศวกรเครือข่ายให้ดู - ข้อเสนอแนะที่ดี แต่เรากำลังย้ายออกจากศูนย์ข้อมูลนี้ดังนั้นจึงอาจไม่คุ้มค่าเมื่อเรานำเซิร์ฟเวอร์ใหม่สองตัวมาที่อื่น ฉันคิดว่าคุณอาจถูกต้องว่าเป็นปัญหาเครือข่าย - อาจมีปัญหากับ load balancer หรือ firewall ขอบคุณอีกครั้งสำหรับข้อมูลเชิงลึกของคุณ!
Alex Forbes

13

ฉันประสบปัญหาเดียวกันในการติดตั้งใหม่ของ Ubuntu Oneiric 11.10 ที่ใช้เว็บเซิร์ฟเวอร์ (apache2) กับเว็บไซต์ที่โหลดจำนวนมาก ใน Ubuntu Oneiric 11.10 syncookies ถูกเปิดใช้งานโดยค่าเริ่มต้น

ฉันมีข้อความเคอร์เนลเดียวกันที่ระบุว่าเป็นไปได้ของการโจมตี SYN บนเว็บเซิร์ฟเวอร์:

เคอร์เนล: [739408.882650] TCP: SYN ที่เป็นไปได้ท่วมที่พอร์ต 80 การส่งคุกกี้

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

การปรับnet.ipv4.tcp_max_syn_backlogพารามิเตอร์ไม่ได้นำไปสู่การปรับปรุงใด ๆ - ข้อความยังคงดำเนินต่อไปในอัตราเดียวกัน ความจริงที่ว่าจำนวนการเชื่อมต่อ SYN_RECV นั้นต่ำมาก (ในกรณีของฉันที่อายุต่ำกว่า 250) เป็นตัวบ่งชี้ว่าต้องมีพารามิเตอร์อื่น ๆ ที่รับผิดชอบข้อความนี้

ฉันพบข้อความข้อผิดพลาดนี้https://bugzilla.redhat.com/show_bug.cgi?id=734991บนไซต์หมวกแดงที่ระบุว่าข้อความเคอร์เนลอาจเป็นผลมาจากข้อผิดพลาด (หรือการกำหนดค่าผิดพลาด) ที่ด้านแอปพลิเคชัน . แน่นอนว่าข้อความในบันทึกมีความเข้าใจผิดมาก! เนื่องจากนี่ไม่ใช่พารามิเตอร์เคอร์เนลที่รับผิดชอบในกรณีนั้น แต่พารามิเตอร์ของแอปพลิเคชันของคุณผึ้งจะถูกส่งผ่านไปยังเคอร์เนล

ดังนั้นเราควรดูพารามิเตอร์การกำหนดค่าของแอปพลิเคชันเว็บเซิร์ฟเวอร์ของเราด้วย หยิบเอกสาร apache และไปที่http://httpd.apache.org/docs/2.0/mod/mpm_common.html#listenbacklog

ค่าเริ่มต้นของListenBacklogพารามิเตอร์คือ 511 (ซึ่งสอดคล้องกับจำนวนการเชื่อมต่อที่คุณสังเกตเห็นในเซิร์ฟเวอร์หมวกสีแดงของคุณเซิร์ฟเวอร์อื่นของคุณอาจมีการกำหนดค่าจำนวนที่ต่ำกว่า)

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

เพื่อแก้ปัญหานี้ฉันเพิ่มบรรทัดต่อไปนี้/etc/apache2/ports.confหรือหนึ่งในไฟล์. conf อื่นที่จะโหลดโดย apache ( /etc/apache2/apache2.confควรเป็น ok):

ListenBackLog 5000

คุณควรตั้งค่าที่net.ipv4.tcp_max_syn_backlogเหมาะสม ในความเข้าใจของฉันเคอร์เนลสูงสุดจะ จำกัด ค่าที่คุณจะสามารถกำหนดค่าในการกำหนดค่า apache วิ่งไปเลย:

sudo sysctl -w net.ipv4.tcp_max_syn_backlog=5000

หลังจากปรับแต่งการตั้งค่าอย่าลืมรีสตาร์ท apache ของคุณ:

sudo service apache2 restart ( or sudo /etc/init.d/apache2 restart )

ในกรณีของฉันการเปลี่ยนแปลงการกำหนดค่านี้หยุดเคอร์เนลคำเตือนทันที ฉันสามารถสร้างข้อความได้โดยตั้งค่า ListenBackLog ต่ำในการกำหนดค่า apache


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

ฉันสามารถยืนยันได้ว่านี่ใช้งานได้จริง ๆ แล้วมันเป็นคุณสมบัติต่อต้านเคอร์เนล DDOS แต่เมื่อคุณได้รับว่ามีปริมาณการใช้งานเว็บมากพอจะปิดกั้นผู้ใช้ที่ถูกกฎหมายของคุณ!
Areeb Soo Yasir

5

หลังจากการทดสอบบางอย่างกับเคอร์เนล 3.4.9 จำนวนการเชื่อมต่อ SYN_RECV ใน netstat ขึ้นอยู่กับ

  • /proc/sys/net/core/somaxconn ปัดขึ้นเป็นกำลังต่อไปของ 2 (เช่น 128 -> 256)
  • 75% ของ/proc/sys/net/ipv4/tcp_max_syn_backlogถ้า/proc/sys/net/ipv4/tcp_syncookiesถูกตั้งค่าเป็น0หรือ 100% หาก/proc/sys/net/ipv4/tcp_syncookiesถูกตั้งค่าเป็น1
  • ListenBackLog ในการกำหนดค่า apache ปัดขึ้นเป็นกำลังต่อไปของ 2 (เช่น 128 -> 256)

ใช้พารามิเตอร์ต่ำสุดของแต่ละพารามิเตอร์นี้ หลังจากเปลี่ยน somaxconn หรือ ListenBackLog apache จะต้องเริ่มต้นใหม่

และหลังจากเพิ่ม tcp_max_syn_backlog apache ก็จะต้องเริ่มต้นใหม่

หากไม่มี tcp_syncookies apache กำลังบล็อกเหตุใดในกรณีนี้มีเพียง 75% ของ tcp_max_syn_backlog เป็นข้อ จำกัด และการเพิ่มพารามิเตอร์นี้จะเพิ่มการเชื่อมต่อ SYN_RECV เป็น 100% ของค่าเก่าโดยไม่ต้องรีสตาร์ท apache


และการโทร/bin/echo m >/proc/sysrq-triggerมักจะนำไปสู่การเกิดน้ำท่วม SYN ที่เป็นไปได้ในพอร์ต 80 การส่งข้อความคุกกี้
usoft
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.