Postgres การนำแนวปฏิบัติที่ดีที่สุดไปปฏิบัติ


21

folks,

ฉันสามารถใช้ความช่วยเหลือของคุณเพื่อทำให้การออกแบบการควบคุมการเข้าถึงผู้ใช้ของ Postgres ดีขึ้นและสอดคล้องกับแนวปฏิบัติที่ดีที่สุด ฉันกำลังช่วยเซิร์ฟเวอร์ Postgres ขนาดเล็กที่ผลิตออกมา แต่ฉันไม่ใช่ผู้ดูแลระบบ DB ดังนั้นฉันรู้ว่าเพียงพอที่จะเป็นอันตราย

มีเซิร์ฟเวอร์เดียวที่ติดตั้ง Postgres v9.2 หนึ่งตัว การติดตั้งนี้จะโฮสต์ฐานข้อมูลหลายฐานโดยแต่ละแห่งจะให้บริการ "ลูกค้า" ที่แตกต่างกันอย่างสมบูรณ์ ในคำอื่น ๆ ลูกค้า 1 จะไม่ไม่ควรใช้ฐานข้อมูล 2 และอื่น ๆ ในระหว่างการดำเนินงานปกติฐานข้อมูลจะถูกเข้าถึงโดยอินสแตนซ์ที่ตรงกันของ CakePHP ซึ่งอยู่ร่วมกันบนเซิร์ฟเวอร์เดียวกันกับ Postgres แม้ว่าอาจมีการปรับให้เหมาะสมที่สุดสำหรับการปรับใช้นี้ แต่ฉันก็สนใจบทบาท Psql เป็นส่วนใหญ่

จากสิ่งที่ฉันอ่านดูเหมือนว่าบทบาทสามประเภทจะสมเหตุสมผล:

  • Superuser postgres ด้วยรหัสผ่านที่ไม่ใช่ค่าเริ่มต้น
  • บทบาทผู้ดูแลระบบที่ไม่มีสิทธิ์ superuser สำหรับการบำรุงรักษาตามปกติการสร้างฐานข้อมูลการสำรองข้อมูลการคืนค่า ควรจะสามารถทำอะไรกับฐานข้อมูลลูกค้าทั้งหมด
  • บทบาทของผู้ใช้ที่มีเพียงความสามารถในการ CRUD ในฐานข้อมูลนั้น ๆ สิทธิเพิ่มเติมเกี่ยวกับฐานข้อมูลของตนเองสามารถยอมรับได้หากการดำเนินการล้างข้อมูล

การนำการออกแบบไปใช้นั้นเป็นสิ่งที่ฉันมั่นใจน้อยมาก การเป็นเจ้าของฐานข้อมูล 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 แยกต่างหาก (เช่นบริการ) สำหรับลูกค้าแต่ละราย นี่คือสิ่งที่เราทำในขณะนี้สำหรับสภาพแวดล้อมการผลิตขนาดใหญ่ในขณะนี้และฉันจะไม่ทำมันแตกต่างกันเว้นแต่ว่าจำนวนของฐานข้อมูลจะใหญ่ขึ้นจริง ๆ และแต่ละคนก็จะน้อยมาก แน่นอนแอปพลิเคชันยังต้องทราบวิธีเชื่อมต่อกับแหล่งข้อมูลที่แตกต่างกันสำหรับผู้เช่าแต่ละราย (ลูกค้า)
Florin Asăvoaie

ข้าง @ FlorinAsăvoaieคำพูดของเขา ไม่ควรทุกฐานข้อมูลมีผู้ใช้เจ้าของและผู้ใช้แบบสอบถามของตัวเอง? สิ่งนี้จะทำให้ง่ายขึ้นในการทำให้ผู้ใช้บางคนอยู่ในห้องเก็บรหัสผ่านเพื่อวัตถุประสงค์ในการบำรุงรักษา
hspaans

คำตอบ:


5

ฉันรู้ว่านี่เป็นคำถามเก่า แต่ฉันจะพยายามตอบแม้ตอนนี้เนื่องจากฉันต้องทำวิจัยบางอย่างที่เกี่ยวข้องกับเรื่องนี้

