MySQL คือระบบฐานข้อมูลเชิงสัมพันธ์ข้ามแพลตฟอร์มแบบเครือข่ายเต็มรูปแบบ และระบบจัดการฐานข้อมูลแบบกระจายพร้อมสถาปัตยกรรมไคลเอ็นต์/เซิร์ฟเวอร์ MySQL คือระบบฐานข้อมูลเชิงสัมพันธ์ข้ามแพลตฟอร์มแบบเครือข่ายเต็มรูปแบบ และระบบจัดการฐานข้อมูลแบบกระจายพร้อมสถาปัตยกรรมไคลเอ็นต์/เซิร์ฟเวอร์ มีข้อดีคือมีฟังก์ชั่นอันทรงพลัง ใช้งานง่าย การจัดการสะดวก ทำงานรวดเร็ว มีความปลอดภัยและความน่าเชื่อถือสูง ผู้ใช้สามารถใช้หลายภาษาในการเขียนโปรแกรมเพื่อเข้าถึงฐานข้อมูล MySQL โดยเฉพาะเมื่อใช้งานร่วมกับ PHP ก็เป็นได้ การผสมผสานสีทองและใช้กันอย่างแพร่หลาย
เนื่องจาก MySQL เป็นฐานข้อมูลหลายแพลตฟอร์ม การกำหนดค่าเริ่มต้นจึงควรได้รับการพิจารณาว่าสามารถใช้ได้ในสถานการณ์ต่างๆ ดังนั้นการเสริมความปลอดภัยเพิ่มเติมจึงควรดำเนินการในสภาพแวดล้อมการใช้งานของเราเอง ในฐานะผู้ดูแลระบบ MySQL เรามีหน้าที่รับผิดชอบในการรักษาความปลอดภัยของข้อมูลและความสมบูรณ์ของระบบฐานข้อมูล MySQL
การกำหนดค่าความปลอดภัยของฐานข้อมูล MySQL จะต้องเริ่มต้นจากสองด้าน ได้แก่ ความปลอดภัยของระบบภายในและความปลอดภัยของเครือข่ายภายนอก นอกจากนี้ เรายังจะแนะนำปัญหาและเคล็ดลับบางประการที่ควรคำนึงถึงเมื่อเขียนโปรแกรมโดยย่อ
ความปลอดภัยภายในระบบ
ก่อนอื่น เรามาแนะนำโครงสร้างไดเร็กทอรีฐานข้อมูล MySQL กันก่อน หลังจากติดตั้ง MySQL แล้ว ไดเร็กทอรีข้อมูลและฐานข้อมูลจะเริ่มต้นได้หลังจากรันสคริปต์ mysql_db_install หากเราใช้แพ็คเกจซอร์สโค้ด MySQL ในการติดตั้ง และไดเร็กทอรีการติดตั้งคือ /usr/local/mysql ดังนั้นไดเร็กทอรีข้อมูลโดยทั่วไปจะเป็น /usr/local/mysql/var ระบบฐานข้อมูลประกอบด้วยชุดฐานข้อมูล ซึ่งแต่ละชุดประกอบด้วยชุดตารางฐานข้อมูล MySQL ใช้ชื่อฐานข้อมูลเพื่อสร้างไดเร็กทอรีฐานข้อมูลในไดเร็กทอรีข้อมูล แต่ละตารางฐานข้อมูลใช้ชื่อตารางฐานข้อมูลเป็นชื่อไฟล์ และไฟล์สามไฟล์ที่มีนามสกุล MYD, MYI และ frm จะถูกวางไว้ในไดเร็กทอรีฐานข้อมูล
ตารางการอนุญาตของ MySQL ให้การควบคุมสิทธิ์ที่ยืดหยุ่นสำหรับการเข้าถึงฐานข้อมูล แต่หากผู้ใช้ภายในเครื่องมีสิทธิ์ในการอ่านไฟล์ไลบรารี ผู้โจมตีจะต้องจัดทำแพ็คเกจและคัดลอกไดเร็กทอรีฐานข้อมูลเท่านั้น จากนั้นจึงคัดลอกไปยังไดเร็กทอรีข้อมูลของเขาเอง เข้าถึงไดเร็กทอรีข้อมูลที่ถูกขโมย ฐานข้อมูล ดังนั้นความปลอดภัยของโฮสต์ที่ MySQL ตั้งอยู่จึงเป็นปัญหาที่สำคัญที่สุด หากโฮสต์ไม่ปลอดภัยและถูกควบคุมโดยผู้โจมตี ความปลอดภัยของ MySQL ก็ไม่สามารถพูดถึงได้ ประการที่สองคือความปลอดภัยของไดเร็กทอรีข้อมูลและไฟล์ข้อมูลซึ่งเป็นปัญหาของการตั้งค่าสิทธิ์
เมื่อพิจารณาจากเวอร์ชันไบนารี่เก่าของไซต์หลัก MySQL คุณลักษณะของไดเร็กทอรีข้อมูลในเวอร์ชัน 3.21.xx คือ 775 ซึ่งเป็นอันตรายมาก ผู้ใช้ในเครื่องสามารถอ่านไดเร็กทอรีข้อมูลได้ ดังนั้นไฟล์ฐานข้อมูลจึงไม่ปลอดภัยอย่างยิ่ง คุณลักษณะของไดเร็กทอรีข้อมูลในเวอร์ชัน 3.22.xx คือ 770 คุณลักษณะนี้ค่อนข้างเป็นอันตรายเช่นกัน ผู้ใช้ภายในในกลุ่มเดียวกันสามารถอ่านและเขียนได้ ดังนั้นไฟล์ข้อมูลจึงไม่ปลอดภัย คุณลักษณะของไดเร็กทอรีข้อมูลในเวอร์ชัน 3.23.xx คือ 700 ซึ่งดีกว่า เฉพาะผู้ใช้ที่เริ่มฐานข้อมูลเท่านั้นที่สามารถอ่านและเขียนไฟล์ฐานข้อมูลได้ ทำให้มั่นใจถึงความปลอดภัยของไฟล์ข้อมูลในเครื่อง
หากผู้ใช้ที่เริ่มฐานข้อมูล MySQL คือ mysql แสดงว่าไดเร็กทอรีและไฟล์ต่อไปนี้ปลอดภัย โปรดใส่ใจกับไดเร็กทอรีข้อมูลและคุณลักษณะต่อไปนี้:
เปลือก>ls -l /usr/local/mysql
รวม 40
drwxrwxr-x 2 รูท รูท 4096 27 ก.พ. 20:07 bin
drwxrwxr-x 3 รูท รูท 4096 27 ก.พ. 20:07 น. รวม
drwxrwxr-x 2 รูท รูท 4096 27 ก.พ. 20:07 ข้อมูล
drwxrwxr-x 3 รูต รูท 4096 27 ก.พ. 20:07 lib
drwxrwxr-x 2 รูต รูต 4096 27 ก.พ. 20:07 libexec
drwxrwxr-x 3 รูต รูท 4096 27 ก.พ. 20:07 คน
drwxrwxr-x 6 รูต รูท 4096 27 ก.พ. 20:07 ทดสอบ mysql
drwxrwxr-x 3 รูต รูต 4096 27 ก.พ. 20:07 แชร์
drwxrwxr-x 7 รูตรูต 4096 27 ก.พ. 20:07 sql-bench
drwx------ 4 mysql mysql 4096 27 ก.พ. 20:07 น
เปลือก>ls -l /usr/local/mysql/var
รวม 8
drwx------ 2 mysql mysql 4096 27 ก.พ. 20:08 mysql
drwx------ 2 mysql mysql 4096 27 กุมภาพันธ์ 20:08 น. ทดสอบ
เปลือก>ls -l /usr/local/mysql/var/mysql
รวม 104
-rw------- 1 mysql mysql 0 27 กุมภาพันธ์ 20:08 columns_priv.MYD
-rw------- 1 mysql mysql 1,024 27 ก.พ. 20:08 columns_priv.MYI
-rw------- 1 mysql mysql 8778 27 ก.พ. 20:08 columns_priv.frm
-rw------- 1 mysql mysql 302 27 ก.พ. 20:08 db.MYD
-rw------- 1 mysql mysql 3072 27 ก.พ. 20:08 db.MYI
-rw------- 1 mysql mysql 8982 27 ก.พ. 20:08 db.frm
-rw------- 1 mysql mysql 0 27 ก.พ. 20:08 func.MYD
-rw------- 1 mysql mysql 1,024 27 ก.พ. 20:08 func.MYI
-rw------- 1 mysql mysql 8641 27 ก.พ. 20:08 func.frm
-rw------- 1 mysql mysql 0 27 ก.พ. 20:08 น. โฮสต์ MYD
-rw------- 1 mysql mysql 1,024 27 ก.พ. 20:08 โฮสต์ MyI
-rw------- 1 mysql mysql 8958 27 ก.พ. 20:08 น. host.frm
-rw------- 1 mysql mysql 0 27 ก.พ. 20:08 tables_priv.MYD
-rw------- 1 mysql mysql 1,024 27 ก.พ. 20:08 tables_priv.MYI
-rw------- 1 mysql mysql 8877 27 ก.พ. 20:08 tables_priv.frm
-rw------- 1 mysql mysql 428 27 ก.พ. 20:08 ผู้ใช้ MYD
-rw------- 1 mysql mysql 2048 27 ก.พ. 20:08 ผู้ใช้ MYI
-rw------- 1 mysql mysql 9148 27 ก.พ. 20:08 user.frm
หากเจ้าของและคุณลักษณะของไฟล์เหล่านี้ไม่เป็นเช่นนั้น โปรดใช้คำสั่งสองคำสั่งต่อไปนี้เพื่อแก้ไข:
เปลือก> chown -R mysql.mysql /usr/local/mysql/var
เปลือก> chmod -R go-rwx /usr/local/mysql/var
การใช้ผู้ใช้รูทเพื่อเริ่มบริการระยะไกลถือเป็นข้อห้ามด้านความปลอดภัยมาโดยตลอด เนื่องจากหากมีปัญหากับเซอร์วิสโปรแกรม ผู้โจมตีจากระยะไกลมีแนวโน้มที่จะได้รับการควบคุมโฮสต์อย่างสมบูรณ์ MySQL ได้ทำการเปลี่ยนแปลงเล็กน้อยตั้งแต่เวอร์ชัน 3.23.15 ตามค่าเริ่มต้น ผู้ใช้ mysql จะต้องเริ่มบริการหลังการติดตั้ง และผู้ใช้รูทไม่ได้รับอนุญาตให้เริ่มทำงาน หากคุณต้องใช้ผู้ใช้ root เพื่อเริ่มต้น คุณต้องเพิ่มพารามิเตอร์ --user=root (./safe_mysqld --user=root &) เนื่องจากมีคำสั่ง SQL ของ LOAD DATA INFILE และ SELECT... INTO OUTFILE ใน MySQL หากผู้ใช้รูทเริ่มเซิร์ฟเวอร์ MySQL ผู้ใช้ฐานข้อมูลจะมีสิทธิ์ในการเขียนของผู้ใช้รูท อย่างไรก็ตาม MySQL ยังมีข้อจำกัดบางประการ ตัวอย่างเช่น LOAD DATA INFILE สามารถอ่านได้เฉพาะไฟล์ที่อ่านได้ทั่วโลกเท่านั้น และ SELECT... INTO OUTFILE ไม่สามารถเขียนทับไฟล์ที่มีอยู่ได้
ไม่สามารถละเลยไฟล์บันทึกในเครื่องได้ รวมถึงบันทึกของเชลล์และบันทึกของ MySQL เอง เพื่อความสะดวกเมื่อเข้าสู่ระบบภายในเครื่องหรือสำรองฐานข้อมูล บางครั้งผู้ใช้บางรายอาจรวมรหัสผ่านฐานข้อมูลโดยตรงในพารามิเตอร์บรรทัดคำสั่ง เช่น:
เปลือก> / usr / local / mysql / bin / mysqldump -uroot -ptest ทดสอบ> test.sql
เปลือก> / usr / local / mysql / bin / mysql -uroot -ptest
คำสั่งเหล่านี้จะถูกบันทึกลงในไฟล์ประวัติโดยเชลล์ ตัวอย่างเช่น bash จะเขียนไฟล์ .bash_history ในไดเร็กทอรีผู้ใช้ หากไฟล์เหล่านี้ถูกอ่านโดยไม่ได้ตั้งใจ รหัสผ่านของฐานข้อมูลจะรั่วไหล คำสั่ง SQL ที่ดำเนินการหลังจากที่ผู้ใช้ล็อกอินเข้าสู่ฐานข้อมูลจะถูกบันทึกโดย MySQL ในไฟล์ .mysql_history ในไดเร็กทอรีผู้ใช้ หากผู้ใช้ฐานข้อมูลเปลี่ยนรหัสผ่านฐานข้อมูลโดยใช้คำสั่ง SQL รหัสผ่านนั้นก็จะรั่วไหลผ่านไฟล์ .mysql_history ด้วย ดังนั้นเราจึงไม่ควรเพิ่มรหัสผ่านโดยตรงหลัง -p ระหว่างการล็อกอินและสำรองข้อมูลของเชลล์ แต่ให้ป้อนรหัสผ่านฐานข้อมูลหลังจากพร้อมท์
นอกจากนี้ เราไม่ควรปล่อยให้ทั้งสองไฟล์นี้บันทึกการดำเนินการของเรา เผื่อไว้
เปลือก> RM .bash_history .mysql_history
เปลือก> ln -s /dev/null .bash_history
เปลือก> ln -s /dev/null .mysql_history
คำสั่งทั้งสองนี้เชื่อมโยงทั้งสองไฟล์นี้เข้ากับ /dev/null ดังนั้นการดำเนินการของเราจะไม่ถูกบันทึกในสองไฟล์นี้
การรักษาความปลอดภัยเครือข่ายภายนอก
หลังจากติดตั้งฐานข้อมูล MySQL แล้ว ตารางผู้ใช้บนแพลตฟอร์ม Unix จะมีลักษณะดังนี้:
mysql> ใช้ mysql;
ฐานข้อมูลมีการเปลี่ยนแปลง
mysql> เลือก Host,User,Password,Select_priv,Grant_priv จากผู้ใช้;
+-----------+-+----------+-------------+----- --------
|. โฮสต์ |. ผู้ใช้ |. รหัสผ่าน |
+-----------+-+----------+-------------+----- --------
|. localhost |. ราก |. Y |
|. redhat |. ราก |
|. localhost |. |
|. redhat |. N |
+-----------+-+----------+-------------+----- --------
4 แถวในชุด (0.00 วินาที)
ตารางผู้ใช้บนแพลตฟอร์ม Windows มีลักษณะดังนี้:
mysql> ใช้ mysql;
ฐานข้อมูลมีการเปลี่ยนแปลง
mysql> เลือก Host,User,Password,Select_priv,Grant_priv จากผู้ใช้;
+-----------+-+----------+-------------+----- --------
|. โฮสต์ |. ผู้ใช้ |. รหัสผ่าน |
+-----------+-+----------+-------------+----- --------
|. localhost |. ราก |. Y |
|. % |. ราก |. Y |
|. localhost |. |. Y |
|. % |. ยังไม่มีข้อความ |
+-----------+-+----------+-------------+----- --------
4 แถวในชุด (0.00 วินาที)
มาดูตารางผู้ใช้บนแพลตฟอร์ม Unix กันก่อน ในหมู่พวกเขา redhat เป็นเพียงชื่อเครื่องของเครื่องทดสอบของฉัน ดังนั้นจริงๆ แล้ว MySQL บนแพลตฟอร์ม Unix อนุญาตให้เครื่องนี้เชื่อมต่อกับฐานข้อมูลตามค่าเริ่มต้นเท่านั้น อย่างไรก็ตาม รหัสผ่านผู้ใช้รูทเริ่มต้นจะว่างเปล่า ดังนั้นสิ่งสำคัญสูงสุดคือการเพิ่มรหัสผ่านให้กับผู้ใช้รูท มีสามวิธีในการเพิ่มรหัสผ่านให้กับผู้ใช้ฐานข้อมูล:
1) ใช้คำสั่ง mysqladmin ที่พรอมต์เชลล์เพื่อเปลี่ยนรหัสผ่านผู้ใช้รูท:
เปลือก> mysqladmin - ทดสอบรหัสผ่าน uroot
ด้วยวิธีนี้ รหัสผ่านของผู้ใช้รูทฐานข้อมูล MySQL จะถูกเปลี่ยนเพื่อทดสอบ (การทดสอบเป็นเพียงตัวอย่างเท่านั้น รหัสผ่านที่เราใช้จริงจะต้องไม่ใช้รหัสผ่านที่เดาง่ายเช่นนี้)
2) ใช้ตั้งรหัสผ่านเพื่อแก้ไขรหัสผ่าน:
mysql> ตั้งรหัสผ่านสำหรับ root@localhost=password('test' );
ในขณะนี้ รหัสผ่านของผู้ใช้รูทถูกเปลี่ยนเพื่อทดสอบ
3) แก้ไขรหัสผ่านผู้ใช้รูทของตารางผู้ใช้โดยตรง:
mysql> ใช้ mysql;
mysql> อัปเดตชุดผู้ใช้รหัสผ่าน = รหัสผ่าน ('ทดสอบ') โดยที่ผู้ใช้ = 'รูท';
mysql> สิทธิ์ฟลัช;
ด้วยวิธีนี้ รหัสผ่านของผู้ใช้รูทฐานข้อมูล MySQL จึงถูกเปลี่ยนเพื่อทดสอบด้วย คำสั่งสุดท้าย สิทธิ์ล้างข้อมูล หมายถึงการรีเฟรชตารางการอนุญาตหน่วยความจำอย่างแรง มิฉะนั้น รหัสผ่านในแคชจะยังคงถูกใช้อยู่ ในขณะนี้ ผู้ใช้ที่ผิดกฎหมายสามารถเข้าสู่ระบบด้วยผู้ใช้รูทและรหัสผ่านที่ว่างเปล่าได้จนกระทั่งเซิร์ฟเวอร์ MySQL ถูกรีสตาร์ท
เรายังเห็นผู้ใช้ที่ไม่ระบุตัวตนซึ่งผู้ใช้ว่างเปล่า แม้ว่าจะไม่มีสิทธิ์อนุญาตภายใต้แพลตฟอร์ม Unix แต่เราควรลบออกด้วยเหตุผลด้านความปลอดภัย:
mysql> ลบออกจากผู้ใช้โดยที่ user='';