PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Đặc quyền và quản lý người dùng PostgreSQL - Điều bạn nên biết

Quản lý người dùng trong PostgreSQL có thể phức tạp. Thông thường, người dùng mới được quản lý, phối hợp, trong một vài lĩnh vực quan trọng trong môi trường. Thông thường, các đặc quyền là hoàn hảo trên một mặt, nhưng lại được định cấu hình không chính xác ở mặt khác. Bài đăng trên blog này sẽ cung cấp 'Mẹo và Thủ thuật' thực tế cho người dùng hoặc vai trò, vì chúng ta sẽ biết điều đó, thiết lập trong PostgreSQL.

Các lĩnh vực chủ đề chúng tôi sẽ tập trung vào là:

  • Đảm nhận vai trò của PostgreSQL

Bạn sẽ tìm hiểu về vai trò, thuộc tính vai trò, các phương pháp hay nhất để đặt tên cho vai trò của bạn và các thiết lập vai trò phổ biến.

  • Tệp pg_hba.conf

Trong phần này, chúng ta sẽ xem xét một trong các tệp chính và cài đặt của nó, cho các kết nối phía máy khách và giao tiếp với máy chủ.

  • Các đặc quyền và hạn chế ở cấp độ Cơ sở dữ liệu, Bảng và Cột.

Bạn đang tìm cách định cấu hình các vai trò để có hiệu suất và cách sử dụng tối ưu? Các bảng của bạn có chứa dữ liệu nhạy cảm, chỉ các vai trò đặc quyền mới có thể truy cập được không? Tuy nhiên, với nhu cầu cho phép các vai trò khác nhau thực hiện công việc hạn chế? Những câu hỏi này và nhiều câu hỏi khác sẽ được giải đáp trong phần này.

Đảm nhận vai trò của PostgreSQL - 'Vai trò' là gì và cách tạo vai trò?

Quyền truy cập cơ sở dữ liệu trong PostgreSQL được xử lý với khái niệm vai trò, tương tự như người dùng. Vai trò cũng có thể đại diện cho các nhóm người dùng trong hệ sinh thái PostgreSQL.

PostgreSQL thiết lập khả năng cho các vai trò để gán đặc quyền cho các đối tượng cơ sở dữ liệu mà chúng sở hữu, cho phép truy cập và hành động đối với các đối tượng đó. Vai trò có khả năng cấp quyền thành viên cho một vai trò khác. Các thuộc tính cung cấp các tùy chọn tùy chỉnh để xác thực ứng dụng khách được phép.

Các thuộc tính cho vai trò thông qua lệnh CREATE ROLE, có sẵn trong tài liệu PostgreSQL chính thức.

Dưới đây là những thuộc tính bạn sẽ thường chỉ định khi thiết lập một vai trò mới. Hầu hết những điều này là tự giải thích. Tuy nhiên, một mô tả ngắn gọn được cung cấp để làm rõ mọi sự nhầm lẫn cùng với cách sử dụng ví dụ.

SUPERUSER - Một cơ sở dữ liệu SUPERUSER đáng được cảnh báo. Tóm lại, các vai trò có thuộc tính này có thể tạo ra một SUPERUSER khác. Thực tế là, thuộc tính này là bắt buộc để tạo một vai trò SUPERUSER khác. Vì các vai trò có thuộc tính này bỏ qua tất cả các lần kiểm tra quyền, hãy cấp đặc quyền này một cách thận trọng.

CREATEDB - Cho phép vai trò tạo cơ sở dữ liệu.

CREATEROLE - Với thuộc tính này, một vai trò có thể đưa ra lệnh CREATE ROLE. Do đó, hãy tạo các vai trò khác.

ĐĂNG NHẬP - Cho phép khả năng đăng nhập. Tên vai trò có thuộc tính này có thể được sử dụng trong lệnh kết nối máy khách. Thêm chi tiết về thuộc tính này với các ví dụ sắp tới.

Các thuộc tính nhất định có một lệnh có tên đối lập cực rõ ràng và thường là lệnh mặc định khi không được xác định.

ví dụ:
SUPERUSER | NOSUPERUSER
CREATEROLE | NOCREATEROLE
LOGIN | NOLOGIN

