การกำหนดเส้นทางที่รวดเร็วและ NAT ใน Linux

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

บิตของประวัติศาสตร์

หัวข้อเรื่องการหมดพื้นที่ที่อยู่ IPv4 ไม่ใช่เรื่องใหม่อีกต่อไป เมื่อถึงจุดหนึ่ง รายการรอปรากฏใน RIPE จากนั้นการแลกเปลี่ยนก็เกิดขึ้นซึ่งมีการซื้อขายบล็อคที่อยู่และมีการสรุปข้อตกลงเพื่อเช่า ผู้ให้บริการโทรคมนาคมเริ่มให้บริการการเข้าถึงอินเทอร์เน็ตโดยใช้ที่อยู่และการแปลพอร์ตทีละน้อย บางคนไม่ได้รับที่อยู่เพียงพอที่จะออกที่อยู่ "สีขาว" ให้กับสมาชิกแต่ละคน ในขณะที่บางคนเริ่มประหยัดเงินโดยปฏิเสธที่จะซื้อที่อยู่ในตลาดรอง ผู้ผลิตอุปกรณ์เครือข่ายสนับสนุนแนวคิดนี้เพราะว่า ฟังก์ชันนี้มักจะต้องใช้โมดูลส่วนขยายหรือใบอนุญาตเพิ่มเติม ตัวอย่างเช่น ในสายผลิตภัณฑ์เราเตอร์ MX ของ Juniper (ยกเว้น MX104 และ MX204 ล่าสุด) คุณสามารถดำเนินการ NAPT บนการ์ดบริการ MS-MIC แยกต่างหาก Cisco ASR1k ต้องมีใบอนุญาต CGN Cisco ASR9k ต้องใช้โมดูล A9K-ISM-100 แยกต่างหาก และใบอนุญาต A9K-CGN -LIC ให้กับเขา โดยทั่วไปแล้วความสุขต้องเสียเงินเป็นจำนวนมาก

IPTables

งานการดำเนินการ NAT ไม่จำเป็นต้องใช้ทรัพยากรการประมวลผลแบบพิเศษซึ่งสามารถแก้ไขได้ด้วยโปรเซสเซอร์อเนกประสงค์ซึ่งติดตั้งไว้เช่นในเราเตอร์ที่บ้าน ในระดับผู้ให้บริการโทรคมนาคม ปัญหานี้สามารถแก้ไขได้โดยใช้เซิร์ฟเวอร์สินค้าโภคภัณฑ์ที่ใช้ FreeBSD (ipfw/pf) หรือ GNU/Linux (iptables) เราจะไม่พิจารณา FreeBSD เพราะ... ฉันหยุดใช้ระบบปฏิบัติการนี้ไปนานแล้ว ดังนั้นเราจะใช้ GNU/Linux ต่อไป

การเปิดใช้งานการแปลที่อยู่ไม่ใช่เรื่องยากเลย ก่อนอื่นคุณต้องลงทะเบียนกฎใน iptables ในตาราง nat:

iptables -t nat -A POSTROUTING -s 100.64.0.0/10 -j SNAT --to <pool_start_addr>-<pool_end_addr> --persistent

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

net.ipv4.ip_forward = 1
net.ipv4.ip_local_port_range = 8192 65535

net.netfilter.nf_conntrack_generic_timeout = 300
net.netfilter.nf_conntrack_tcp_timeout_syn_sent = 60
net.netfilter.nf_conntrack_tcp_timeout_syn_recv = 60
net.netfilter.nf_conntrack_tcp_timeout_established = 600
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 60
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 45
net.netfilter.nf_conntrack_tcp_timeout_last_ack = 30
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120
net.netfilter.nf_conntrack_tcp_timeout_close = 10
net.netfilter.nf_conntrack_tcp_timeout_max_retrans = 300
net.netfilter.nf_conntrack_tcp_timeout_unacknowledged = 300
net.netfilter.nf_conntrack_udp_timeout = 30
net.netfilter.nf_conntrack_udp_timeout_stream = 60
net.netfilter.nf_conntrack_icmpv6_timeout = 30
net.netfilter.nf_conntrack_icmp_timeout = 30
net.netfilter.nf_conntrack_events_retry_timeout = 15
net.netfilter.nf_conntrack_checksum=0

และประการที่สอง เนื่องจากขนาดเริ่มต้นของตารางการแปลไม่ได้ออกแบบมาเพื่อทำงานภายใต้เงื่อนไขของผู้ให้บริการโทรคมนาคม จึงจำเป็นต้องเพิ่มขึ้น:

net.netfilter.nf_conntrack_max = 3145728

นอกจากนี้ยังจำเป็นต้องเพิ่มจำนวนที่เก็บข้อมูลสำหรับตารางแฮชที่จัดเก็บการออกอากาศทั้งหมด (นี่คือตัวเลือกในโมดูล nf_conntrack):

options nf_conntrack hashsize=1572864

