Postgres 역할 모범 사례 구현


21

사람들,

Postgres 사용자 액세스 제어 설계를 모범 사례에 더 적합하고 잘 맞출 수 있도록 귀하의 도움을 사용할 수 있습니다. 소규모 프로덕션 Postgres 서버를 출시하는 데 도움을 주지만 DB 관리자는 아니므로 위험 할 정도로 충분히 알고 있습니다.

Postgres v9.2를 한 번 설치 한 서버가 하나 있습니다. 이 설치는 각각 다른 "고객"을 제공하는 여러 데이터베이스를 호스팅합니다. 즉, customer1은 database2 등을 사용하지 않아야합니다. 정상적인 작업 동안 데이터베이스는 각각 CakePHP의 일치하는 인스턴스에 의해 액세스되며 각각 Postgres와 동일한 서버에 있습니다. 이 배포에는 최적화가 가능하지만 Psql 역할에 관심이 많습니다.

내가 읽은 것을 기준으로 세 가지 유형의 역할이 의미가있는 것 같습니다.

  • 기본 비밀번호가 아닌 수퍼 유저 postgres
  • 일상적인 유지 관리, DB 생성, 백업, 복원에 대한 수퍼 유저 권한이없는 관리자 역할. 모든 고객 데이터베이스로 무엇이든 할 수 있어야합니다.
  • 해당 데이터베이스에서 CRUD 기능 만있는 사용자 역할 구현을 정리하면 자체 DB에 대한 더 많은 권한을 견딜 수 있습니다.

그 디자인을 구현하는 것은 내가 덜 확신하는 곳입니다. DB 대 테이블의 소유권과 누가 누구로부터 물려 받아야 하는가. 아래는 내 데이터베이스와 사용자입니다. 구현을 평가하기에 충분한 정보입니까?

     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

외부 연결 및 암호를 명확하게 방지하기 위해 pg_hba.conf는 다음과 같습니다.

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

1
필자의 경험에 따르면, 다른 많은 이점을 제공하는 최상의 분리는 각 고객에 대해 별도의 PostGreSQL 클러스터 (예 : 서비스)를 실행하는 것입니다. 이것은 현재 대규모 프로덕션 환경에서 수행하는 작업이며 DB 수가 실제로 커지고 각 데이터베이스가 작지 않으면 다르게 수행하지 않을 것입니다. 물론 애플리케이션은 각 테넌트 (고객)마다 다른 데이터 소스에 연결하는 방법도 알아야합니다.
Florin Asăvoaie

@ FlorinAsăvoaie 그의 말 외에. 모든 데이터베이스에 자체 소유자 사용자 및 쿼리 사용자가 없어야합니까? 따라서 유지 관리 목적으로 특정 사용자를 암호 저장소에 쉽게 넣을 수 있습니다.
hspaans

답변:


5

나는 이것이 오래된 질문이라는 것을 알고 있지만 이것과 관련된 연구를해야하기 때문에 지금도 대답하려고 노력할 것입니다.

당신이 할하려는 것은이라고 멀티 테넌시 (multi-tenancy) 데이터베이스 수준에서. 이는 두 가지 방법으로 달성 할 수 있습니다.

  1. 그러나 단일 데이터베이스 클러스터에서 OP가 어떻게 설명했는지, 개인적 선택은 다음과 같습니다.

    • postgres 사용자는 피어 인증을 사용하며 비밀번호 연결이 허용되지 않습니다. 내 생각에 MD5 인증은 나쁜 습관입니다. 데이터베이스 일관성이나 이런 종류의 문제로 인해 문제가 발생하더라도 postgres가 피어 인증을 사용하도록 허용하면 로그인 할 수 있습니다.
    • 각 고객은 데이터베이스가 아닌 자체 스키마를 가져와야 합니다. 이에 대한 여러 가지 이유가 있습니다.
      • 전체 데이터베이스를 소유하면 많은 권한이 부여됩니다.
      • 특정 테이블 만 소유하면 개발자에게 문제가 발생하며 항상 관리자에게 권한 및 항목 추가를 요청해야합니다.
      • 따라서 일반 설정에서는 각각 테이블, 뷰, 트리거 등 스키마 내부에 항목을 작성할 수 있습니다.
      • 모두 사용자 이름을 제외하고 동일한 연결 문자열을 사용합니다. postgres에서 기본적으로 사용자 이름을 가진 스키마가있는 경우 자동으로 search_path에 있습니다.
    • 보안 조치로 각 스키마에 액세스 할 수있는 관리자가없는 것을 선택했습니다. 각 스키마를 자신의 사용자로 덤프하거나 PostgreSQL의 PITR 기술을 사용하여 백업을 수행해야합니다. 여전히 postgres 사용자를 사용하여 새 스키마를 만들어야합니다. sudo 규칙과 스크립트를 사용하겠습니다.
    • 많은 보안 모범 사례에서는 기본 스키마를 삭제하는 것이 좋습니다.
    • 이 솔루션은 각 고객의 DB가 작고 많은 고객이있는 경우에 매우 적합합니다.
    • 애플리케이션이 다중 테넌시를 처리하는 경우 모든 고객에 대해 단일 연결 풀을 사용할 수 있습니다. 물론 이렇게하면 위의 많은 보안 향상 기능이 제거되지만 특히 많은 고객이있는 경우 (500-1000 개의 별도 데이터 원본이 있고 연결 풀링을 사용하는 경우 상당히 압도적 임) 성능상의 이점이있을 수 있습니다.
  2. 각 고객은 자신의 데이터베이스 클러스터를 얻습니다. 이것은 일반적으로 각 고객 당 큰 데이터베이스가있는 응용 프로그램으로 작업하기 때문에 선호하는 솔루션입니다.

    • 이것은 매우 우수한 데이터 분리를 제공합니다. 각 고객에 대해 별도의 스토리지 볼륨을 사용하고 CPU 및 메모리 제한을 할당 할 수 있습니다 (Docker 사용).
    • 각 고객이 필요로하는 것에 대한 유연성이 뛰어납니다. 그것들은 비슷하거나 특징이있을 수 있습니다.
    • 양방향으로 (확장 및 축소) 확장이 매우 쉽습니다.
    • 또한 각 클러스터가 연결을 수신하는 별도의 가상 IP를 사용하므로 데이터 소스를 재구성 할 필요가 없도록 확장 할 수 있습니다.
    • PITR 백업은 고객별로 이루어 지므로 스키마 별 다중 테넌시에 비해 단일 고객을보다 쉽게 ​​복원 할 수 있습니다.
    • 복잡한 설정에서 각 고객은 여러 데이터베이스, 스키마, 사용자 및 역할 등이 필요할 수 있으므로 이러한 경우 더 나은 솔루션입니다.

위의 조합을 사용하고 pgBouncer를 라우터로 사용할 수도 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.