Blog Personal Inganta

Berbagi pengetahuan untuk memperkaya pemahaman

18 Oct 2020

Mengelola Akses Sebuah Postgres Kluster Menggunakan Peran

Banyak perusahaan rintisan teknologi yang tidak memiliki perekayasa dengan spesialis basis data. Tugas-tugas yang berhubungan dengan basis data dibagi kepada perekayasa yang ada seperti pengembang perangkat lunak, perekayasa infrastruktur, dan perekayasa keamanan. Ketiadaan spesialis basis data menyebabkan basis data dianggap sebagai komponen pendukung yang diharapkan dapat berjalan sendiri dengan investasi waktu dan sumber daya yang seadanya. Kondisi ini menyebabkan banyak yang bergantung pada layanan basis data yang disediakan oleh penyedia komputasi awan.

Salah satu layanan basis data yang siap digunakan pada layanan komputasi awan AWS adalah AWS Relational Database Service (RDS). AWS RDS menawarkan kemudahaan operasional database antara lain instalasi dengan konfigurasi yang telah disetel oleh ahli basis data AWS, pembuatan rekam cadang (backup) secara otomatis, dan kemudahaan pengaturan skalabilitas. AWS RDS mendukung berbagai jenis basis data relasional seperti MySQL, Microsoft SQL Server, dan Postgres. Selain itu basis data relasional pada AWS RDS bisa berjalan secara tunggal ataupun dalam bentuk kluster.

Salah satu basis data relasional yang menjadi pilihan pengembang perangkat lunak saat ini adalah Postgres. Pada artikel ini akan dijabarkan beberapa contoh pengelolaan peran pada basis data Postgres yang dijalankan pada AWS RDS.

Kepemilikan objek pada Postgres

Ada banyak jenis objek pada sebuah kluster basis data Postgres. Contoh objek yang dikenali secara umum adalah Database, Schema, Table, Function, and Sequence. Setiap objek pada Postgres mempunya pemilik. Pemilik suatu objek adalah peran (role) yang menciptakan objek tersebut. Kepemilikan objek pada Postgres bisa dipindahkan dari satu role ke role yang lain. Postgres tidak membedakan antara pengguna (user) atau grup (group). Keduanya diimplementasikan sebagai role pada Postgres. Postgres mensyaratkan hanya pemilik objek yang dapat menghapus objek tersebut.

Postgres pada AWS RDS

Pada saat pembuatan kluster Postgres pada RDS, kita diharuskan membuat master pengguna dan kata kunci untuk pengguna tersebut. Pengguna ini memiliki hak akses istimewa yang cukup tinggi tetapi bukan superuser. Keterbatasan ini menyebabkan Postgres AWS RDS tidak bisa digunakan pada kasus yang mengharuskan akses ke hak istimewa superuser. Koneksi jaringan menuju Postgres RDS dienkripsi menggunakan protokol keamanan TLS. Data yang tersimpan pada media penyimpanan bisa dienkripsi menggunakan layanan AWS Key Management Service (KMS). kedua fitur di atas memudahkan operator basis data untuk mematuhi aturan proteksi data dimana data harus terenkripsi baik pada saat pengiriman dan penyimpanan (encrypted in transit and at rest).

Mengelola akses terhadap Postgres menggunakan peran (role)

Akses ke basis data Postgres perlu dikelola dengan baik untuk menghindari hal-hal yang tidak diinginkan seperti kebocoran data atau penghapusan data secara tidak sengaja. Pengelolaan akses terhadap Postgres sebaiknya dilakukan dengan mengacu pada prinsip hak istimewa terkecil (principle of least privilege). Pengguna yang berwenang untuk memantau data diberikan akses secukupnya untuk membaca objek-objek yang diperlukan saja. Pada Postgres, prinsip hak istimewa terkecil ini dapat diimplementasikan menggunakan role dan GRANT. Postgres memiliki konvensi bahwa role yang tidak memiliki kata kunci digunakan untuk menyatakan pengguna dan role yang tidak memiliki kata kunci (sehingga tidak memungkin untuk login) sebagai grup. Berdasarkan pemakai peran, akun pada Postgres bisa dibagi menjadi 2 jenis. Mereka adalah akun basis data untuk perekayasa dan akun untuk aplikasi.

