Keamanan dan DBMS: apa yang perlu Anda ingat ketika memilih alat keamanan

Keamanan dan DBMS: apa yang perlu Anda ingat ketika memilih alat keamanan

Nama saya Denis Rozhkov, saya kepala pengembangan perangkat lunak di perusahaan Gazinformservice, di tim produk Jatoba. Perundang-undangan dan peraturan perusahaan memberlakukan persyaratan tertentu untuk keamanan penyimpanan data. Tidak ada seorang pun yang ingin pihak ketiga mendapatkan akses ke informasi rahasia, jadi isu-isu berikut ini penting untuk proyek apa pun: identifikasi dan otentikasi, mengelola akses ke data, memastikan integritas informasi dalam sistem, mencatat peristiwa keamanan. Oleh karena itu, saya ingin membicarakan beberapa poin menarik mengenai keamanan DBMS.

Artikel ini disusun berdasarkan pidato di @DatabasesMeetup, terorganisir Solusi Cloud Mail.ru. Jika Anda tidak ingin membaca, Anda dapat menonton:


Artikel ini akan terdiri dari tiga bagian:

  • Cara mengamankan koneksi.
  • Apa yang dimaksud dengan audit tindakan dan bagaimana mencatat apa yang terjadi di sisi database dan menghubungkannya.
  • Bagaimana melindungi data dalam database itu sendiri dan teknologi apa yang tersedia untuk ini.

Keamanan dan DBMS: apa yang perlu Anda ingat ketika memilih alat keamanan
Tiga komponen keamanan DBMS: perlindungan koneksi, audit aktivitas, dan perlindungan data

Mengamankan koneksi Anda

Anda dapat terhubung ke database baik secara langsung atau tidak langsung melalui aplikasi web. Biasanya, pengguna bisnis, yaitu orang yang bekerja dengan DBMS, berinteraksi dengannya secara tidak langsung.

Sebelum berbicara tentang perlindungan koneksi, Anda perlu menjawab pertanyaan penting yang menentukan bagaimana langkah-langkah keamanan akan disusun:

  • Apakah satu pengguna bisnis setara dengan satu pengguna DBMS?
  • apakah akses ke data DBMS disediakan hanya melalui API yang Anda kendalikan, atau apakah tabel diakses secara langsung;
  • apakah DBMS dialokasikan ke segmen terlindungi yang terpisah, siapa yang berinteraksi dengannya dan bagaimana caranya;
  • apakah pooling/proxy dan lapisan perantara digunakan, yang dapat mengubah informasi tentang bagaimana koneksi dibangun dan siapa yang menggunakan database.

Sekarang mari kita lihat alat apa saja yang dapat digunakan untuk mengamankan koneksi:

  1. Gunakan solusi kelas firewall database. Lapisan perlindungan tambahan, minimal, akan meningkatkan transparansi tentang apa yang terjadi di DBMS, dan maksimal, Anda akan dapat memberikan perlindungan data tambahan.
  2. Gunakan kebijakan kata sandi. Penggunaannya bergantung pada bagaimana arsitektur Anda dibangun. Bagaimanapun, satu kata sandi dalam file konfigurasi aplikasi web yang terhubung ke DBMS tidak cukup untuk perlindungan. Ada sejumlah alat DBMS yang memungkinkan Anda mengontrol apakah pengguna dan kata sandi perlu diperbarui.

    Anda dapat membaca lebih lanjut tentang fungsi penilaian pengguna di sini, Anda juga dapat mengetahui tentang Penilai Kerentanan MS SQL di sini

  3. Perkaya konteks sesi dengan informasi yang diperlukan. Jika sesinya buram, Anda tidak memahami siapa yang bekerja di DBMS dalam kerangkanya, Anda dapat, dalam kerangka operasi yang dilakukan, menambahkan informasi tentang siapa melakukan apa dan mengapa. Informasi ini dapat dilihat dalam audit.
  4. Konfigurasikan SSL jika Anda tidak memiliki pemisahan jaringan antara DBMS dan pengguna akhir; itu tidak berada dalam VLAN terpisah. Dalam kasus seperti ini, sangat penting untuk melindungi saluran antara konsumen dan DBMS itu sendiri. Alat keamanan juga tersedia dalam sumber terbuka.

