Cách bảo mật cơ sở dữ liệu PostgreSQL

Linh Le

Những bước sau sẽ giúp bật kết nối SSL và định cấu hình phù hợp cho các đặc quyền của người dùng để giữ an toàn cho cơ sở dữ liệu của bạn

Một tháng nữa thế giới sẽ chứng kiến một thảm họa bảo mật cơ sở dữ liệu khác. Dường như vi phạm về an ninh cơ sở dữ liệu đang trở nên phổ biến hơn khi các “diễn viên xấu tính” nhận ra rằng các cơ sở dữ liệu có chứa rất nhiều dữ liệu đáng giá.

Câu hỏi đặt ra ở đây là tại sao vấn đề này cứ mãi không chấm dứt được? Câu trả lời mà bạn dễ dàng nghe được sẽ là do thực thi không hiệu quả các giao thức bảo mật cơ sở dữ liệu. Nhưng làm sao chúng ta mới có thể ngăn chặn việc này?

Tuy nhiên, c ómột tin tốt là chúng ta có khả năng ngăn chặn được vấn đề này xảy ra. Cơ sở dữ liệu không nhất thiết phải bị đối mặt với các rủi ro như vậy, chỉ cần bạn thực hiện các biện pháp phòng ngừa cần thiết. Giải pháp ở đây nằm ở hai chữ: cấu hình. Đừng chỉ sử dụng thiết lập sử dụng ngay được (out-of-box settings). Hãy sử dụng iptables để bảo mật quyền truy cập. (Theo như những gì có thể xác định được sau vụ Exactis bị xâm phạm gần đây, việc sử dụng iptables hoặc một tính năng tương tự đã được thiết lập lúc xảy ra sự cố, và sau đó đã ngăn chặn được hành động xâm phạm.)

Trong bài viết này, chúng tôi sẽ xem xét các bước bạn có thể thực hiện để bảo mật PostgreSQL chống lại sự xâm nhập và tấn công. Trước tiên, chúng ta sẽ xem xét triển khai các kết nối SSL và xác thực bằng chứng chỉ (certificate-based authentication) trong PostgreSQL. Sau đó, chúng ta sẽ xem xét cách tạo người dùng và nhóm trong PostgreSQL để cung cấp mức tối thiểu truy cập cơ sở dữ liệu thích hợp.

Là một cơ sở dữ liệu mã nguồn mở đã được thử và được xác định đúng, PostgreSQL được sử dụng ở nhiều doanh nghiệp và trong triển khai cơ sở dữ liệu khởi động. Chắc chắn có rất nhiều dữ liệu trong PostgreSQL cần được bảo vệ.

Cấu hình kết nối an toàn trong PostgreSQL

PostgreSQL cho phép bạn kích hoạt mã hóa dữ liệu qua dây thông qua SSL. PostgreSQL sử dụng các kết nối SSL để mã hóa giao tiếp giữa máy khách và máy chủ. Để sử dụng SSL, bạn phải cài đặt OpenSSL trên cả máy khách và máy chủ của mình.

Các bước để mã hóa các kết nối bằng SSL

Để tiếp tục, bạn phải tạo tệp chứng thực máy khách (Client Certificate) và chứng thực máy chủ (Server Certificate) được đăng ký với nhà cung cấp chứng thực số (CA).

  1. Tạo một yêu cầu ký chứng chỉ (CSR) và một  key-file.

$ openssl genrsa out rootCA.key 1024

$ openssl req x509 new key rootCA.key days 365 out rootCA.crt subj ‘/C=XX/L=Default City/O=Default Company Ltd/CN=root’

  1. Tạo server certificate đã được đăng ký với nhà cung cấp chứng thực số gốc.

$ openssl genrsa out server.key 1024

$ openssl req new key server.key out server.csr subj ‘/C=XX/L=Default City/O=Default Company Ltd/CN=pgservername’

$ openssl x509 req in server.csr CA rootCA.crt CAkey rootCA.key CAcreateserial out server.crt days 365

(Lưu ý rằng CN trong dòng thứ hai ở trên phải là tên máy chủ dùng cho xác thực máy chủ.)

  1. Tạo client certificate đã được đăng ký với nhà cung cấp chứng thực số gốc.

$ openssl genrsa out postgresql.key 1024

$ openssl req new key postgresql.key out postgresql.csr subj ‘/C=XX/L=Default City/O=Default Company Ltd/CN=postgres’

