Thứ hai, 05/08/2013 | 00:00 GMT+7

Sử dụng roles và quản lý cấp quyền trong postgresql trên vps

PostgreSQL là một hệ quản trị database open-souce sử dụng ngôn ngữ truy vấn SQL. PostgreSQL là một công cụ mạnh mẽ được dùng để quản lý dữ liệu ứng dụng và web trên VPS của bạn. Trong bài viết này, ta sẽ thảo luận về cách quản lý chuẩn về quyền truy cập, nhằm cung cấp cho ứng dụng những quyền phù hợp trên database này ,  rồi giới hạn không cho phép tác động quyền lên database khác.

Ta sẽ sử dụng PostgreSQL trên server Ubuntu, cũng tương tự như các bản Linux khác.

Khởi tạo cài đặt PostgreSQL 

Nếu bạn chưa cài đặt PostgreSQL trên Ubuntu, hãy nhập các lệnh sau để cài đặt:

sudo apt-get update
sudo apt-get install postgresql postgresql-contrib

Trong quá trình cài đặt, PostgreSQL sẽ tạo một user mặc định để vận hành. Ta sẽ sử dụng user này cho các bước đầu tiên. Đăng nhập bằng lệnh sau:

sudo su - postgres

Môi trường hiện đã được chuẩn bị và ta có thể bắt đầu tìm hiểu về cách PostgreSQL xử lý các quyền.

Các khái niệm về quyền PostgreSQL

PostgreSQL (hoặc đơn giản là "postgres") quản lý quyền thông qua khái niệm "roles" - Role nghĩa là "Vai trò".

Role khác với quyền kiểu Unix truyền thống ở chỗ không có sự phân biệt giữa user và group.

Role này có thể là thành viên (member) của các role khác, cho phép chúng đảm nhận các quyền cho phép của các role đã xác định trước đó. Role cũng có thể sở hữu các đối tượng và kiểm soát quyền truy cập vào đối tượng đó cho các role khác.

Cách xem role trong PostgreSQL

Ta có thể xem các role hiện tại trong PostgreSQL bằng cách đăng nhập vào giao diện dấu nhắc bằng lệnh sau:

psql

Để nhận danh sách các role, hãy nhập:

\du
                             List of roles
 Role name |                   Attributes                   | Member of 
-----------+------------------------------------------------+-----------
 postgres  | Superuser, Create role, Create DB, Replication | {}

Như bạn thấy, chỉ có một role mặc định và nó có nhiều quyền mạnh mẽ.

Cách tạo role trong PostgreSQL

Có một số cách khác nhau để tạo role cho Postgres. Có thể tạo các role từ bên trong Postgres hoặc từ dòng lệnh, 2 cách như sau.

Cách tạo role từ bên trong PostgreSQL

Cách cơ bản nhất để tạo role mới là từ bên trong giao diện dấu nhắc của Postgres.

Bạn có thể tạo một role mới theo cú pháp sau:

CREATE ROLE new_role_name;

Hãy tạo một role mới có tên "demo_role":

CREATE ROLE demo_role;
CREATE ROLE

Nếu ta kiểm tra lại những user đã xác định, ta sẽ nhận được những điều sau:

\du
                             List of roles
 Role name |                   Attributes                   | Member of 
-----------+------------------------------------------------+-----------
 demo_role | Cannot login                                   | {}
 postgres  | Superuser, Create role, Create DB, Replication | {}
Thông tin duy nhất mà ta được cung cấp là role mới không có quyền đăng nhập. Điều này là ổn vào lúc này.

Cách tạo role từ dòng lệnh

Một phương pháp thay thế để tạo role là sử dụng lệnh "createuser".

Thoát khỏi dấu nhắc lệnh PostgreSQL trong giây lát bằng lệnh:

\q

Tạo một role được gọi là "test_user" bằng lệnh sau:

createuser test_user
Shall the new role be a superuser? (y/n) n
Shall the new role be allowed to create databases? (y/n) n
Shall the new role be allowed to create more new roles? (y/n) n

Bạn sẽ được hỏi một loạt câu hỏi xác định một số quyền ban đầu cho role mới. Nếu bạn trả lời "n" cho tất cả các dấu nhắc này, bạn sẽ tạo một user tương tự như user trước đó ta đã tạo.

Ta có thể đăng nhập lại vào dấu nhắc Postgres và chạy lại lệnh "\ du" để xem sự khác biệt giữa hai role mới:

psql
\du
                             List of roles
 Role name |                   Attributes                   | Member of 
