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


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

Artikel ini ditulis oleh @Databases Meetup, yang diselenggarakan oleh Mail.ru Cloud Solutions . Jika Anda tidak ingin membaca, Anda dapat melihat:


Artikel ini akan memiliki tiga bagian:

  • Cara melindungi koneksi.
  • Apa itu audit tindakan dan bagaimana cara merekam apa yang terjadi pada bagian basis data dan menghubungkannya.
  • Bagaimana melindungi data dalam database itu sendiri dan teknologi apa yang ada untuk ini.


Tiga komponen keamanan DBMS: perlindungan koneksi, audit aktivitas, dan perlindungan data

Perlindungan Koneksi


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

Sebelum berbicara tentang mengamankan koneksi, Anda perlu menjawab pertanyaan penting yang tergantung pada bagaimana langkah-langkah keamanan akan dibangun:

  • apakah satu pengguna bisnis setara dengan satu pengguna DBMS;
  • Apakah akses ke data DBMS disediakan hanya melalui API yang Anda kontrol, atau apakah ada akses ke tabel secara langsung;
  • apakah DBMS dialokasikan dalam segmen yang dilindungi secara terpisah, siapa yang berinteraksi dengannya dan bagaimana;
  • apakah pooling / proxy dan middleware digunakan, yang dapat mengubah informasi tentang bagaimana koneksi dibangun dan siapa yang menggunakan database.

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

  1. Gunakan solusi kelas firewall basis data. Lapisan perlindungan tambahan, setidaknya, akan meningkatkan transparansi dari apa yang terjadi di DBMS, sebagai maksimum - Anda dapat memberikan perlindungan data tambahan.
  2. . , . โ€” -, , . , , .

    , MS SQL Vulnerability Assessmen
  3. . , , , , , . .
  4. Konfigurasikan SSL, jika Anda tidak memiliki pemisahan jaringan DBMS dari pengguna akhir, ia tidak berada dalam VLAN terpisah. Dalam kasus seperti itu, perlu untuk melindungi saluran antara konsumen dan DBMS itu sendiri. Alat perlindungan adalah di antara sumber terbuka.

Bagaimana ini akan mempengaruhi kinerja DBMS?


Mari kita lihat contoh PostgreSQL tentang bagaimana SSL memengaruhi beban CPU, menambah timing dan mengurangi TPS, jika terlalu banyak sumber daya yang digunakan jika Anda mengaktifkannya.

Kami memuat PostgreSQL menggunakan pgbench - ini adalah program sederhana untuk menjalankan tes kinerja. Berulang kali mengeksekusi satu urutan perintah, mungkin dalam sesi database paralel, dan kemudian menghitung kecepatan transaksi rata-rata.

Tes 1 tanpa SSL dan menggunakan SSL - koneksi dibuat dengan 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 lain :

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 :
 TANPA SSLSSL
Koneksi dibuat pada setiap transaksi
rata-rata latensi171.915 ms187.695 ms
tps termasuk membangun koneksi58.16811253.278062
tps tidak termasuk membangun koneksi64.08454658.725846
CPU24%28%
Semua transaksi dilakukan dalam satu koneksi.
rata-rata latensi6,722 ms6,342 ms
tps termasuk membangun koneksi1587.6572781576.792883
tps tidak termasuk membangun koneksi1588.3805741577.694766
CPU17%21%

Pada beban yang ringan, efek SSL sebanding dengan kesalahan pengukuran. Jika jumlah data yang ditransfer sangat besar, situasinya mungkin berbeda. Jika kami membuat satu koneksi untuk setiap transaksi (ini jarang terjadi, biasanya koneksi dibagi di antara pengguna), Anda memiliki banyak koneksi / pemutusan, efeknya mungkin sedikit lebih. Artinya, mungkin ada risiko penurunan kinerja, namun perbedaannya tidak terlalu besar sehingga tidak menggunakan perlindungan.

Harap dicatat bahwa ada perbedaan yang kuat ketika membandingkan mode operasi: dalam sesi yang sama, Anda bekerja atau berbeda. Ini bisa dimengerti: sumber daya dihabiskan untuk membuat setiap koneksi.