Berikut berbagai contoh penyusuan peran pada Postgres:

Akun aplikasi sebagai pemilik basis data

Ide besarnya adalah setiap basis data pada kluster Postgres dimiliki oleh masing-masing akun aplikasi. Pengguna yang membutuhkan akses baca tulis akan diberikan akses ke akun aplikasi melalui perintah GRANT. Untuk akses baca, dibuat satu group (role tanpa kata kunci) yang memiliki hak khusus baca. Setiap perekayasa yang membutuhkan akses baca akan dibuatkan akun baru dan diberi akses ke grup dengan hak istimewa baca di atas. Berikut langkah-langkah untuk implementasi contoh di atas:

  1. Masuk ke kluster Postgres menggunakan akun master.
  2. Buat akun database untuk aplikasi, CREATE USER <nama peran akun aplikasi> WITH ENCRYPTED PASSWORD <kata kunci akun aplikasi>;
  3. Buat basis data untuk aplikasi dan cabut seluruh akses ke basis data tersebut.
    CREATE DATABASE <nama basis data aplikasi> OWNER <nama peran akun aplikasi>;
    REVOKE CONNECT ON DATABASE <nama basis data aplikasi> FROM PUBLIC;
    
  4. Buat grup dengan hak istimewa baca terhadap basis data di atas.
    CREATE ROLE <nama peran khusus baca>;
    GRANT CONNECT ON DATABASE <nama basis data aplikasi> TO <nama peran khusus baca>;
    \c <nama basis data aplikasi>
    GRANT USAGE ON SCHEMA public TO <nama peran khusus baca>;
    # Perintah SQL di bawah perlu dieksekusi setiap kali ada ada objek baru yang dibuat pada basis data
    GRANT SELECT ON ALL TABLES IN SCHEMA public TO <nama peran khusus baca>;
    GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO <nama peran khusus baca>;
    
  5. Buat akun khusus baca untuk perekayasa.
    CREATE USER <nama akun khusus baca> WITH ENCRYPTED PASSWORD <kata kunci>;
    GRANT <nama peran khusus baca> TO <nama akun khusus baca>;
    

Pemisahan peran DML dan DDL

Perintah SQL bisa dibagi menjadi 2 bagian besar. Mereka adalah bahasa untuk mendefinisikan objek pada basis data (Data Definition Language / DDL) dan bahasa untuk memanipulasi data (Data Manipulation Language / DML). Pada contoh sebelumnya akun aplikasi memiliki hak istimewa terhadap kedua kelompok bahasa di atas. Kita bisa memperkecil hak istimewa akun aplikasi untuk fokus pada DML. Kemudian membuat peran baru untuk mengeksekusi perintah DDL.

Perintah DDL dan DML dengan resiko tinggi bisa dikelola secara terpisah dengan DML. Alur eksekusi yang berbeda untuk perintah DDL berguna untuk meningkatkan keamanan basis data. Hal ini juga memungkinkan untuk dilakukan audit yang lebih teliti terhadap perintah DDL. Selain itu pengecekan berlapis untuk perintah DML yang beresiko tinggi seperti penghapusan tabel ataupun seluruh data pada tabel baiknya dilakukan secara terpisah dari alur aplikasi. Hal ini untuk meminimalisasi kemungkinan terjadinya penghapusan data secara tidak sengaja.