-----------+------------------------------------------------+-----------
 demo_role | Cannot login                                   | {}
 postgres  | Superuser, Create role, Create DB, Replication | {}
 test_user |                                                | {}

Như bạn thấy, các lệnh này không tạo ra kết quả giống hệt nhau. User test_user được tạo từ dòng lệnh không có thuộc tính "Cannot login".

Cách xóa role trong PostgreSQL

Như một bài tập, ta hãy thử lấy "demo_role" để có các quyền tương tự như "test_user". Ta sẽ thử điều này trong quá trình tạo trước và sau đó sẽ tìm hiểu cách thay đổi quyền của một role hiện có.

Trước khi có thể thực hành xác định quyền cho "demo_role" khi tạo, ta cần hủy role hiện tại để có thể thử lại.

Bạn có thể xóa role bằng cú pháp sau:

DROP ROLE role_name;

Xóa role "demo_role" bằng lệnh:

DROP ROLE demo_role;
DROP ROLE

Nếu ta chạy lệnh trên một user không tồn tại, sẽ nhận được lỗi sau:

DROP ROLE demo_role;
ERROR:  role "demo_role" does not exist

Để tránh trường hợp này: thực hiện lệnh drop (xóa) user nếu đã có và không làm gì nếu user không tồn tại, hãy sử dụng cú pháp sau:

DROP ROLE IF EXISTS role_name;

Như bạn thấy, với tùy chọn này lệnh sẽ hoàn thành:

DROP ROLE IF EXISTS demo_role;
NOTICE:  role "demo_role" does not exist, skipping
DROP ROLE

Cách xác định các quyền khi tạo role

Bây giờ, ta sẵn sàng tạo lại role "demo_role" với các quyền đã thay đổi. Ta có thể làm điều này bằng cách chỉ định các quyền ta muốn sau mệnh đề tạo chính:

CREATE ROLE role_name WITH optional_permissions;

Bạn có thể xem danh sách đầy đủ các tùy chọn bằng lệnh:

\h CREATE ROLE

Ta muốn cung cấp cho user này khả năng đăng nhập - login, vì vậy sẽ nhập:

CREATE ROLE demo_role WITH LOGIN;
CREATE ROLE

Nếu kiểm tra lại các thuộc tính, có thể thấy rằng hai user hiện có các quyền giống hệt nhau:

\du
                             List of roles
 Role name |                   Attributes                   | Member of 
-----------+------------------------------------------------+-----------
 demo_role |                                                | {}
 postgres  | Superuser, Create role, Create DB, Replication | {}
 test_user |                                                | {}

Nếu ta muốn đến trạng thái này mà không cần chỉ định thuộc tính "login" với mỗi lần tạo role, ta có thể sử dụng lệnh sau thay vì lệnh "CREATE ROLE":

CREATE USER role_name;

Sự khác biệt giữa hai lệnh là "CREATE USER" tự động cung cấp các quyền đăng nhập role.

Cách thay đổi quyền của role trong PostgreSQL

Để thay đổi các thuộc tính của một role đã được tạo, ta sử dụng lệnh "ALTER ROLE".

Lệnh này cho phép ta xác định các thay đổi quyền mà không cần phải xóa và tạo lại user như đã trình bày trước đó.

Cú pháp cơ bản là:

ALTER ROLE role_name WITH attribute_options;

Ví dụ: ta có thể thay đổi "demo_role" trở lại trạng thái trước đó của nó bằng cách ra lệnh sau:

ALTER ROLE demo_role WITH NOLOGIN;
ALTER ROLE

Ta có thể thấy các quyền đã hoàn nguyên về trạng thái trước đó:

\du
                             List of roles
 Role name |                   Attributes                   | Member of 
-----------+------------------------------------------------+-----------
 demo_role | Cannot login                                   | {}
 postgres  | Superuser, Create role, Create DB, Replication | {}
 test_user |                                                | {}

Ta có thể dễ dàng thay đổi nó trở lại bằng lệnh sau:

ALTER ROLE demo_role WITH LOGIN;

Cách đăng nhập với quyền user khác trong PostgreSQL

Theo mặc định, user chỉ được phép đăng nhập local nếu tên user hệ thống trùng với tên user PostgreSQL.

Ta có thể giải quyết vấn đề này bằng cách thay đổi kiểu đăng nhập hoặc bằng cách chỉ định rằng PostgreSQL sẽ sử dụng đăng nhập qua mạng loopback, giao diện này sẽ thay đổi kiểu kết nối thành từ xa.

Ta sẽ thảo luận về phương án thứ hai (đăng nhập qua mạng). Trước tiên, ta cần cung cấp cho user mà ta muốn kết nối làm password để ta có thể xác thực.