Hãy cùng xem xét một số thuộc tính này hoạt động cho các cấu hình khác nhau mà bạn có thể thiết lập để bắt đầu.

Tạo và loại bỏ các vai trò

Tạo một vai trò tương đối đơn giản. Đây là một ví dụ nhanh:

postgres=# CREATE ROLE $money_man;
ERROR: syntax error at or near "$"
LINE 1: CREATE ROLE $money_man;

Điều gì đã xảy ra ở đó? Hóa ra, tên vai trò không thể bắt đầu bằng bất kỳ thứ gì khác ngoài một chữ cái.

"Còn việc đặt tên trong dấu ngoặc kép thì sao?" Hãy xem:

postgres=# CREATE ROLE "$money_man";
CREATE ROLE

Điều đó đã hiệu quả, mặc dù có lẽ không phải là một ý kiến ​​hay. Làm thế nào về một ký tự đặc biệt ở giữa tên?

postgres=# CREATE ROLE money$_man;
CREATE ROLE

Không có vấn đề gì ở đó. Ngay cả khi không có dấu ngoặc kép, không có lỗi nào được trả lại.

Tôi chỉ không thích cấu trúc tên của $ money_man cho người dùng. Tôi đang thả cho bạn $ money_man và bắt đầu lại từ đầu. Lệnh DROP ROLE xử lý việc xóa một vai trò. Đây là nó đang được sử dụng.

postgres=# DROP ROLE $money_man;
ERROR: syntax error at or near "$"
LINE 1: DROP ROLE $money_man;

Và một lỗi khác với vai trò $ money_man. Một lần nữa, sử dụng dấu ngoặc kép.

postgres=# DROP ROLE "$money_man";
DROP ROLE

Đặc quyền ĐĂNG NHẬP

Hãy xem xét hai người dùng khác nhau, một người có đặc quyền ĐĂNG NHẬP và một người không có. Tôi cũng sẽ gán mật khẩu cho họ.

postgres=# CREATE ROLE nolog_user WITH PASSWORD 'pass1';
CREATE ROLE
postgres=# CREATE ROLE log_user WITH LOGIN PASSWORD 'pass2';
CREATE ROLE

Lưu ý:Các mật khẩu được cung cấp cho các vai trò hư cấu ở trên chỉ dành cho mục đích trình diễn. Bạn phải luôn cố gắng cung cấp mật khẩu duy nhất và cứng khi thực hiện các vai trò. Mặc dù có mật khẩu tốt hơn là không có mật khẩu, nhưng mật khẩu cứng thậm chí còn tốt hơn mật khẩu tầm thường.

Hãy gán log_user các thuộc tính CREATEDB và CREATEROLE bằng lệnh ALTER ROLE.

postgres=# ALTER ROLE log_user CREATEROLE CREATEDB;
ALTER ROLE

Bạn có thể xác minh các thuộc tính tập hợp này, bằng cách kiểm tra danh mục pg_role. Hai cột quan tâm là rolcreaterole và rolcishedb. Cả hai đều thuộc kiểu dữ liệu Boolean, vì vậy chúng phải được đặt thành t là true cho các thuộc tính này.

Xác nhận với một truy vấn CHỌN tương tự.

postgres=# SELECT rolcreaterole, rolcreatedb FROM pg_roles WHERE rolname = 'log_user';
rolcreaterole | rolcreatedb 
---------------+-------------
t | t
(1 row)
Tải xuống Báo cáo chính thức hôm nay Quản lý &Tự động hóa PostgreSQL với ClusterControlTìm hiểu về những điều bạn cần biết để triển khai, giám sát, quản lý và mở rộng PostgreSQLTải xuống Báo cáo chính thức

Làm thế nào bạn có thể xác định các vai trò hiện có trong cơ sở dữ liệu?

Hai phương pháp khả dụng là lệnh psql \ du hoặc chọn từ danh mục pg_roles.

Ở đây cả hai đều đang được sử dụng.

postgres=> \du
List of roles
Role name | Attributes | Member of 
------------+------------------------------------------------------------+-----------
log_user | Create role, Create DB | {}
nolog_user | Cannot login | {}

