การตรวจสอบฐานข้อมูลที่ The Grid
เผยแพร่แล้ว: 2018-09-29เนื่องจากเมื่อเร็วๆ นี้ SendGrid กลายเป็นบริษัทที่ซื้อขายในตลาดหลักทรัพย์ เราจำเป็นต้องมีบันทึกการตรวจสอบฉบับสมบูรณ์ของการเปลี่ยนแปลงทั้งหมดในส่วนย่อยของฐานข้อมูลของเรา ชุดย่อยนี้รวมอินสแตนซ์ขนาดเล็กบางตัวที่ไม่เห็นการรับส่งข้อมูลปริมาณมาก แต่ยังรวมถึงคลัสเตอร์เก่าของเราบางส่วนที่มีความสำคัญต่อเวลาทำงานของพอร์ทัลลูกค้าของเราและขั้นตอนการสมัคร
สิ่งนี้ยังส่งผลกระทบต่อที่เก็บข้อมูลบางแห่งที่มีความต้องการเวลาทำงานสูงและการเปิดตัวออนไลน์ (โดยไม่ต้องหยุดทำงานเพื่อเขียน) เป็นที่น่าพอใจ ด้วยกำหนดเส้นตายภายนอกที่ใกล้มือและรู้ขอบเขตของโครงการแล้ว เราจึงเริ่มจัดทำแผน
ในขั้นตอนการวางแผน เราระบุคำถามเปิดสองสามข้อที่เราต้องการคำตอบสำหรับ:
- เรามีตัวเลือกอะไรบ้างสำหรับซอฟต์แวร์ที่สามารถทำได้
- คาดหวังผลกระทบด้านประสิทธิภาพอะไรบ้าง และเราสามารถทดสอบสิ่งนั้นล่วงหน้าได้มากน้อยเพียงใด
- เราสามารถทำได้โดยไม่ต้องหยุดทำงานสำหรับความพร้อมใช้งานในการเขียนหรือไม่
ทางเลือก ทางเลือก
ที่ SendGrid เราปฏิบัติตามกระบวนการพิมพ์เขียวการออกแบบสำหรับโครงการขนาดใหญ่หรือข้ามทีม โครงการนี้เกี่ยวข้องกับทีมจำนวนมากในฐานะผู้มีส่วนได้ส่วนเสีย ได้แก่ :
- การตรวจสอบภายใน ในฐานะทีมที่รับผิดชอบในการกำหนดว่าที่เก็บข้อมูลใดอยู่ในขอบเขตสำหรับการควบคุมการปฏิบัติตามข้อกำหนดนี้ และสำหรับการรวบรวมหลักฐานถึงเวลาตรวจสอบ
- InfoSec เป็นทีมที่จะวิเคราะห์และจัดการการตอบสนองต่อเหตุการณ์ที่ได้รับจากบันทึกการตรวจสอบฐานข้อมูลเหล่านี้
- DB Ops ในฐานะทีมเขียนโค้ดที่ปรับใช้ จัดการ และปรับแต่งคุณลักษณะใหม่นี้ไปยังฐานข้อมูลที่อยู่ในขอบเขต
ฉันตั้งใจที่จะเขียนพิมพ์เขียวนี้ และตรวจสอบให้แน่ใจว่าผู้มีส่วนได้ส่วนเสียทั้งหมดได้รับการตรวจสอบและได้รับการอนุมัติจากทีมสถาปัตยกรรมของเรา แม้ว่าฉันได้ค้นคว้าเกี่ยวกับหัวข้อการบันทึกการตรวจสอบใน MySQL เมื่อสองสามปีก่อนและมีความคิดว่าภูมิทัศน์ของตัวเลือกเป็นอย่างไร ฉันไม่ต้องการเข้าใกล้โครงการด้วยอคติและต้องการยังคงตรวจสอบมากกว่าหนึ่ง และให้ทุกคนมีกรณีที่ชัดเจนว่าเหตุใดเราจึงเลือกวิธีแก้ปัญหาแบบใดแบบหนึ่งมากกว่าแบบอื่น
พิมพ์เขียวนี้ไม่ปกติตรงที่ฉันเขียนมันพร้อมๆ กันในขณะที่กำลังตรวจสอบว่าโซลูชันที่ตอบสนองความต้องการของธุรกิจจะเป็นอย่างไร ดังนั้นฉันจึงรู้ว่าจะต้องกรอกรายละเอียดจำนวนมากในขณะที่เราทำการวิจัย
ตัวเลือกของเราคือ:
- ปลั๊กอินตรวจสอบ Percona
- Mcafee MySQL Audit
แม้ว่าสิ่งเหล่านี้จะไม่ใช่ทางเลือกเดียวในตลาด แต่เรารู้สึกว่าสิ่งเหล่านี้ใกล้เคียงกับขนาดและแนวทางปฏิบัติในการพัฒนาของเรามากที่สุดเพื่อรับประกันว่าจะถูกรวมเข้าในการดำเนินการจริง ตัวเลือกทางการค้าอื่นๆ ในตลาดไม่ผ่านเกณฑ์นั้นที่จะรวมอยู่ในเกณฑ์มาตรฐาน
หลังเป็นโซลูชันที่ใหม่กว่าซึ่งเพิ่งเปิดโดย Mcafee และน่าสนใจมากพอที่จะพิจารณาเพราะมันอ้างว่าสนับสนุนการกรองระดับตารางซึ่งปลั๊กอิน Percona ไม่ได้ทำ เนื่องจากเราทราบดีว่าคลัสเตอร์หนึ่งในขอบเขตของเราจำเป็นต้องตรวจสอบตารางประมาณ 24 ตารางจากทั้งหมด 300 ตาราง ดูเหมือนว่าจะเป็นคุณลักษณะที่มีคุณค่าเพียงพอที่จะทำให้ปลั๊กอิน Mcafee เป็นคู่แข่งกัน
ในทางกลับกัน ปลั๊กอิน Percona Audit เป็นโซลูชันโอเพ่นซอร์สที่ใช้กันอย่างแพร่หลายมากที่สุดสำหรับคุณลักษณะนี้ มีมาให้ในตัวแต่ปิดใช้งานในเซิร์ฟเวอร์ Percona ซึ่งเราใช้อยู่แล้ว อย่างไรก็ตาม มันไม่ได้มีการกรองเหตุการณ์ในระดับตาราง ซึ่งหมายความว่าเราจำเป็นต้องทำสิ่งนั้นนอกชั้นฐานข้อมูล
อบออก
ด้วยความช่วยเหลือจากทีมงานพันธมิตรของเราที่ Pythian เราจึงเริ่มการเปรียบเทียบแบบแยกส่วน ในตอนแรก เราเปรียบเทียบวิธีการติดตั้งและปรับแต่งแต่ละตัวเลือก ทีมงานตัดสินใจอย่างรวดเร็วว่าเรามีข้อแลกเปลี่ยนในมือของเรา แม้ว่าปลั๊กอิน Mcafee รองรับตัวกรองตารางแบบเนทีฟ แต่ก็ไม่รองรับการใช้ rsyslog เป็นวิธีการสตรีมเหตุการณ์ นี่หมายความว่าถ้าเราใช้มัน เราจะต้องเขียนไฟล์ในเครื่องไปยังดิสก์และต้องจัดการการส่งมันออกไปที่กองการมอนิเตอร์
สิ่งนี้ถือว่าไม่พึงปรารถนา เนื่องจากมีแนวโน้มมากที่สุดที่จะเพิ่มบทลงโทษด้านประสิทธิภาพของการใช้ปลั๊กอินการตรวจสอบ การเขียนเหตุการณ์การตรวจสอบในเครื่องแล้วอ่านอีกครั้งโดยกระบวนการที่แยกจากกันจะนำความจุ IOPS ออกจากปริมาณการใช้งานจริงของเรา และเพิ่มความเสี่ยงให้กับอินสแตนซ์ฐานข้อมูล เนื่องจากเราต้องจัดการขนาดของไฟล์เหล่านี้บนดิสก์ เกรงว่ามันจะขยายและทำให้ฐานข้อมูล เวลาหยุดทำงาน
ในทางกลับกันของการประนีประนอมคือปลั๊กอิน Percona รองรับการส่งเหตุการณ์ไปยัง syslog โดยกำเนิด แต่ไม่มีตัวกรองตารางใด ๆ เรารู้ว่านี่หมายความว่ากลุ่มที่มีงานยุ่งในขอบเขตจะส่งเหตุการณ์จำนวนมาก ซึ่งส่วนใหญ่ไม่ได้มาจากตารางที่เราต้องการตรวจสอบจริงๆ สิ่งนี้ทำให้เกิดความเสี่ยงต่อเลเยอร์ syslog-receive/logstash ของสแต็กการตรวจสอบของ InfoSec เนื่องจาก DB ops ไม่มีสิทธิ์เข้าถึงจึงหมายความว่าความสำเร็จของโครงการนี้เป็นความพยายามในการเป็นเจ้าของร่วมกัน
ในท้ายที่สุด เราตัดสินใจใช้โซลูชันที่มีชิ้นส่วนที่เคลื่อนไหวน้อยลง และวางแผนการปรับใช้ของเราเพื่อให้ทราบโดยเร็วที่สุดหากจำเป็นต้องปรับขนาด logstash เพื่อจัดการกับการกรองเหตุการณ์นับพันต่อวินาที ดังนั้นจึงตัดสินใจเดินหน้าด้วยปลั๊กอินตรวจสอบของ Percona
การวางแผนการทำให้ใช้งานได้
ขอบเขตการติดตั้ง
เราตัดสินใจที่จะทำให้การปรับใช้นี้ง่ายขึ้นโดยการติดตั้งและเปิดใช้งานปลั๊กอินบนโหนดทั้งหมดในคลัสเตอร์ที่กำหนด ซึ่งหมายความว่าเราขจัดความจำเป็นในการเตรียมการเปิดหรือปิดเครื่องมือตรวจสอบเมื่อโหนดตัวเขียนในคลัสเตอร์เปลี่ยนแปลง เราไม่มีข้อกังวลใดๆ เกี่ยวกับสตรีมการจำลองแบบที่ทำให้เกิดเหตุการณ์ที่ซ้ำกันเมื่อมีการใช้การเปลี่ยนแปลง เนื่องจากปลั๊กอินไม่ได้บันทึกการเปลี่ยนแปลงสตรีมการจำลองตามการออกแบบ
ไม่มีการหยุดทำงาน
เราต้องการทำให้สิ่งนี้เป็นการปรับใช้ที่ราบรื่นโดยไม่มีการหยุดทำงานในคลัสเตอร์ที่ได้รับผลกระทบ ซึ่งจะช่วยลดจำนวนการวางแผนและการประสานที่เราต้องดำเนินการกับทีมจัดส่งโดยใช้คลัสเตอร์เหล่านี้ และลดผลกระทบต่อลูกค้าลงอย่างมาก แต่เรายังต้องการให้ปลั๊กอินส่งเหตุการณ์ไปยัง rsyslog ในสถานที่เฉพาะ ด้วยการกำหนดค่าแบบกำหนดเองที่จะส่งเหตุการณ์ไปยังเซิร์ฟเวอร์การรวม syslog ของทีม InfoSec การกำหนดค่าเหล่านี้บางส่วนได้รับการบันทึกว่าไม่ใช่ไดนามิกโดย Percona และนั่นนำเสนอความเป็นไปได้ที่ทุกอินสแตนซ์ในขอบเขตสำหรับโปรเจ็กต์นี้จะเกิดการหยุดทำงานในขณะที่เรารีสตาร์ทอินสแตนซ์ mysql ด้วยการกำหนดค่าปลั๊กอินการตรวจสอบที่จำเป็น
เราเริ่มทดสอบคำสั่งการทำงานต่างๆ ในการปรับใช้ปลั๊กอินด้วยอินสแตนซ์การทดสอบเฉพาะในสภาพแวดล้อมการจัดเตรียมของเรา และสามารถแสดงให้เห็นว่าถ้าเรามีการจัดการการกำหนดค่าของเราวางการกำหนดค่าที่จำเป็นทั้งหมดในตอนแรก จากนั้นรัน คำสั่ง โหลดปลั๊กอิน คำสั่งนั้นจะ เริ่มต้นด้วยการกำหนดค่าที่ต้องการ
สิ่งนี้พิสูจน์แล้วว่ามีประโยชน์ทั้งในการทำให้แผนการทำโปรเจ็กต์นี้สำเร็จได้ง่ายขึ้น และลดระยะเวลาในการเปิดตัวโปรเจ็กต์นี้ ซึ่งเป็นการซื้อเวลาให้เราปรับแต่งการกรองเหตุการณ์และทำงานร่วมกับทีมรักษาความปลอดภัยในการวิเคราะห์และตรวจจับ
ใช้การจัดการการกำหนดค่า
เราใช้ตำราของเชฟเพื่อจัดการฐานข้อมูลของเรา เห็นได้ชัดว่าเราวางแผนที่จะใช้เชฟในการปรับใช้ ปรับแต่ง และตรวจสอบปลั๊กอินการตรวจสอบ แต่เนื่องจากจำเป็นต้องเปิดใช้งานในส่วนย่อยของคลัสเตอร์ของเราเท่านั้น ซึ่งหมายความว่าเราจำเป็นต้องควบคุมตำแหน่งที่จะเปิดใช้งานเพื่อไม่ให้เกะกะพื้นที่จัดเก็บบันทึกด้วยข้อมูลที่ไม่เกี่ยวข้องกับเป้าหมายธุรกิจของเราที่นี่
สำหรับการจัดการฐานข้อมูล MySQL เราใช้แบบจำลองตำราอาหารแบบห่อเพื่อจัดการการกำหนดค่า ตำราอาหาร 'ฐาน' หลักกำหนดว่าอินสแตนซ์ฐานข้อมูลควรมีลักษณะอย่างไร จากนั้นตำราอาหารต่อคลัสเตอร์จะห่อเพื่อแก้ไขแอตทริบิวต์หรือเพิ่มการกำหนดค่าที่เกี่ยวข้องกับคลัสเตอร์เฉพาะ การออกแบบนั้นทำให้ง่ายต่อการเพิ่มโค้ดจำนวนมากที่จะสร้างไฟล์การกำหนดค่าที่จำเป็น จากนั้นโหลดปลั๊กอินในสูตรใหม่หนึ่งสูตร ซึ่งเราสามารถเปิดหรือปิดตามแอตทริบิวต์ของเชฟได้ นอกจากนี้ เรายังตัดสินใจตามขอบเขตของการเปลี่ยนแปลงที่เราทำ ซึ่งรับประกันว่าจะต้องเผยแพร่รหัสนี้เป็นเวอร์ชันรองของตำราอาหาร
นอกจากนี้เรายังตรวจสอบให้แน่ใจว่าเชฟได้ลบการตรวจสอบ sensu ที่เกี่ยวข้องและปิดการสตรีมการตรวจสอบเมื่อแอตทริบิวต์ถูกตั้งค่าเป็นเท็จ ทั้งนี้เพื่อให้แน่ใจว่าเชฟสามารถทำสิ่งที่ถูกต้องได้ หากคลัสเตอร์ไม่อยู่ในขอบเขตอีกต่อไปหรือจำเป็นต้องหยุดทำงานด้วยเหตุผลที่ไม่ต่อเนื่องใดๆ ดังนั้นเราจึงไม่จำเป็นต้องเปลี่ยนโหนดด้วยตนเองเพื่อให้สอดคล้องกับการเปลี่ยนแปลงแอตทริบิวต์
การตรวจสอบ
คุณไม่สามารถประกาศความสำเร็จของสิ่งที่คุณไม่ได้ติดตาม แต่การตรวจสอบยังเป็นมากกว่าการตบตรวจสอบ sensu บางรายการโดยไม่ได้คำนึงถึงกรณีความล้มเหลวที่เรากำลังติดตาม และเราคาดหวังการดำเนินการใดในการตอบสนองต่อการตรวจสอบเหล่านี้ที่ล้มเหลวในสักวันหนึ่ง ข้าพเจ้าจึงวางแผนการเฝ้าติดตามในไปป์ไลน์นี้โดยคำนึงถึง 2 ประการ
- เราทุกคนต้องตกลงกันเกี่ยวกับขอบเขตความเป็นเจ้าของที่ชัดเจนในระบบนี้ โดยเฉพาะอย่างยิ่งเนื่องจากระบบนี้ต้องแบกรับความรับผิดชอบของ 2 ทีมที่มีการหมุนเวียนเมื่อเรียกแยกกัน
- การตรวจสอบใหม่ที่เพิ่มเข้ามาสำหรับสิ่งนี้จำเป็นต้องมาพร้อมกับรันบุ๊กที่เราเชื่อมโยงในการตรวจสอบ อธิบายว่าการตรวจสอบนี้ล้มเหลวอย่างไรและจะแก้ไขได้อย่างไร
จากกฎ 2 ข้อนั้น ฉันได้เพิ่มการตรวจสอบที่เจาะจงมาก ณ จุดนี้ ฉันคิดว่าจะเพิ่มการตรวจสอบ 'สังเคราะห์' แบบ end-to-end ด้วย แต่ฉันละเว้นจากการทำเช่นนั้นเนื่องจากการตรวจสอบแบบ end to end ที่นี่จะล้มเหลวในการบอกเราว่าส่วนใดของระบบล้มเหลวซึ่งหมายความว่าเราจะมีปัญหา แม้กระทั่งการเพจทีมที่เหมาะสมกับมัน และฉันไม่ใช่ผู้สนับสนุนการเพจคนในเวลากลางคืน 'เผื่อไว้'
เราตัดสินใจที่จะตรวจสอบสิ่งต่อไปนี้:
- ตรวจสอบการกำหนดค่า mysql สดของปลั๊กอินการตรวจสอบเพื่อให้แน่ใจว่า
- ปลั๊กอินอยู่ในสถานะใช้งานอยู่
- audit_log_policy ถูกตั้งค่า เป็น QUERIES
การตรวจสอบนี้เป็นการยืนยันว่า DB ในขอบเขตไม่มีการกำหนดค่าเปลี่ยนแปลงทันที เนื่องจากการตั้งค่าเหล่านี้เป็นไดนามิกและสามารถเปลี่ยนแปลงภายนอก ไฟล์ my.cnf บนดิสก์ได้
- ตรวจสอบพอร์ตที่เราส่งบันทึกไปยังกองตรวจสอบเพื่อให้แน่ใจว่าข้อมูลกำลังไหล โดยพื้นฐานแล้ว ตรวจสอบให้แน่ใจว่าปลายอีกด้านหนึ่งของสตรีม syslog ทำงาน การตรวจสอบนี้ได้รับการจัดการตามความหมายที่เรียกว่าการ ตรวจสอบโดยรวม ดังนั้นจึงไม่ได้เพจทีม InfoSec อย่างร้ายแรง
อุปสรรคระหว่างทาง
ตรวจสอบการกำหนดค่าปลั๊กอิน
การทำซ้ำครั้งแรกของโครงการนี้มีวัตถุประสงค์เพื่อใช้ประโยชน์จาก คุณลักษณะ audit_log_exclude_commands เพื่อจำกัดเหตุการณ์ที่เราปล่อยไว้เฉพาะข้อมูลหรือการจัดการสคีมา เราเรียนรู้อย่างรวดเร็วว่ารายการการกำหนดค่านี้อิงตามนั้นยาวกว่าที่คาดไว้มาก
การกำหนดค่า rsyslog
นี่คือสิ่งที่ผมไม่รู้มาก่อนโครงการนี้ การกำหนดค่า Rsyslog เกือบจะเป็นภาษาของตัวเอง ตัวอย่างเช่น:
- ใช้ @ ที่สอง หน้าปลายทางระยะไกลเพื่อส่งบันทึกผ่าน TCP แทน UDP เราต้องการใช้สิ่งอำนวยความสะดวกนี้เพื่อรับประกันว่าบันทึกจะถูกส่งออกไปอีกเล็กน้อย
- rsyslog มี หน้าเฉพาะ เกี่ยวกับวิธีการกำหนดค่าสำหรับการส่งต่อที่เชื่อถือได้ ซึ่งพิสูจน์แล้วว่ามีประโยชน์มากสำหรับมือใหม่ในเครื่องมือเช่นฉัน
- โดยค่าเริ่มต้น rsyslog จะส่งข้อมูลไปยัง /var/log/messages ซึ่งไม่เป็นที่ต้องการในกรณีของฉันเพราะนี่เป็นเหตุการณ์มากมาย หากคุณต้องการสร้างสิ่งอำนวยความสะดวกที่คุณใช้อยู่ ไม่ต้องทำเช่นนั้น คุณต้องเพิ่ม local5.* ~ ที่ส่วนท้ายของการกำหนดค่าของคุณ
ซ้อมหนีไฟ
ฉันจะพูดถึงผลกระทบด้านประสิทธิภาพสำหรับฐานข้อมูลในขอบเขตในภายหลัง แต่เนื่องจาก rsyslog ถูกใช้เป็นส่วนสำคัญสำหรับการออกแบบนี้ เราจำเป็นต้องเจาะลึกว่า rsyslog จะทำงานอย่างไรเมื่อปลายทางระยะไกลไม่พร้อมใช้งานหรือไม่ตอบสนอง วิธีที่ดีที่สุดในการทำเช่นนั้นคือการทำให้เกิดการหยุดชะงักของการสื่อสารนั้นโดยใช้กฎ iptables ในการผลิตบนฐานข้อมูลใดฐานข้อมูลหนึ่งที่อยู่ในขอบเขตที่เรารู้ว่ามีปริมาณงานธุรกรรมสูง ดังนั้นจึงมีเหตุการณ์การตรวจสอบจำนวนมากต่อวินาที นี่คือวิธีการฝึกซ้อมดับเพลิง
- ยืนยันว่าเหตุการณ์การตรวจสอบกำลังไหลผ่านพอร์ต TCP ที่กำหนด
- ใช้กฎ iptables เพื่อยกเลิกการรับส่งข้อมูลทั้งหมดบนพอร์ตนั้น /sbin/iptables -A OUTPUT -p tcp –dport {PORT-NUMBER-HERE} -j DROP
- ดูกิจกรรมการเขียนดิสก์และไฟล์ใน WorkDirectory ที่กำหนดค่าไว้ ในการกำหนดค่าของ rsyslog ชื่อไฟล์จะขึ้นอยู่กับ ActionQueueFileName ของสถานที่ที่ได้รับกิจกรรมเหล่านี้
ตามที่คาดไว้ ไฟล์เริ่มสพูลในไดเร็กทอรีนี้ เราเห็นการเพิ่มขึ้นอย่างรวดเร็วในกิจกรรม IOP ของดิสก์ เมื่อจำนวนไฟล์ที่กำหนดชื่อคิวรวมกันเป็นค่าของ ActionQueueMaxDiskSpace แล้ว rsyslog จะหยุดสร้างไฟล์เหล่านี้ ดิสก์ IOPs ถูกทำให้เป็นมาตรฐาน และเป็นที่ชัดเจนว่าตอนนี้เรากำลังวางเหตุการณ์บนพื้นในเลเยอร์ rsyslog สิ่งที่น่าประทับใจกว่าที่ได้เห็นก็คือ หลังจากที่เราลบกฎที่ดื่มได้ rsyslog ได้ส่งเหตุการณ์ทั้งหมดที่สพูลไปยังดิสก์อีกครั้ง ดังนั้นเราจึงไม่สูญเสียเหตุการณ์สำหรับที่เก็บการวิเคราะห์ของเรา ตราบใดที่เราไม่ได้มีขนาดสปูลเกิน เราได้เรียนรู้บางสิ่งจากการทดลองนั้น
- rsyslog ทำงานตามที่บันทึกไว้ ดีกว่าเสมอที่จะพิสูจน์ด้วยการทดลองโดยตรง
- เรามักจะต้องกำหนดพื้นที่ดิสก์คิวที่แตกต่างกันต่อคลัสเตอร์ ขึ้นอยู่กับปริมาณของเหตุการณ์ที่แต่ละรายการสร้างขึ้น เนื่องจากการเข้าคิวบนดิสก์เพิ่มความเสี่ยงให้กับความจุของ IOP และความจุของดิสก์ จึงเป็นสิ่งที่เราต้องทบทวนเป็นระยะและตรวจสอบอีกครั้ง
ในโพสต์ถัดไป ฉันจะพูดถึงสิ่งที่สังเกตของเราหลังจากปรับใช้โปรเจ็กต์นี้กับการผลิต และสิ่งที่ทำให้สิ่งนี้ไม่ขัดขวางการผลิตให้ได้มากที่สุด