Dalam posting sebelumnya tentang keamanan MySQL, kami telah membahas berbagai opsi yang dapat digunakan untuk membuat instance MySQL Anda lebih aman. Mereka termasuk:
- Langkah-langkah keamanan umum MySQL;
- Mengontrol akses di MySQL;
- Membuat, mengubah, dan menghapus pengguna di MySQL;
- Memberikan dan mencabut hak istimewa ke dan dari pengguna di MySQL;
- Memeriksa hak istimewa apa yang diberikan kepada pengguna di MySQL.
Dalam postingan ini, kita akan membahas opsi lainnya, termasuk:
- Kategori akun di MySQL;
- Peran di MySQL;
- Akun yang dicadangkan di MySQL;
- Manajemen kata sandi di MySQL;
- Penguncian akun di MySQL;
- Plugin keamanan yang ditawarkan oleh MySQL;
- Mengamankan cadangan MySQL.
Perlu diingat bahwa sekali lagi, kami tidak akan membahas sepenuhnya semua yang perlu Anda ketahui, tetapi kami akan mencoba memberikan titik awal yang baik untuk melakukan penelitian Anda sendiri.
Kategori Akun di MySQL
Kategori akun diperkenalkan di MySQL 8 - khususnya, di MySQL 8.0.16. Inilah intinya:
- Ada dua kategori akun terpisah:pengguna biasa dan pengguna sistem;
- Pengguna biasa adalah pengguna tanpa hak istimewa SYSTEM_USER - pengguna sistem adalah pengguna dengan hak istimewa SYSTEM_USER;
- Pengguna biasa dapat mengubah akun biasa - pengguna tersebut tidak dapat mengubah akun sistem;
- Pengguna sistem dapat memodifikasi akun sistem dan akun biasa;
- Akun biasa dapat dimodifikasi oleh pengguna biasa dan pengguna sistem;
- Akun sistem hanya dapat diubah oleh pengguna sistem.
Untuk menggunakan kategori akun dalam keamanan MySQL, perlu diingat bahwa hak istimewa SYSTEM_USER memengaruhi hal-hal seperti manipulasi akun, dan mematikan sesi dan pernyataan di dalamnya - konsep ini di MySQL memungkinkan pembatasan modifikasi tertentu pada akun tertentu sehingga membuat MySQL lebih aman. Kategori akun juga dapat digunakan untuk melindungi akun sistem dari manipulasi oleh akun biasa:untuk melakukannya, jangan berikan hak istimewa modifikasi skema mysql ke akun biasa.
Untuk memberikan hak istimewa kepada SYSTEM_USER akun, gunakan kueri berikut pada akun yang dibuat:
GRANT SYSTEM_USER ON *.* TO system_user;
Peran di MySQL
Di MySQL, peran adalah kumpulan hak istimewa. Saat Anda memberi akun pengguna peran di MySQL, Anda memberikan semua hak istimewa yang terkait dengan peran itu. Peran dapat dibuat menggunakan pernyataan CREATE ROLE:
CREATE ROLE ‘role_1’, ‘role_2’;
Nama peran terdiri dari bagian pengguna dan bagian host - bagian pengguna tidak boleh kosong dan bagian host default ke “%” jika tidak ditentukan.
Saat peran dibuat, Anda harus memberikan hak istimewa kepada mereka. Hak istimewa dapat diberikan menggunakan pernyataan GRANT:
- BERIKAN SEMUA PADA demo_database.* KEPADA 'demo_user'; akan memberikan semua hak istimewa kepada pengguna bernama demo_user di database bernama demo_database;
- GRANT INSERT, SELECT, UPDATE, DELETE ON database.* TO 'demo_user'; akan memberikan hak INSERT, SELECT, UPDATE, dan DELETE kepada pengguna bernama demo_user pada database bernama demo_database;
- HIBAH PILIH PADA demo_database.* UNTUK 'demo_user'; akan memberikan hak istimewa SELECT kepada pengguna bernama demo_user di database bernama demo_database.
Untuk menetapkan peran ke pengguna individu, gunakan sintaks ini:
GRANT ‘role_name’ TO ‘user_name’@’localhost’;
Untuk menetapkan beberapa peran ke pengguna individu, gunakan sintaks ini:
GRANT ‘role_1’, ‘role_2’ TO ‘user_name’@’localhost’;
Untuk menetapkan peran ke beberapa pengguna secara bersamaan, gunakan sintaks ini:
GRANT ‘role_name’ TO ‘user1’@’localhost’, ‘user2’@’localhost’;
Peran dapat membantu dalam mencegah insiden keamanan karena jika penyerang mengetahui kata sandi pengguna yang tidak memiliki hak istimewa secara keliru dengan menganggap pengguna sangat "kuat" dalam hal peran, aplikasi Anda (dan database Anda) dapat terselamatkan dengan sangat baik.
Akun yang Dicadangkan di MySQL
Jika menyangkut akun yang dicadangkan, ingatlah bahwa MySQL membuat akun selama inisialisasi direktori data. Ada beberapa akun yang harus dipertimbangkan dicadangkan di MySQL:
- 'root'@'localhost' - akun ini adalah akun superuser dan memiliki hak istimewa seperti dewa di semua database MySQL (dapat melakukan operasi apa pun di database MySQL mana pun). Perlu dicatat bahwa pengguna root juga dapat diganti namanya untuk menghindari membuka akun yang sangat istimewa. Untuk mengganti nama akun, jalankan kueri berikut:
RENAME USER ‘root’@’localhost’ TO ‘username’@’localhost’;
- Pastikan untuk mengeluarkan HAK ISTIMEWA; pernyataan setelah mengganti nama akun agar perubahan diterapkan.
- 'mysql.sys'@'localhost' - akun ini adalah pengguna sistem yang digunakan sebagai penentu tampilan, prosedur, dan fungsi dalam skema sistem. Ditambahkan di MySQL 5.7.9 untuk menghindari masalah yang mungkin muncul jika akun root diganti namanya.
- 'mysql.session'@'localhost' - akun ini digunakan secara internal oleh plugin untuk mengakses server.
Dalam hal ini, Anda tidak dapat melakukan banyak hal dari segi keamanan, tetapi perlu diingat bahwa akun root memiliki hak istimewa seperti dewa yang berarti ia dapat melakukan operasi apa pun di seluruh basis data MySQL dan berhati-hati saat memutuskan siapa yang akan memberikan hak istimewa untuk mengakses akun. Juga, ingat untuk apa akun MySQL lainnya digunakan.
Manajemen Kata Sandi di MySQL
MySQL juga mendukung fitur manajemen kata sandi. Beberapa di antaranya adalah:
- Kemampuan untuk kedaluwarsa sandi secara berkala;
- Kemampuan untuk menghindari penggunaan ulang sandi;
- Kemampuan untuk membuat sandi;
- Kemampuan untuk memeriksa apakah sandi yang digunakan kuat;
- Kemampuan untuk mengunci sementara pengguna setelah terlalu banyak upaya login yang gagal.
Sekarang, kita akan melihat opsi ini lebih lanjut.
Untuk kedaluwarsa kata sandi secara manual, gunakan pernyataan ALTER USER seperti:
ALTER USER ‘user’@’localhost’ PASSWORD EXPIRE;
Untuk menyetel kebijakan global, ubah file my.cnf sedemikian rupa sehingga menyertakan parameter default_password_lifetime. Parameter dapat ditentukan di bawah bagian [mysqld] (contoh berikut menetapkan masa pakai kata sandi menjadi 3 bulan (90 hari)):
default_password_lifetime=90
Jika Anda ingin sandi tidak pernah kedaluwarsa, setel parameter default_password_litetime ke 0.
Anda juga dapat menyetel kedaluwarsa sandi untuk pengguna tertentu. Jika Anda ingin mengatur interval kedaluwarsa kata sandi untuk pengguna yang disebut demo_user, Anda dapat menggunakan contoh berikut:
ALTER USER ‘demo_user’@’localhost’ PASSWORD EXPIRE INTERVAL 90 DAY;
Untuk menonaktifkan masa berlaku sandi:
ALTER USER ‘demo_user’@’localhost’ PASSWORD EXPIRE NEVER;
Untuk menyetel ulang kebijakan kedaluwarsa sandi global:
ALTER USER ‘demo_user’@’localhost’ PASSWORD EXPIRE DEFAULT;
Pembatasan penggunaan kembali kata sandi tidak mengizinkan kata sandi digunakan kembali - untuk menggunakan fitur ini, gunakan variabel password_history dan password_reuse_interval. Anda dapat meletakkan variabel-variabel ini di my.cnf dengan melihat contoh di bawah ini atau mengaturnya saat runtime dengan menambahkan SET PERSIST di depan pernyataan di bawah ini.
Untuk melarang penggunaan kembali salah satu dari 5 sandi yang digunakan sebelumnya yang lebih baru dari 365 hari, gunakan:
password_history=5
password_reuse_interval=365
Memerlukan minimal 5 perubahan sandi sebelum mengizinkan penggunaan kembali:
ALTER USER ‘demo_user’@’localhost’ PASSWORD HISTORY 5;
Hal yang sama dapat dilakukan saat membuat pengguna - ganti ALTER USER dengan CREATE USER.
Untuk membuat sandi acak saat membuat pengguna, jalankan:
CREATE USER [email protected] IDENTIFIED BY RANDOM PASSWORD;
Untuk mengubah sandi pengguna menjadi sandi yang dibuat secara acak:
SET PASSWORD FOR [email protected] TO RANDOM;
Kata sandi acak Anda akan ditampilkan di bawahnya.
Perlu diingat bahwa sandi acak default memiliki panjang 20 karakter. Panjangnya dapat dikontrol oleh variabel generate_random_password_length yang memiliki rentang dari 5 hingga 255.
Untuk memeriksa apakah sandi yang digunakan kuat, Anda dapat menggunakan variabel VALIDATE_PASSWORD_STRENGTH - fungsi menampilkan angka dari 0 hingga 100 dengan 0 sebagai yang terlemah dan 100 sebagai yang terkuat:
PILIH VALIDATE_PASSWORD_STRENGTH('sandi');
Penguncian Akun di MySQL
MySQL 8.0.19 juga memperkenalkan kemampuan untuk mengunci akun pengguna untuk sementara. Ini dapat dilakukan dengan menggunakan variabel FAILED_LOGIN_ATTEMPTS dan PASSWORD_LOCK_TIME.
Untuk mengaktifkan penguncian akun saat membuat pengguna, jalankan:
CREATE USER ‘demo_user’@’localhost’ IDENTIFIED BY ‘password’ FAILED_LOGIN_ATTEMPTS 5 PASSWORD_LOCK_TIME 5;
Nilai setelah FAILED_LOGIN_ATTEMPTS menentukan setelah berapa kali gagal akun terkunci, nilai setelah PASSWORD_LOCK_TIME menentukan waktu penguncian akun dalam hari. Anda juga dapat menentukan nilai yang tidak berakhir hingga akun dibuka dengan menentukan PASSWORD_LOCK_TIME sebagai TIDAK TERBATAS.
Plugin Keamanan yang Ditawarkan oleh MySQL
MySQL juga menawarkan beberapa plugin yang dapat lebih meningkatkan kemampuan keamanan. MySQL menawarkan:
- Plugin otentikasi;
- Plugin kontrol koneksi;
- Plugin validasi sandi;
- Plugin audit;
- Plugin firewall;
Plugin ini dapat digunakan untuk beberapa hal dari segi keamanan:
Plugin Otentikasi
Plugin otentikasi dapat memungkinkan pengguna untuk memilih di antara beberapa metode otentikasi pluggable yang tersedia di MySQL. Mereka dapat digunakan bersama dengan pernyataan CREATE USER atau ALTER USER. Berikut contohnya:
CREATE USER ‘user_1’@’localhost’ IDENTIFIED WITH mysql_native_password BY ‘password’;
Kueri ini akan menerapkan autentikasi menggunakan metode hashing sandi asli.
Plugin Kontrol Koneksi
Plugin kontrol koneksi dapat menyebabkan peningkatan penundaan dalam respons server terhadap upaya koneksi jika upaya koneksi melebihi jumlah tertentu - plugin tersebut dapat menghentikan potensi serangan brute force. Pustaka plugin ini diperkenalkan ke MySQL dalam versi 5.7.17 dan dapat ditambahkan ke MySQL baik melalui my.cnf atau dengan memuat plugin ke server saat runtime.
Untuk menambahkan plugin ke my.cnf , tambahkan baris berikut di bawah [mysqld]:
plugin-load-add=connection_control.so
Setelah memodifikasi file, simpan perubahan Anda dan mulai ulang MySQL.
Untuk memuat plugin ke server saat runtime, jalankan:
INSTALL PLUGIN CONNECTION_CONTROL SONAME ‘connection_control.so’;
INSTALL PLUGIN CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS SONAME ‘connection_control.so’;
Sesuaikan akhiran .so seperlunya. Jika Anda telah menyelesaikan semuanya dengan benar, tabel CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS akan berisi semua upaya yang gagal untuk menyambung.
Plugin Validasi Kata Sandi
Plugin validasi sandi dapat memungkinkan pengguna menggunakan sandi yang lebih kuat jika digunakan dengan benar. Plugin validasi kata sandi dapat diinstal melalui my.cnf atau dengan memuat plugin ke server saat runtime. Untuk menginstal plugin melalui my.cnf, tambahkan baris berikut di bawah [mysqld], lalu restart server:
plugin-load-add=validate_password.so
Untuk memuat plugin saat runtime, jalankan pernyataan berikut:
INSTALL PLUGIN validate_password SONAME ‘validate_password.so’;
Untuk memuat plugin saat runtime dan mencegahnya dihapus, tambahkan validasi-password=FORCE_PLUS_PERMANENT ke my.cnf.
Untuk mencegah server berjalan jika plugin tidak diinisialisasi, gunakan opsi --validate-password dengan nilai FORCE atau FORCE_PLUS_PERMANENT.
Kebijakan kekuatan sandi juga dapat diubah:untuk melakukannya, ubah nilaivalidasi_password_policy menjadi RENDAH, SEDANG, atau KUAT. Nilai LOW hanya memeriksa panjang kata sandi, kebijakan MEDIUM menambahkan beberapa ketentuan dan kebijakan STRONG menambahkan ketentuan bahwa substring kata sandi yang terdiri dari 4 karakter atau lebih tidak boleh cocok dengan kata-kata dalam file kamus yang dapat ditentukan dengan memodifikasi variabelvalid_password_dictionary_file.
Plugin Keyring
Plugin keyring dapat mengaktifkan komponen server dan plugin untuk menyimpan informasi sensitif dengan aman untuk pengambilan. Untuk memuat plugin ke MySQL, tambahkan berikut ini di bawah [mysqld]:
early-plugin-load=keyring_file.so
Untuk menentukan file keyring vault, tambahkan berikut ini (variabel keyring_vault_config harus mengarah ke file konfigurasi):
loose-keyring_vault_config=”/var/lib/mysql_keyring/keyring_vault.conf”
File keyring harus berisi variabel vault_url yang mendefinisikan alamat server vault, variabel secret_mount_point yang mendefinisikan nama mount point tempat penyimpanan keyring vault, dan token yang seharusnya ditentukan oleh server vault. Secara opsional, variabel vault_ca juga dapat ditentukan (harus mengarah ke sertifikat CA yang digunakan untuk menandatangani sertifikat vault).
Mulai ulang server agar perubahan diterapkan;
Plugin Audit
Plugin audit dapat mengaktifkan pemantauan, pencatatan, dan pemblokiran aktivitas yang dilakukan di server MySQL. Untuk menginstal MySQL Enterprise Audit, jalankan skrip yang terletak di direktori berbagi instans MySQL Anda (hindari memasukkan kata sandi instans MySQL Anda di terminal - gunakan my.cnf):
mysql < /path/to/audit_log_filter_linux_install.sql
Anda juga dapat mencegah plugin dihapus saat runtime - tambahkan yang berikut di bagian [mysqld]:
audit_log=FORCE_PLUS_PERMANENT
Mulai ulang server untuk menerapkan perubahan. Perhatikan bahwa logging berbasis aturan tidak mencatat peristiwa yang dapat diaudit secara default, jadi untuk membuatnya mencatat semuanya, buat filter:
SELECT audit_log_filter_set_filter(‘log_filter’, ‘{ “filter”: { “log”: true } }’);
Kemudian tetapkan ke akun:
SELECT audit_log_filter_set_user(‘%’, ‘log_filter’);
Perhatikan bahwa plugin audit hanya tersedia di MySQL Enterprise Edition;
Plugin Firewall
Plugin firewall dapat memungkinkan pengguna mengizinkan atau menolak eksekusi pernyataan SQL tertentu berdasarkan pola tertentu. MySQL Enterprise Firewall diperkenalkan di MySQL 5.6.24 - mampu melindungi data dengan memantau, memperingatkan, dan memblokir aktivitas yang tidak sah:mampu memblokir serangan injeksi SQL, memantau ancaman, dan memblokir lalu lintas yang mencurigakan serta mendeteksi intrusi ke data. Firewall juga dapat mencatat pernyataan yang diblokir - pernyataan tersebut dapat diperiksa dan penghitungan pernyataan yang disetujui dan ditolak secara real-time juga dapat diamati.
Untuk menginstal MySQL Enterprise Firewall, cukup aktifkan saat menginstal MySQL Server di Windows, juga dapat diinstal, dinonaktifkan, atau dihapus dengan bantuan MySQL Workbench 6.3.4. Firewall juga dapat diinstal secara manual dengan menjalankan skrip di direktori berbagi instalasi MySQL Anda. Untuk mengaktifkan firewall, tambahkan baris berikut di bawah [mysqld] dan restart server:
mysql_firewall_mode=ON
Firewall juga dapat diaktifkan saat runtime:
SET GLOBAL mysql_firewall_mode = ON;
Atau, untuk mempertahankan firewall (artinya firewall tidak harus diaktifkan kembali pada setiap restart server berikutnya):
SET PERSIST mysql_firewall_mode = ON;
Kemudian, berikan hak istimewa FIREWALL_ADMIN ke akun mana pun yang mengelola firewall dan hak istimewa FIREWALL_USER ke akun mana pun yang seharusnya hanya memiliki akses ke aturan firewallnya sendiri. Juga, berikan hak istimewa EXECUTE untuk prosedur tersimpan firewall di database mysql. Agar firewall berfungsi, daftarkan profil dengannya, lalu latih firewall untuk mengetahui pernyataan yang diizinkan yang dapat dijalankan oleh database dan setelah itu beri tahu firewall untuk mencocokkan pernyataan yang masuk dengan daftar putih yang ditetapkan. Setiap profil memiliki mode operasional - MATI, PEREKAM, MELINDUNGI, atau DETEKSI. OFF menonaktifkan profil, RECORDING melatih firewall, MELINDUNGI mengizinkan atau menolak eksekusi pernyataan dan DETECTING mendeteksi (tetapi tidak memblokir) upaya penyusupan. Aturan untuk profil tertentu dapat diatur ulang dengan menyetel nilainya ke RESET. OFF akan menonaktifkan profil. Untuk menyetel mode, gunakan kueri berikut di mana name adalah nama profil dan OFF adalah mode operasional:
CALL mysql.sp_set_firewall_mode(name, ‘OFF’);
Plugin firewall juga hanya tersedia di MySQL Enterprise Edition.
Mengamankan Cadangan MySQL
Mengenai backup MySQL, Anda memiliki beberapa opsi.
- Jika Anda menggunakan mysqldump, Anda dapat menyimpan nama pengguna dan kata sandi Anda di my.cnf dan memanggil mysqldump seperti itu (perintah berikut akan membuang semua database ke dalam file /home/backup.sql):
$ mysqldump --defaults-extra-file=/var/lib/my.cnf --single-transaction --all-databases > /home/backup.sql
- Dengan menyimpan nama pengguna dan kata sandi Anda di dalam my.cnf, Anda tidak menulis kata sandi Anda di dalam terminal - metode untuk mengambil cadangan lebih aman karena ketika dump sedang menjalankan perintah dapat dilihat melalui kapak ps perintah.
-
Anda juga dapat mempertimbangkan untuk menggunakan mysqldump-secure yang merupakan skrip pembungkus yang sesuai dengan POSIX yang mampu mengompresi dan mengenkripsi cadangan dengan mempertimbangkan keamanan yang kuat .
-
Cadangan dapat dienkripsi dengan menggunakan OpenSSL - cukup ambil cadangan Anda, lalu enkripsi dengan perintah berikut:
$ openssl enc -aes-256-cbc -salt -in backup.tar.gz -out backup.tar.gz.enc -k password
Perintah di atas akan membuat file terenkripsi baru backup.tar.gz.enc di direktori saat ini. File akan dienkripsi dengan kata sandi yang Anda pilih (ganti kata sandi dengan kata sandi yang Anda inginkan). File dapat didekripsi nanti dengan menjalankan perintah berikut:
$ openssl aes-256-cbc -d -in backup.tar.gz.enc -out backup.tar.gz -k password
Ganti sandi dengan sandi Anda.
-
mysqldump memiliki opsi lain untuk mengenkripsi cadangan Anda (contoh berikut juga mengompresnya dengan gzip):
$ mysqldump --all-databases --single-transaction --triggers --routines | gzip | openssl enc -aes-256-cbc -k password > backup.xb.enc
Ganti sandi dengan sandi yang Anda inginkan.
-
Anda juga dapat mengenkripsi cadangan Anda menggunakan mariabackup atau xtrabackup. Berikut ini contoh dari dokumentasi MariaDB:
$ mariabackup --user=root --backup --stream=xbstream | openssl enc -aes-256-cbc -k password > backup.xb.enc
Ganti sandi dengan sandi yang Anda inginkan.
-
Cadangan juga dapat dienkripsi menggunakan ClusterControl - jika opsi enkripsi diaktifkan untuk cadangan tertentu, ClusterControl akan mengenkripsi cadangan menggunakan AES-256 CBC (enkripsi terjadi pada node cadangan). Jika cadangan disimpan di node pengontrol, file cadangan dialirkan dalam format terenkripsi menggunakan socat atau netcat. Jika kompresi diaktifkan, ClusterControl pertama-tama akan mengompres cadangan, setelah itu - mengenkripsinya. Kunci enkripsi akan dihasilkan secara otomatis jika tidak ada, kemudian disimpan di dalam konfigurasi CMON di opsi backup_encryption_key. Ingatlah bahwa kunci ini dikodekan dan harus didekodekan terlebih dahulu. Untuk melakukannya, jalankan perintah berikut:
$ cat /etc/cmon.d/cmon_ClusterID.cnf | grep ^backup_encryption_key | cut -d"'" -f2 | base64 -d > keyfile.key
Perintah akan membaca backup_encryption_key dan mendekode nilainya menjadi keluaran biner. File kunci dapat digunakan untuk mendekripsi cadangan seperti:
$ cat backup.aes256 | openssl enc -d -aes-256-cbc -pass file:/path/to/keyfile.key > backup_file.xbstream.gz
Untuk contoh lainnya, periksa dokumentasi ClusterControl.
Kesimpulan
Dalam posting tentang keamanan MySQL ini, kami membahas beberapa langkah keamanan yang dapat berguna jika Anda merasa perlu untuk memperketat keamanan instance MySQL Anda. Meskipun kami tidak sepenuhnya membahas semuanya, kami merasa bahwa poin-poin ini dapat menjadi titik awal yang baik ketika memperketat keamanan instalasi MySQL Anda. Ambil dari postingan ini apa yang Anda inginkan, lakukan riset Anda sendiri, dan terapkan langkah-langkah keamanan yang paling sesuai dengan situasi Anda.