หลังจากการยักย้ายง่าย ๆ เหล่านี้ จะได้การออกแบบที่ใช้งานได้อย่างสมบูรณ์ซึ่งสามารถแปลที่อยู่ลูกค้าจำนวนมากเป็นกลุ่มที่อยู่ภายนอกได้ อย่างไรก็ตาม ประสิทธิภาพของโซลูชันนี้ยังไม่เป็นที่ต้องการมากนัก ในความพยายามครั้งแรกของฉันในการใช้ GNU/Linux สำหรับ NAT (ประมาณปี 2013) ฉันสามารถรับประสิทธิภาพได้ประมาณ 7Gbit/s ที่ 0.8Mpps ต่อเซิร์ฟเวอร์ (Xeon E5-1650v2) ตั้งแต่นั้นเป็นต้นมา ได้มีการปรับแต่งประสิทธิภาพต่างๆ มากมายในสแต็กเครือข่ายเคอร์เนล GNU/Linux ประสิทธิภาพของเซิร์ฟเวอร์หนึ่งตัวบนฮาร์ดแวร์เดียวกันได้เพิ่มขึ้นเป็นเกือบ 18-19 Gbit/s ที่ 1.8-1.9 Mpps (ซึ่งเป็นค่าสูงสุด) แต่ความต้องการปริมาณการรับส่งข้อมูลที่ประมวลผลโดยเซิร์ฟเวอร์เดียวเพิ่มขึ้นเร็วกว่ามาก เป็นผลให้มีการพัฒนาแผนงานเพื่อสร้างความสมดุลระหว่างโหลดบนเซิร์ฟเวอร์ที่แตกต่างกัน แต่ทั้งหมดนี้เพิ่มความซับซ้อนในการตั้งค่า บำรุงรักษา และรักษาคุณภาพของบริการที่มีให้

NTFables

ปัจจุบัน กระแสนิยมในซอฟต์แวร์ “ถุงขนของ” คือการใช้ DPDK และ XDP มีการเขียนบทความจำนวนมากในหัวข้อนี้ มีการกล่าวสุนทรพจน์ที่แตกต่างกันมากมาย และมีผลิตภัณฑ์เชิงพาณิชย์ปรากฏขึ้น (เช่น SKAT จาก VasExperts) แต่ด้วยทรัพยากรการเขียนโปรแกรมที่จำกัดของผู้ให้บริการโทรคมนาคม การสร้าง "ผลิตภัณฑ์" ใดๆ ตามกรอบงานเหล่านี้ด้วยตนเองจึงค่อนข้างเป็นปัญหา การใช้งานโซลูชันดังกล่าวจะยากขึ้นมากในอนาคต โดยเฉพาะอย่างยิ่ง จะต้องพัฒนาเครื่องมือวินิจฉัย ตัวอย่างเช่น tcpdump มาตรฐานที่มี DPDK จะไม่ทำงานเช่นนั้น และจะไม่เห็นแพ็กเก็ตที่ส่งกลับไปยังสายโดยใช้ XDP ท่ามกลางการพูดถึงเทคโนโลยีใหม่ๆ สำหรับเอาท์พุตการส่งต่อแพ็กเก็ตไปยังพื้นที่ผู้ใช้ พวกเขาก็ไม่มีใครสังเกตเห็น รายงาน и บทความ Pablo Neira Ayuso ผู้ดูแล iptables เกี่ยวกับการพัฒนาโฟลว์ออฟโหลดใน nftables มาดูกลไกนี้กันดีกว่า

แนวคิดหลักคือหากเราเตอร์ส่งแพ็กเก็ตจากเซสชันหนึ่งไปในทั้งสองทิศทางของโฟลว์ (เซสชัน TCP เข้าสู่สถานะ ESTABLISHED) ก็ไม่จำเป็นต้องส่งแพ็กเก็ตที่ตามมาของเซสชันนี้ผ่านกฎไฟร์วอลล์ทั้งหมดเพราะ การตรวจสอบทั้งหมดนี้จะยังคงจบลงด้วยการที่แพ็กเก็ตถูกถ่ายโอนไปยังเส้นทางเพิ่มเติม และเราไม่จำเป็นต้องเลือกเส้นทางจริงๆ - เรารู้อยู่แล้วว่าเราต้องส่งแพ็กเก็ตไปยังอินเทอร์เฟซใดและไปยังโฮสต์ใดภายในเซสชันนี้ สิ่งที่เหลืออยู่คือการจัดเก็บข้อมูลนี้และใช้สำหรับการกำหนดเส้นทางในระยะแรกของการประมวลผลแพ็คเก็ต เมื่อดำเนินการ NAT จำเป็นต้องจัดเก็บข้อมูลเพิ่มเติมเกี่ยวกับการเปลี่ยนแปลงที่อยู่และพอร์ตที่แปลโดยโมดูล nf_conntrack ใช่แน่นอน ในกรณีนี้ เจ้าหน้าที่ตำรวจและข้อมูลอื่น ๆ และกฎทางสถิติใน iptables หยุดทำงาน แต่ภายในกรอบงานของ NAT ที่แยกจากกันหรือเช่นเขตแดนสิ่งนี้ไม่สำคัญนักเนื่องจากบริการ จะถูกกระจายไปตามอุปกรณ์ต่างๆ

