Postgres thực hiện tốt nhất thực hành


21

Mọi người,

Tôi có thể sử dụng trợ giúp của bạn để làm cho thiết kế kiểm soát truy cập người dùng Postgres của tôi tốt hơn và phù hợp hơn với các thực tiễn tốt nhất. Tôi đang giúp triển khai một máy chủ Postgres sản xuất nhỏ nhưng tôi không phải là quản trị viên DB, vì vậy tôi biết chỉ cần đủ nguy hiểm.

Có một máy chủ với một lần cài đặt Postgres v9.2. Cài đặt này lưu trữ nhiều cơ sở dữ liệu, mỗi cơ sở phục vụ đầy đủ một "khách hàng" khác nhau. Nói cách khác, customer1 sẽ không, không nên sử dụng cơ sở dữ liệu2, v.v. Trong các hoạt động bình thường, các cơ sở dữ liệu được truy cập bởi một phiên bản trùng khớp của CakePHP, tất cả cùng nằm trên cùng một máy chủ với Postgres. Mặc dù có thể có tối ưu hóa có thể có trong triển khai này, nhưng tôi chủ yếu quan tâm đến vai trò của Psql.

Dựa trên những gì tôi đọc, có vẻ như ba loại vai trò sẽ có ý nghĩa:

  • Superuser postgres với mật khẩu không mặc định
  • Vai trò quản trị viên không có đặc quyền siêu người dùng để bảo trì định kỳ, tạo DB, sao lưu, khôi phục. Có thể làm bất cứ điều gì với tất cả các cơ sở dữ liệu khách hàng.
  • Vai trò người dùng chỉ với khả năng CRUD trong cơ sở dữ liệu tương ứng của họ. Nhiều quyền hơn trên DB riêng của họ có thể được dung thứ nếu nó làm sạch việc thực hiện.

Thực hiện thiết kế đó là nơi tôi kém tự tin hơn nhiều. Quyền sở hữu của DB so với bảng và cũng như ai nên thừa hưởng từ người hơi lầy lội. Dưới đây là cơ sở dữ liệu của tôi và người dùng của tôi. Là đủ thông tin để đánh giá việc thực hiện?

     Role name |                   Attributes                   |     Member of     
    -----------+------------------------------------------------+-------------------
     admin     | Create role, Create DB                         | {user1, user2}
     postgres  | Superuser, Create role, Create DB              | {}
     user1     |                                                | {}
     user2     |                                                | {}

    postgres=# \l
                                 List of databases
       Name    |  Owner   | Encoding | Collate | Ctype |   Access privileges   
    -----------+----------+----------+---------+-------+-----------------------
     admin     | postgres | UTF8     | en_US   | en_US | =Tc/postgres         +
               |          |          |         |       | postgres=CTc/postgres+
               |          |          |         |       | admin=CTc/postgres
     postgres  | postgres | UTF8     | en_US   | en_US | 
     template0 | postgres | UTF8     | en_US   | en_US | =c/postgres          +
               |          |          |         |       | postgres=CTc/postgres
     template1 | postgres | UTF8     | en_US   | en_US | =c/postgres          +
               |          |          |         |       | postgres=CTc/postgres
     user1     | admin    | UTF8     | en_US   | en_US | =Tc/admin            +
               |          |          |         |       | admin=CTc/admin      +
               |          |          |         |       | user1=CTc/admin
     user2     | admin    | UTF8     | en_US   | en_US | =Tc/admin            +
               |          |          |         |       | admin=CTc/admin      +
               |          |          |         |       | user2=CTc/admin

Để ngăn chặn các kết nối bên ngoài và mật khẩu rõ ràng, pg_hba.conf là như sau:

local   all             all                                     md5
host    all             all             127.0.0.1/32            md5
host    all             all             ::1/128                 md5

1
Theo kinh nghiệm của tôi, sự tách biệt tốt nhất cũng mang lại một lượng lớn lợi thế khác là chạy các cụm PostGreQuery riêng biệt (ví dụ: dịch vụ) cho mỗi khách hàng. Đây là những gì chúng tôi hiện đang làm cho một môi trường sản xuất lớn ngay bây giờ và tôi sẽ không làm điều đó khác đi trừ khi số lượng DB sẽ trở nên rất lớn và mỗi trong số chúng sẽ rất nhỏ. Tất nhiên, ứng dụng cũng cần biết cách kết nối với một nguồn dữ liệu khác nhau cho mỗi người thuê (khách hàng).
Florin Asăvoaie

Bên cạnh @ FlorinAsăvoaie nhận xét của mình. Không phải mọi cơ sở dữ liệu đều có người dùng chủ sở hữu và người dùng truy vấn riêng? Điều này sẽ giúp việc đưa một số người dùng vào kho mật khẩu dễ dàng hơn cho mục đích bảo trì.
hspaans