$ openssl x509 req in postgresql.csr CA rootCA.crt CAkey rootCA.key CAcreateserial out postgresql.crt days 365

  1. Sao chép tệp chứng thực máy chủ (server.crt), khóa riêng của máy chủ (server.key) và nhà cung cấp chứng thực số gốc (rootCA.crt) vào thư mục dữ liệu PostgreSQL hoặc một vị trí bảo mật mà superuser PostgreSQL (postgres) có thể truy cập vào được. Sau khi sao chép, cho phép các đặc quyền chỉ đọc đối với người dùng PostgreSQL.

$ cd $PGDATA

$ chmod 0400 server.crt server.key rootCA.crt

  1. Đặt các tham số thích hợp trong PostgreSQL để bật chế độ SSL.

$ psql

ALTER SYSTEM SET ssl TO ‘ON’;

ALTER SYSTEM SET ssl_ca_file TO ‘root.crt’;

ALTER SYSTEM SET ssl_cert_file TO ‘server.crt’;

ALTER SYSTEM SET ssl_key_file TO ‘server.key’;

  1. OpenSSL hỗ trợ một loạt các thuật toán mã hóa. Bạn sẽ muốn chọn mật mã phù hợp với tiêu chuẩn tổ chức của mình. Khi đã chọn mật mã bạn muốn sử dụng, hãy đặt tham số sau trong PostgreSQL.

psql

ALTER SYSTEM SET ssl_ciphers TO ‘your_desired_cipher’; (=> Change requires Server Reload)

Phép mã hóa (cipher) mặc định là: HIGH:MEDIUM:+3DES:!aNULL

  1. Bạn có thể tải lại hoặc khởi động lại máy chủ PostgreSQL để áp dụng các tham số này.

$ psql c “select pg_reload_conf()”

hoặc

$ pg_ctl D $PGDATA restart mf

  1. Để bật mã hóa bằng SSL, bạn phải sửa đổi host thành hostssl trong tệp pg_hba.conf. Ví dụ: để bật SSL cho kết nối cục bộ, hãy thay thế host bằng hostssl cho kết nối cục bộ.

$ vim $PGDATA/pg_hba.conf

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

 

# IPv4 local connections:

# host all all 127.0.0.1/32 trust

hostssl all all 127.0.0.1/32 trust

 

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

  1. Bạn có thể thêm các mục tương tự để cho phép mã hóa các kết nối từ các ứng dụng hoặc ứng dụng từ xa.

$ vim $PGDATA/pg_hba.conf

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

 

# IPv4 local connections:

# host all all 127.0.0.1/32 trust

hostssl all all 127.0.0.1/32 trust

hostssl all all app_server_1/32 md5

hostssl all all app_server_2/32 md5

 

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

  1. Once you have made the changes to pg_hba.conf file, you must perform a SIGHUP or reload.

$ psql c “select pg_reload_conf()”

  1. Kiểm tra kết nối cục bộ cho SSL. Đây là giao diện trước và sau khi bật SSL cho kết nối cục bộ.

Trước

=======

 

$ psql h localhost

psql (10.4)

Type “help” for help.

postgres=#

Sau

=======

 

$ psql h localhost

psql (10.4)

SSL connection (protocol: TLSv1.2, cipher: ECDHERSAAES256GCMSHA384, bits: 256, compression: off)

Type “help” for help.

postgres=#

Nếu bạn sử dụng hostssl cho các kết nối ứng dụng từ xa thì việc giao tiếp đến máy chủ cơ sở dữ liệu được tự động mã hóa.

Các bước để bật xác thực bằng client certificate

  1. Client certificate có thể được sử dụng cho danh tính người dùng của máy khách hoặc máy chủ ứng dụng. Nó đặc biệt hữu ích cho việc xác thực. Giờ thì bạn có thể sao chép các client certificate được tạo trong Bước 3 (ở trên) vào máy chủ ứng dụng từ xa của mình. Sau khi sao chép, hãy đặt các đặc quyền thích hợp. Ví dụ: IP của máy chủ ứng dụng của tôi cho thử nghiệm này là 192.168.0.13.

$ scp postgresql.crt postgresql.key rootCA.crt postgres@192.168.0.13:/var/lib/pgsql

Sau khi sao chép vào máy chủ ứng dụng, hãy cấp đặc quyền chỉ-đọc cho người dùng OS thích hợp trong máy chủ ứng dụng.