องค์ประกอบ

ในการใช้ฟังก์ชั่นนี้เราต้องการ:

  • ใช้เคอร์เนลสด แม้ว่าฟังก์ชั่นนี้จะปรากฏในเคอร์เนล 4.16 แต่เป็นเวลานานแล้วที่มันเป็น "ดิบ" มากและทำให้เกิดความตื่นตระหนกเคอร์เนลเป็นประจำ ทุกอย่างมีเสถียรภาพประมาณเดือนธันวาคม 2019 เมื่อเคอร์เนล LTS 4.19.90 และ 5.4.5 เปิดตัว
  • เขียนกฎ iptables ใหม่ในรูปแบบ nftables โดยใช้ nftables เวอร์ชันล่าสุด ใช้งานได้ทุกประการในเวอร์ชัน 0.9.0

หากทุกอย่างชัดเจนในหลักการในประเด็นแรก สิ่งสำคัญคืออย่าลืมรวมโมดูลไว้ในการกำหนดค่าระหว่างการประกอบ (CONFIG_NFT_FLOW_OFFLOAD=m) ดังนั้นจุดที่สองจะต้องมีคำอธิบาย กฎ nftables มีการอธิบายแตกต่างไปจากใน iptables อย่างสิ้นเชิง เอกสาร เผยเกือบทุกประเด็นยังมีความพิเศษอีกด้วย ตัวแปลง กฎตั้งแต่ iptables ไปจนถึง nftables ดังนั้นฉันจะยกตัวอย่างการตั้งค่า NAT และโฟลว์ออฟโหลดเท่านั้น ตำนานเล็กๆ เช่น: , - นี่คืออินเทอร์เฟซเครือข่ายที่การรับส่งข้อมูลผ่าน ในความเป็นจริงอาจมีมากกว่าสองรายการ , — ที่อยู่เริ่มต้นและสิ้นสุดของช่วงของที่อยู่ “สีขาว”

การกำหนดค่า NAT นั้นง่ายมาก:

#! /usr/sbin/nft -f

table nat {
        chain postrouting {
                type nat hook postrouting priority 100;
                oif <o_if> snat to <pool_addr_start>-<pool_addr_end> persistent
        }
}

ด้วยโฟลว์ออฟโหลดจะซับซ้อนกว่าเล็กน้อย แต่ค่อนข้างเข้าใจได้:

#! /usr/sbin/nft -f

table inet filter {
        flowtable fastnat {
                hook ingress priority 0
                devices = { <i_if>, <o_if> }
        }

        chain forward {
                type filter hook forward priority 0; policy accept;
                ip protocol { tcp , udp } flow offload @fastnat;
        }
}

อันที่จริงแล้วคือการตั้งค่าทั้งหมด ตอนนี้การรับส่งข้อมูล TCP/UDP ทั้งหมดจะตกอยู่ในตาราง fastnat และประมวลผลได้เร็วยิ่งขึ้นมาก

ผลการวิจัย

เพื่อให้ชัดเจนว่าสิ่งนี้ "เร็วกว่ามาก" แค่ไหน ฉันจะแนบภาพหน้าจอของการโหลดบนเซิร์ฟเวอร์จริงสองตัวด้วยฮาร์ดแวร์เดียวกัน (Xeon E5-1650v2) กำหนดค่าเหมือนกัน โดยใช้เคอร์เนล Linux เดียวกัน แต่ดำเนินการ NAT ใน iptables (NAT4) และใน nftables (NAT5)

การกำหนดเส้นทางที่รวดเร็วและ NAT ใน Linux

ไม่มีกราฟของแพ็กเก็ตต่อวินาทีในภาพหน้าจอ แต่ในโปรไฟล์โหลดของเซิร์ฟเวอร์เหล่านี้ ขนาดแพ็กเก็ตเฉลี่ยจะอยู่ที่ประมาณ 800 ไบต์ ดังนั้นค่าจึงสูงถึง 1.5Mpps อย่างที่คุณเห็น เซิร์ฟเวอร์ที่มี nftables มีประสิทธิภาพสำรองมหาศาล ปัจจุบัน เซิร์ฟเวอร์นี้ประมวลผลได้ถึง 30Gbit/s ที่ 3Mpps และสามารถตอบสนองข้อจำกัดของเครือข่ายทางกายภาพที่ 40Gbps ได้อย่างชัดเจน ในขณะที่มีทรัพยากร CPU ว่าง

ฉันหวังว่าเนื้อหานี้จะเป็นประโยชน์สำหรับวิศวกรเครือข่ายที่พยายามปรับปรุงประสิทธิภาพของเซิร์ฟเวอร์ของพวกเขา

ที่มา: will.com

เพิ่มความคิดเห็น