This document discusses securing MariaDB installations through socket authentication and user account management. It recommends configuring MariaDB to use socket authentication for the root user instead of passwords to eliminate the need for root password management across servers. It also recommends creating individual user accounts with passwords for applications instead of shared accounts, restricting MariaDB to only listen on localhost, encrypting connections using SSL, and encrypting data at rest. The document provides configuration examples for implementing these recommendations in MariaDB.
5. Password management is a pain
ssh host1.example.com
Password: XXX
$ mysql -u root -p
Password: AAA
ssh host1.example.com
Password: ZZZ
$ mysql -u root -p
Password: BBB
What if the
sysadmin has
x 20 to manage?
6. Automating passwords hurts even more
Example: Ansible scripts for cluster
# Galera replicates users table and nodes need to have the
same debian-sys-maint configs
- name: update debian-sys-maint user
mysql_user:
name: debian-sys-maint
password: "{{ galera_debian_sys_maint_password }}"
priv: "*.*:ALL,GRANT"
append_privs: yes
host: localhost
state: present
# Update same debian-sys-maint configs for all nodes
- name: update debian.cnf
template:
src: debian.cnf.j2
dest: /etc/mysql/debian.cnf
mode: 0600
owner: mysql
group: root
- name: Create xtrabackup user and grant priviledges
mysql_user:
name: xtrabackup
password: "{{ galera_xtrabackup_password }}"
priv: "*.*:RELOAD,LOCK TABLES,REPLICATION CLIENT,SUPER"
append_privs: yes
host: localhost
state: present
- name: update mysql root password for all root accounts
mysql_user:
name: root
host: "{{ item }}"
priv: "*.*:ALL,GRANT"
password: "{{ galera_root_password }}"
with_items:
- "{{ inventory_hostname }}"
- 127.0.0.1
- ::1
- localhost
ignore_errors: True
Failing to sync the password configuration
makes the node fail completely!
7.
8. How ”secure storage” is an
environment variable?
docker run -d --name mysql -p 3306:3306
-e MYSQL_ROOT_PASSWORD=password
mariadb:latest
ps -e?
grep .bash_history?
9. Don't waste time on secrets management.
Secure yourself against leaking passwords.
Don't use passwords at all.
Because you dont' have to.
10. The irony
ssh host1.example.com
Password: XXX
root$ mysql -u root -p
Password: ABC
mysqld: wrong password!
root$ service mysql stop
root$ scp -r /var/lib/mysql
host2.example.com
root$ rm -rf
root$ echo ”Revenge!” | wall
11. Goal: eliminate the root passwords
Yes, Debian/Ubuntu has two
MariaDB> select host,user,plugin
from user;
+-----------+------------------+--------+
| host | user | plugin |
+-----------+------------------+--------+
| localhost | root | |
| htpc | root | |
| 127.0.0.1 | root | |
| ::1 | root | |
| localhost | debian-sys-maint | |
+-----------+------------------+--------+
$ cat /etc/mysql/debian.cnf
# Automatically generated for Debian scripts.
DO NOT TOUCH!
[client]
host = localhost
user = debian-sys-maint
password = z3tm0eLnX6k2fnvb
socket = /var/run/mysqld/mysqld.sock
[mysql_upgrade]
host = localhost
user = debian-sys-maint
password = z3tm0eLnX6k2fnvb
socket = /var/run/mysqld/mysqld.sock
basedir = /usr
12. unix_socket to the rescue!
MariaDB> install plugin unix_socket SONAME
'auth_socket';
MariaDB> grant usage on *.* to 'root'@'localhost'
identified via unix_socket;
MariaDB> select host,user,plugin from user;
+-----------+------------------+-------------+
| host | user | plugin |
+-----------+------------------+-------------+
| localhost | root | unix_socket |
| htpc | root | |
| 127.0.0.1 | root | |
| ::1 | root | |
| localhost | debian-sys-maint | |
+-----------+------------------+-------------+
13. unix_socket in action
root$ mysql -u root
Welcome to the MariaDB monitor. Commands end with ;
Your MariaDB connection id is 38
Server version: 10.0.26
user$ sudo mysql -u root
Welcome to the MariaDB monitor. Commands end with ;
Your MariaDB connection id is 29
Server version: 10.0.26
MariaDB [(none)]>
14. unix_socket in action
root$ mysql
Welcome to the MariaDB monitor. Commands end with ;
root$ mysql -u root -psurelywrongpassword
Welcome to the MariaDB monitor. Commands end with ;
root$ mysql -u somebodyelse
ERROR 1045 (28000): Access denied for user
'somebodyelse'@'localhost' (using password: NO)
15. Caveat: logging in as root with password from the
local host (using whatever name) will stop working
user$ mysql -u root -p
Enter password:
ERROR 1698 (28000): Access
denied for user
'root'@'localhost'
user$ mysql -u root -h
127.0.0.1 -p
Enter password:
ERROR 1698 (28000): Access
denied for user
'root'@'localhost'
16. Great! When will this be by default?
● New installs in Debian testing since Dec
2015, will be in Stretch
● New installs Ubuntu since 15.10+
● Future: official in all MariaDB releases
..but only new installs. We don't want to
mess up password usage in normal
version upgrades.
17. Debian credits and contributions
Development
● by me (mariadb.org) and Daniel Black (openquery.com.au)
● in Debian (http://git.debian.org/?p=pkg-mysql/mariadb-10.0.git)
Contributions are welcome!
18. Create per user accounts
root$ mysql
Welcome to the MariaDB monitor. Commands end with ;
MariaDB> CREATE DATABASE mydb;
MariaDB> GRANT ALL ON mydb.* TO myapp@localhost
IDENTIFIED BY 'pass123';
MariaDB> GRANT SELECT,INSERT,UPDATE ON mydb.* TO
myremoteapp@'192.168.1.%' IDENTIFIED BY '456pass'
REQUIRE SSL;
(Extra tip: Don't flush. Grant does it automatically.)
New in 10.1: Password policies
New in 10.2: REQUIRE SSL in CREATE USER
19. Restrict connections
/etc/mysql/mariadb.conf.d/50-server.cnf
[mysqld]
# Instead of skip-networking the default is now to
# listen only on localhost which is more compatible
# and is not less secure.
bind-address = 127.0.0.1
Options:
- unix socket = enable skip-networking
- bind to localhost = default in Debian
- bind to public IP = disable bind-address
20. Encrypt connections 1/2
/etc/mysql/mariadb.conf.d/50-server.cnf
[mysqld]
# For generating SSL certificates I recommend
# the OpenSSL GUI "tinyca".
ssl-ca=/etc/mysql/cacert.pem
ssl-cert=/etc/mysql/server-cert.pem
ssl-key=/etc/mysql/server-key.pem
ssl-cipher=TLSv1.2
MariaDB has supported the TLSv1.2 protocol
since 10.0.15 with OpenSSL (not in Debian).
Limit MariaDB to TLSv1.2 ciphers only with
--ssl-cipher=TLSv1.2
22. Encrypt data at rest
/etc/mysql/mariadb.conf.d/50-server.cnf
[mysqld]
!include enable_encryption.preset
Database level encryption is superior to data
level or filesystem level encryption in terms of
flexibility and protection. Overhead is only
3–5%. Implementation in MariaDB was
contributed by Google.
But you really need to read up a lot :)