Bagaimana hal ini mempengaruhi kinerja DBMS?

Mari kita lihat contoh PostgreSQL untuk melihat bagaimana SSL memengaruhi beban CPU, meningkatkan pengaturan waktu dan mengurangi TPS, dan apakah SSL akan menghabiskan terlalu banyak sumber daya jika Anda mengaktifkannya.

Memuat PostgreSQL menggunakan pgbench adalah program sederhana untuk menjalankan tes kinerja. Ini mengeksekusi serangkaian perintah berulang kali, mungkin dalam sesi database paralel, dan kemudian menghitung tingkat transaksi rata-rata.

Tes 1 tanpa SSL dan menggunakan SSL β€” koneksi dibuat untuk setiap transaksi:

pgbench.exe --connect -c 10 -t 5000 "host=192.168.220.129 dbname=taskdb user=postgres sslmode=require 
sslrootcert=rootCA.crt sslcert=client.crt sslkey=client.key"

vs

pgbench.exe --connect -c 10 -t 5000 "host=192.168.220.129 dbname=taskdb user=postgres"

Tes 2 tanpa SSL dan menggunakan SSL β€” semua transaksi dilakukan dalam satu koneksi:

pgbench.exe -c 10 -t 5000 "host=192.168.220.129 dbname=taskdb user=postgres sslmode=require
sslrootcert=rootCA.crt sslcert=client.crt sslkey=client.key"

vs

pgbench.exe -c 10 -t 5000 "host=192.168.220.129 dbname=taskdb user=postgres"

Pengaturan lainnya:

scaling factor: 1
query mode: simple
number of clients: 10
number of threads: 1
number of transactions per client: 5000
number of transactions actually processed: 50000/50000

Hasil tes:

 
TIDAK ADA SSL
SSL

Koneksi dibuat untuk setiap transaksi

rata-rata latensi
171.915 ms
187.695 ms

tps termasuk pembuatan koneksi
58.168112
53.278062

tps tidak termasuk pembuatan koneksi
64.084546
58.725846

CPU
24%
28%

Semua transaksi dilakukan dalam satu koneksi

rata-rata latensi
6.722 ms
6.342 ms

tps termasuk pembuatan koneksi
1587.657278
1576.792883

tps tidak termasuk pembuatan koneksi
1588.380574
1577.694766

CPU
17%
21%

Pada beban ringan, pengaruh SSL sebanding dengan kesalahan pengukuran. Jika jumlah data yang ditransfer sangat besar, situasinya mungkin berbeda. Jika kami membuat satu koneksi per transaksi (ini jarang terjadi, biasanya koneksi dibagi antar pengguna), Anda memiliki banyak koneksi/pemutusan, dampaknya mungkin sedikit lebih besar. Artinya, mungkin ada risiko penurunan performa, namun perbedaannya tidak terlalu besar jika tidak menggunakan proteksi.

Harap dicatat bahwa ada perbedaan besar jika Anda membandingkan mode pengoperasian: Anda bekerja dalam sesi yang sama atau berbeda. Hal ini dapat dimengerti: sumber daya dihabiskan untuk membuat setiap koneksi.

Kami memiliki kasus ketika kami menghubungkan Zabbix dalam mode kepercayaan, yaitu md5 tidak dicentang, tidak perlu otentikasi. Kemudian pelanggan meminta untuk mengaktifkan mode otentikasi md5. Hal ini memberikan beban berat pada CPU, dan kinerja menurun. Kami mulai mencari cara untuk mengoptimalkan. Salah satu solusi yang mungkin untuk masalah ini adalah dengan menerapkan pembatasan jaringan, membuat VLAN terpisah untuk DBMS, menambahkan pengaturan untuk memperjelas siapa yang terhubung dari mana dan menghapus otentikasi. Anda juga dapat mengoptimalkan pengaturan otentikasi untuk mengurangi biaya saat mengaktifkan otentikasi, tetapi secara umum penggunaan metode otentikasi yang berbeda mempengaruhi kinerja dan memerlukan pertimbangan faktor-faktor ini ketika merancang daya komputasi server (perangkat keras) untuk DBMS.