postgres=> SELECT rolname FROM pg_roles;
rolname 
----------------------
nolog_user
log_user
(2 rows)

Đăng nhập

Hãy cho cả hai vai trò, một cơ hội để đăng nhập vào máy chủ.

psql -U nolog_user -W postgres
Password for user nolog_user: 
psql: FATAL: no pg_hba.conf entry for host "[local]", user "nolog_user", database "postgres", SSL off
psql -U log_user -W postgres
Password for user log_user: 
psql: FATAL: no pg_hba.conf entry for host "[local]", user "log_user", database "postgres", SSL off

Để giải quyết vấn đề này, chúng ta phải tìm hiểu tệp pg_hba.conf đó. Giải pháp được thảo luận khi chúng tôi tiếp tục trong bài đăng này, đến phần cụ thể đó.

Những điểm rút ra có thể hành động

  • CREATE ROLE và đối tác của nó, DROP ROLE, là các lệnh bạn phải thực hiện để triển khai và loại bỏ các vai trò.
  • ALTER ROLE xử lý việc thay đổi các thuộc tính của một vai trò.
  • Các vai trò hợp lệ trong tất cả các cơ sở dữ liệu do định nghĩa ở cấp độ cụm cơ sở dữ liệu.
  • Xin lưu ý rằng việc tạo một tên vai trò bắt đầu bằng một ký tự đặc biệt, yêu cầu bạn phải 'giải quyết' tên đó bằng dấu ngoặc kép.
  • Các vai trò và đặc quyền của họ được thiết lập bằng cách sử dụng các thuộc tính.
  • Để thiết lập các vai trò cần thuộc tính LOGIN theo mặc định, CREATE USER là một lệnh tùy chọn theo ý của bạn. Được sử dụng thay cho CREATE ROLE role_name LOGIN, về cơ bản chúng tương đương nhau.

Tệp pg_hba.conf - Thiết lập nền tảng chung giữa máy chủ và máy khách

Việc bao gồm tất cả các khía cạnh và cài đặt cho tệp pg_hba.conf trong một bài đăng blog sẽ là điều tốt nhất. Thay vào đó, phần này sẽ trình bày những cạm bẫy phổ biến mà bạn có thể gặp phải và giải pháp để khắc phục chúng.

Kết nối thành công đòi hỏi một nỗ lực tổng thể từ cả hai bộ phận. Các vai trò kết nối với máy chủ, vẫn phải đáp ứng các hạn chế truy cập được đặt ở cấp cơ sở dữ liệu, sau khi chuyển các cài đặt trong tệp pg_hba.conf.

Các ví dụ có liên quan về mối quan hệ này được đưa vào khi phần này tiếp tục.

Để tìm tệp pg_hba.conf của bạn, hãy đưa ra một truy vấn CHỌN tương tự, trên pg_settings XEM. Bạn phải đăng nhập với tư cách là SUPERUSER để truy vấn chế độ XEM này.

postgres=# SELECT name, setting
FROM pg_settings WHERE name LIKE '%hba%';
name | setting 
----------+-------------------------------------
hba_file | /etc/postgresql/10/main/pg_hba.conf
(1 row)

Tệp pg_hba.conf chứa các bản ghi chỉ định một trong bảy định dạng có sẵn cho một yêu cầu kết nối nhất định. Xem toàn bộ phổ tại đây.

Với mục đích của bài đăng blog này, chúng tôi sẽ xem xét các cài đặt bạn có thể sử dụng cho môi trường cục bộ.

Có lẽ máy chủ này là để bạn tiếp tục học tập và nghiên cứu (như của tôi).

Tôi phải đặc biệt lưu ý rằng những cài đặt này không phải là cài đặt tối ưu cho một hệ thống cứng có nhiều người dùng.

Các trường cho loại kết nối này là:

local database user auth-method [auth-options]

Ý họ là:

cục bộ - kết nối được thử với các ổ cắm miền Unix.

cơ sở dữ liệu - Chỉ định (các) cơ sở dữ liệu được đặt tên cho khớp bản ghi này.

