Trong thế giới ngày nay, các tổ chức ngày càng phải đối mặt với mức độ đe dọa tấn công mạng chưa từng có đối với tài sản thông tin của họ.
Các cuộc tấn công mạng có thể có nhiều hình thức. Một cuộc tấn công như vậy được gọi là SQL injection . Với SQL injection, những kẻ lừa đảo nhắm mục tiêu vào cơ sở dữ liệu phụ trợ của bất kỳ hệ thống nào. Thông thường, các hệ thống này được công khai. Tin tặc cố gắng gửi các truy vấn dường như vô hại và thông thường đến cơ sở dữ liệu - ngoại trừ các tham số có thể tiết lộ thông tin mà chúng không được phép nhìn thấy hoặc làm hỏng cơ sở dữ liệu với thông tin sai hoặc làm hỏng hệ thống.
Các chuyên gia an ninh mạng luôn chạy đua với thời gian để nắm bắt được mức độ tinh vi của các cuộc tấn công này và giống như hầu hết các cuộc chiến tranh lớn khác, nó hiện đang diễn ra ở mọi mặt trận. Điều này có nghĩa là bảo mật phải được triển khai ở mọi lớp trong ngăn xếp của ứng dụng - bao gồm cả lớp cơ sở dữ liệu.
Các DBA dày dạn thường cố gắng bảo mật cơ sở dữ liệu bằng các biện pháp như kiểm soát truy cập dựa trên vai trò (RBAC), xác thực liên kết, kiểm tra hoặc SSL. Tuy nhiên, bất kỳ biện pháp bổ sung nào để bảo mật cơ sở dữ liệu cũng cần được xem xét.
Một trong những biện pháp bảo vệ như vậy là tường lửa cơ sở dữ liệu. Giống như tường lửa thông thường, tường lửa cơ sở dữ liệu lọc ra lưu lượng truy cập dựa trên danh sách trắng hoặc danh sách đen. Họ cũng có thể “học” từ các mẫu truy cập hệ thống để hiểu những tuyên bố nào có thể đáng tin cậy và điều gì không thể. Việc sử dụng một công cụ như thế này sẽ thêm một lớp bảo vệ mạnh mẽ chống lại việc đưa vào SQL.
Trong bài viết này, chúng ta sẽ nói về Tường lửa SQL , một tường lửa cơ sở dữ liệu để bảo vệ cơ sở dữ liệu PostgreSQL. SQL Firewall được xây dựng và hỗ trợ bởi 2ndQuadrant, công ty hàng đầu về công nghệ PostgreSQL.
Tường lửa SQL hoạt động như thế nào
SQL Firewall là một phần mở rộng cho PostgreSQL 9.4 trở lên. Mặc dù nó hiện được hỗ trợ lên đến PostgreSQL phiên bản 10, nhưng vẫn đang tiếp tục làm việc để hỗ trợ các phiên bản sau.
Vì là một phần mở rộng nên SQL Firewall rất đơn giản để cài đặt và định cấu hình. Sau khi được cấu hình, nó có thể được sử dụng để đưa các câu lệnh SQL vào danh sách trắng dựa trên cơ sở dữ liệu cho người dùng cá nhân. Danh sách trắng đến từ việc “đào tạo” tiện ích mở rộng với khối lượng công việc điển hình của ứng dụng - thường đến từ việc chạy lặp lại một bộ thử nghiệm bao gồm tất cả các tình huống có thể xảy ra. Sau khi danh sách trắng được tinh chỉnh và hoàn thiện, nó có thể được xuất và sau đó được nhập vào các phiên bản PostgreSQL khác phục vụ khối lượng công việc tương tự.
Ví dụ:trước khi khởi chạy ứng dụng, mỗi người dùng được cấu hình có thể chạy khối lượng công việc mẫu chất lượng sản xuất dựa trên cơ sở dữ liệu trong một môi trường được kiểm soát. Tài khoản người dùng con người có thể chỉ được phép chạy các truy vấn chỉ đọc trong khi tài khoản người dùng ứng dụng có thể được phép chạy cả đọc và ghi. Sau đó SQL Firewall sẽ đọc các truy vấn cho cả tài khoản người dùng và tài khoản người dùng ứng dụng, đồng thời ghi các truy vấn chỉ cho tài khoản người dùng ứng dụng. Nếu sau đó người dùng cố gắng chạy CHÈN, XÓA hoặc CẬP NHẬT, thì Tường lửa SQL sẽ từ chối hoạt động. Khi ứng dụng phát triển, danh sách trắng cũng có thể được đào tạo lại với khối lượng công việc thay đổi.
Mọi câu lệnh bị chặn đều được ghi lại bằng Tường lửa SQL, có nghĩa là các nhóm vận hành có thể gửi các nhật ký này tới các giải pháp quản lý nhật ký của họ và được cảnh báo mỗi khi có ngoại lệ.
Thiết lập Môi trường
Trong bài viết này, chúng tôi sẽ cài đặt SQL Firewall cho phiên bản PostgreSQL 10 một nút chạy trên Red Hat Enterprise Linux 7. Tại thời điểm viết bài, RHEL / CentOS 7 và PostgreSQL 10 là những phiên bản được hỗ trợ cao nhất. Tuy nhiên, như đã đề cập trước đây, chúng tôi sẽ hỗ trợ thêm.
Lưu ý
[Xin lưu ý rằng SQL Firewall là một sản phẩm được cấp phép thương mại dành cho khách hàng Hỗ trợ 24/7. Nó không có sẵn để tải xuống từ trang web công cộng 2ndQuadrant.]
Bước 1:Cài đặt PostgreSQL 10
Hệ thống thử nghiệm của chúng tôi là phiên bản Amazon EC2 chạy Red Hat Enterprise Linux 7.2.
# cat /etc/redhat-release Red Hat Enterprise Linux Server release 7.2 (Maipo)
Chúng tôi chạy lệnh sau để tải xuống repo RPM cho PostgreSQL 10 (x86-64).
# yum install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm -y
Tiếp theo, chúng tôi cài đặt máy chủ và gói ứng dụng khách.
# yum install postgresql10-server postgresql10 -y
Khi các gói được cài đặt thành công, chúng tôi chạy lệnh initdb để khởi tạo cơ sở dữ liệu.
# /usr/pgsql-10/bin/postgresql-10-setup initdb Initializing database ... OK
Tiếp theo, chúng tôi thực hiện thay đổi sau đối với tệp postgresql.conf. Theo mặc định, nó nằm trong thư mục / var / lib / pgsql / 10 / data /.
listen_addresses = '*'
Và sau đó, thêm dòng sau vào tệp pg_hba.conf (một lần nữa, theo mặc định, nó nằm trong thư mục / var / lib / pgsql / 10 / data /).
host all all <our IP address range> md5
Sau đó, chúng tôi khởi động dịch vụ PostgreSQL và cho phép nó tự động khởi động.
# systemctl start postgresql-10.service # systemctl enable postgresql-10.service
Cuối cùng, chúng tôi đăng nhập vào phiên bản cơ sở dữ liệu từ psql với tư cách là người dùng postgres và thay đổi mật khẩu.
# su - postgres -bash-4.2$ psql psql (10.12) Type "help" for help. postgres=# \password Enter new password: Enter it again: postgres=#
Bước 2:Khôi phục cơ sở dữ liệu mẫu
Để mô phỏng một hệ thống sản xuất, chúng tôi đã khôi phục hai cơ sở dữ liệu mẫu trong máy chủ PostgreSQL của chúng tôi. Các cơ sở dữ liệu này được cung cấp công khai:
- Pagila :Phiên bản PostgreSQL của cơ sở dữ liệu MySQL Sakila phổ biến
- Chinook :Cơ sở dữ liệu về cửa hàng phương tiện kỹ thuật số
Bước 3:Tạo vai trò và người dùng
Với cơ sở dữ liệu đã tạo, chúng tôi tạo ra hai vai trò người dùng. Một cái được gọi là “human_user”, cái còn lại được gọi là “app_user”.
Vai trò người dùng đại diện cho bất kỳ người nào truy cập cơ sở dữ liệu từ back-end hoặc bằng một công cụ khách. Vai trò app_user đại diện cho tài khoản mà ứng dụng sẽ sử dụng để kết nối với cơ sở dữ liệu.
psql -d postgres -c "CREATE ROLE human_user WITH NOSUPERUSER NOCREATEDB NOCREATEROLE NOINHERIT LOGIN NOREPLICATION PASSWORD '<a tough password>';" psql -d postgres -c "CREATE ROLE app_user WITH NOSUPERUSER NOCREATEDB NOCREATEROLE NOINHERIT LOGIN NOREPLICATION PASSWORD '<a tough password>';"
Vai trò người dùng sau đó được cấp quyền truy cập cơ sở dữ liệu chinook và pagila bằng cách chạy các lệnh sau với tư cách là người dùng postgres:
$ psql -d postgres -c "GRANT CONNECT ON DATABASE pagila, chinook TO app_user;" $ psql -d chinook -c "GRANT USAGE ON SCHEMA public TO app_user;" $ psql -d chinook -c "GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO app_user;" $ psql -d chinook -c "GRANT SELECT, INSERT, UPDATE, DELETE, TRUNCATE, TRIGGER, REFERENCES ON ALL TABLES IN SCHEMA public TO app_user;" $ psql -d chinook -c "GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO app_user;" $ psql -d pagila -c "GRANT USAGE ON SCHEMA public TO app_user;" $ psql -d pagila -c "GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO app_user;" $ psql -d pagila -c "GRANT SELECT, INSERT, UPDATE, DELETE, TRUNCATE, TRIGGER, REFERENCES ON ALL TABLES IN SCHEMA public TO app_user;" $ psql -d pagila -c "GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO app_user;" $ psql -d postgres -c "GRANT CONNECT ON DATABASE pagila, chinook TO human_user;" $ psql -d chinook -c "GRANT USAGE ON SCHEMA public TO human_user;" $ psql -d chinook -c "GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO human_user;" $ psql -d chinook -c "GRANT SELECT, INSERT, UPDATE, DELETE, TRUNCATE, TRIGGER, REFERENCES ON ALL TABLES IN SCHEMA public TO human_user;" $ psql -d chinook -c "GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO human_user;" $ psql -d pagila -c "GRANT USAGE ON SCHEMA public TO human_user;" $ psql -d pagila -c "GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO human_user;" $ psql -d pagila -c "GRANT SELECT, INSERT, UPDATE, DELETE, TRUNCATE, TRIGGER, REFERENCES ON ALL TABLES IN SCHEMA public TO human_user;" $ psql -d pagila -c "GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO human_user;"
Bước 4:Cài đặt tường lửa SQL
Cài đặt Tường lửa SQL là một quá trình đơn giản. Đầu tiên, chúng tôi cài đặt gói.
# rpm -ivh postgresql10-sqlfirewall-3.0-1.el7.x86_64.rpm warning: postgresql10-sqlfirewall-3.0-1.el7.x86_64.rpm: Header V4 RSA/SHA1 Signature, key ID ******: NOKEY Preparing... ################################# [100%] Updating / installing... 1:postgresql10-sqlfirewall-3.0-1.el################################# [100%]
Sau đó, chúng tôi cập nhật tệp postgresql.conf bằng cách thay đổi thông số shared_preload_libraries.
shared_preload_libraries = 'sqlfirewall'
Sau khi hoàn tất, chúng tôi khởi động lại dịch vụ PostgreSQL.
# systemctl restart postgresql-10.service
Khi dịch vụ được khởi động lại, chúng tôi đăng nhập vào phiên bản với tư cách là người dùng postgres và thêm phần mở rộng vào cả cơ sở dữ liệu mẫu.
$ psql -U postgres -d chinook -c "CREATE EXTENSION sqlfirewall;" Password for user postgres: CREATE EXTENSION -bash-4.2$ psql -U postgres -d pagila -c "CREATE EXTENSION sqlfirewall;" Password for user postgres: CREATE EXTENSION
Hình ảnh bên dưới cho thấy các tiện ích mở rộng được cài đặt trên cả hai cơ sở dữ liệu. Lưu ý rằng có một lược đồ đặc biệt được gọi là “sqlfirewall” cũng được tạo trong cả hai cơ sở dữ liệu. Lược đồ này chứa tất cả các đối tượng cơ sở dữ liệu liên quan đến hoạt động của Tường lửa SQL.
Chúng tôi cũng có thể thấy một vai trò mới có tên “sqlfirewall_manager” được tạo tự động. Người dùng được thêm vào vai trò này có thể truy cập các chức năng và chế độ xem trong lược đồ sqlfirewall.
Bước 5:Định cấu hình tường lửa SQL
Sau đó, một số tham số được thêm vào postgresql.conf tập tin. Đối với Red Hat Enterprise Linux và các bản phân phối dẫn xuất của nó, vị trí thư mục mặc định cho tệp này là / var / lib / pgsql / 10 / data /.
Trong đoạn mã sau, chúng tôi đang chỉnh sửa tệp và thêm một số thông số.
# vim /var/lib/pgsql/10/data/postgresql.conf sqlfirewall.whitelist = 'verbose' sqlfirewall.track = 'all' sqlfirewall.track_utility = 'true' sqlfirewall.save = 'true'
Sau đó, chúng tôi tải lại tất cả cấu hình.
$ psql -U postgres -d postgres Password for user postgres: psql (10.12) Type "help" for help. postgres=# SELECT pg_reload_conf(); pg_reload_conf ---------------- t (1 row)
Tiếp theo, chúng tôi để quá trình ngủ trong một giây.
postgres=# SELECT pg_sleep(1); pg_sleep ---------- (1 row)
và sau đó kiểm tra trạng thái danh sách trắng trong cả hai cơ sở dữ liệu. Nếu các bước được làm theo, cả hai cơ sở dữ liệu phải được bật danh sách trắng.
postgres=# \connect pagila You are now connected to database "pagila" as user "postgres". pagila=# show sqlfirewall.whitelist; sqlfirewall.whitelist ----------------------- verbose (1 row) pagila=# \connect chinook; You are now connected to database "chinook" as user "postgres". chinook=# show sqlfirewall.whitelist; sqlfirewall.whitelist ----------------------- verbose (1 row)
Hãy xem qua các thông số chúng tôi vừa thêm.
sqlfirewall.whitelist tham số được sử dụng để kích hoạt chức năng lập danh sách trắng của tường lửa. Tham số này có thể có một trong hai giá trị:"verbose" hoặc "bảo vệ".
Với tùy chọn dài dòng, Tường lửa SQL sẽ hiển thị thông báo cảnh báo cho người dùng khi họ cố gắng chạy một truy vấn không thuộc danh sách trắng mà họ không được phép làm như vậy. Khi giá trị được đặt thành bảo vệ, Tường lửa SQL sẽ hiển thị thông báo chung chung “quyền bị từ chối”. Như một phương pháp hay nhất, chúng tôi khuyên bạn nên đặt giá trị thành “bảo vệ”, điều này không cung cấp cho tin tặc bất kỳ ý tưởng nào tại sao lệnh bị từ chối. Chúng tôi đã đặt thông số này thành "verbose" chỉ cho mục đích trình diễn.
Các giá trị được chỉ định cho sqlfirewall.track và sqlfirewall.track_utility các tham số đảm bảo Tường lửa SQL đang theo dõi tất cả các câu lệnh cho mục đích lập danh sách trắng.
Cuối cùng, đặt sqlfirewall.save tham số thành “true” đảm bảo các câu lệnh trong danh sách trắng vẫn tồn tại ngay cả khi máy chủ được khởi động lại.
Chạy SQL Firewall
Chạy SQL Firewall liên quan đến việc gọi một số hàm đi kèm với phần mở rộng.
Bước 1:Tìm hiểu các chức năng tường lửa của SQL
Tiện ích mở rộng Tường lửa SQL tạo một số hàm trong lược đồ sqlfirewall của cơ sở dữ liệu nơi nó được cài đặt. Hầu hết các chức năng này chỉ có thể được thực thi bởi superusers hoặc thành viên của vai trò sqlfirewall_manager.
Hãy nhanh chóng đi qua một số chức năng này.
sqlfirewall_whitelist_mode là chức năng chính mà chúng tôi sẽ làm việc. Hàm này cho phép lập danh sách trắng câu lệnh cho một người dùng PostgreSQL cụ thể. Nó có hai tham số:một là tên người dùng, một là whitelist_mode.
whitelist_mode tham số có thể có ba giá trị:
- Khi nó được đặt thành “ RECORD ”, SQL Firewall sẽ ghi lại tất cả các câu lệnh được thực thi bởi người dùng trong danh sách trắng của người dùng
- Khi được đặt thành “ ENFORCE ”, SQL Firewall sẽ thực thi danh sách trắng. Bất kỳ câu lệnh nào không có trong danh sách trắng sẽ gây ra lỗi
- Giá trị của “ TẮT ”Tắt chức năng lập danh sách trắng cho người dùng và người dùng sẽ không thể thực hiện bất kỳ truy vấn nào
Nếu bạn muốn xóa các truy vấn trong danh sách trắng cho một người dùng, hãy chạy sqlfirewall_whitelist_delete chức năng thay thế. Hàm này nhận một tham số duy nhất:tên người dùng. Sau khi chạy, hàm sqlfirewall_whitelist_delete sẽ xóa tất cả các câu lệnh trong danh sách trắng cho người dùng.
sqlfirewall_whitelist_delete_entry được sử dụng để xóa các ID truy vấn riêng lẻ khỏi danh sách trắng của người dùng. Điều này có thể hữu ích khi bạn có quá nhiều truy vấn được phép cho một người dùng và muốn tinh chỉnh nó. Hàm nhận hai tham số:tên người dùng và ID truy vấn. Bạn có thể tìm thấy ID của truy vấn mà bạn muốn loại trừ khỏi danh sách trắng bằng cách xem ở chế độ xem sqlfirewall.
sqlfirewall_whitelist_users hàm không nhận bất kỳ tham số nào. Nó trả về danh sách những người dùng đã bật danh sách trắng cho tài khoản của họ.
Bạn có thể xuất danh sách trắng cho người dùng bằng cách sử dụng sqlfirewall_whitelist_export hàm số. Hàm này nhận hai tham số:tên người dùng và tên tệp nơi nó xuất các câu lệnh trong danh sách cho phép của người dùng. Tệp phải ở vị trí mà quá trình máy chủ PostgreSQL có quyền ghi vào.
Tương tự như hàm sqlfirewall_whitelist_export, hàm sqlfirewall_whitelist_import được sử dụng để nhập tệp danh sách trắng đã xuất cho người dùng sang phiên bản PostgreSQL khác cho người dùng đó. Hàm này cũng nhận hai tham số, tên người dùng và tệp được nhập. Tệp phải ở vị trí mà quá trình máy chủ PostgreSQL có thể đọc nó từ đó.
Ngoài ra, cơ sở dữ liệu đích cần phải là bản sao nhị phân của cơ sở dữ liệu nguồn - có nghĩa là, đích phải là một phần của bản sao trực tuyến hoặc bản sao PostgreSQL được tạo từ nguồn bằng lệnh pg_basebackup. Cơ sở dữ liệu được tạo từ kết xuất hợp lý của cơ sở dữ liệu nguồn không thể nhập tệp danh sách trắng - trong những trường hợp như vậy, danh sách trắng phải được định cấu hình theo cách thủ công.
Bước 2:Bật danh sách trắng cho người dùng
Bây giờ chúng ta có một số ý tưởng về các chức năng Tường lửa SQL, hãy bắt đầu quá trình lập danh sách trắng cho cả người dùng và người dùng ứng dụng trong cơ sở dữ liệu pagila và chinook.
Trong đoạn mã bên dưới, chúng tôi đang chạy các lệnh sau với tư cách là superuser postgres.
postgres=# \connect pagila You are now connected to database "pagila" as user "postgres". pagila=# SELECT sqlfirewall.sqlfirewall_whitelist_mode('human_user', 'RECORD'); sqlfirewall_whitelist_mode ---------------------------- t (1 row) pagila=# SELECT sqlfirewall.sqlfirewall_whitelist_mode('app_user', 'RECORD');\ sqlfirewall_whitelist_mode ---------------------------- t (1 row) pagila=# \connect chinook You are now connected to database "chinook" as user "postgres". chinook=# SELECT sqlfirewall.sqlfirewall_whitelist_mode('human_user', 'RECORD'); sqlfirewall_whitelist_mode ---------------------------- t (1 row) chinook=# SELECT sqlfirewall.sqlfirewall_whitelist_mode('app_user', 'RECORD'); sqlfirewall_whitelist_mode ---------------------------- t (1 row)
Chúng tôi cũng có thể xác nhận bằng cách chạy hàm sqlfirewall_whitelist_users ().
$ psql -U postgres -d pagila -c "SELECT sqlfirewall.sqlfirewall_whitelist_users();" Password for user postgres: sqlfirewall_whitelist_users ----------------------------- (17479,human_user,RECORD) (17480,app_user,RECORD) (2 rows) $ psql -U postgres -d chinook -c "SELECT sqlfirewall.sqlfirewall_whitelist_users();" Password for user postgres: sqlfirewall_whitelist_users ----------------------------- (17479,human_user,RECORD) (17480,app_user,RECORD) (2 rows)
Bước 3:Chạy Khối lượng công việc
Với việc bật và ghi danh sách trắng, chúng tôi chuyển sang tài khoản app_user và chạy một số truy vấn như hình dưới đây. Lưu ý cách app_user đang chọn các “trường ID” khác nhau (customer_id, staff_id, EmployeeID, v.v.) từ các bảng khác nhau.
postgres=# \c - app_user Password for user app_user: You are now connected to database "postgres" as user "app_user". postgres=> \connect pagila You are now connected to database "pagila" as user "app_user". pagila=> SELECT customer_id, first_name, last_name, email FROM public.customer; ... pagila=> SELECT payment_id, customer_id, payment_date, amount FROM public.payment; ... pagila=> SELECT staff_id, first_name, last_name, email FROM public.staff; ... pagila=> \connect chinook; You are now connected to database "chinook" as user "app_user". chinook=> SELECT "CustomerId", "FirstName", "LastName", "Phone" FROM public."Customer"; ... chinook=> SELECT "EmployeeId", "FirstName", "LastName", "Phone", "Email" FROM public."Employee"; ...
Tiếp theo, chúng tôi chuyển sang tài khoản human_user và chạy một số truy vấn đơn giản trên một số bảng mà app_user đã truy cập.
postgres=# \c - human_user Password for user human_user: You are now connected to database "postgres" as user "human_user". postgres=> \connect pagila; You are now connected to database "pagila" as user "human_user". pagila=> SELECT payment_date, amount FROM public.payment; ... pagila=> SELECT first_name, last_name, email FROM public.customer; ... pagila=> \connect chinook; You are now connected to database "chinook" as user "human_user". chinook=> SELECT "FirstName", "LastName", "Phone", "Email" FROM public."Employee"; ...
Nếu chúng tôi truy vấn chế độ xem sqlfirewall từ bất kỳ cơ sở dữ liệu nào với tư cách là người dùng postgres, chúng tôi có thể thấy các truy vấn đã được đưa vào danh sách trắng cho mỗi người dùng.
Bước 4:Thực thi danh sách trắng
Với khối lượng công việc mẫu hiện đã được thu thập, chúng tôi thực thi danh sách trắng cho cả hai tài khoản người dùng trong cả hai cơ sở dữ liệu bằng cách chạy các lệnh sau. Các lệnh phải được chạy bởi một superuser; trong trường hợp này, chúng tôi đang chạy chúng với tư cách là người dùng đăng bài.
postgres=# \connect pagila; You are now connected to database "pagila" as user "postgres". pagila=# SELECT sqlfirewall.sqlfirewall_whitelist_mode('human_user', 'ENFORCE'); sqlfirewall_whitelist_mode ---------------------------- t (1 row) pagila=# SELECT sqlfirewall.sqlfirewall_whitelist_mode('app_user', 'ENFORCE'); sqlfirewall_whitelist_mode ---------------------------- t (1 row) pagila=# \connect chinook; You are now connected to database "chinook" as user "postgres". chinook=# SELECT sqlfirewall.sqlfirewall_whitelist_mode('human_user', 'ENFORCE'); sqlfirewall_whitelist_mode ---------------------------- t (1 row) chinook=# SELECT sqlfirewall.sqlfirewall_whitelist_mode('app_user', 'ENFORCE'); sqlfirewall_whitelist_mode ---------------------------- t (1 row)
Bước 5:Kiểm tra
Để kiểm tra danh sách trắng, chúng tôi đã đăng nhập vào cơ sở dữ liệu pagila với tư cách là human_user và cố gắng chạy các lệnh đã được chạy trước đó
chinook=# \c - human_user; Password for user human_user: You are now connected to database "chinook" as user "human_user". chinook=> \connect pagila; You are now connected to database "pagila" as user "human_user". pagila=> SELECT payment_date, amount FROM public.payment; ... pagila=> SELECT first_name, last_name, email FROM public.customer; ...
Các lệnh thành công. Điều này là do những lệnh này đã được chạy bởi human_user trước đó và đã được đưa vào danh sách trắng.
Bây giờ chúng ta thử chạy lệnh sau. Lưu ý cách người dùng đang cố gắng chạy một truy vấn với hai trường bổ sung. Truy vấn này đã được chạy bởi app_user trước đây.
pagila=> SELECT payment_id, customer_id, payment_date, amount FROM public.payment;
Câu lệnh không thành công với thông báo như sau:
ERROR: Execution of non-whitelisted statement prohibited
Điều này đang xảy ra vì trước đó người dùng đã chạy lệnh chỉ chọn hai trường từ bảng này, không phải các trường bổ sung (ID thanh toán và ID khách hàng) mà anh ta đang cố gắng truy cập bây giờ. Tường lửa SQL đã ghi lại truy vấn trước đó của anh ấy dưới dạng khối lượng công việc đã biết và đưa truy vấn đó vào danh sách trắng. Khi anh ta cố gắng thêm hai trường mới đó vào truy vấn của mình, tường lửa đang chặn anh ta.
Nếu bạn nghĩ về nó, đây là cách một hacker có thể muốn đánh cắp một giá trị trường ID để nó có thể được sử dụng trong mệnh đề WHERE của một truy vấn khác để lấy thêm thông tin. Sử dụng phương pháp danh sách trắng sẽ chặn điều đó một cách hiệu quả.
Vì vậy, điều gì sẽ xảy ra nếu người dùng cần hai trường bổ sung này cho mục đích hợp pháp? Trong trường hợp này, chế độ danh sách trắng cho người dùng cần được thay đổi trở lại thành “GHI” để các truy vấn mới có thể chạy và Tường lửa SQL có thể đưa chúng vào danh sách trắng.
Hãy chạy một bài kiểm tra khác trước khi kết thúc. Lần này, chúng tôi sẽ giả sử một tin tặc đã xâm nhập tài khoản app_user và muốn chạy một tuyên bố xóa đối với bảng "thanh toán". Hãy nhớ rằng chúng tôi đã cấp cho người dùng các đặc quyền DELETE và TRUNCATE trên bảng.
Vì vậy, chúng tôi đăng nhập với tư cách là app_user và chạy câu lệnh DELETE.
pagila=> \c - app_user Password for user app_user: You are now connected to database "pagila" as user "app_user". pagila=> DELETE FROM public.payment; ERROR: Execution of non-whitelisted statement prohibited
Kết luận
Tuyên bố bị từ chối vì nó không có trong danh sách cho phép. Ngay cả khi người dùng có quyền xóa dữ liệu khỏi bảng, SQL Firewall đã chặn nó ngay lập tức.
Như bạn có thể thấy, SQL Firewall là một công cụ bảo mật mạnh mẽ. Nó có các tính năng an toàn cho phép nó được sử dụng trên chế độ sản xuất giả. Trong chế độ này, người dùng thử nghiệm có thể được định cấu hình để đưa các câu lệnh của họ vào danh sách trắng và sau đó chức năng có thể được kiểm tra.
Tuy nhiên, các DBA và quản trị viên hệ thống cần lưu ý một số điểm sau:
Trước hết, khi chế độ danh sách trắng của người dùng được đặt thành “GHI”, Tường lửa SQL không ngăn người dùng chạy bất kỳ truy vấn nào. Nói cách khác, SQL Firewall phải được đào tạo đầu tiên trước khi nó có thể chặn người dùng. Đó là lý do tại sao điều quan trọng là phải đảm bảo các đặc quyền truy cập cơ sở dữ liệu bình thường cũng được áp dụng cho bất kỳ tài khoản người dùng nào. Điều này càng quan trọng hơn vì các thành viên của vai trò superuser và sqlfirewall_manager được miễn trừ khỏi các quy tắc tường lửa. SQL Firewall không phải là sự thay thế cho bảo mật cơ sở dữ liệu hiện có - nó có sẵn để bổ sung cho nó.
Thứ hai, khi liệt kê các câu lệnh SELECT, INSERT, UPDATE và DELETE riêng lẻ, SQL Firewall sẽ coi các tên đối tượng được sử dụng trong các lệnh này được viết trong các trường hợp khác nhau (chữ hoa, chữ thường hoặc chữ thường) là giống nhau. Tất cả các lệnh khác sẽ được so sánh trên cơ sở các chuỗi truy vấn văn bản. Vì vậy, ví dụ:Tường lửa SQL sẽ coi “BEGIN” và “bắt đầu” và “Bắt đầu” như một phần của các truy vấn riêng biệt.
Thứ ba, danh sách trắng của Tường lửa SQL không tự động sao chép qua các nút dự phòng trong môi trường sao chép. Tuy nhiên, bạn có thể xuất danh sách trắng bằng cách sử dụng hàm sqlfirewall_whitelist_export và nhập nó vào một máy chủ khác bằng cách sử dụng hàm sqlfirewall_whitelist_import. Rất tiếc, việc sao lưu cơ sở dữ liệu hoặc lược đồ sqlfirewall và khôi phục trong trường hợp đích sẽ không hoạt động. Ngoài ra, máy chủ đích cần có cùng tài khoản người dùng để danh sách trắng trở nên hữu ích.
Cần phải xem xét cẩn thận tất cả các loại truy vấn có thể có mà người dùng có thể thực hiện đối với cơ sở dữ liệu và chạy danh sách trắng ở chế độ "GHI" trong thời gian cần thiết để nắm bắt tất cả khối lượng công việc bình thường. Việc ghi lại quá ít có thể hạn chế tài khoản người dùng chạy các truy vấn hợp pháp, trong khi ghi quá lâu có thể thêm lệnh vào danh sách trắng một cách không cần thiết. Điều này có thể gây ra sự chậm trễ cho SQL Firewall khi nó so sánh các câu lệnh trong chế độ thực thi.