สิ่งที่คุณพยายามทำเรียกว่าการครอบครองหลายระดับฐานข้อมูล สามารถทำได้สองวิธี:

  1. ในคลัสเตอร์ฐานข้อมูลเดียวว่า OP อธิบายได้อย่างไรตัวเลือกส่วนบุคคลของฉันจะเป็นเช่นนี้:

    • ผู้ใช้ postgres ใช้การรับรองความถูกต้องแบบเพียร์และไม่อนุญาตการเชื่อมต่อรหัสผ่าน การตรวจสอบ MD5 ในความคิดของฉันเป็นวิธีที่ไม่ดี หากคุณมีปัญหาเกี่ยวกับความสอดคล้องของฐานข้อมูลหรือสิ่งต่าง ๆ คุณจะยังสามารถเข้าสู่ระบบได้หากคุณให้ postgres ใช้ peer auth
    • ลูกค้าแต่ละรายควรได้รับสคีมาของตนเองไม่ใช่ฐานข้อมูล มีหลายเหตุผลสำหรับสิ่งนี้:
      • การเป็นเจ้าของฐานข้อมูลทั้งหมดจะให้สิทธิพิเศษมากมาย
      • การเป็นเจ้าของตารางที่เฉพาะเจาะจงจะทำให้เกิดปัญหาสำหรับนักพัฒนาและจะต้องขอให้ผู้ดูแลระบบเพิ่มสิทธิ์และเนื้อหา
      • ดังนั้นในการตั้งค่าปกติพวกเขาแต่ละคนจะสามารถเข้าถึงเพื่อสร้างสิ่งต่าง ๆ ภายในสคีมาของพวกเขารวมถึงตารางมุมมองทริกเกอร์ ฯลฯ
      • พวกเขาทั้งหมดใช้สายเชื่อมต่อเดียวกันยกเว้นชื่อผู้ใช้ ใน postgres โดยค่าเริ่มต้นหากคุณมีสคีมาที่มีชื่อผู้ใช้ของคุณมันจะอยู่ใน search_path ของคุณโดยอัตโนมัติ
    • ฉันจะเลือกที่จะไม่มีผู้ใช้ที่เป็นผู้ดูแลระบบที่สามารถเข้าถึงแต่ละสคีมาเป็นมาตรการรักษาความปลอดภัย คุณควรทำการสำรองข้อมูลโดยการทิ้งแต่ละ schema กับผู้ใช้ของตนเองหรือใช้เทคนิค PITR ของ PostgreSQL คุณยังคงต้องใช้ผู้ใช้ postgres เพื่อสร้างสกีมาใหม่ฉันจะใช้กฎ sudo และสคริปต์สำหรับสิ่งนั้น
    • แนวทางปฏิบัติด้านความปลอดภัยที่ดีหลายข้อแนะนำให้วางสคีมาเริ่มต้นไว้ - ไปเลย
    • โซลูชันนี้เหมาะสมอย่างยิ่งหากฐานข้อมูลสำหรับลูกค้าแต่ละรายมีขนาดเล็กและคุณมีลูกค้ามากมาย
    • หากแอปพลิเคชันของคุณจัดการกับการเช่าหลาย ๆ แอปนั้นสามารถใช้พูลการเชื่อมต่อเดียวสำหรับลูกค้าทั้งหมด แน่นอนว่านี่เป็นการกำจัดการปรับปรุงด้านความปลอดภัยหลายอย่างด้านบน แต่อาจมีประโยชน์ด้านประสิทธิภาพโดยเฉพาะอย่างยิ่งเมื่อคุณมีลูกค้าจำนวนมาก (ถ้าคุณมีแหล่งข้อมูลแยกกัน 500-1,000 รายการและคุณใช้การรวมการเชื่อมต่อ
  2. ลูกค้าแต่ละรายจะได้รับคลัสเตอร์ฐานข้อมูลของตนเอง นี่เป็นโซลูชันที่ฉันต้องการโดยเฉพาะอย่างยิ่งเพราะฉันมักจะทำงานกับแอปพลิเคชันที่มีฐานข้อมูลขนาดใหญ่ต่อลูกค้าแต่ละราย

    • อันนี้นำมาซึ่งการแยกข้อมูลที่ดีมาก คุณสามารถใช้โวลุ่มการเก็บข้อมูลแยกต่างหากสำหรับลูกค้าแต่ละรายจัดสรรซีพียูและข้อ จำกัด หน่วยความจำ (โดยใช้นักเทียบท่า?)
    • ความยืดหยุ่นที่ดีมากกับสิ่งที่ลูกค้าแต่ละรายต้องการในอินสแตนซ์ของพวกเขา พวกเขาอาจจะคล้ายกันหรือมีคุณสมบัติที่แตกต่าง
    • ง่ายมากที่จะขยายในทั้งสองทิศทาง (ขึ้นและออก)
    • ฉันยังใช้ IP เสมือนแยกต่างหากที่แต่ละคลัสเตอร์รับฟังการเชื่อมต่อทำให้ปรับขนาดได้โดยไม่ต้องการกำหนดค่าแหล่งข้อมูลใหม่
    • การสำรองข้อมูล PITR เป็นแบบต่อลูกค้าดังนั้นจึงง่ายต่อการกู้คืนลูกค้ารายเดียวเมื่อเปรียบเทียบกับการเช่าต่อหลายสคีมา
    • ในการตั้งค่าที่ซับซ้อนลูกค้าแต่ละรายอาจต้องการฐานข้อมูลหลายแบบแผนผู้ใช้และบทบาทเป็นต้นดังนั้นนี่จึงเป็นวิธีแก้ปัญหาที่ดีกว่าในกรณีเหล่านี้

คุณยังสามารถใช้การรวมกันของข้างต้นและใช้ pgBouncer เป็นเราเตอร์

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.