How to enable Encryption for MariaDB
Last updated: October 29th 2024
Introduction
By default, MariaDB stores table data in plain text inside “*.ibd” files on your server. Anyone with read access to the directory can obtain and read tables in your database which might be a security concern.
MariaDB versions greater than 10.1 have a lot of great security features including the support for data encryption, which can be enabled in a few steps. In this article, we’ll explain how you can encrypt your MariaDB databases and tables to avoid the risk of data theft.
Prerequisites
- A fresh Webdock cloud Ubuntu instance.
- You have shell (SSH) access to your VPS.
Please note: If you are a Webdock user, you can simply run the "Enable MariaDB Encryption" script (find it in the Script Library) which performs all the below actions as well as forces encryption for new DB tables.
Setting Up
As mentioned in the introduction, MariaDB doesn’t use table encryption by default. So anyone can read plaintext data stored in them. MySQL tables are stored in *.ibd file formats and can be read using the “strings” command.
These files are usually located in “/var/lib/mysql/” directory but if not, they can be found using the “find” command, and then parsed to “strings” command to retrieve clean plaintext data.
# find / -name *.ibd 2>/dev/null
Sample output:
/var/lib/mysql/phpmyadmin/pma__users.ibd /var/lib/mysql/test/lorem.ibd ...snip...
Then
# strings /var/lib/mysql/test/lorem.ibd | head -n 20 OR # find / -name *.ibd 2>/dev/null | xargs strings
You’ll get plaintext table data shown in the output.
Generate Keys
In order to enable encryption in MariaDB, you’ll first need to generate encrypted keys that’ll be used in encryption.
Generate random 4-5 HEX strings using openssl utility, starting with the line number and a semicolon “;”.
# sudo su # mkdir -p /etc/mysql/encryption # cd /etc/mysql/encryption # echo "1;"$(openssl rand -hex 32) > keys # echo "2;"$(openssl rand -hex 32) >> keys # echo "3;"$(openssl rand -hex 32) >> keys # echo "4;"$(openssl rand -hex 32) >> keys
This is how these keys will look like
# cat keys
Sample output:
1;d87bd3a4eddbf6ca7312b35f49930833507a7e3470a65a5c0e99525815025afe 2;e916611f0e7d091c33913f3bebd70f475b40dd7fe2f7f63d384ebf4a74181ecf 3;3d69be819dfcf68eb0333651d4d8e88592b56bff59f5e85c774e61129b3b5138 4;e7b0144fa62372278ac25218eb52c61ff8a993c25ec9d2a9edca3aa0355ae0b8
Now, encrypt these keys with a long random password. You can either use your own personal password or you can generate one using openssl.
# openssl rand -hex 128 > password_file
Now encrypt “keys” file using this long random password.
# openssl enc -aes-256-cbc -md sha1 -pass file:password_file -in keys -out keys.enc
The above command will create an encrypted key file “keys.enc” which MariaDB will use to encrypt tables.
Updating MariaDB Configuration
MariaDB uses the “file_key_management” plugin to encrypt tables. We’ll specify the password and key in the database configuration file. MariaDB configuration files are usually located in “/etc/mysql”, by default it reads all “.cnf” files located in “/etc/mysql/mariadb.conf.d”.
You can add the following lines in “/etc/mysql/my.cnf” or create a new configuration file.
# sudo vim /etc/mysql/mariadb.conf.d/encryption.cnf
Paste the following content:
[mariadb] ## File Key Management plugin_load_add = file_key_management file_key_management_filename = /etc/mysql/encryption/keys.enc file_key_management_filekey = FILE:/etc/mysql/encryption/password_file file_key_management_encryption_algorithm = aes_cbc ## InnoDB/XtraDB Encryption Setup innodb_default_encryption_key_id = 1 innodb_encrypt_tables = ON innodb_encrypt_log = ON innodb_encryption_threads = 4 ## Aria Encryption Setup aria_encrypt_tables = ON ## Temp & Log Encryption encrypt-tmp-disk-tables = 1 encrypt-tmp-files = 1 encrypt_binlog = ON
After that, change ownership and permission of these sensitive files so no other user can read it.
# cd /etc/mysql/ # sudo chown -R mysql:root ./encryption # sudo chmod 500 /etc/mysql/encryption/
# cd ./encryption # chmod 400 keys.enc password_file # chmod 644 /etc/mysql/mariadb.conf.d/encryption.cnf
Restart the database service.
# sudo service mysql restart OR # sudo service mariadb restart
Encrypting Database Tables
After the configuration has been applied, you can encrypt existing tables in your database using the ‘alter’ command with “ENCRYPTED=YES” option.
# mysql -h 127.0.0.1 -u root Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 4 Server version: 10.1.10-MariaDB Source distribution Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | test | +--------------------+ 2 rows in set (0.001 sec) MariaDB [(none)]> use test; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed MariaDB [test]> show tables; +----------------+ | Tables_in_test | +----------------+ | lorem | +----------------+ 1 row in set (0.001 sec) MariaDB [test]> alter table lorem ENCRYPTED=Yes; Query OK, 0 rows affected (0.002 sec) Records: 0 Duplicates: 0 Warnings: 0 MariaDB [test]>
To decrypt the table: Use the same alter command but set "ENCRYPTION=No"
Verify that encryption has been applied by running “strings” command again on the database file. You’ll get unreadable encrypted data in the output
# strings /var/lib/mysql/test/lorem.ibd | head -n 20
While creating new tables, you can supply the extra ‘ENGINE=InnoDB ENCRYPTED=YES’ option if you want the table to be encrypted.
MariaDB [test]> CREATE TABLE ipsum ( UserId INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY, FirstName VARCHAR(30) NOT NULL, LastName VARCHAR(30) NOT NULL ) ENGINE=InnoDB ENCRYPTED=YES;
Or if you don’t want users to create tables without encryption, add this extra line in your encryption configuration file, so that all new tables are encrypted by default.
# sudo vim /etc/mysql/mariadb.conf.d/encryption.cnf ...snip... innodb-encrypt-tables=FORCE ...snip...
You can verify the above steps by running the “strings” command on “.*ibd” files to check whether the encryption is working or not.
Encrypting All Tables on Specific Database
If you want to encrypt all tables of a specific database, follow these instructions.
To enable encryption on all tables within a specific database, start by generating the necessary ALTER TABLE commands. This will prepare a list of commands to apply encryption to each table.
Step 1: Switch to the Database
USE your_database_name;
Step 2: Generate Encryption Commands for All Tables
Run the following query to generate the ALTER TABLE statements needed to enable encryption on each table in your chosen database. Replace "your_database_name" with the name of your database.
SELECT GROUP_CONCAT(CONCAT('ALTER TABLE ', table_name, ' ENCRYPTED=\'YES\'') SEPARATOR ';\n') FROM information_schema.tables WHERE table_schema = 'your_database_name';
Example Output:
ALTER TABLE table1 ENCRYPTED='YES'; ALTER TABLE table2 ENCRYPTED='YES'; ALTER TABLE table3 ENCRYPTED='YES'; ALTER TABLE table4 ENCRYPTED='YES'; ALTER TABLE table5 ENCRYPTED='YES';
Step 3: Execute the Generated Commands
Once the commands are generated as shown above, copy and execute each ALTER TABLE command to enable encryption on the tables.
Conclusion
In this article, we learned how we can configure MariaDB to encrypt our database tables for enhanced security. If you want to get more information, please refer to their official documentation here.
Thanks go out to community members Sorin and Usama for the research and writing of this article.
Related articles
-
Server Security Checklist
In this article we list a number of things you should check if you are setting up a server from scratch as well as a few things which can enhance security on our Perfect Server Stacks.
Last updated: November 10th 2022
-
How to check for open ports on your Ubuntu server
This article details various approaches to finding out which ports are open and accessible on your server.
Last updated: November 10th 2022
-
How to work with your firewall (UFW - Uncomplicated Firewall)
In this article we show how UFW - or Uncomplicated Firewall - works along with common commands and usage examples.
Last updated: January 10th 2024
-
SSH Security Configuration Settings
This article lists various settings for the SSH Daemon which impact server security.
Last updated: February 1st 2024
-
How to configure Fail2Ban for common services
How fail2ban can be configured for common services as well as how to utilize the fail2ban CLI tools to check status of various jails, unbanning users and more.
Last updated: August 22nd 2023
-
How to Secure Nginx with Naxsi Firewall on Ubuntu 18.04 VPS
This Article describes how you can set up and configure Naxsi firewall on a Webdock LEMP stack on Ubuntu Bionic 18.04.
Last updated: November 10th 2022
-
How to Secure Nginx with Naxsi Firewall on Ubuntu 20.04 VPS
This Article describes how you can set up and configure Naxsi firewall on a Webdock LEMP stack on Ubuntu Focal 20.04.
Last updated: March 8th 2024
-
How to configure Security Headers in Nginx and Apache
Here we outline which security headers are important to set in different scenarios in Nginx and Apache.
Last updated: November 10th 2022
-
How to Scan Your Webdock Server for Malware and Virus
This guide provides basic step-by-step instructions to install various tools to scan your server for malware and viruses.
Last updated: July 19th 2023
-
How To Use Our Free BotGuard Bot Protection
In this article we show you how to activate and use our Free BotGuard Bot Protection which is included for free with all our VPS servers.
Last updated: November 4th 2024
-
Enhancing Nginx Security with IP Filtering and Password
A guide to enhance Nginx security with IP filtering (specific IP, and, IP ranges) and Password
Last updated: November 25th 2023
-
Securing Ubuntu: How to Detect System Vulnerabilities
Detect system vulnerabilities using Vuls
Last updated: December 20th 2023
-
Secure VPS Communication with SSL and UFW
A detailed guide to securely your communicate with your servers without requiring a VLAN setup.
Last updated: March 4th 2024
-
Configuring UFW and Fail2Ban to Mitigate Basic DDos Attacks
Instructions to protect your server from basic DDos attacks using UFW and Fail2Ban
Last updated: May 28th 2024