Berikut implementasi pemisahan peran untuk DML dan DDL:

  1. Masuk ke kluster Postgres menggunakan akun master.
  2. Buat akun basis data dengan hak istimewa eksekusi perintah DDL.
    CREATE USER <peran DDL> WITH ENCRYPTED PASSWORD '<kata kunci akun DDL>';
    
  3. Buat basis data untuk aplikasi.
    CREATE DATABASE <nama basis data aplikasi> OWNER <peran DDL>;
    REVOKE CONNECT ON DATABASE <nama basis data aplikasi> FROM PUBLIC;
    
  4. Buat akun basis data untuk aplikasi.
    CREATE USER <akun aplikasi> WITH ENCRYPTED PASSWORD '<kata kunci akun aplikasi>';
    GRANT CONNECT ON DATABASE <nama basis data aplikasi> TO <akun aplikasi>;
    \c <nama basis data aplikasi>
    # Perintah SQL di bawah perlu dieksekusi setiap kali ada ada objek baru yang dibuat pada basis data
    GRANT USAGE ON SCHEMA public TO <akun aplikasi>;
    GRANT SELECT, INSERT, UPDATE, REFERENCES, TRIGGER ON ALL TABLES IN SCHEMA public TO <akun aplikasi>;
    GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO <akun aplikasi>;
    GRANT USAGE, SELECT, UPDATE ON ALL SEQUENCES IN SCHEMA public TO <akun aplikasi>;
    
  5. Buat grup dengan hak istimewa baca terhadap basis data di atas.
    CREATE ROLE <nama peran khusus baca>;
    GRANT CONNECT ON DATABASE <nama basis data aplikasi> TO <nama peran khusus baca>;
    \c <nama basis data aplikasi>
    GRANT USAGE ON SCHEMA public TO <nama peran khusus baca>;
    # Perintah SQL di bawah perlu dieksekusi setiap kali ada ada objek baru yang dibuat pada basis data
    GRANT SELECT ON ALL TABLES IN SCHEMA public TO <nama peran khusus baca>;
    GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO <nama peran khusus baca>;
    
  6. Buat akun khusus baca untuk perekayasa.
    CREATE USER <nama akun khusus baca> WITH ENCRYPTED PASSWORD <kata kunci>;
    GRANT <nama peran khusus baca> TO <nama akun khusus baca>;
    

Menggunakan akun IAM AWS untuk masuk kluster Postgres RDS

AWS RDS mendukung fitur masuk ke dalam kluster dengan menggunakan kredensial IAM sebagai metode autentikasi. Lebih tepatnya, kita bisa menggunakan fitur autentikasi IAM untuk mendapatkan kata kunci untuk masuk ke kluster Postgres RDS. Fitur ini bisa diaktifkan melalui konsol web RDS ataupun antarmuka baris perintah AWS. Jika melalui konsol web RDS, opsi ini bisa dilihat pada opsi Password and IAM database authentication pada bagian Database authentication ketika memodifikasi basis data.

Berikut langkah-langkah yang diperlukan untuk mengkonfigurasi autentikasi basis data menggunakan IAM.

  1. Buat kebijakan IAM untuk autentikasi basis data. Berikut contoh menggunakan terraform.
    locals {
        region = "" # Wilayah AWS dimana basis data RDS berada
        account_id = "" # ID akun AWS
        db_resource_id = "" # Resource ID dari database. Unik per wilayah AWS dan nilainya tetap
        db_user = "" # Akun basis data yang akan dihubungkan dengan akun IAM
    }
    
    data "aws_iam_policy_document" "iam_database_access" {
        statement {
            actions = ["rds-db:connect"]
            resources = ["arn:aws:rds-db:${local.region}:${local.account_id}:dbuser:${local.db_resource_id}/${local.db_user}"]
        }
    }
    
  2. Buat akun basis data.
    1. Masuk ke kluster Postgres menggunakan akun master
    2. Buat akun basis data dan hubungan dengan IAM
      CREATE USER <akun basis data>;
      GRANT rds_iam TO <akun basis data>;
      
  3. Konek mengggunakan psql dan antarmuka baris perintah AWS.
    export RDSHOST="<alamat RDS Postgres>"
    export PGPASSWORD="$(aws rds generate-db-auth-token --hostname $RDSHOST --port 5432 --region <wilayah RDS Postgres> --username <akun basis data> )"
    psql -h $RDSHOST -U <akun basis data> <nama basis data aplikasi>
    

Kesimpulan

AWS RDS adalah layanan yang menarik digunakan untuk mengelola basis data relasional. Layanan ini memudahkan pengelola basis data untuk melakukan instalasi, penyetelan ahli, dan pembuatan rekam cadang otomatis. Fitur enkripsi pada jaringan dan media penyimpanan meningkat keamanan data yang tersimpan pada basis data RDS. Pada artikel dijelaskan beberapa contoh struktur yang bisa digunakan untuk membantu pengelolaan akses terhadap kluster Postgres. Akses terhadap kluster Postgres tersebut bisa diatur secara fleksible dengan bantuan role dan GRANT. Autentikasi basis data menggunakan IAM mengurangi beban kerja administrator basis data dalam mengelola kata kunci untuk pengguna dengan memanfaatkan akun AWS IAM.