Ngày nay, bảo mật dữ liệu là ưu tiên hàng đầu. Đôi khi nó được thực thi bởi các quy định bên ngoài như PCI-DSS hoặc HIPAA, đôi khi là do bạn quan tâm đến dữ liệu của khách hàng và danh tiếng của mình. Có rất nhiều khía cạnh bảo mật mà bạn cần lưu ý - truy cập mạng, bảo mật hệ điều hành, tài trợ, mã hóa, v.v. Trong bài đăng trên blog này, chúng tôi sẽ cung cấp cho bạn 10 mẹo về những điều cần xem xét khi bảo mật thiết lập MySQL hoặc MariaDB của bạn.
1. Xóa người dùng không có mật khẩu
MySQL từng đi kèm với một nhóm người dùng được tạo trước, một số người trong số đó có thể kết nối với cơ sở dữ liệu mà không cần mật khẩu hoặc thậm chí tệ hơn là những người dùng ẩn danh. Điều này đã thay đổi trong MySQL 5.7, theo mặc định, chỉ đi kèm với tài khoản gốc sử dụng mật khẩu bạn chọn lúc cài đặt. Tuy nhiên, vẫn có những bản cài đặt MySQL được nâng cấp từ các phiên bản trước và những bản cài đặt này vẫn giữ được những người dùng kế thừa. Ngoài ra, MariaDB 10.2 trên Centos 7 đi kèm với người dùng ẩn danh:
MariaDB [(none)]> select user, host, password from mysql.user where user like '';
+------+-----------------------+----------+
| user | host | password |
+------+-----------------------+----------+
| | localhost | |
| | localhost.localdomain | |
+------+-----------------------+----------+
2 rows in set (0.00 sec)
Như bạn có thể thấy, chúng chỉ bị giới hạn ở quyền truy cập từ localhost nhưng bất kể, bạn không muốn có những người dùng như vậy. Mặc dù các đặc quyền của họ bị giới hạn, họ vẫn có thể chạy một số lệnh có thể hiển thị thêm thông tin về cơ sở dữ liệu - ví dụ:phiên bản có thể giúp xác định thêm các vectơ tấn công.
[[email protected] ~]# mysql -uanonymous_user
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 19
Server version: 10.2.11-MariaDB MariaDB Server
Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> SHOW GRANTS\G
*************************** 1. row ***************************
Grants for @localhost: GRANT USAGE ON *.* TO ''@'localhost'
1 row in set (0.00 sec)
MariaDB [(none)]> \s
--------------
mysql Ver 15.1 Distrib 10.2.11-MariaDB, for Linux (x86_64) using readline 5.1
Connection id: 19
Current database:
Current user: [email protected]
SSL: Not in use
Current pager: stdout
Using outfile: ''
Using delimiter: ;
Server: MariaDB
Server version: 10.2.11-MariaDB MariaDB Server
Protocol version: 10
Connection: Localhost via UNIX socket
Server characterset: latin1
Db characterset: latin1
Client characterset: utf8
Conn. characterset: utf8
UNIX socket: /var/lib/mysql/mysql.sock
Uptime: 12 min 14 sec
Threads: 7 Questions: 36 Slow queries: 0 Opens: 17 Flush tables: 1 Open tables: 11 Queries per second avg: 0.049
--------------
Xin lưu ý rằng người dùng có mật khẩu rất đơn giản gần như không an toàn như người dùng không có bất kỳ mật khẩu nào. Các mật khẩu như "password" hoặc "qwerty" không thực sự hữu ích.
2. Truy cập từ xa chặt chẽ
Trước hết, truy cập từ xa cho superusers - điều này được thực hiện theo mặc định khi cài đặt MySQL (5.7) hoặc MariaDB (10.2) mới nhất - chỉ có quyền truy cập cục bộ. Tuy nhiên, khá phổ biến khi thấy những siêu nhân có sẵn vì nhiều lý do khác nhau. Phổ biến nhất, có thể là do cơ sở dữ liệu được quản lý bởi những người muốn giúp công việc của họ dễ dàng hơn, vì vậy họ sẽ thêm quyền truy cập từ xa vào cơ sở dữ liệu của mình. Đây không phải là một cách tiếp cận tốt vì truy cập từ xa giúp dễ dàng khai thác các lỗ hổng bảo mật tiềm ẩn (hoặc đã được xác minh) trong MySQL - trước tiên bạn không cần phải có kết nối với máy chủ.
Một bước khác - đảm bảo rằng mọi người dùng chỉ có thể kết nối với MySQL từ các máy chủ cụ thể. Bạn luôn có thể xác định một số mục nhập cho cùng một người dùng ([email protected], [email protected]), điều này sẽ giúp giảm nhu cầu về các ký tự đại diện ([email protected]’% ’).
3. Xóa cơ sở dữ liệu thử nghiệm
Cơ sở dữ liệu thử nghiệm, theo mặc định, có sẵn cho mọi người dùng, đặc biệt là cho những người dùng ẩn danh. Những người dùng như vậy có thể tạo bảng và ghi vào chúng. Điều này có thể tự trở thành một vấn đề - bất kỳ lần ghi nào cũng sẽ thêm một số chi phí và làm giảm hiệu suất cơ sở dữ liệu. Hiện tại, sau khi cài đặt mặc định, chỉ có MariaDB 10.2 trên Centos 7 bị ảnh hưởng bởi điều này - Oracle MySQL 5.7 và Percona Server 5.7 không có sẵn lược đồ ‘thử nghiệm’.
[[email protected] ~]# mysql -uanonymous_user
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 13
Server version: 10.2.11-MariaDB MariaDB Server
Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> SHOW GRANTS\G
*************************** 1. row ***************************
Grants for @localhost: GRANT USAGE ON *.* TO ''@'localhost'
1 row in set (0.00 sec)
MariaDB [(none)]> USE test;
Database changed
MariaDB [test]> CREATE TABLE testtable (a INT);
Query OK, 0 rows affected (0.01 sec)
MariaDB [test]> INSERT INTO testtable VALUES (1), (2), (3);
Query OK, 3 rows affected (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 0
MariaDB [test]> SELECT * FROM testtable;
+------+
| a |
+------+
| 1 |
| 2 |
| 3 |
+------+
3 rows in set (0.00 sec)
Tất nhiên, vẫn có thể xảy ra trường hợp MySQL 5.7 của bạn đã được nâng cấp từ các phiên bản trước, trong đó lược đồ ‘test’ không bị xóa - bạn nên lưu ý điều này và kiểm tra xem bạn đã tạo nó chưa.
4. Truy cập Obfuscate vào MySQL
Ai cũng biết rằng MySQL chạy trên cổng 3306 và siêu người dùng của nó được gọi là 'root'. Để làm cho mọi thứ khó hơn, khá đơn giản để thay đổi điều này. Ở một mức độ nào đó, đây là một ví dụ về bảo mật thông qua sự che giấu nhưng ít nhất nó có thể ngăn chặn các nỗ lực tự động để có được quyền truy cập vào người dùng ‘root’. Để thay đổi cổng, bạn cần chỉnh sửa my.cnf và đặt biến 'cổng' thành một số giá trị khác. Đối với người dùng - sau khi MySQL được cài đặt, bạn nên tạo một siêu người dùng mới (CẤP TẤT CẢ… VỚI TÙY CHỌN CẤP) và sau đó xóa tài khoản ‘[email protected]’ hiện có.
5. An ninh mạng
Lý tưởng nhất là MySQL sẽ không khả dụng qua mạng và tất cả các kết nối sẽ được xử lý cục bộ thông qua Unix socket. Trong một số thiết lập, điều này có thể xảy ra - trong trường hợp đó, bạn có thể thêm biến ‘bỏ qua mạng’ trong my.cnf. Điều này sẽ ngăn MySQL sử dụng bất kỳ giao tiếp TCP / IP nào, chỉ có ổ cắm Unix mới khả dụng trên Linux (Đường ống được đặt tên và bộ nhớ dùng chung trên máy chủ Windows).
Tuy nhiên, hầu hết thời gian, bảo mật chặt chẽ như vậy là không khả thi. Trong trường hợp đó, bạn cần phải tìm một giải pháp khác. Đầu tiên, bạn có thể sử dụng tường lửa của mình để chỉ cho phép lưu lượng truy cập từ các máy chủ cụ thể đến máy chủ MySQL. Ví dụ:máy chủ ứng dụng (mặc dù chúng sẽ ổn với việc truy cập MySQL thông qua proxy), lớp proxy và có thể là máy chủ quản lý. Các máy chủ khác trong mạng của bạn có thể không cần truy cập trực tiếp vào máy chủ MySQL. Điều này sẽ hạn chế khả năng bị tấn công vào cơ sở dữ liệu của bạn, trong trường hợp một số máy chủ trong mạng của bạn bị xâm phạm.
Nếu bạn tình cờ sử dụng proxy cho phép đối sánh biểu thức chính quy cho các truy vấn, bạn có thể sử dụng chúng để phân tích lưu lượng truy cập SQL và chặn các truy vấn đáng ngờ. Nhiều khả năng máy chủ ứng dụng của bạn sẽ không chạy “DELETE * FROM your_table;” một cách thường xuyên. Nếu cần xóa một số dữ liệu, nó có thể được thực thi bằng tay, cục bộ, trên phiên bản MySQL. Bạn có thể tạo các quy tắc như vậy bằng cách sử dụng một cái gì đó như ProxySQL:chặn, viết lại, chuyển hướng các truy vấn như vậy. MaxScale cũng cung cấp cho bạn một tùy chọn để chặn các truy vấn dựa trên các biểu thức chính quy.
6. Kiểm tra plugin
Nếu bạn quan tâm đến việc thu thập dữ liệu về ai đã thực thi cái gì và khi nào, có một số plugin kiểm tra có sẵn cho MySQL. Nếu bạn sử dụng MySQL Enterprise, bạn có thể sử dụng MySQL Enterprise Audit, đây là một phần mở rộng cho MySQL Enterprise. Percona và MariaDB cũng có phiên bản plugin kiểm tra của riêng họ. Cuối cùng, plugin McAfee cho MySQL cũng có thể được sử dụng với các phiên bản MySQL khác nhau. Nói chung, các plugin đó thu thập ít nhiều dữ liệu giống nhau - kết nối và ngắt kết nối các sự kiện, truy vấn được thực thi, bảng được truy cập. Tất cả những thứ này chứa thông tin về người dùng nào đã tham gia vào sự kiện đó, từ máy chủ lưu trữ mà nó đã đăng nhập từ đâu, nó xảy ra khi nào, v.v. Đầu ra có thể là XML hoặc JSON, vì vậy việc phân tích nó dễ dàng hơn nhiều so với phân tích các nội dung nhật ký chung (mặc dù dữ liệu khá giống nhau). Đầu ra như vậy cũng có thể được gửi đến nhật ký hệ thống và hơn nữa, một số loại máy chủ nhật ký để xử lý và phân tích.
7. Tắt THÔNG TIN ĐỊA PHƯƠNG TẢI DỮ LIỆU
Nếu cả máy chủ và máy khách đều có khả năng chạy LOAD DATA LOCAL INFILE, máy khách sẽ có thể tải dữ liệu từ tệp cục bộ đến máy chủ MySQL từ xa. Điều này, có khả năng, có thể giúp đọc các tệp mà máy khách có quyền truy cập - ví dụ:trên máy chủ ứng dụng, người ta có thể truy cập bất kỳ tệp nào mà máy chủ HTTP có quyền truy cập. Để tránh điều này, bạn cần đặt local-infile =0 trong my.cnf
8. Đặc quyền tệp
Bạn phải nhớ rằng bảo mật MySQL cũng phụ thuộc vào thiết lập hệ điều hành. MySQL lưu trữ dữ liệu dưới dạng tệp. Máy chủ MySQL ghi nhiều thông tin vào nhật ký. Đôi khi thông tin này chứa dữ liệu - chẳng hạn như nhật ký truy vấn chậm, nhật ký chung hoặc nhật ký nhị phân. Bạn cần đảm bảo rằng thông tin này an toàn và chỉ những người dùng phải truy cập mới có thể truy cập được. Thông thường, nó có nghĩa là chỉ người gốc và người dùng có quyền mà MySQL đang chạy, mới có quyền truy cập vào tất cả các tệp liên quan đến MySQL. Hầu hết thời gian đó là một người dùng chuyên dụng được gọi là 'mysql'. Bạn nên kiểm tra các tệp cấu hình MySQL và tất cả các nhật ký được tạo bởi MySQL và xác minh rằng chúng không thể đọc được bởi những người dùng khác.
9. SSL và mã hóa dữ liệu khi chuyển tuyến
Ngăn mọi người truy cập vào các tệp cấu hình và nhật ký là một chuyện. Vấn đề còn lại là đảm bảo dữ liệu được truyền qua mạng một cách an toàn. Ngoại trừ các thiết lập trong đó tất cả các máy khách là cục bộ và sử dụng Unix socket để truy cập MySQL, trong phần lớn các trường hợp, dữ liệu tạo thành một tập hợp kết quả cho một truy vấn sẽ rời khỏi máy chủ và được chuyển đến máy khách qua mạng. Dữ liệu cũng có thể được chuyển giữa các máy chủ MySQL, ví dụ qua MySQLreplication tiêu chuẩn hoặc trong một cụm Galera. Lưu lượng truy cập mạng có thể bị phát hiện và thông qua các phương tiện đó, dữ liệu của bạn sẽ bị lộ.
Để ngăn điều này xảy ra, có thể sử dụng SSL để mã hóa lưu lượng truy cập, cả phía máy chủ và phía máy khách. Bạn có thể tạo kết nối SSL giữa máy khách và máy chủ MySQL. Bạn cũng có thể tạo kết nối SSL giữa chủ và nô lệ của mình hoặc giữa các nút của cụm Galera. Điều này sẽ đảm bảo rằng tất cả dữ liệu được truyền đi đều an toàn và không thể bị kẻ tấn công đánh cắp quyền truy cập vào mạng của bạn.
Tài liệu MySQL trình bày chi tiết cách thiết lập mã hóa SSL. Nếu bạn thấy nó quá cồng kềnh, ClusterControl có thể giúp bạn triển khai một môi trường an toàn để nhân rộng MySQL hoặc cụm Galera chỉ bằng một vài cú nhấp chuột:
10. Mã hóa dữ liệu lúc còn lại
Bảo mật dữ liệu khi truyền bằng cách sử dụng mã hóa SSL chỉ giải quyết một phần vấn đề. Bạn cũng cần quan tâm đến dữ liệu ở trạng thái nghỉ - tất cả dữ liệu được lưu trữ trong cơ sở dữ liệu. Mã hóa dữ liệu lúc nghỉ cũng có thể là một yêu cầu đối với các quy định bảo mật như HIPAA hoặc PCI DSS. Mã hóa như vậy có thể được thực hiện ở nhiều cấp độ - bạn có thể mã hóa toàn bộ đĩa lưu trữ các tệp. Bạn chỉ có thể mã hóa cơ sở dữ liệu MySQL thông qua chức năng có sẵn trong các phiên bản MySQL hoặc MariaDB mới nhất. Mã hóa cũng có thể được thực hiện trong ứng dụng để nó mã hóa dữ liệu trước khi lưu trữ trong cơ sở dữ liệu. Mọi tùy chọn đều có ưu và nhược điểm:mã hóa đĩa chỉ có thể hữu ích khi đĩa bị đánh cắp vật lý, nhưng các tệp sẽ không được mã hóa trên máy chủ cơ sở dữ liệu đang chạy. Mã hóa cơ sở dữ liệu MySQL giải quyết vấn đề này, nhưng nó không thể ngăn truy cập vào dữ liệu khi tài khoản gốc bị xâm phạm. Mã hóa mức ứng dụng là linh hoạt và an toàn nhất, nhưng sau đó bạn sẽ mất đi sức mạnh của SQL - khá khó để sử dụng các cột được mã hóa trong mệnh đề WHERE hoặc JOIN.
Tất cả các phiên bản của MySQL đều cung cấp một số loại dữ liệu khi mã hóa phần còn lại. Oracle’s MySQL sử dụng Mã hóa dữ liệu minh bạch để mã hóa không gian bảng InnoDB. Điều này có sẵn trong dịch vụ MySQL Enterprise thương mại. Nó cung cấp một tùy chọn để mã hóa không gian bảng InnoDB, các tệp khác cũng lưu trữ dữ liệu ở một số dạng (ví dụ:nhật ký nhị phân, nhật ký chung, nhật ký truy vấn chậm) không được mã hóa. Điều này cho phép chuỗi công cụ (MySQL Enterprise Backup nhưng cũng như xtrabackup, mysqldump, mysqlbinlog) hoạt động chính xác với thiết lập như vậy.
Bắt đầu từ MySQL 5.7.11, phiên bản cộng đồng của MySQL cũng được hỗ trợ mã hóa vùng bảng InnoDB. Sự khác biệt chính so với cung cấp của doanh nghiệp là cách các khóa được lưu trữ - các khóa không được đặt trong một kho tiền an toàn, điều này cần thiết để tuân thủ quy định. Điều này có nghĩa là bắt đầu từ Máy chủ Percona 5.7.11, cũng có thể mã hóa không gian bảng InnoDB. Trong Máy chủ Percona 5.7.20 được xuất bản gần đây, hỗ trợ mã hóa nhật ký nhị phân đã được thêm vào. Nó cũng có thể tích hợp với máy chủ Hashicorp Vault thông qua plugin keyring_vault, khớp (và thậm chí mở rộng - mã hóa nhật ký nhị phân) các tính năng có sẵn trong phiên bản Oracle’s MySQL Enterprise.
MariaDB đã bổ sung hỗ trợ mã hóa dữ liệu trong 10.1.3 - đây là một triển khai nâng cao, riêng biệt. Nó cung cấp cho bạn khả năng không chỉ mã hóa không gian bảng InnoDB mà còn cả các tệp nhật ký InnoDB. Do đó, dữ liệu an toàn hơn nhưng một số công cụ sẽ không hoạt động trong cấu hình như vậy. Xtrabackup sẽ không hoạt động với các bản ghi làm lại được mã hóa - MariaDB đã tạo một fork, MariaDB Backup, bổ sung hỗ trợ cho mã hóa MariaDB. Cũng có vấn đề với mysqlbinlog.
Bất kể bạn sử dụng hương vị MySQL nào, miễn là nó là phiên bản gần đây, bạn sẽ có các tùy chọn để triển khai mã hóa dữ liệu ở trạng thái nghỉ thông qua máy chủ cơ sở dữ liệu, đảm bảo rằng dữ liệu của bạn được bảo mật thêm.
Bảo mật MySQL hoặc MariaDB không phải là chuyện nhỏ, nhưng chúng tôi hy vọng 10 mẹo này sẽ giúp ích cho bạn.
Tóm tắt
Trong bối cảnh ngày nay, bảo mật dữ liệu là ưu tiên hàng đầu đối với mọi quản trị viên cơ sở dữ liệu. Cho dù động lực của bạn là tuân thủ các yêu cầu quy định hay bảo vệ khách hàng và danh tiếng doanh nghiệp của bạn, thì mười mẹo này để bảo mật cơ sở dữ liệu MySQL và MariaDB sẽ giúp bạn bảo mật hơn nữa cơ sở hạ tầng của mình và mang lại cho bạn sự yên tâm.
Có nhiều biện pháp cần xem xét khi đảm bảo cơ sở hạ tầng cơ sở dữ liệu của bạn được an toàn. Trong bài đăng này, chúng tôi đã đề cập đến các nguyên tắc cơ bản như mã hóa dữ liệu, kiểm soát truy cập mạng, xác thực và đặc quyền của người dùng, bảo mật hệ điều hành, v.v.
Phần mềm tự động hóa quản lý cơ sở dữ liệu, như ClusterControl, có thể là một công cụ tuyệt vời để hỗ trợ các nỗ lực bảo mật cơ sở dữ liệu tổng thể của bạn. Nếu bạn đang tìm kiếm thông tin chi tiết hơn về từng bước bạn phải thực hiện để bảo mật cơ sở dữ liệu MySQL của mình, hãy nhớ xem Phần 1 và Phần 2 của loạt bài về Cách bảo mật MySQL. Để được cập nhật thông tin về các phương pháp hay nhất khác về quản lý cơ sở dữ liệu, hãy theo dõi chúng tôi trên Twitter, LinkedIn và đăng ký nhận bản tin của chúng tôi để cập nhật.