Postgresロールのベストプラクティスの実装


21

皆さん、

Postgresのユーザーアクセス制御の設計を改善し、ベストプラクティスに沿ったものにするために、あなたの助けを借りることができます。私は小規模な実稼働Postgresサーバーの展開を手伝っていますが、私はDB管理者ではないので、危険になるのに十分なことを知っています。

Postgres v9.2のインストールが1つあるサーバーが1つあります。このインストールは複数のデータベースをホストし、それぞれが異なる「顧客」に完全にサービスを提供します。つまり、customer1はdatabase2を使用しない、使用しないなどです。通常の操作中、データベースはそれぞれ、Postgresと同じサーバーに共存するCakePHPの一致するインスタンスによってアクセスされます。この展開には最適化が考えられますが、私は主にPsqlロールに興味があります。

私が読んだものに基づいて、次の3つのタイプの役割が理にかなっているようです。

  • デフォルト以外のパスワードを持つスーパーユーザー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の数が実際に大きくなり、それぞれが実際に少なくならない限り、私はこれを変更しません。もちろん、アプリケーションは、テナント(顧客)ごとに異なるデータソースに接続する方法を知る必要もあります。
フローリンAsăvoaie15年

@FlorinAsăvoaieのほかに彼の発言。すべてのデータベースに独自の所有者ユーザーとクエリユーザーを含めるべきではありませんか?これにより、メンテナンスのために特定のユーザーをパスワードボールトに入れることが容易になります。
hspaans

回答:


5

これは古い質問であることは知っていますが、これに関連する調査を行うようになったので、今でも答えようとします。

あなたがやろうとしていることは、データベースレベルでのマルチテナンシーと呼ばれます。これは2つの方法で実現できます。

  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.