Kesimpulan: dalam sejumlah solusi, bahkan perbedaan kecil dalam otentikasi dapat sangat mempengaruhi proyek dan akan menjadi buruk jika hal ini menjadi jelas hanya ketika diterapkan dalam produksi.

Audit tindakan

Audit tidak hanya bisa dilakukan pada DBMS. Audit adalah tentang memperoleh informasi tentang apa yang terjadi di berbagai segmen. Ini bisa berupa firewall database atau sistem operasi tempat DBMS dibangun.

Dalam DBMS tingkat Perusahaan komersial semuanya baik-baik saja dengan audit, tetapi dalam open source - tidak selalu. Inilah yang dimiliki PostgreSQL:

  • log default - pencatatan bawaan;
  • extensions: pgaudit - jika logging default tidak cukup bagi Anda, Anda dapat menggunakan pengaturan terpisah yang memecahkan beberapa masalah.

Tambahan laporan di video:

"Pencatatan log pernyataan dasar dapat disediakan oleh fasilitas logging standar dengan log_statement = all.

Hal ini dapat diterima untuk pemantauan dan penggunaan lainnya, namun tidak memberikan tingkat detail yang biasanya diperlukan untuk audit.

Tidaklah cukup hanya memiliki daftar semua operasi yang dilakukan pada database.

Pernyataan spesifik yang menarik bagi auditor juga harus dapat ditemukan.

Pencatatan log standar menunjukkan apa yang diminta pengguna, sedangkan pgAudit berfokus pada detail tentang apa yang terjadi saat database mengeksekusi kueri.

Misalnya, auditor mungkin ingin memverifikasi bahwa tabel tertentu dibuat dalam jangka waktu pemeliharaan yang terdokumentasi.

Ini mungkin tampak seperti tugas sederhana dengan audit dasar dan grep, tetapi bagaimana jika Anda diberikan contoh seperti ini (yang sengaja membingungkan):

LAKUKAN$$
MULAI
JALANKAN 'BUAT TABEL impor' || 'ant_table(id int)';
AKHIR$$;

Pencatatan log standar akan memberi Anda ini:

LOG: pernyataan: LAKUKAN $$
MULAI
JALANKAN 'BUAT TABEL impor' || 'ant_table(id int)';
AKHIR$$;

Tampaknya menemukan tabel yang diinginkan mungkin memerlukan beberapa pengetahuan kode jika tabel dibuat secara dinamis.

Ini tidak ideal, karena lebih baik jika hanya mencari berdasarkan nama tabel.

Di sinilah pgAudit berguna.

Untuk masukan yang sama, akan menghasilkan keluaran berikut di log:

AUDIT: SESI,33,1,FUNGSI,LAKUKAN,,,"LAKUKAN $$
MULAI
JALANKAN 'BUAT TABEL impor' || 'ant_table(id int)';
AKHIR$$;"
AUDIT: SESSION,33,2,DDL,CREATE TABLE,TABLE,public.important_table,CREATE TABLE important_table (id INT)

Tidak hanya blok DO yang dicatat, tetapi juga teks lengkap CREATE TABLE dengan tipe pernyataan, tipe objek, dan nama lengkap, sehingga memudahkan pencarian.

Saat mencatat pernyataan SELECT dan DML, pgAudit dapat dikonfigurasi untuk mencatat entri terpisah untuk setiap hubungan yang dirujuk dalam pernyataan tersebut.

Tidak diperlukan penguraian untuk menemukan semua pernyataan yang menyentuh tabel tertentu (*) Β».

Bagaimana hal ini mempengaruhi kinerja DBMS?

Mari kita jalankan pengujian dengan audit penuh diaktifkan dan lihat apa yang terjadi pada kinerja PostgreSQL. Mari aktifkan logging database maksimum untuk semua parameter.

Hampir tidak ada yang kami ubah pada file konfigurasi, yang terpenting aktifkan mode debug5 untuk mendapatkan informasi yang maksimal.

postgresql.conf