Kami memiliki kasus ketika kami menghubungkan Zabbix dalam mode kepercayaan, yaitu, kami tidak memeriksa MD5, tidak perlu otentikasi. Kemudian pelanggan diminta untuk mengaktifkan mode otentikasi MD5. Ini memberi beban besar pada CPU, kinerja dicelupkan. Mereka mulai mencari cara untuk mengoptimalkan. Salah satu solusi yang mungkin untuk masalah ini adalah menerapkan pembatasan jaringan, membuat VLAN terpisah untuk DBMS, menambah pengaturan sehingga jelas siapa yang terhubung dari mana dan menghapus otentikasi. Anda juga dapat mengoptimalkan pengaturan otentikasi untuk mengurangi biaya yang memungkinkan otentikasi, tetapi secara umum, menggunakan berbagai metode otentikasi mempengaruhi kinerja dan memerlukan faktor-faktor ini untuk dipertimbangkan ketika merancang kekuatan komputasi server (perangkat keras) untuk DBMS.

Kesimpulan: dalam sejumlah solusi, bahkan nuansa kecil otentikasi dapat sangat mempengaruhi proyek dan itu buruk ketika menjadi jelas hanya ketika diimplementasikan dalam suatu produk.

Audit tindakan


Audit bukan hanya DBMS. Audit adalah penerimaan informasi tentang apa yang terjadi pada segmen yang berbeda. Ini bisa berupa firewall basis data dan sistem operasi tempat DBMS dibuat.

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

  • log default - logging bawaan;
  • ekstensi: pgaudit - jika Anda tidak memiliki cukup penebangan default, Anda dapat menggunakan pengaturan terpisah yang menyelesaikan beberapa masalah.

Penambahan laporan dalam video:

โ€œPendaftaran dasar pernyataan dapat diberikan dengan fasilitas logging standar dengan log_statement = semua.

Ini dapat diterima untuk pemantauan dan penggunaan lainnya, tetapi tidak memberikan tingkat detail yang biasanya diperlukan untuk audit.

Tidak cukup hanya memiliki daftar semua operasi yang dilakukan dengan database.

Seharusnya juga dimungkinkan untuk menemukan pernyataan spesifik yang menarik bagi auditor.

Alat pencatatan standar menunjukkan apa yang diminta pengguna, sementara pgAudit berfokus pada detail tentang apa yang terjadi ketika database membuat permintaan.

Misalnya, auditor mungkin ingin memastikan bahwa tabel tertentu telah dibuat di jendela pemeliharaan yang terdokumentasi.

Ini mungkin tampak seperti tugas sederhana untuk audit dan grep dasar, tetapi bagaimana jika Anda menemukan sesuatu seperti ini (sengaja membingungkan) contoh:

DO $$
BEGIN
EXECUTE 'CREATE TABLE import import' || 'ant_table (id INT)';
AKHIR $$;

Pencatatan standar akan memberi Anda ini:

LOG: pernyataan: DO $$
BEGIN
EXECUTE 'CREATE TABLE import' || 'ant_table (id INT)';
AKHIR $$;

Tampaknya mencari tabel minat mungkin memerlukan beberapa pengetahuan kode dalam kasus di mana tabel dibuat secara dinamis.

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

Di sinilah pgAudit akan berguna.

Untuk input yang sama, ini akan menampilkan output ini dalam log:

AUDIT: SESI, 33.1, FUNGSI, LAKUKAN ,,, โ€œJANGAN $$
MULAI
PELAKSANAAN 'CREATE TABLE import' || 'ant_table (id INT)';
AKHIR $$; "
AUDIT: SESI, 33,2, DDL, CREATE TABLE, TABLE, public.important_table, CREATE TABLE important_table (id INT)

Tidak hanya blok DO yang didaftarkan, tetapi juga teks lengkap CREATE TABLE dengan jenis operator, jenis objek dan nama lengkap, membuatnya lebih mudah untuk mencari.

Dalam menjalankan majalah operator SELECT dan DML pgAudit dapat dikonfigurasi untuk mencatat entri terpisah untuk setiap hubungan, yang dirujuk dalam pernyataan.