Cung cấp password cho "test_user" bằng lệnh sau:

\password test_user

Bạn cần nhập và xác nhận password. Bây giờ, thoát khỏi giao diện PostgreSQL và thoát trở lại user thường của bạn.

\q
exit

PostgreSQL giả định khi bạn đăng nhập, bạn sẽ sử dụng tên user trùng với tên user hệ điều hành của bạn và bạn cũng sẽ kết nối với database có cùng tên.

Đây không phải là trường hợp của tình huống ta đang cần, vì ta đang cần đăng nhập qua Mạng.  Vì vậy ta cần chỉ định rõ ràng các tùy chọn mà ta muốn sử dụng. Sử dụng cú pháp sau:

psql -U user_name -d database_name -h 127.0.0.1 -W

"User_name" phải được thay thế bằng tên user mà ta muốn kết nối. Tương tự, "database_name" phải là tên của database hiện có mà bạn có quyền truy cập.

Phần "-h 127.0.0.1" là phần chỉ định rằng ta sẽ kết nối với máy local, nhưng thông qua interface mạng, cho phép ta xác thực. Cờ "-W" cho PostgreSQL biết rằng ta sẽ nhập password.

Để đăng nhập bằng "test_user", ta có thể sử dụng lệnh sau:

psql -U test_user -d postgres -h 127.0.0.1 -W
Password for user test_user:

Bạn cần nhập password mà bạn đã cấu hình. Trong ví dụ , ta sử dụng database "postgres". Đây là database mặc định được cài đặt trong quá trình cài đặt.

Nếu bạn thực hiện một số hành động trong phiên này, bạn sẽ thấy rằng bạn không có khả năng làm nhiều việc, là do ta đã không cấp quyền cho "test_user" để quản lý nhiều thứ.

Hãy thoát ra và quay lại phiên quản trị:

\q
sudo su - postgres
psql

Cách cấp quyền trong PostgreSQL

Khi một database hoặc bảng được tạo, thường chỉ có role đã tạo ra database (không bao gồm các role có quyền cao nhất - superuser) mới có quyền sửa đổi nó. Ta có thể thay đổi hành vi này bằng cách cấp quyền cho các role khác.

Ta có thể cấp quyền bằng lệnh "GRANT". Cú pháp chung ở đây:

GRANT permission_type ON table_name TO role_name;

Tạo một bảng đơn giản để thực hành:

CREATE TABLE demo (
name varchar(25),
id serial,
start_date date);
NOTICE:  CREATE TABLE will create implicit sequence "demo_id_seq" for serial column "demo.id"
CREATE TABLE

Ta có thể thấy kết quả với:

\d
             List of relations
 Schema |    Name     |   Type   |  Owner   
--------+-------------+----------+----------
 public | demo        | table    | postgres
 public | demo_id_seq | sequence | postgres
(2 rows)

Bây giờ ta có thể cấp một số quyền cho bảng "demo" mới cho "demo_role". Cấp cho user quyền "UPDATE" bằng lệnh sau:

GRANT UPDATE ON demo TO demo_role;

Ta có thể cấp toàn quyền cho user bằng cách thay thế loại quyền bằng từ "ALL":

GRANT ALL ON demo TO test_user;

Nếu ta muốn chỉ định quyền cho mọi user trên hệ thống, ta có thể sử dụng từ "PUBLIC" thay vì một user cụ thể:

GRANT INSERT ON demo TO PUBLIC;

Để xem bảng tài trợ, hãy sử dụng lệnh sau:

\z
                                    Access privileges
 Schema |    Name     |   Type   |     Access privileges      | Column access privileges 
--------+-------------+----------+----------------------------+--------------------------
 public | demo        | table    | postgres=arwdDxt/postgres +| 
        |             |          | demo_role=w/postgres      +| 
        |             |          | test_user=arwdDxt/postgres+| 
        |             |          | =a/postgres                | 
 public | demo_id_seq | sequence |                            | 
(2 rows)

Điều này hiển thị tất cả các quyền cấp mà ta vừa chỉ định.

Cách xóa quyền trong PostgreSQL

Bạn có thể xóa quyền bằng lệnh "REVOKE". Lệnh thu hồi sử dụng cú pháp gần giống như lệnh cấp:

REVOKE permission_type ON table_name FROM user_name;

Ta có thể sử dụng các từ viết tắt giống nhau (ALL và PUBLIC) để làm cho lệnh dễ dàng hơn:

REVOKE INSERT ON demo FROM PUBLIC;

Cách sử dụng role group trong PostgreSQL

