Việc sử dụng CẤP PHÉP TRÊN SCHEMA chính xác là gì?


121

Tôi đang cố gắng tạo cơ sở dữ liệu Postgres lần đầu tiên, vì vậy đây có lẽ là một câu hỏi ngu ngốc. Tôi đã chỉ định các quyền chỉ đọc cơ bản cho vai trò db phải truy cập cơ sở dữ liệu từ các tập lệnh php của tôi và tôi có một sự tò mò: nếu tôi thực thi

GRANT some_or_all_privileges ON ALL TABLES IN SCHEMA schema TO role;

có cần phải thực hiện không

GRANT USAGE ON SCHEMA schema TO role;

?

Từ tài liệu :

CÔNG DỤNG: Đối với các lược đồ, cho phép truy cập vào các đối tượng có trong lược đồ được chỉ định (giả sử rằng các yêu cầu đặc quyền riêng của đối tượng cũng được đáp ứng). Về cơ bản, điều này cho phép người được cấp quyền "tra cứu" các đối tượng trong lược đồ.

Tôi nghĩ rằng nếu tôi có thể chọn hoặc thao tác bất kỳ dữ liệu nào có trong lược đồ, tôi có thể truy cập vào bất kỳ đối tượng nào của chính lược đồ đó. Liệu tôi có sai? Nếu không, GRANT USAGE ON SCHEMAthì dùng để làm gì? Và tài liệu có ý nghĩa chính xác gì với "giả sử rằng các yêu cầu đặc quyền riêng của đối tượng cũng được đáp ứng"?

Câu trả lời:


126

GRANTs trên các đối tượng khác nhau là riêng biệt. GRANTnhập vào cơ sở dữ liệu không có GRANTquyền đối với lược đồ bên trong. Similiarly,GRANT việc nhập vào một lược đồ không cấp quyền cho các bảng bên trong.

Nếu bạn có quyền SELECTtừ một bảng, nhưng không có quyền xem nó trong lược đồ chứa nó thì bạn không thể truy cập vào bảng.

Các bài kiểm tra quyền được thực hiện theo thứ tự:

Do you have `USAGE` on the schema? 
    No:  Reject access. 
    Yes: Do you also have the appropriate rights on the table? 
        No:  Reject access. 
        Yes: Check column privileges.

Sự nhầm lẫn của bạn có thể phát sinh từ thực tế là publiclược đồ có mặc định GRANTlà tất cả các quyền đối với vai trò publicmà mọi người dùng / nhóm đều là thành viên. Vì vậy, mọi người đã có cách sử dụng trên lược đồ đó.

Cụm từ:

(giả sử rằng các yêu cầu đặc quyền riêng của đối tượng cũng được đáp ứng)

Đang nói rằng bạn phải có USAGEtrên một lược đồ để sử dụng các đối tượng bên trong nó, nhưng cóUSAGE trên một lược đồ tự nó không đủ để sử dụng các đối tượng trong lược đồ, bạn cũng phải có quyền đối với chính các đối tượng đó.

Nó giống như một cây thư mục. Nếu bạn tạo một thư mục somedirvới tệp somefilebên trong nó, sau đó đặt nó để chỉ người dùng của bạn mới có thể truy cập vào thư mục hoặc tệp (chế độ rwx------trên dir, chế độ rw-------trên tệp) thì không ai khác có thể liệt kê thư mục để xem tệp tồn tại.

Nếu bạn cấp quyền đọc trên toàn thế giới đối với tệp (chế độ rw-r--r--) nhưng không thay đổi quyền đối với thư mục thì điều đó không có gì khác biệt. Không ai có thể nhìn thấy tệp để đọc nó, bởi vì họ không có quyền liệt kê thư mục.

Thay vào đó, nếu bạn đặt rwx-r-xr-xtrên thư mục, đặt nó để mọi người có thể liệt kê và xem qua thư mục nhưng không thay đổi quyền đối với tệp, mọi người có thể liệt kê tệp nhưng không thể đọc được vì họ không có quyền truy cập vào tệp.

Bạn cần đặt cả hai quyền để mọi người thực sự có thể xem tệp.