Tidak perlu menguraikan untuk menemukan semua pernyataan yang terkait dengan tabel tertentu ( * ) " .

Bagaimana ini akan mempengaruhi kinerja DBMS?


Mari kita jalankan tes dengan audit penuh diaktifkan dan lihat apa yang terjadi dengan kinerja PostgreSQL. Kami mengaktifkan pendataan basis data maksimum dalam segala hal.

Kami hampir tidak mengubah apa pun dalam file konfigurasi, dari yang penting - aktifkan mode debug5 untuk mendapatkan informasi maksimal.

postgresql.conf
log_destination = 'stderr'
logging_collector = pada
log_truncate_on_rotation = pada
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 =
debug_print_rewritten = pada
debug_print_plan = pada
debug_pretty_print = pada
log_checkpoints = pada
log_donnonnections
= pada
log_disconnections = pada
log_dapatation = pada
log_lock_waits = pada
log_replication_commands = pada
log_temp_files = 0
log_time =

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

$ 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:
Tanpa loggingDengan logging
Total waktu pengisian basis data43,74 dtk53,23 dtk
RAM24%40%
CPU72%91%
Tes 1 (50 koneksi)
Jumlah transaksi dalam 10 menit7416932445
Transaksi / dtk12354
Penundaan rata-rata405 ms925 ms
Tes 2 (150 koneksi pada 100 memungkinkan)
Jumlah transaksi dalam 10 menit8172731429
Transaksi / dtk13652
Penundaan rata-rata550 ms1432 ms
Tentang ukuran
Ukuran DB2251 MB2262 MB
Ukuran Log Basis Data0 Mb4587 Mb

Intinya: audit penuh tidak terlalu baik. Data dari audit akan berubah volume, seperti data dalam database itu sendiri, atau bahkan lebih. Jumlah penebangan yang dihasilkan saat bekerja dengan DBMS adalah masalah umum pada produk.

Kami melihat parameter lain:

  • Kecepatan tidak banyak berubah: tanpa logging - 43.74 detik, dengan logging - 53.23 detik.
  • Performa pada RAM dan CPU akan tenggelam, karena Anda perlu membuat file dengan audit. Juga terlihat pada yang produktif.

Dengan peningkatan jumlah koneksi, tentu saja, kinerjanya akan sedikit memburuk.

Di perusahaan dengan audit, itu bahkan lebih sulit:

  • ada banyak data;
  • audit diperlukan tidak hanya melalui syslog di SIEM, tetapi juga ke file: tiba-tiba terjadi sesuatu dengan syslog, file di mana data disimpan harus dekat dengan database;
  • audit memerlukan rak terpisah, agar tidak tenggelam pada disk I / O, karena membutuhkan banyak ruang;
  • Kebetulan karyawan IS membutuhkan GOST di mana-mana, mereka memerlukan identifikasi tamu.

Pembatasan akses data


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

Apa yang bisa digunakan secara keseluruhan:

  1. Enkripsi dan kebingungan prosedur dan fungsi (Wrapping) - yaitu, alat dan utilitas terpisah yang membuat kode tidak dapat dibaca dari kode yang dapat dibaca. Benar, maka itu tidak dapat diubah atau dikembalikan lagi. Pendekatan semacam itu kadang-kadang diperlukan setidaknya di sisi DBMS - logika pembatasan lisensi atau logika otorisasi dienkripsi secara tepat di tingkat prosedur dan fungsi.
  2. (RLS) โ€” , , - - .
  3. (Masking) โ€” , , - . , .
  4. Security DBA/Application DBA/DBA โ€” , , , database- application-. open source , . , .
  5. . , , .
  6. โ€” .
  7. End-to-end encryption โ€” client-side .
  8. . , โ€” , .

?


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

Mari kita coba dengan pgcrypto . Buat tabel dengan data terenkripsi dan data biasa. Di bawah ini adalah perintah untuk membuat tabel, di baris pertama perintah yang berguna adalah membuat ekstensi itu sendiri dengan pendaftaran 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, kami akan mencoba membuat pengambilan sampel data dari setiap tabel dan melihat waktu eksekusi.

Pilihan 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 aktif.

  id | text1 | text2
------ + ------- + -------
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.