Các role đủ linh hoạt để cho phép group các role khác để cho phép kiểm soát quyền trên diện rộng.

Ví dụ: ta có thể tạo một role mới được gọi là "temporary_users" và sau đó thêm "demo_role" và "test_user" vào role đó:

CREATE ROLE temporary_users;
GRANT temporary_users TO demo_role;
GRANT temporary_users TO test_user;

Như vậy, hai user này có thể quản lý quyền của họ bằng cách điều khiển role group "temporary_users" thay vì quản lý từng thành viên riêng lẻ.

Ta có thể xem thông tin thành viên của role bằng lệnh:

\du
                                    List of roles
    Role name    |                   Attributes                   |     Member of     
-----------------+------------------------------------------------+-------------------
 demo_role       |                                                | {temporary_users}
 postgres        | Superuser, Create role, Create DB, Replication | {}
 temporary_users | Cannot login                                   | {}
 test_user       |                                                | {temporary_users}

Bất kỳ thành viên nào của role group đều có thể hoạt động như role group mà họ là thành viên bằng cách sử dụng lệnh "set role".

Vì user "postgres" mà ta đăng nhập hiện có quyền của user cấp cao, ta có thể sử dụng "set role" ngay cả khi ta không phải là thành viên của group đó:

SET ROLE temporary_users;

Bây giờ, bất kỳ bảng nào được tạo đều thuộc sở hữu của role temporary_users:

CREATE TABLE hello (
name varchar(25),
id serial,
start_date date);

Ta có thể kiểm tra quyền sở hữu bảng bằng cách ra lệnh này:

\d
                 List of relations
 Schema |     Name     |   Type   |      Owner      
--------+--------------+----------+-----------------
 public | demo         | table    | postgres
 public | demo_id_seq  | sequence | postgres
 public | hello        | table    | temporary_users
 public | hello_id_seq | sequence | temporary_users
(4 rows)

Như bạn thấy, bảng mới (và chuỗi liên kết với kiểu dữ liệu nối tiếp) được sở hữu bởi role "temporary_users".

Ta có thể quay lại các quyền role ban đầu của bạn bằng lệnh sau:

RESET ROLE;

Nếu ta cung cấp cho user thuộc tính "inherit" bằng lệnh "alter role", user đó sẽ tự động có tất cả các quyền của role mà họ thuộc về mà không cần sử dụng lệnh "set role":

ALTER ROLE test_user INHERIT;

Bây giờ test_user sẽ có mọi quyền đối với các role mà nó là thành viên.

Ta có thể xóa role group (hoặc bất kỳ role nào) bằng lệnh "drop role":

DROP ROLE temporary_users;
ERROR:  role "temporary_users" cannot be dropped because some objects depend on it
DETAIL:  owner of table hello
owner of sequence hello_id_seq

Điều này sẽ gây ra lỗi cho bạn vì ta đã tạo một bảng do "temporary_users" sở hữu. Ta có thể giải quyết vấn đề này bằng cách chuyển quyền sở hữu sang một role khác:

ALTER TABLE hello OWNER TO demo_role;

Nếu ta kiểm tra, ta có thể thấy rằng "temporary_users" không còn sở hữu bất kỳ bảng nào:

\d
              List of relations
 Schema |     Name     |   Type   |   Owner   
--------+--------------+----------+-----------
 public | demo         | table    | postgres
 public | demo_id_seq  | sequence | postgres
 public | hello        | table    | demo_role
 public | hello_id_seq | sequence | demo_role
(4 rows)

Bây giờ ta có thể loại bỏ role "temporary_users" thành công bằng cách chạy lại lệnh:

DROP ROLE temporary_users;

Điều này sẽ hủy role temporary_users. Các thành viên cũ của temporary_users không bị xóa.

Kết luận

Đến đây bạn đã có các kỹ năng cơ bản cần thiết để quản trị quyền database PostgreSQL. Điều quan trọng là phải biết cách quản lý quyền để các ứng dụng của bạn có thể truy cập database mà ứng dụng cần, đồng thời không làm gián đoạn dữ liệu được sử dụng bởi các ứng dụng khác.


Tags:

Các tin trước

Lệnh truy vấn SQL trong postgresql sử dụng select 2013-08-02
Các lệnh truy cấn quản lý bảng dữ liệu trong postgresql trên cloud-server 2013-08-01
Bảo mật MySQL và MariaDB Databases trên Linux VPS 2013-07-23
Cài đặt Firewall với UFW trên Ubuntu và Debian Cloud Server 2013-06-25
Cơ bản nhất về MYSQL trên Ubuntu CentOS 2012-06-12