Điều tương tự trong Pg. Bạn cần cả USAGEquyền lược đồ và quyền đối tượng để thực hiện một hành động trên một đối tượng, chẳng hạn như SELECTtừ một bảng.

(Sự tương tự giảm xuống một chút là PostgreSQL chưa có bảo mật cấp hàng, vì vậy người dùng vẫn có thể "thấy" rằng bảng tồn tại trong lược đồ bằng cách nhập trực tiếp SELECTtừ đó pg_class. Họ không thể tương tác với nó theo bất kỳ cách nào Tuy nhiên, vì vậy nó chỉ là phần "danh sách" không hoàn toàn giống nhau.)


2
Bây giờ nó rất rõ ràng với ví dụ thư mục :) Tôi phải nói rằng đây là một vấn đề nếu bạn chèn một số bảng hoặc hàng với superuser, ví dụ như khi bạn thêm postGIS bằng cách sử dụng CREATE EXTENSION. Nó ít nhiều là vấn đề tương tự với các tệp được tạo trên Linux khi bạn đang sử dụng su. Sẽ rất tốt nếu có một loại sudo -ecâu lệnh for trong pqsl.
Marco Sulla

Dù sao thì bây giờ tôi đã nhận ra rằng các GRANTcâu lệnh không cụ thể cho các bảng không phải là điều tôi muốn, vì chúng ảnh hưởng đến tất cả cơ sở dữ liệu ...: s
Marco Sulla

1
@LucasMalor Er ... không, họ không. GRANTtrên một lược đồ ảnh hưởng đến lược đồ đó. GRANT ... ON ALL TABLES IN SCHEMA ...ảnh hưởng đến tất cả các bảng trong một lược đồ trong một cơ sở dữ liệu cụ thể. Không có GRANTs nào ảnh hưởng đến tất cả cơ sở dữ liệu (ok, ngoại trừ việc nhập GRANTvai trò thành viên cho người dùng).
Craig Ringer

Xin lỗi, tôi đã thực thi các câu lệnh khi đăng nhập là superuser "postgres" và chúng ảnh hưởng đến cơ sở dữ liệu "postgres". Tôi nghĩ rằng nếu bạn chạy psqlmà không có -d dbbạn đang hoạt động "bên ngoài" bất kỳ db nào, nhưng bạn luôn được kết nối với một db và theo mặc định, bạn được kết nối với db có cùng tên vai trò của bạn. db = role = user = group ... hơi khó hiểu: D
Marco Sulla

@LucasMalor Hãy nghĩ về nó theo cách này. Theo mặc định, bạn kết nối với một DB có cùng tên với vai trò đăng nhập ("người dùng") mà bạn kết nối. "Người dùng" chỉ là vai trò có WITH LOGIN; về cơ bản, tất cả những gì có thể là một nhóm, và nhóm có thể được thiết lập để có thể đăng nhập.
Craig Ringer

72

Đối với hệ thống sản xuất, bạn có thể sử dụng cấu hình này:

--ACCESS DB
REVOKE CONNECT ON DATABASE nova FROM PUBLIC;
GRANT  CONNECT ON DATABASE nova  TO user;

--ACCESS SCHEMA
REVOKE ALL     ON SCHEMA public FROM PUBLIC;
GRANT  USAGE   ON SCHEMA public  TO user;

--ACCESS TABLES
REVOKE ALL ON ALL TABLES IN SCHEMA public FROM PUBLIC ;
GRANT SELECT                         ON ALL TABLES IN SCHEMA public TO read_only ;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO read_write ;
GRANT ALL                            ON ALL TABLES IN SCHEMA public TO admin ;

adminCũng không nên được cấp CREATEtrên lược đồ?
Dan

2
Quyền truy cập được phân bổ theo mô hình phân cấp: BD -> SCHEMA -> TABLES . Với GRANT USAGE ON SCHEMA, người dùng quản trị không thể tạo bảng nhưng anh ta có thể làm điều đó với ALL GRANT ALL ON SCHEMA....
bilelovitch

@bilelovitch: ý bạn là grant all on schema public to admin? Tái bút: Tôi cũng đã thêm grant usage, select on all sequences in schema public to read_only/read_write; grant execute on all functions in schema public to read_only/read_write;
Marco Sulla,