Pengambilan sampel dari sebuah 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 aktif.

  id | dekripsi | dekripsi
----- + -------------- + ------------
1 | \ x31 | \ x31
2 | \ x32 | \ x32
3 | \ x33 | \ x33
...
999 | \ x393939 | \ x393939
1000 | \ x31303030 | \ x31303030
(1000 baris)

Waktu: 50.203 ms

Hasil tes :
 Tanpa enkripsiPgcrypto (decrypt)
Ambil 1000 baris1,386 ms50.203 ms
CPUlima belas%35%
RAM + 5%

Enkripsi memiliki dampak besar pada kinerja. Dapat dilihat bahwa waktunya telah meningkat, karena operasi mendekripsi data terenkripsi (dan dekripsi biasanya masih dibungkus dengan logika Anda) membutuhkan sumber daya yang signifikan. Artinya, gagasan mengenkripsi semua kolom yang berisi beberapa jenis data penuh dengan penurunan kinerja.

Namun, enkripsi bukan peluru perak yang menyelesaikan semua masalah. Data yang didekripsi dan kunci dekripsi dalam proses dekripsi dan transfer data terletak di server. Oleh karena itu, kunci dapat dicegat oleh mereka yang memiliki akses penuh ke server database, misalnya, administrator sistem.

Ketika seluruh kolom untuk semua pengguna memiliki satu kunci (bahkan jika tidak untuk semua, tetapi untuk sekelompok pelanggan 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 dari klien dan server, repositori key-vault yang sama muncul - produk terpisah yang menyediakan manajemen kunci di sisi DBMS.


Contoh enkripsi semacam itu di MongoDB

Fitur keamanan dalam DBMS komersial dan open source


FungsiSebuah tipeKebijakan kata sandiAuditMelindungi kode sumber untuk prosedur dan fungsiRLSEnkripsi
Peramalkomersial+++++
Msqlkomersial+++++
Jatobakomersial++++ekstensi
PostgreSQLGratisekstensiekstensi-+ekstensi
MongodbGratis-+--Hanya tersedia di MongoDB Enterprise

Tabelnya jauh dari lengkap, tetapi situasinya adalah ini: dalam produk komersial, masalah keamanan telah dipecahkan sejak lama, dalam sumber terbuka, sebagai aturan, beberapa add-on digunakan untuk keamanan, banyak fungsi tidak cukup, kadang-kadang Anda harus menambahkan sesuatu. Misalnya, kebijakan kata sandi - di PostgreSQL ada banyak ekstensi yang berbeda ( 1 , 2 , 3 , 4 , 5 ) yang menerapkan kebijakan kata sandi, tetapi, menurut pendapat saya, tidak ada yang mencakup semua kebutuhan segmen korporasi domestik.

Apa yang harus dilakukan jika tidak ada yang dibutuhkan ? Misalnya, saya ingin menggunakan DBMS tertentu, di mana tidak ada fungsi yang diperlukan pelanggan.

Kemudian Anda dapat menggunakan solusi pihak ketiga yang bekerja dengan DBMS yang 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 butuhkan, mengimplementasikan akses data dan enkripsi dalam aplikasi di tingkat prosedur. Benar, dengan GOST akan lebih sulit. Tetapi secara umum - Anda dapat menyembunyikan data sesuai kebutuhan, memasukkannya ke dalam DBMS, lalu mendapatkannya dan mendekripsi sebagaimana mestinya, tepat di tingkat aplikasi. Pada saat yang sama, segera pikirkan tentang bagaimana Anda akan melindungi algoritma ini pada aplikasi. Menurut pendapat kami, ini harus dilakukan di tingkat DBMS, karena akan bekerja lebih cepat.

Pembicaraan ini pertama kali dilakukan di @Databases Meetup oleh Mail.ru Cloud Solutions. Tonton videonyapenampilan lain dan mendaftar untuk pengumuman acara Telegram di Sekitar Kubernetes di Mail.ru Group .

Apa lagi yang harus dibaca pada topik :

  1. Lebih dari Ceph: MCS Block Cloud Storage .
  2. Bagaimana memilih database untuk proyek, agar tidak memilih lagi .

All Articles