log_destinasi = 'stderr'
logging_collector = aktif
log_truncate_on_rotation = aktif
log_rotation_age = 1d
log_rotation_size = 10MB
log_min_messages = debug5
log_min_error_statement = debug5
log_min_duration_statement = 0
debug_print_parse = aktif
debug_print_rewrite = aktif
debug_print_plan = aktif
debug_pretty_print = aktif
log_checkpoints = aktif
log_koneksi = aktif
log_disconnections = aktif
log_durasi = aktif
log_hostname = aktif
log_lock_wait = aktif
log_replication_commands = aktif
log_temp_files = 0
log_timezone = 'Eropa/Moskow'

Pada DBMS PostgreSQL dengan parameter 1 CPU, 2,8 GHz, 2 GB RAM, 40 GB HDD, kami melakukan tiga tes beban menggunakan perintah:

$ pgbench -p 3389 -U postgres -i -s 150 benchmark
$ pgbench -p 3389 -U postgres -c 50 -j 2 -P 60 -T 600 benchmark
$ pgbench -p 3389 -U postgres -c 150 -j 2 -P 60 -T 600 benchmark

Hasil tes:

Tidak ada pencatatan
Dengan masuk

Total waktu pengisian basis data
43,74 dtk
53,23 dtk

Ram
24%
40%

CPU
72%
91%

Tes 1 (50 koneksi)

Jumlah transaksi dalam 10 menit
74169
32445

Transaksi/detik
123
54

Latensi Rata-Rata
405 ms
925 ms

Tes 2 (150 koneksi dengan 100 kemungkinan)

Jumlah transaksi dalam 10 menit
81727
31429

Transaksi/detik
136
52

Latensi Rata-Rata
550 ms
1432 ms

Tentang ukuran

ukuran DB
2251 MB
2262 MB

Ukuran log basis data
0 MB
4587 MB

Kesimpulannya: audit penuh tidaklah baik. Data hasil audit akan sama besarnya dengan data di database itu sendiri, atau bahkan lebih. Jumlah logging yang dihasilkan ketika bekerja dengan DBMS merupakan masalah umum dalam produksi.

Mari kita lihat parameter lainnya:

  • Kecepatannya tidak banyak berubah: tanpa logging - 43,74 detik, dengan logging - 53,23 detik.
  • Kinerja RAM dan CPU akan menurun, karena Anda perlu membuat file audit. Hal ini juga terlihat pada produktivitas.

Dengan bertambahnya jumlah koneksi, tentu saja kinerjanya akan sedikit menurun.

Di perusahaan yang memiliki audit, hal ini bahkan lebih sulit:

  • ada banyak data;
  • audit diperlukan tidak hanya melalui syslog di SIEM, tetapi juga dalam file: jika terjadi sesuatu pada syslog, harus ada file yang dekat dengan database tempat data disimpan;
  • rak terpisah diperlukan untuk audit agar tidak menyia-nyiakan disk I/O, karena memakan banyak ruang;
  • Kebetulan karyawan keamanan informasi memerlukan standar Gost di mana-mana, mereka memerlukan identifikasi negara.

Membatasi akses ke data

Mari kita lihat teknologi yang digunakan untuk melindungi data dan mengaksesnya di DBMS komersial dan open source.

Apa yang biasanya dapat Anda gunakan:

  1. Enkripsi dan pengaburan prosedur dan fungsi (Pembungkusan) - yaitu, alat dan utilitas terpisah yang membuat kode yang dapat dibaca menjadi tidak dapat dibaca. Benar, maka itu tidak dapat diubah atau difaktorkan ulang kembali. Pendekatan ini terkadang diperlukan setidaknya di sisi DBMS - logika pembatasan lisensi atau logika otorisasi dienkripsi secara tepat pada tingkat prosedur dan fungsi.
  2. Membatasi visibilitas data berdasarkan baris (RLS) adalah ketika pengguna yang berbeda melihat satu tabel, tetapi komposisi baris di dalamnya berbeda, yaitu sesuatu tidak dapat ditampilkan kepada seseorang di tingkat baris.
  3. Mengedit data yang ditampilkan (Masking) adalah ketika pengguna dalam satu kolom tabel melihat data atau hanya tanda bintang, yaitu untuk beberapa pengguna informasi akan ditutup. Teknologi ini menentukan pengguna mana yang diperlihatkan berdasarkan tingkat akses mereka.
  4. Keamanan DBA/Aplikasi Kontrol akses DBA/DBA lebih pada membatasi akses ke DBMS itu sendiri, yaitu karyawan keamanan informasi dapat dipisahkan dari administrator database dan administrator aplikasi. Ada sedikit teknologi seperti itu di open source, tetapi ada banyak teknologi seperti itu di DBMS komersial. Mereka diperlukan ketika ada banyak pengguna yang memiliki akses ke server itu sendiri.
  5. Membatasi akses ke file di tingkat sistem file. Anda dapat memberikan hak dan hak akses ke direktori sehingga setiap administrator hanya memiliki akses ke data yang diperlukan.
  6. Akses wajib dan pembersihan memori - teknologi ini jarang digunakan.
  7. Enkripsi end-to-end langsung dari DBMS merupakan enkripsi sisi klien dengan manajemen kunci di sisi server.
  8. Enkripsi data. Misalnya, enkripsi kolom adalah saat Anda menggunakan mekanisme yang mengenkripsi satu kolom database.

