Salah satu faktor dan dasar terbesar dari tata kelola data adalah keamanan. Ini adalah praktik yang baik untuk menerapkan keamanan basis data setiap kali Anda melibatkan manajemen data Anda untuk konsumsi perusahaan atau massal.
Keamanan data adalah salah satu aspek terpenting dalam mengelola database. Ini memainkan peran penting yang harus diterapkan oleh setiap manajemen basis data. Ketika diterapkan dan dilakukan dengan benar, hasilnya tidak hanya akan meningkatkan keamanan data Anda tetapi juga mempengaruhi stabilitas sistem, meningkatkan siklus hidup pengembangan, meningkatkan kepatuhan data Anda, dan meningkatkan kesadaran keamanan hingga ke tingkat tim Anda. Semua orang tidak ingin data mereka berakhir di tangan yang salah. Jika data dilanggar, tidak hanya membahayakan kerahasiaan dan integritas data Anda, tetapi juga membuat organisasi Anda terbuka terhadap risiko keuangan yang signifikan. Bahkan untuk implementasi manajemen basis data yang sederhana, jika Anda mengetahui seseorang telah menyusup ke sistem Anda, perasaan tidak aman dan takut tentang konsekuensi apa yang akan membawa Anda benar-benar tidak nyaman.
Menentukan apakah koneksi server MySQL Anda aman bergantung pada seberapa aman MySQL mentransmisikan data-in-transit. Dengan koneksi tidak terenkripsi antara klien MySQL dan server, seseorang yang memiliki akses ke jaringan dapat melihat semua lalu lintas Anda dan memeriksa data yang dikirim atau diterima antara klien dan server.
Bila Anda harus memindahkan informasi melalui jaringan dengan cara yang aman, sambungan yang tidak terenkripsi tidak dapat diterima. Untuk membuat segala jenis data tidak dapat dibaca, gunakan enkripsi. Algoritme enkripsi harus menyertakan elemen keamanan untuk menahan berbagai jenis serangan yang diketahui seperti mengubah urutan pesan terenkripsi atau memutar ulang data dua kali.
Tapi MySQL saya aman, kan?
Percaya bahwa MySQL Anda aman tanpa menentukan pemeriksaan stabilitas dan kerentanannya seperti sebuah agama. Anda cenderung percaya bahkan tanpa melihatnya, bahkan tanpa menyentuhnya. Masalahnya, MySQL adalah sebuah teknologi dan keberadaannya tidak didasarkan pada pemikiran abstrak. Itu harus diuji, itu harus dibuktikan, dan itu membutuhkan keamanan dan mengikuti praktik terbaik yang telah diuji juga oleh orang lain.
Menentukan apakah koneksi server MySQL Anda dalam perjalanan aman atau jika dienkripsi bergantung pada "bagaimana Anda mengatur database Anda?" atau "siapa yang mengatur database Anda?".
MySQL mendukung koneksi terenkripsi antara klien dan server menggunakan protokol TLS (Transport Layer Security). TLS kadang-kadang disebut sebagai SSL (Secure Sockets Layer) tetapi MySQL sebenarnya tidak menggunakan protokol SSL untuk koneksi terenkripsi karena enkripsinya lemah dan SSL sudah tidak digunakan lagi untuk TLS. TLS menggunakan algoritma enkripsi untuk memastikan bahwa data yang diterima melalui jaringan publik dapat dipercaya. Ini memiliki mekanisme untuk mendeteksi perubahan data, kehilangan, atau pemutaran ulang. TLS juga menggabungkan algoritme yang menyediakan verifikasi identitas menggunakan standar X.509. SSL atau TLS digunakan secara bergantian, tetapi untuk konteks enkripsi dengan MySQL, TLS digunakan di mana MySQL mendukung koneksi terenkripsi menggunakan protokol TLSv1, TLSv1.1, TLSv1.2, dan TLSv1.3.
X.509 memungkinkan untuk mengidentifikasi seseorang di Internet. Dalam istilah dasar, harus ada beberapa entitas yang disebut “Otoritas Sertifikat” (atau CA) yang memberikan sertifikat elektronik kepada siapa saja yang membutuhkannya. Sertifikat bergantung pada algoritma enkripsi asimetris yang memiliki dua kunci enkripsi (kunci publik dan kunci rahasia). Pemilik sertifikat dapat menunjukkan sertifikat kepada pihak lain sebagai bukti identitas. Sertifikat terdiri dari kunci publik pemiliknya. Data apa pun yang dienkripsi menggunakan kunci publik ini hanya dapat didekripsi menggunakan kunci rahasia yang sesuai, yang dipegang oleh pemilik sertifikat.
Sama seperti Spartan menggunakan Scytale
Scytale dikenal digunakan sebagai cara untuk mengenkripsi dan mendekripsi pesan yang digunakan sekitar 400 SM. oleh Spartan. Mereka akan menulis pesan di selembar papirus (sejenis kertas) yang dililitkan di sekitar tongkat. Penerima hanya dapat menguraikan pesan jika diameter dan ukuran tongkatnya benar. Ini berfungsi sebagai cara untuk mengenkripsi dan menghindari ekstraksi pesan atau data yang tidak sah ke tujuan target.
Sama seperti MySQL, menggunakan protokol dan sandi SSL/TLS adalah cara untuk menghindari seseorang mengekstrak data Anda atau membajak data Anda saat melewati kabel atau melalui internet.
Secara default, program MySQL mencoba terhubung menggunakan enkripsi jika server mendukung koneksi terenkripsi, kembali ke koneksi tidak terenkripsi jika koneksi terenkripsi tidak dapat dibuat. Sejak versi MySQL>=5.7, file TLS/SSL dan RSA dapat dibuat atau dibuat dengan dukungan variabel. Untuk distribusi MySQL yang dikompilasi menggunakan OpenSSL, server MySQL memiliki kemampuan untuk secara otomatis menghasilkan file SSL dan RSA yang hilang saat startup. Auto_generate_certs, sha256_password_auto_generate_rsa_keys, dan caching_sha2_password_auto_generate_rsa_keys (versi>=8.0), variabel sistem mengontrol pembuatan otomatis file-file ini. Variabel ini diaktifkan secara default. Mereka dapat diaktifkan saat startup dan diperiksa tetapi tidak disetel saat runtime.
Secara default, variabel ini disetel ke AKTIF atau diaktifkan. Jika tidak, pengguna dapat memanggil utilitas mysql_ssl_rsa_setup secara manual. Untuk beberapa jenis distribusi, seperti paket RPM dan DEB, pemanggilan mysql_ssl_rsa_setup terjadi selama inisialisasi direktori data. Dalam hal ini, distribusi MySQL tidak perlu dikompilasi menggunakan OpenSSL selama perintah openssl tersedia.
Setelah file-file ini tersedia dan/atau dibuat, MySQL tetap tidak akan menggunakan koneksi enkripsi karena alasan berikut. Seperti disebutkan sebelumnya, secara default, program klien MySQL mencoba membuat koneksi terenkripsi jika server mendukung koneksi terenkripsi, dengan kontrol lebih lanjut tersedia melalui --ssl-mode (atau --ssl <=5.7.11 karena ini sudah usang) pilihan:
-
Secara default, jika koneksi MySQL tidak ditandai dengan --ssl-mode, nilai default diatur ke --ssl-mode=DIINGINKAN. Oleh karena itu, klien mencoba untuk menyambung menggunakan enkripsi, kembali ke sambungan tidak terenkripsi jika sambungan terenkripsi tidak dapat dibuat.
-
Dengan --ssl-mode=REQUIRED, klien memerlukan koneksi terenkripsi dan gagal jika tidak dapat dibuat.
-
Dengan --ssl-mode=DISABLED, klien menggunakan koneksi yang tidak terenkripsi.
-
Dengan --ssl-mode=VERIFY_CA atau --ssl-mode=VERIFY_IDENTITY, klien memerlukan koneksi terenkripsi dan juga melakukan verifikasi terhadap sertifikat CA server dan (dengan VERIFY_IDENTITY) terhadap nama host server dalam sertifikatnya.
Dengan mekanisme default MySQL untuk menggunakan koneksi pilihan, kemungkinan mencoba untuk mencoba menggunakan koneksi terenkripsi atau aman tetapi ini masih menyisakan beberapa hal yang harus dilakukan dan ditentukan.
Seperti yang disebutkan sebelumnya, variabel auto_generate_certs, sha256_password_auto_generate_rsa_keys, dan caching_sha2_password_auto_generate_rsa_keys (versi>=8.0) membantu menghasilkan file SSL/TLS dan RSA yang diperlukan, dengan pengguna normal tanpa persyaratan apa pun selama koneksi akan tetap merasa tidak aman. Misalnya, mari kita buat pengguna bernama dbadmin.
mysql> create user 'dbadmin'@'192.168.40.%' identified by '[email protected]';
Query OK, 0 rows affected (0.01 sec)
mysql> GRANT ALL PRIVILEGES ON *.* TO 'dbadmin'@'192.168.40.%';
Query OK, 0 rows affected (0.01 sec)
Kemudian verifikasi apakah variabel disetel dengan benar yang harus diaktifkan sebagaimana adanya secara default:
mysql> show global variables where variable_name in ('auto_generate_certs','sha256_password_auto_generate_rsa_keys','caching_sha2_password_auto_generate_rsa_keys');
+----------------------------------------------+-------+
| Variable_name | Value |
+----------------------------------------------+-------+
| auto_generate_certs | ON |
| caching_sha2_password_auto_generate_rsa_keys | ON |
| sha256_password_auto_generate_rsa_keys | ON |
+----------------------------------------------+-------+
3 rows in set (0.00 sec)
Memverifikasi apakah file dibuat sesuai dengan jalur /var/lib/mysql/ (atau jalur datadir untuk MySQL ini):
$ find /var/lib/mysql -name "*.pem"
/var/lib/mysql/ca-key.pem
/var/lib/mysql/ca.pem
/var/lib/mysql/server-key.pem
/var/lib/mysql/server-cert.pem
/var/lib/mysql/client-key.pem
/var/lib/mysql/client-cert.pem
/var/lib/mysql/private_key.pem
/var/lib/mysql/public_key.pem
Kemudian verifikasi apakah file SSL dimuat dengan benar:
mysql> show global variables like 'ssl%';
+---------------+-----------------+
| Variable_name | Value |
+---------------+-----------------+
| ssl_ca | ca.pem |
| ssl_capath | |
| ssl_cert | server-cert.pem |
| ssl_cipher | |
| ssl_crl | |
| ssl_crlpath | |
| ssl_fips_mode | OFF |
| ssl_key | server-key.pem |
+---------------+-----------------+
8 rows in set (0.00 sec)
Tentukan keamanan koneksi Anda
Sekarang, ini terlihat bagus. Ini juga berarti bahwa MySQL siap menerima koneksi terenkripsi. Tetapi menghubungkan ke MySQL apa adanya, sebagaimana dinyatakan itu akan menggunakan --ssl-mode=PREFFERED secara default, atau jika --ssl-mode tidak ditentukan, itu masih akan gagal untuk menggunakan koneksi yang tidak terenkripsi. Lihat di bawah:
$ mysql [email protected] -h 192.168.40.110 -udbadmin -e "status;"|grep ssl -i
SSL: Tidak digunakan
Ini menunjukkan bahwa itu tidak menggunakan koneksi aman. Memeriksa variabel status sesi SSL jika ada sandi yang digunakan mengungkapkan kosong:
mysql> show global status like 'ssl%';
+--------------------------------+--------------------------+
| Variable_name | Value |
+--------------------------------+--------------------------+
| Ssl_accept_renegotiates | 0 |
| Ssl_accepts | 2 |
| Ssl_callback_cache_hits | 0 |
| Ssl_cipher | |
| Ssl_cipher_list | |
| Ssl_client_connects | 0 |
| Ssl_connect_renegotiates | 0 |
| Ssl_ctx_verify_depth | 18446744073709551615 |
| Ssl_ctx_verify_mode | 5 |
| Ssl_default_timeout | 0 |
| Ssl_finished_accepts | 2 |
| Ssl_finished_connects | 0 |
| Ssl_server_not_after | Aug 28 12:48:46 2031 GMT |
| Ssl_server_not_before | Aug 30 12:48:46 2021 GMT |
| Ssl_session_cache_hits | 0 |
| Ssl_session_cache_misses | 0 |
| Ssl_session_cache_mode | SERVER |
| Ssl_session_cache_overflows | 0 |
| Ssl_session_cache_size | 128 |
| Ssl_session_cache_timeouts | 0 |
| Ssl_sessions_reused | 0 |
| Ssl_used_session_cache_entries | 0 |
| Ssl_verify_depth | 0 |
| Ssl_verify_mode | 0 |
| Ssl_version | |
+--------------------------------+--------------------------+
25 rows in set (0.002 sec)
Menegakkan koneksi aman
Karena menunjukkan bahwa koneksi masih belum diamankan, MySQL memperkenalkan variabel require_secure_transport yang mengharuskan semua koneksi yang akan dibuat harus dienkripsi dan diamankan. Setiap upaya untuk terhubung untuk koneksi yang tidak aman gagal. Misalnya, mengaktifkannya di server:
mysql> set global require_secure_transport=1;
Query OK, 0 rows affected (0.00 sec)
Mencoba terhubung sebagai klien menggunakan koneksi tidak terenkripsi akan gagal:
$ mysql [email protected] -h 192.168.40.110 -udbadmin
ERROR 3159 (HY000): Connections using insecure transport are prohibited while --require_secure_transport=ON.
Untuk terhubung dengan sukses dan aman, Anda perlu menentukan variabel ssl-ca, ssl-cert, ssl-key. Lihat di bawah:
$ mysql [email protected] -h 192.168.40.110 -udbadmin --ssl-ca=/tmp/pem/ca.pem --ssl-cert=/tmp/pem/server-cert.pem --ssl-key=/tmp/pem/server-key.pem -e "show global status like 'ssl%'\G"
*************************** 1. row ***************************
Variable_name: Ssl_accept_renegotiates
Value: 0
*************************** 2. row ***************************
Variable_name: Ssl_accepts
Value: 16
*************************** 3. row ***************************
Variable_name: Ssl_callback_cache_hits
Value: 0
*************************** 4. row ***************************
Variable_name: Ssl_cipher
Value: TLS_AES_256_GCM_SHA384
*************************** 5. row ***************************
Variable_name: Ssl_cipher_list
Value: TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-DSS-AES128-SHA256:DHE-DSS-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-DSS-AES128-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES256-SHA:CAMELLIA256-SHA:CAMELLIA128-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA
*************************** 6. row ***************************
Variable_name: Ssl_client_connects
Value: 0
*************************** 7. row ***************************
Variable_name: Ssl_connect_renegotiates
Value: 0
*************************** 8. row ***************************
Variable_name: Ssl_ctx_verify_depth
Value: 18446744073709551615
*************************** 9. row ***************************
Variable_name: Ssl_ctx_verify_mode
Value: 5
*************************** 10. row ***************************
Variable_name: Ssl_default_timeout
Value: 7200
*************************** 11. row ***************************
Variable_name: Ssl_finished_accepts
Value: 11
*************************** 12. row ***************************
Variable_name: Ssl_finished_connects
Value: 0
*************************** 13. row ***************************
Variable_name: Ssl_server_not_after
Value: Aug 28 12:48:46 2031 GMT
*************************** 14. row ***************************
Variable_name: Ssl_server_not_before
Value: Aug 30 12:48:46 2021 GMT
*************************** 15. row ***************************
Variable_name: Ssl_session_cache_hits
Value: 0
*************************** 16. row ***************************
Variable_name: Ssl_session_cache_misses
Value: 0
*************************** 17. row ***************************
Variable_name: Ssl_session_cache_mode
Value: SERVER
*************************** 18. row ***************************
Variable_name: Ssl_session_cache_overflows
Value: 0
*************************** 19. row ***************************
Variable_name: Ssl_session_cache_size
Value: 128
*************************** 20. row ***************************
Variable_name: Ssl_session_cache_timeouts
Value: 0
*************************** 21. row ***************************
Variable_name: Ssl_sessions_reused
Value: 0
*************************** 22. row ***************************
Variable_name: Ssl_used_session_cache_entries
Value: 0
*************************** 23. row ***************************
Variable_name: Ssl_verify_depth
Value: 18446744073709551615
*************************** 24. row ***************************
Variable_name: Ssl_verify_mode
Value: 5
*************************** 25. row ***************************
Variable_name: Ssl_version
Value: TLSv1.3
Atau, jika pengguna dibuat dengan SSL DIBUTUHKAN misalnya, itu juga harus menghubungkan Anda menggunakan SSL terlepas dari kebutuhan_secure_transport dinonaktifkan, yang merupakan nilai defaultnya. Perhatikan bahwa, jika require_secure_transport diaktifkan, kemampuannya melengkapi persyaratan SSL per akun, yang diutamakan. Oleh karena itu, jika sebuah akun didefinisikan dengan REQUIRE SSL, mengaktifkan require_secure_transport tidak memungkinkan penggunaan akun untuk terhubung menggunakan file soket Unix.
Memastikan penerapan server MySQL dienkripsi dan aman
Bebas repot adalah hal yang selalu kami nantikan sehingga tidak ada masalah dan kekhawatiran lain yang perlu dikhawatirkan. ClusterControl menyebarkan database MySQL menggunakan koneksi terenkripsi dan menghasilkan sertifikat SSL dan RSA untuk Anda. Misalnya, tangkapan layar di bawah ini menunjukkan aktivitas pekerjaan perintah Create Cluster dari ClusterControl.
Ini menyiapkan file SSL dan RSA dan menempatkannya di /etc/ jalur mysql/certs/ seperti di bawah ini:
mysql> show global variables like 'ssl%';
+---------------+--------------------------------+
| Variable_name | Value |
+---------------+--------------------------------+
| ssl_ca | /etc/mysql/certs/server_ca.crt |
| ssl_capath | |
| ssl_cert | /etc/mysql/certs/server.crt |
| ssl_cipher | |
| ssl_crl | |
| ssl_crlpath | |
| ssl_key | /etc/mysql/certs/server.key |
+---------------+--------------------------------+
7 rows in set (0.00 sec)
Kemudian ClusterControl juga mengelompokkan file SSL dan RSA yang dihasilkan secara terpusat di bawah panel navigasi Manajemen Kunci seperti yang ditunjukkan di bawah ini:
Setelah diterapkan, yang harus Anda lakukan adalah membuat pengguna dengan SSL DIBUTUHKAN atau memiliki require_secure_transport jika Anda ingin menerapkan lapisan terenkripsi dan aman untuk koneksi server MySQL Anda.