người dùng - Tên người dùng cơ sở dữ liệu phù hợp với bản ghi này. Trường này cũng cho phép một danh sách được phân tách bằng dấu phẩy gồm nhiều người dùng hoặc tất cả.

auth-method - Được sử dụng khi kết nối khớp với bản ghi duy nhất này. Các lựa chọn có thể có cho trường này là:

  • tin tưởng
  • từ chối
  • scram-sha-256
  • md5
  • mật khẩu
  • gss
  • sspi
  • danh tính
  • ngang hàng
  • ldap
  • bán kính
  • chứng chỉ
  • pam
  • bsd

Các dòng được đặt trong tệp pg_hba.conf cho các vai trò nolog_user và log_user trông giống như sau:

local all nolog_user password
local all log_user password

Lưu ý:Vì mật khẩu được gửi dưới dạng văn bản rõ ràng, mật khẩu này không nên được sử dụng trong môi trường không đáng tin cậy với mạng không đáng tin cậy.

Hãy xem ba cột thú vị từ pg_hba_file_rules VIEW với truy vấn bên dưới. Một lần nữa, vai trò của bạn cần thuộc tính SUPERUSER để truy vấn chế độ XEM này.

postgres=# SELECT database, user_name, auth_method
postgres-# FROM pg_hba_file_rules
postgres-# WHERE CAST(user_name AS TEXT) LIKE '%log_user%';
database | user_name | auth_method 
----------+--------------+-------------
{all} | {nolog_user} | password
{all} | {log_user} | password
(2 rows)

Chúng tôi có thể thấy thông tin giống hệt nhau từ các dòng được cung cấp ở trên được tìm thấy trong tệp pg_hba.conf như chúng tôi có thể từ truy vấn kèm theo. Thoạt nhìn, có vẻ như cả hai vai trò đều có thể đăng nhập.

Chúng tôi sẽ kiểm tra và xác nhận.

psql -U nolog_user -W postgres
Password for user nolog_user: 
psql: FATAL: role "nolog_user" is not permitted to log in
psql -U log_user -W postgres
Password for user log_user: 
psql (10.1)
Type "help" for help.
postgres=>

Điểm mấu chốt ở đây là, mặc dù nolog_user và log_user đều có thể đăng nhập theo tệp pg_hba.conf, nhưng chỉ log_user mới được phép đăng nhập thực sự.

Trong trường hợp log_user đã vượt qua các giới hạn truy cập cấp cơ sở dữ liệu (Bằng cách có thuộc tính LOGIN), nolog_user đã không.

Hãy chỉnh sửa dòng log_user trong tệp pg_hba.conf và thay đổi tên cơ sở dữ liệu mà vai trò này được phép truy cập. Đây là sự thay đổi, cho biết log_user hiện chỉ có thể đăng nhập vào cơ sở dữ liệu dùng thử.

local trial log_user password

Trước tiên, hãy thử đăng nhập vào cơ sở dữ liệu postgres, mà log_user trước đây đã có quyền truy cập do cờ tất cả.

$ psql -U log_user -W postgres
Password for user log_user: 
psql: FATAL: no pg_hba.conf entry for host "[local]", user "log_user", database "postgres", SSL off

Bây giờ với cơ sở dữ liệu dùng thử, log_user có đặc quyền

$ psql -U log_user -W trial
Password for user log_user: 
psql (10.1)
Type "help" for help.
trial=>

Không có lỗi ở đó và lời nhắc dùng thử => hiển thị cơ sở dữ liệu hiện được kết nối.

Các cài đặt này cũng áp dụng trong môi trường máy chủ, sau khi kết nối được thiết lập.

Hãy thử kết nối lại với cơ sở dữ liệu postgres đó:

trial=> \c postgres;
Password for user log_user: 
FATAL: no pg_hba.conf entry for host "[local]", user "log_user", database "postgres", SSL off
Previous connection kept

Thông qua các ví dụ được trình bày ở đây, bạn nên biết các tùy chọn tùy chỉnh cho các vai trò trong cụm của bạn.

Lưu ý:Thông thường, cần tải lại tệp pg_hba.conf để các thay đổi có hiệu lực.

Sử dụng tiện ích pg_ctl để tải lại máy chủ của bạn.

Cú pháp sẽ là:

pg_ctl reload [-D datadir] [-s]

Để biết datadir của bạn ở đâu, bạn có thể truy vấn hệ thống pg_settings XEM, nếu đăng nhập với tư cách là SUPERUSER với truy vấn CHỌN tương tự như bên dưới.

postgres=# SELECT setting FROM pg_settings WHERE name = 'data_directory';
           setting           
-----------------------------
 /var/lib/postgresql/10/main
(1 row)

Sau đó, cung cấp trình bao của bạn cho người dùng postgres (hoặc SUPERUSER khác) với:

$ sudo -u postgres bash

Trừ khi bạn đã thêm tiện ích pg_ctl vào $ PATH của mình, bạn phải đủ điều kiện để sử dụng nó, sau đó chuyển lệnh để thực thi, cùng với vị trí datadir.

Đây là một ví dụ:

$ /usr/lib/postgresql/10/bin/pg_ctl reload -D /var/lib/postgresql/10/main
server signaled

Hãy kiểm tra trạng thái của máy chủ với:

$ /usr/lib/postgresql/10/bin/pg_ctl status -D /var/lib/postgresql/10/main
pg_ctl: server is running (PID: 1415)
/usr/lib/postgresql/10/bin/postgres "-D" "/var/lib/postgresql/10/main" "-c" "config_file=/etc/postgresql/10/main/postgresql.conf"

Những điểm rút ra có thể hành động

  • Các vai trò phải vượt qua các yêu cầu từ cả tệp pg_hba.conf và đặc quyền truy cập cấp cơ sở dữ liệu.
  • tệp pg_hba.conf được kiểm tra từ trên xuống cho mỗi yêu cầu kết nối. Thứ tự trong tệp rất quan trọng.

Đặc quyền và Hạn chế của Cơ sở dữ liệu, Bảng và Cột - Điều chỉnh các Vai trò phù hợp cho Nhiệm vụ và Trách nhiệm

Để các vai trò sử dụng các đối tượng cơ sở dữ liệu (bảng, dạng xem, cột, hàm, v.v.), chúng phải được cấp đặc quyền truy cập cho chúng.

Lệnh GRANT xác định các đặc quyền cần thiết này.

Chúng ta sẽ xem xét một vài ví dụ để hiểu được bản chất của việc sử dụng nó.

Tạo cơ sở dữ liệu

Vì log_user đã được cấp thuộc tính CREATEDB và CREATEROLE, chúng tôi có thể sử dụng vai trò này để tạo cơ sở dữ liệu thử nghiệm có tên là trial.

postgres=> CREATE DATABASE trial:
CREATE DATABASE

Ngoài việc tạo VAI TRÒ mới:

postgres=> CREATE ROLE db_user WITH LOGIN PASSWORD 'scooby';
CREATE ROLE

Cuối cùng, log_user sẽ kết nối với cơ sở dữ liệu dùng thử mới:

postgres=> \c trial;
Password for user log_user: 
You are now connected to database "trial" as user "log_user".
trial=>

Lưu ý lời nhắc được đổi thành tên 'dùng thử' cho biết rằng chúng tôi được kết nối với cơ sở dữ liệu đó.

Hãy sử dụng log_user để TẠO một bảng giả.