Bagaimana hal ini mempengaruhi kinerja DBMS?

Mari kita lihat contoh enkripsi kolom di PostgreSQL. Ada modul pgcrypto, memungkinkan Anda menyimpan bidang yang dipilih dalam bentuk terenkripsi. Hal ini berguna ketika hanya beberapa data yang berharga. Untuk membaca bidang terenkripsi, klien mengirimkan kunci dekripsi, server mendekripsi data dan mengembalikannya ke klien. Tanpa kuncinya, tidak ada yang bisa melakukan apa pun dengan data Anda.

Mari kita uji dengan pgcrypto. Mari buat tabel dengan data terenkripsi dan data biasa. Di bawah ini adalah perintah untuk membuat tabel, di baris pertama ada perintah yang berguna - membuat ekstensi itu sendiri dengan registrasi DBMS:

CREATE EXTENSION pgcrypto;
CREATE TABLE t1 (id integer, text1 text, text2 text);
CREATE TABLE t2 (id integer, text1 bytea, text2 bytea);
INSERT INTO t1 (id, text1, text2)
VALUES (generate_series(1,10000000), generate_series(1,10000000)::text, generate_series(1,10000000)::text);
INSERT INTO t2 (id, text1, text2) VALUES (
generate_series(1,10000000),
encrypt(cast(generate_series(1,10000000) AS text)::bytea, 'key'::bytea, 'bf'),
encrypt(cast(generate_series(1,10000000) AS text)::bytea, 'key'::bytea, 'bf'));

Selanjutnya, mari kita coba membuat sampel data dari setiap tabel dan melihat waktu eksekusinya.

Memilih dari tabel tanpa fungsi enkripsi:

psql -c "timing" -c "select * from t1 limit 1000;" "host=192.168.220.129 dbname=taskdb
user=postgres sslmode=disable" > 1.txt

Stopwatch menyala.

  identitas | teks1 | teks2
β€”+β€”β€”-+β€”β€”-
1 | 1 | 1
2 | 2 | 2
3 | 3 | 3
...
997 | 997 | 997
998 | 998 | 998
999 | 999 | 999
1000 | 1000 | 1000
(1000 baris)

Waktu: 1,386 ms

Pilihan dari tabel dengan fungsi enkripsi:

psql -c "timing" -c "select id, decrypt(text1, 'key'::bytea, 'bf'),
decrypt(text2, 'key'::bytea, 'bf') from t2 limit 1000;"
"host=192.168.220.129 dbname=taskdb user=postgres sslmode=disable" > 2.txt

Stopwatch menyala.

  identitas | mendekripsi | mendekripsi
--------------------------------------------------
1 | x31 | x31
2 | x32 | x32
3 | x33 | x33
...
999 | x393939 | x393939
1000 | x31303030 | x31303030
(1000 baris)

Waktu: 50,203 ms

Hasil tes:

 
Tanpa enkripsi
Pgcrypto (mendekripsi)

Contoh 1000 baris
1,386 ms
50,203 ms

CPU
15%
35%

Ram
 
+ 5%