2

Đây là giải pháp cuối cùng của tôi cho một db đơn giản, dành cho Linux:

# Read this before!
#
# * roles in postgres are users, and can be used also as group of users
# * $ROLE_LOCAL will be the user that access the db for maintenance and
#   administration. $ROLE_REMOTE will be the user that access the db from the webapp
# * you have to change '$ROLE_LOCAL', '$ROLE_REMOTE' and '$DB'
#   strings with your desired names
# * it's preferable that $ROLE_LOCAL == $DB

#-------------------------------------------------------------------------------

//----------- SKIP THIS PART UNTIL POSTGRES JDBC ADDS SCRAM - START ----------//

cd /etc/postgresql/$VERSION/main
sudo cp pg_hba.conf pg_hba.conf_bak
sudo -e pg_hba.conf

# change all `md5` with `scram-sha-256`
# save and exit

//------------ SKIP THIS PART UNTIL POSTGRES JDBC ADDS SCRAM - END -----------//

sudo -u postgres psql

# in psql:
create role $ROLE_LOCAL login createdb;
\password $ROLE_LOCAL
create role $ROLE_REMOTE login;
\password $ROLE_REMOTE

create database $DB owner $ROLE_LOCAL encoding "utf8";
\connect $DB $ROLE_LOCAL

# Create all tables and objects, and after that:

\connect $DB postgres

revoke connect on database $DB from public;
revoke all on schema public from public;
revoke all on all tables in schema public from public;

grant connect on database $DB to $ROLE_LOCAL;
grant all on schema public to $ROLE_LOCAL;
grant all on all tables in schema public to $ROLE_LOCAL;
grant all on all sequences in schema public to $ROLE_LOCAL;
grant all on all functions in schema public to $ROLE_LOCAL;

grant connect on database $DB to $ROLE_REMOTE;
grant usage on schema public to $ROLE_REMOTE;
grant select, insert, update, delete on all tables in schema public to $ROLE_REMOTE;
grant usage, select on all sequences in schema public to $ROLE_REMOTE;
grant execute on all functions in schema public to $ROLE_REMOTE;

alter default privileges for role $ROLE_LOCAL in schema public
    grant all on tables to $ROLE_LOCAL;

alter default privileges for role $ROLE_LOCAL in schema public
    grant all on sequences to $ROLE_LOCAL;

alter default privileges for role $ROLE_LOCAL in schema public
    grant all on functions to $ROLE_LOCAL;

alter default privileges for role $ROLE_REMOTE in schema public
    grant select, insert, update, delete on tables to $ROLE_REMOTE;

alter default privileges for role $ROLE_REMOTE in schema public
    grant usage, select on sequences to $ROLE_REMOTE;

alter default privileges for role $ROLE_REMOTE in schema public
    grant execute on functions to $ROLE_REMOTE;

# CTRL+D

1
Người dùng nào phải được sử dụng cho "# Tạo tất cả các bảng và đối tượng, và sau đó:"? Ai là chủ nhân của những chiếc bàn và những đồ vật khác trong trường hợp của bạn?
Christophe Furmaniak

@ChristopheFurmaniak, bạn nói đúng, tôi đã sửa quy trình. Chủ sở hữu của db và các đối tượng của nó là $ ROLE_LOCAL và sau khi tạo cấu trúc db, chúng ta phải quay lại postgres superuser.
Marco Sulla

Tôi tin rằng bạn gặp sự cố trong lệnh "ALTER DEFAULT PRIVILEGES ..." của mình. Lệnh này được sử dụng để kích hoạt cấp đặc quyền cho một người dùng (vai trò) khi một người dùng (vai trò) khác tạo một đối tượng. Xem trang 11, phần 7.1, của tài liệu này để làm rõ. Hiện tại ROLE_REMOTE của bạn sẽ không có quyền truy cập vào bất kỳ đối tượng nào mà ROLE_LOCAL sẽ tạo. Các lệnh ROLE_LOCAL chỉ cung cấp các priv mà vai trò đã có với tư cách là Chủ sở hữu của các đối tượng đó. Tương tự với các lệnh ROLE_REMOTE.
emispowder
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.