Đôi khi không thể tránh khỏi việc chạy các máy chủ cơ sở dữ liệu MySQL trên mạng công cộng hoặc mạng tiếp xúc. Đây là thiết lập phổ biến trong môi trường lưu trữ chia sẻ, nơi một máy chủ được cấu hình với nhiều dịch vụ và thường chạy trong cùng một máy chủ với máy chủ cơ sở dữ liệu. Đối với những người có kiểu thiết lập này, bạn phải luôn có một số biện pháp bảo vệ chống lại các cuộc tấn công mạng như từ chối dịch vụ, hack, bẻ khóa, vi phạm dữ liệu; tất cả có thể dẫn đến mất dữ liệu. Đây là những điều mà chúng tôi luôn muốn tránh cho máy chủ cơ sở dữ liệu của mình.
Dưới đây là một số mẹo mà chúng tôi có thể thực hiện để cải thiện bảo mật MySQL hoặc MariaDB của mình.
Quét Máy chủ Cơ sở dữ liệu Thường xuyên
Bảo vệ chống lại bất kỳ tệp độc hại nào trong máy chủ là rất quan trọng. Quét máy chủ thường xuyên để tìm kiếm bất kỳ vi-rút, phần mềm gián điệp, phần mềm độc hại hoặc rootkit nào, đặc biệt nếu máy chủ cơ sở dữ liệu được đặt chung với các dịch vụ khác như máy chủ thư, HTTP, FTP, DNS, WebDAV, telnet, v.v. Thông thường, hầu hết các vấn đề tấn công cơ sở dữ liệu bắt nguồn từ cấp ứng dụng đang gặp phải trên mạng công cộng. Vì vậy, điều quan trọng là phải quét tất cả các tệp, đặc biệt là các tệp web / ứng dụng vì chúng là một trong những điểm nhập để vào máy chủ. Nếu những thứ đó bị xâm nhập, tin tặc có thể xâm nhập vào thư mục ứng dụng và có khả năng đọc các tệp ứng dụng. Chúng có thể chứa thông tin nhạy cảm, chẳng hạn, thông tin đăng nhập cơ sở dữ liệu.
ClamAV là một trong những giải pháp chống vi-rút được biết đến rộng rãi và đáng tin cậy nhất cho nhiều hệ điều hành, bao gồm cả Linux. Nó miễn phí và rất dễ cài đặt và đi kèm với một cơ chế phát hiện khá tốt để tìm kiếm những thứ không mong muốn trong máy chủ của bạn. Lên lịch quét định kỳ trong cron job, ví dụ:
0 3 * * * /bin/freshclam ; /bin/clamscan / --recursive=yes -i > /tmp/clamav.log ; mail -s clamav_log_`hostname` [email protected] < /tmp/clamav.log
Bên trên sẽ cập nhật cơ sở dữ liệu virus ClamAV, quét tất cả các thư mục và tệp tin và gửi cho bạn email về tình trạng thực thi và báo cáo hàng ngày vào lúc 3 giờ sáng.
Sử dụng Đặc quyền và Vai trò Người dùng Nghiêm ngặt hơn
Khi tạo người dùng MySQL, không cho phép tất cả các máy chủ truy cập vào máy chủ MySQL bằng máy chủ ký tự đại diện (%). Bạn nên quét máy chủ MySQL của mình và tìm bất kỳ giá trị máy chủ ký tự đại diện nào, như được hiển thị trong câu lệnh sau:
mysql> SELECT user,host FROM mysql.user WHERE host = '%';
+---------+------+
| user | host |
+---------+------+
| myadmin | % |
| sbtest | % |
| user1 | % |
+---------+------+
Từ kết quả ở trên, nghiêm ngặt hoặc xóa tất cả người dùng chỉ có giá trị '%' trong cột Máy chủ. Người dùng cần truy cập máy chủ MySQL từ xa có thể được buộc sử dụng phương pháp đường hầm SSH, phương pháp này không yêu cầu cấu hình máy chủ từ xa cho người dùng MySQL. Hầu hết các máy khách quản trị MySQL như MySQL Workbench và HeidiSQL có thể được định cấu hình để kết nối với máy chủ MySQL thông qua điều chỉnh SSH, do đó có thể loại bỏ hoàn toàn kết nối từ xa cho người dùng MySQL.
Ngoài ra, giới hạn đặc quyền SUPER chỉ cho người dùng từ localhost hoặc kết nối qua tệp ổ cắm UNIX. Hãy thận trọng hơn khi gán đặc quyền FILE cho người dùng không phải root vì nó cho phép đọc và ghi các tệp trên máy chủ bằng cách sử dụng các câu lệnh LOAD DATA INFILE và SELECT ... INTO OUTFILE. Bất kỳ người dùng nào được cấp đặc quyền này cũng có thể đọc hoặc ghi bất kỳ tệp nào mà máy chủ MySQL có thể đọc hoặc ghi.
Thay đổi Cài đặt Mặc định Cơ sở dữ liệu
Bằng cách loại bỏ thiết lập, đặt tên và cấu hình mặc định, chúng ta có thể giảm vectơ tấn công xuống một số lần. Các hành động sau đây là một số ví dụ về cấu hình mặc định mà DBA có thể dễ dàng thay đổi nhưng thường bị bỏ qua liên quan đến MySQL:
- Thay đổi cổng MySQL mặc định thành khác 3306.
- Đổi tên tên người dùng gốc MySQL thành khác "root".
- Thực thi hết hạn mật khẩu và giảm thời gian tồn tại của mật khẩu cho tất cả người dùng.
- Nếu MySQL được đặt chung với máy chủ ứng dụng, chỉ thực thi kết nối thông qua tệp socket UNIX và dừng lắng nghe trên cổng 3306 đối với tất cả các địa chỉ IP.
- Thực thi mã hóa máy khách-máy chủ và mã hóa sao chép máy chủ-máy chủ.
Chúng tôi thực sự đã trình bày chi tiết vấn đề này trong bài đăng blog này, Cách bảo mật máy chủ MySQL / MariaDB.
Thiết lập Nô lệ bị trì hoãn
Máy chủ bị trì hoãn chỉ là một máy chủ nô lệ điển hình, tuy nhiên máy chủ nô lệ cố ý thực hiện các giao dịch muộn hơn máy chủ ít nhất một khoảng thời gian cụ thể, có sẵn từ MySQL 5.6. Về cơ bản, một sự kiện nhận được từ cái chính sẽ không được thực thi cho đến khi ít nhất N chậm hơn vài giây so với quá trình thực thi của nó trên chính. Kết quả là nô lệ sẽ phản ánh trạng thái của chủ một thời gian trước đây.
Một nô lệ bị trì hoãn có thể được sử dụng để khôi phục dữ liệu, điều này sẽ hữu ích khi vấn đề được phát hiện ngay lập tức, trong khoảng thời gian trì hoãn. Giả sử chúng ta đã cấu hình một nô lệ với độ trễ 6 giờ so với chính. Nếu cơ sở dữ liệu của chúng tôi bị sửa đổi hoặc xóa (vô tình do nhà phát triển hoặc do tin tặc cố ý) trong phạm vi thời gian này, chúng tôi có khả năng hoàn nguyên về thời điểm ngay trước khi nó xảy ra bằng cách dừng máy chủ hiện tại, sau đó đưa máy chủ nô lệ lên cho đến thời điểm nhất định với lệnh sau:
# on delayed slave
mysql> STOP SLAVE;
mysql> START SLAVE UNTIL MASTER_LOG_FILE='xxxxx', MASTER_LOG_POS=yyyyyy;
Trong đó 'xxxxx' là tệp nhật ký nhị phân và 'yyyyy' là vị trí ngay trước khi thảm họa xảy ra (sử dụng công cụ mysqlbinlog để kiểm tra các sự kiện đó). Cuối cùng, thăng cấp nô lệ trở thành chủ mới và dịch vụ MySQL của bạn hiện đã hoạt động trở lại như bình thường. Phương pháp này có lẽ là cách nhanh nhất để khôi phục cơ sở dữ liệu MySQL của bạn trong môi trường sản xuất mà không cần phải tải lại bản sao lưu. Có một số nô lệ bị trì hoãn với thời lượng dài khác nhau, như được hiển thị trong blog này, Nhiều nô lệ sao chép bị trì hoãn để khôi phục sau thảm họa với RTO thấp về cách thiết lập máy chủ sao chép bị trì hoãn hiệu quả về chi phí trên đầu các vùng chứa Docker.
Bật tính năng ghi nhật ký nhị phân
Ghi nhật ký nhị phân thường được khuyến khích bật ngay cả khi bạn đang chạy trên máy chủ MySQL / MariaDB độc lập. Nhật ký nhị phân chứa thông tin về các câu lệnh SQL sửa đổi nội dung cơ sở dữ liệu. Thông tin được lưu trữ dưới dạng "sự kiện" mô tả các sửa đổi. Bất chấp tác động đến hiệu suất, việc có nhật ký nhị phân cho phép bạn có khả năng phát lại máy chủ cơ sở dữ liệu của mình đến chính xác điểm mà bạn muốn khôi phục, còn được gọi là khôi phục tại điểm trong thời gian (PITR). Ghi nhật ký nhị phân cũng là bắt buộc để nhân rộng.
Với tính năng ghi nhật ký nhị phân được bật, người ta phải bao gồm tệp nhật ký nhị phân và thông tin vị trí khi tạo một bản sao lưu đầy đủ. Đối với mysqldump, việc sử dụng cờ --master-data với giá trị 1 hoặc 2 sẽ in ra thông tin cần thiết mà chúng ta có thể sử dụng làm điểm bắt đầu để chuyển tiếp cơ sở dữ liệu khi phát lại các bản ghi nhị phân sau này.
Khi bật ghi nhật ký nhị phân, bạn có thể sử dụng một tính năng khôi phục thú vị khác được gọi là hồi tưởng, được mô tả trong phần tiếp theo.
Bật Flashback
Tính năng hồi tưởng có sẵn trong MariaDB, nơi bạn có thể khôi phục dữ liệu về ảnh chụp nhanh trước đó trong cơ sở dữ liệu MySQL hoặc trong bảng. Flashback sử dụng mysqlbinlog để tạo các câu lệnh khôi phục và nó cần một hình ảnh hàng nhật ký nhị phân ĐẦY ĐỦ cho điều đó. Do đó, để sử dụng tính năng này, máy chủ MySQL / MariaDB phải được cấu hình như sau:
[mysqld]
...
binlog_format = ROW
binlog_row_image = FULL
Sơ đồ kiến trúc sau minh họa cách cấu hình hồi tưởng trên một trong các nô lệ:
Để thực hiện thao tác hồi tưởng, trước tiên bạn phải xác định ngày và giờ khi bạn muốn "xem" dữ liệu hoặc tệp nhật ký nhị phân và vị trí. Sau đó, sử dụng cờ --flashback với tiện ích mysqlbinlog để tạo các câu lệnh SQL để khôi phục dữ liệu về điểm đó. Trong tệp SQL được tạo, bạn sẽ nhận thấy rằng các sự kiện DELETE được chuyển đổi thành INSERT và ngược lại, đồng thời nó cũng hoán đổi các phần WHERE và SET của các sự kiện CẬP NHẬT.
Dòng lệnh sau sẽ được thực thi trên slave2 (được định cấu hình bằng binlog_row_image =FULL):
$ mysqlbinlog --flashback --start-datetime="2020-02-17 01:30:00" /var/lib/mysql/mysql-bin.000028 -v --database=shop --table=products > flashback_to_2020-02-17_013000.sql
Sau đó, tách slave2 khỏi chuỗi sao chép vì chúng tôi sẽ phá vỡ nó và sử dụng máy chủ để khôi phục dữ liệu của chúng tôi:
mysql> STOP SLAVE;
mysql> RESET MASTER;
mysql> RESET SLAVE ALL;
Cuối cùng, nhập tệp SQL đã tạo vào máy chủ MariaDB cho cửa hàng cơ sở dữ liệu trên slave2:
$ mysql -u root -p shop < flashback_to_2020-02-17_013000.sql
Khi những điều trên được áp dụng, bảng "sản phẩm" sẽ ở trạng thái 2020-02-17 01:30:00. Về mặt kỹ thuật, tệp SQL được tạo có thể được áp dụng cho cả máy chủ MariaDB và MySQL. Bạn cũng có thể chuyển nhị phân mysqlbinlog từ máy chủ MariaDB để bạn có thể sử dụng tính năng hồi tưởng trên máy chủ MySQL. Tuy nhiên, việc triển khai MySQL GTID khác với MariaDB, do đó việc khôi phục tệp SQL yêu cầu bạn tắt MySQL GTID.
Một vài lợi ích khi sử dụng flashback là bạn không cần phải dừng máy chủ MySQL / MariaDB để thực hiện thao tác này. Khi lượng dữ liệu cần hoàn nguyên nhỏ, quá trình hồi tưởng nhanh hơn nhiều so với việc khôi phục dữ liệu từ bản sao lưu đầy đủ.
Ghi nhật ký Tất cả Truy vấn Cơ sở dữ liệu
Nhật ký chung về cơ bản ghi lại mọi câu lệnh SQL đang được thực thi bởi máy khách trong máy chủ MySQL. Tuy nhiên, đây có thể không phải là một quyết định phổ biến trên một máy chủ sản xuất bận rộn do ảnh hưởng đến hiệu suất và tiêu thụ không gian. Nếu hiệu suất quan trọng, nhật ký nhị phân có mức độ ưu tiên cao hơn được bật. Nhật ký chung có thể được bật trong thời gian chạy bằng cách chạy các lệnh sau:
mysql> SET global general_log_file='/tmp/mysql.log';
mysql> SET global log_output = 'file';
mysql> SET global general_log = ON;
Bạn cũng có thể đặt đầu ra nhật ký chung thành một bảng:
mysql> SET global log_output = 'table';
Sau đó, bạn có thể sử dụng câu lệnh SELECT tiêu chuẩn đối với bảng mysql.general_log để truy xuất các truy vấn. Dự kiến sẽ có thêm một chút tác động về hiệu suất khi chạy với cấu hình này như được hiển thị trong bài đăng trên blog này.
Nếu không, bạn có thể sử dụng các công cụ giám sát bên ngoài có thể thực hiện lấy mẫu và giám sát truy vấn để bạn có thể lọc và kiểm tra các truy vấn đi vào máy chủ. ClusterControl có thể được sử dụng để thu thập và tóm tắt tất cả các truy vấn của bạn, như được hiển thị trong ảnh chụp màn hình sau đây, nơi chúng tôi lọc tất cả các truy vấn có chứa chuỗi DELETE:
Thông tin tương tự cũng có sẵn trong trang truy vấn hàng đầu của ProxySQL (nếu ứng dụng của bạn kết nối qua ProxySQL):
Điều này có thể được sử dụng để theo dõi các thay đổi gần đây đã xảy ra với máy chủ cơ sở dữ liệu và cũng có thể được sử dụng cho mục đích kiểm toán.
Kết luận
Máy chủ MySQL và MariaDB của bạn phải luôn được bảo vệ tốt vì nó thường chứa dữ liệu nhạy cảm mà những kẻ tấn công đang theo dõi. Bạn cũng có thể sử dụng ClusterControl để quản lý các khía cạnh bảo mật của máy chủ cơ sở dữ liệu của mình, như được giới thiệu trong bài đăng blog này, Cách bảo mật cơ sở dữ liệu nguồn mở của bạn bằng ClusterControl.