Enkripsi berdampak besar pada kinerja. Dapat dilihat bahwa waktunya telah meningkat, karena operasi dekripsi data terenkripsi (dan dekripsi biasanya masih terbungkus dalam logika Anda) memerlukan sumber daya yang signifikan. Artinya, gagasan mengenkripsi semua kolom yang berisi beberapa data penuh dengan penurunan kinerja.

Namun, enkripsi bukanlah obat mujarab yang menyelesaikan semua masalah. Data yang didekripsi dan kunci dekripsi selama proses dekripsi dan transmisi data terletak di server. Oleh karena itu, kunci dapat disadap oleh seseorang yang memiliki akses penuh ke server database, seperti administrator sistem.

Ketika ada satu kunci untuk seluruh kolom untuk semua pengguna (meskipun tidak untuk semua, tetapi untuk klien dengan jumlah terbatas), ini tidak selalu baik dan benar. Itulah sebabnya mereka mulai melakukan enkripsi ujung ke ujung, di DBMS mereka mulai mempertimbangkan opsi untuk mengenkripsi data di sisi klien dan server, dan penyimpanan brankas kunci yang sama muncul - produk terpisah yang menyediakan manajemen kunci pada DBMS samping.

Keamanan dan DBMS: apa yang perlu Anda ingat ketika memilih alat keamanan
Contoh enkripsi di MongoDB

Fitur keamanan dalam DBMS komersial dan open source

Fungsi
Jenis
Kebijakan Kata Sandi
Audit
Melindungi kode sumber prosedur dan fungsi
RLS
enkripsi

Peramal
komersial
+
+
+
+
+

MsSql
komersial
+
+
+
+
+

Jatoba
komersial
+
+
+
+
ekstensi

PostgreSQL
Gratis
ekstensi
ekstensi
-
+
ekstensi

mongodb
Gratis
-
+
-
-
Hanya tersedia di MongoDB Enterprise

Tabelnya masih jauh dari lengkap, tetapi situasinya begini: dalam produk komersial, masalah keamanan telah lama diselesaikan, dalam sumber terbuka, sebagai aturan, beberapa jenis add-on digunakan untuk keamanan, banyak fungsi yang hilang , terkadang Anda harus menambahkan sesuatu. Misalnya, kebijakan kata sandi - PostgreSQL memiliki banyak ekstensi berbeda (1, 2, 3, 4, 5), yang menerapkan kebijakan password, namun menurut saya belum ada satupun yang dapat memenuhi seluruh kebutuhan segmen korporasi dalam negeri.

Apa yang harus dilakukan jika Anda tidak memiliki apa yang Anda perlukan di mana pun? Misalnya, Anda ingin menggunakan DBMS tertentu yang tidak memiliki fungsi yang dibutuhkan pelanggan.

Kemudian Anda dapat menggunakan solusi pihak ketiga yang bekerja dengan DBMS berbeda, misalnya Crypto DB atau Garda DB. Jika kita berbicara tentang solusi dari segmen domestik, maka mereka tahu tentang Gost lebih baik daripada di open source.

Opsi kedua adalah menulis sendiri apa yang Anda perlukan, menerapkan akses data dan enkripsi dalam aplikasi di tingkat prosedur. Benar, dengan Gost akan lebih sulit. Namun secara umum, Anda dapat menyembunyikan data sesuai kebutuhan, memasukkannya ke dalam DBMS, lalu mengambilnya dan mendekripsinya sesuai kebutuhan, langsung di tingkat aplikasi. Pada saat yang sama, segera pikirkan bagaimana Anda akan melindungi algoritma ini dalam aplikasi. Menurut kami, hal ini sebaiknya dilakukan di level DBMS, karena akan bekerja lebih cepat.

Laporan ini pertama kali dipresentasikan pada @Database Pertemuan oleh Solusi Cloud Mail.ru. Lihat Video pertunjukan lainnya dan berlangganan pengumuman acara di Telegram Sekitar Kubernetes di Mail.ru Group.

Apa lagi yang harus dibaca tentang topik tersebut:

  1. Lebih dari Ceph: Penyimpanan blok cloud MCS.
  2. Bagaimana memilih database untuk suatu proyek sehingga Anda tidak perlu memilih lagi.

Sumber: www.habr.com

Tambah komentar