$ chmod 0400 postgresql.crt postgresql.key rootCA.crt

  1. Để sử dụng xác thực bằng client certificate, hãy thêm mục sau vào pg_hba.conf của máy chủ PostgreSQL từ xa của bạn.

$ vi $PGDATA/pg_hba.conf

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

 

hostssl all all 192.168.0.13/32 cert clientcert=1

 

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Tại đây, 192.168.0.13 là địa chỉ IP của máy chủ ứng dụng. Bằng cách này bạn có thể có được nhiều mục nhập.

Quan sát sự khác biệt giữa Bước 9 và Bước 13 ta thấy: Mục nhập pg_hba.conf trong Bước 9 sẽ cho phép giao tiếp qua mã hóa, với các kết nối được mã hóa tự động. Mục nhập pg_hba.conf trong Bước 13 thì xa hơn. Nó cũng sẽ bắt buộc xác thực bằng client certificate để đảm bảo rằng sự giao tiếp đang diễn ra giữa các bên đáng tin cậy.

Give a SIGHUP or reload to put the changes to pg_hba.conf into effect.

$ pg_ctl D $PGDATA reload

  1. Xác thực kết nối từ xa bằng cách sử dụng máy khách psql.

$ psql “port=5432 host=192.168.0.12 user=postgres sslcert=/var/lib/pgsql/postgresql.crt sslkey=/var/lib/pgsql/postgresql.key sslrootcert=/var/lib/pgsql/rootCA.crt sslmode=require”

psql (10.4)

SSL connection (protocol: TLSv1.2, cipher: ECDHERSADESCBC3SHA, bits: 168, compression: off)

Type “help” for help.

postgres=#

Bạn sẽ thấy các kết nối xảy ra qua SSL.

Tạo vai trò người dùng và nhóm an toàn trong PostgreSQL

PostgreSQL cho phép bạn bật mã hóa dữ liệu qua dây thông qua SSL. Tuy nhiên, bạn cũng rất cần hiểu cách bảo mật và quản lý người dùng hoạt động như thế nào trong PostgreSQL. Người dùng trong PostgreSQL phải có các đặc quyền thích hợp là không cấp quyền truy cập quá nhiều. Các bước dưới đây sẽ giúp bạn hiểu cách PostgreSQL triển khai quản lý người dùng đồng thời cũng trình bày một số phương pháp hay nhất.

Người dùng PostgreSQL là gì?

Người dùng PostgreSQL là một vai trò có đặc quyền CONNECT. Cả CREATE USER và CREATE ROLE đều hoạt động tốt để tạo một người dùng PostgreSQL. Tuy nhiên, người dùng phải có vai trò LOGIN. Vai trò LOGIN được gán cho người dùng khi bạn sử dụng bất kỳ phương pháp nào trong ba cách tiếp cận sau:

CREATE USER percuser WITH ENCRYPTED PASSWORD ‘secret’;

hoặc

CREATE ROLE percuser WITH ENCRYPTED PASSWORD ‘secret’;

hoặc

CREATE ROLE percuser;

ALTER ROLE percuser WITH LOGIN ENCRYPTED PASSWORD ‘secret’;

Khi bạn sử dụng CREATE USER với bất kỳ điều nào ở trên, PostgreSQL sẽ tự động sửa đổi cú pháp nội bộ bằng cú pháp sau:

CREATE ROLE percuser

WITH NOSUPERUSER INHERIT NOCREATEROLE NOCREATEDB LOGIN NOREPLICATION NOBYPASSRLS

ENCRYPTED PASSWORD ‘secret’;

Trong cú pháp được tự động sửa đổi bởi PostgreSQL ở trên, chúng ta thấy rằng nó không cấp các ROLES cần thiết để quản lý PostgreSQL.

Sau khi tạo người dùng hoặc vai trò, bạn có thể sử dụng truy vấn sau đây để xem liệu người dùng có thể đăng nhập hay không (có đặc quyền CONNECT):

postgres=# select rolcanlogin from pg_roles where rolname = ‘percuser’;

rolcanlogin

————-

t

(1 row)

Trả về một boolean cho biết liệu người dùng có thể đăng nhập hay không. Ví dụ, khi bạn sử dụng cú pháp sau để tạo một ROLE bạn sẽ thấy rằng vai trò không có đặc quyền CONNECT.

postgres=# CREATE ROLE percrole;

CREATE ROLE

postgres=# select rolcanlogin from pg_roles where rolname = ‘percrole’;

rolcanlogin

————-