trial=> CREATE TABLE another_workload(
trial(> id INTEGER,
trial(> first_name VARCHAR(20),
trial(> last_name VARCHAR(20),
trial(> sensitive_info TEXT);
CREATE TABLE

Role log_user gần đây đã tạo một vai trò trợ giúp, db_user. Chúng tôi yêu cầu db_user có các đặc quyền hạn chế đối với bảng another_workload.

Không nghi ngờ gì nữa, cột nhạy cảm không nên được truy cập bởi vai trò này. Các lệnh INSERT, UPDATE và DELETE cũng không nên được cấp vào lúc này, cho đến khi db_user đáp ứng các kỳ vọng nhất định.

Tuy nhiên, db_user được yêu cầu để đưa ra các truy vấn SELECT. Làm cách nào chúng ta có thể giới hạn các khả năng của vai trò này trong bảng another_workload?

Trước tiên, hãy kiểm tra cú pháp chính xác được tìm thấy trong tài liệu lệnh PostgreSQL GRANT, ở cấp bảng.

GRANT { { SELECT | INSERT | UPDATE | REFERENCES } ( column_name [, ...] )
[, ...] | ALL [ PRIVILEGES ] ( column_name [, ...] ) }
ON [ TABLE ] table_name [, ...]
TO role_specification [, ...] [ WITH GRANT OPTION ]

Tiếp theo, chúng tôi triển khai các yêu cầu đặt ra cho role db_user, áp dụng cú pháp cụ thể.

trial=> GRANT SELECT (id, first_name, last_name) ON TABLE another_workload TO db_user;
GRANT

Lưu ý ngay sau từ khóa SELECT, chúng tôi đã liệt kê các cột mà db_user có thể truy cập. Cho đến khi được thay đổi, nếu db_user cố gắng truy vấn CHỌN trên cột nhạy cảm hoặc bất kỳ lệnh nào khác cho vấn đề đó, các truy vấn đó sẽ không được thực thi.

Với db_user đã đăng nhập, chúng tôi sẽ đưa điều này vào thực tế, thử truy vấn SELECT để trả về tất cả các cột và bản ghi từ bảng.

trial=> SELECT * FROM another_workload;
ERROR: permission denied for relation another_workload

Thông tin chi tiết về cột được bao gồm trong truy vấn này. Do đó, không có bản ghi nào được trả lại cho db_user.

Nhưng db_user có thể CHỌN các cột được phép

trial=> SELECT id, first_name, last_name
trial-> FROM another_workload;
id | first_name | last_name 
-----+------------+-----------
10 | John | Morris
191 | Jannis | Harper
2 | Remmy | Rosebuilt
(3 rows)

Điều đó hoạt động tốt.

Chúng tôi cũng sẽ kiểm tra các lệnh INSERT, UPDATE và DELETE.

trial=> INSERT INTO another_workload(id,first_name,last_name,sensitive_info)
VALUES(17,'Jeremy','Stillman','key code:400Z');
ERROR: permission denied for relation another_workload
trial=> UPDATE another_workload
trial-> SET id = 101
trial-> WHERE id = 10;
ERROR: permission denied for relation another_workload
trial=> DELETE FROM another_workload
trial-> WHERE id = 2;;
ERROR: permission denied for relation another_workload

Bằng cách không gán các lệnh INSERT, UPDATE hoặc DELETE cho db_user, vai trò bị từ chối quyền truy cập sử dụng chúng.

Với rất nhiều tùy chọn có sẵn, việc định cấu hình vai trò của bạn là hầu như vô hạn. Bạn có thể làm cho chúng hoạt động đầy đủ, có thể thực hiện bất kỳ lệnh nào hoặc bị ràng buộc theo yêu cầu của bạn.

Những điểm rút ra có thể hành động

  • Các vai trò được cung cấp đặc quyền truy cập vào các đối tượng cơ sở dữ liệu thông qua lệnh GRANT.
  • Các đối tượng cơ sở dữ liệu và các lệnh chống lại các đối tượng đó, có thể định cấu hình cao trong môi trường PostgreSQL.

Đang kết thúc

Thông qua các ví dụ được cung cấp của bài đăng blog này, bạn sẽ hiểu rõ hơn về:

  1. Tạo một vai trò với các thuộc tính cụ thể.
  2. Đặt kết nối khả thi giữa máy khách và máy chủ, cho phép các vai trò truy cập đăng nhập vào cơ sở dữ liệu.
  3. Khả năng tùy chỉnh cao các vai trò của bạn để đáp ứng các yêu cầu cá nhân đối với quyền truy cập cấp cơ sở dữ liệu, bảng và cột bằng cách triển khai các thuộc tính cần thiết.

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Python Postgres psycopg2 ThreadedConnectionPool đã cạn kiệt

  2. Nhà cung cấp dịch vụ đám mây chuyên sâu:PostgreSQL trên DigitalOcean

  3. Cập nhật hàng loạt / hàng loạt / nâng cấp trong PostgreSQL

  4. Cài đặt Postgres.app trên máy Mac

  5. Barman Cloud - Phần 2:Cloud Backup