Câu trả lời:


5

Tôi biết đây là một câu hỏi cũ nhưng tôi sẽ cố gắng trả lời ngay cả bây giờ, vì tôi phải thực hiện một số nghiên cứu liên quan đến vấn đề này.

Những gì bạn đang cố gắng làm được gọi là đa thuê nhà ở cấp cơ sở dữ liệu. Điều này có thể đạt được theo hai cách:

  1. Tuy nhiên, trong một cụm cơ sở dữ liệu, phần nào cách OP mô tả, tuy nhiên, lựa chọn cá nhân của tôi sẽ là:

    • người dùng postgres sử dụng xác thực ngang hàng và không được phép kết nối mật khẩu. Xác thực MD5, theo tôi, là một thực tiễn tồi. Nếu bạn gặp bất kỳ rắc rối nào với tính nhất quán của cơ sở dữ liệu hoặc loại điều này, bạn vẫn có thể đăng nhập nếu bạn để người đăng sử dụng auth ngang hàng.
    • Mỗi khách hàng nên có lược đồ riêng của họ và không phải cơ sở dữ liệu. Có nhiều lý do cho việc này:
      • Sở hữu toàn bộ cơ sở dữ liệu sẽ cấp rất nhiều đặc quyền.
      • Chỉ sở hữu các bảng cụ thể sẽ mang lại sự cố cho nhà phát triển và luôn yêu cầu quản trị viên thêm quyền và nội dung.
      • Như vậy, trong một thiết lập bình thường, mỗi người trong số họ sẽ có quyền truy cập để tạo ra những thứ bên trong lược đồ của họ, bao gồm các bảng, dạng xem, trình kích hoạt, v.v.
      • Tất cả đều sử dụng cùng một chuỗi kết nối ngoại trừ tên người dùng. Trong postgres, theo mặc định, nếu bạn có một lược đồ với tên người dùng của bạn, nó sẽ tự động trong search_path của bạn.
    • Tôi sẽ chọn không có người dùng quản trị viên có thể truy cập từng lược đồ, như một biện pháp bảo mật. Bạn nên thực hiện sao lưu bằng cách kết xuất từng lược đồ với người dùng của riêng họ hoặc sử dụng kỹ thuật PITR của PostgreQuery. Bạn vẫn sẽ cần sử dụng người dùng postgres để tạo các lược đồ mới, tôi sẽ sử dụng quy tắc sudo và tập lệnh cho điều đó.
    • Nhiều thực tiễn bảo mật tốt khuyên bạn nên bỏ lược đồ mặc định - vì vậy chúng tôi đi.
    • Giải pháp này cực kỳ phù hợp nếu DB cho mỗi khách hàng nhỏ và bạn có hàng tấn khách hàng.
    • Nếu ứng dụng của bạn xử lý nhiều khách thuê, nó có thể sử dụng một nhóm kết nối duy nhất cho tất cả khách hàng. Tất nhiên, điều này giúp loại bỏ nhiều cải tiến bảo mật ở trên nhưng có thể mang lại lợi ích về hiệu suất, đặc biệt khi bạn có số lượng khách hàng lớn (nếu bạn có 500-1000 nguồn dữ liệu riêng biệt và bạn sử dụng kết nối dữ liệu, nó sẽ khá áp đảo).
  2. Mỗi khách hàng có cụm cơ sở dữ liệu riêng của họ. Đây là giải pháp ưa thích của tôi đặc biệt vì tôi thường làm việc với các ứng dụng có cơ sở dữ liệu lớn cho mỗi khách hàng.

    • Điều này mang lại sự phân tách dữ liệu rất tốt. Bạn có thể sử dụng dung lượng lưu trữ riêng cho từng khách hàng, phân bổ giới hạn CPU và Bộ nhớ (sử dụng docker?).
    • Thực sự linh hoạt tốt về những gì mỗi khách hàng cần trong ví dụ của họ. Chúng có thể giống nhau hoặc có các tính năng riêng biệt.
    • Rất dễ dàng để mở rộng quy mô trên cả hai hướng (lên và ra).
    • Tôi cũng sử dụng các IP ảo riêng biệt trong đó mỗi cụm lắng nghe các kết nối, làm cho việc mở rộng quy mô thành không cần cấu hình lại nguồn dữ liệu.
    • Các bản sao lưu PITR là cho mỗi khách hàng, do đó, việc khôi phục một khách hàng sẽ dễ dàng hơn so với việc thuê nhiều lược đồ.
    • Trên các thiết lập phức tạp, mỗi khách hàng có thể cần nhiều cơ sở dữ liệu, lược đồ, người dùng và vai trò, v.v. vì vậy đây là cách giải quyết tốt hơn trong những trường hợp đó.

Bạn cũng có thể sử dụng kết hợp các mục trên và sử dụng pgBouncer làm bộ định tuyến.

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.