f

(1 row)

Xin lưu ý: Luôn tránh tạo bất kỳ người dùng hoặc vai trò nào có tiền tố pg_%.

Sự khác biệt giữa CREATE USER và CREATE ROLE trong PostgreSQL

Khi bạn tạo người dùng bằng CREATE USER, người dùng sẽ tự động nhận được vai trò LOGIN:

postgres=# CREATE USER percuser WITH ENCRYPTED PASSWORD ‘secret’;

CREATE ROLE

postgres=# select rolcanlogin from pg_roles where rolname = ‘percuser’;

rolcanlogin

————-

t

(1 row)

Tuy nhiên, khi bạn tạo một vai trò, bạn phải thêm rõ ràng vai trò LOGIN để cho phép người dùng đăng nhập:

postgres=# CREATE ROLE percuser WITH ENCRYPTED PASSWORD ‘secret’;

CREATE ROLE

postgres=# select rolcanlogin from pg_roles where rolname = ‘percuser’;

rolcanlogin

————-

f

(1 row)

 

postgres=# ALTER ROLE percuser WITH LOGIN;

ALTER ROLE

postgres=# select rolcanlogin from pg_roles where rolname = ‘percuser’;

rolcanlogin

————-

t

(1 row)

Nhóm hoặc vai trò nhóm trong PostgreSQL là gì?

Trong PostgreSQL, một vai trò có thể INHERIT một vai trò khác. Điều này có nghĩa là một vai trò có thể được truy cập bằng cách sử dụng các đặc quyền của một vai trò khác. Điều này có thể thực hiện được bằng cách sử dụng các từ khóa GRANT hoặc INHERIT.

Bạn nên luôn cung cấp đặc quyền truy cập cho người dùng bằng cách sử dụng GROUP ROLES.

Ví dụ: hãy xem xét một tổ chức có:

  • 1 cơ sở dữ liệu (percona)
  • 2 schema (scottand tiger)

Giả sử chúng ta cần tạo 10 người dùng cá nhân và 10 người dùng ứng dụng tuân thủ các yêu cầu sau:

  • Năm trong số những người dùng ứng dụng phải có quyền truy cập chỉ đọc vào các bảng của schema scott và quyền truy cập đọc-ghi vào các bảng của schema tiger.
  • Năm người dùng ứng dụng khác phải có quyền truy cập đọc-ghi vào các bảng schema scott và truy cập chỉ-đọc vào các bảng của schema tiger.
  • Tất cả 10 tài khoản người dùng cá nhân chỉ có thể có quyền truy cập chỉ đọc vào các bảng schema scott tiger.

Trong trường hợp này, bạn có thể tạo 4 vai trò nhóm như sau:

scott_readonly:

CREATE ROLE scott_readonly;

GRANT USAGE, SELECT ON ALL TABLES IN SCHEMA scott TO scott_readonly;

scott_readwrite:

CREATE ROLE scott_readwrite;

GRANT USAGE, SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA scott TO scott_readwrite;

tiger_readonly:

CREATE ROLE tiger_readonly;

GRANT USAGE, SELECT ON ALL TABLES IN SCHEMA tiger TO tiger_readonly;

tiger_readwrite:

CREATE ROLE tiger_readwrite;

GRANT USAGE, SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA tiger TO tiger_readwrite;

Bây giờ, bạn có thể GRANT các vai trò nhóm này cho người dùng dựa trên ba yêu cầu trên.

GRANT scott_readonly,tiger_readonly TO user1;

GRANT scott_readonly,tiger_readwrite TO appuser1;

GRANT scott_readwrite,tiger_readonly TO appuser2;

Bằng cách chỉ định vai trò nhóm cho những người dùng này, bạn có thể tách biệt những đặc quyền nào được cho phép đối với người dùng nào.

Tham khảo: https://www.postgresql.org/docs/10/static/sql-createrole.html

Người dùng và vai trò có phải xét toàn diện cho toàn bộ phiên bản?

Đúng như vậy, người dùng và vai trò trong PostgreSQL là toàn diện đối với toàn bộ phiên bản. Một người dùng có thể được sử dụng để truy cập bất kỳ cơ sở dữ liệu nào. Tương tự, một vai trò nhóm trong PostgreSQL có thể được cấp đặc quyền của nhiều schema/đối tượng trong nhiều cơ sở dữ liệu.

Chia sẻ bài viết ngay

Nguồn bài viết : https://www.infoworld.com