Minule jsme se podívali na přehled balíků MySQL a MariaDB ve Fedoře 24, dnes se podíváme, jak si server s databází sami zprovoznit. Nasazení a zabezpečení jakéhokoliv produkčního serveru není jednoduchá záležitost a pro databázové systémy toto platí dvojnásob, neboť nejen že data mohou být zneužita, ale můžeme o ně i přijít. Proto se v rámci tohoto článku zaměříme pouze na nasazení serveru určeného pro vývoj. V článku budu pracovat pouze s balíky MariaDB databáze, nicméně alternativa MySQL (dostupná v balíku community-mysql) funguje téměř totožně.

Začneme samozřejmě instalací:

$ sudo dnf install mariadb-server

Pokud máme čistý stroj, můžeme rovnou server nastartovat, neboť na rozdíl například od PostgreSQL, adresář s daty (ve Fedoře /var/lib/mysql) bude inicializován automaticky při prvním spuštění.

$ sudo systemctl start mariadb

Ihned poté máme k dispozici root uživatele (jedná se o hlavního uživatele pro databázi, ne o root uživatele v rámci systému), který má nastavené prázdné heslo. Připojit se k serveru lokálně pomocí unix socketu (/var/lib/mysql/mysql.sock) můžeme následovně:

$ mysql -u root

Takto můžeme ihned začít pracovat se serverem, nicméně ani pro vývoj není dobré mít databázi takto nezabezpečenou. Pojďme zacelit alespoň ty největší bezpečnostní mezery. Pro jednoduché zabezpečení existuje utilitka mysql_secure_installation, takže pojďme začít s ní:

$ sudo mysql_secure_installation

Budeme dotázáni na několik základních otázek, jako nastavení hesla pro root uživatele, odstranění testovací databáze, anonymních uživatelů a vhodné je i zamezit vzdálenému přihlášení jako root. V podstatě stačí na všechny otázky odpovědět kladně.

Dále můžeme změnit, na kterých rozhraních bude databázový démon naslouchat, pro vývoj bude často stačit localhost, což je výchozí konfigurace, ale pro použití vzdáleně musíme upravit (bind-address). Tuto a jiné volby můžeme upravit v souborech ve složce /etc/my.cnf.d, což je adresář sdílený jak serverovou, tak klientskou částí MariaDB i MySQL. Například právě pro výše zmíněnou změnu, nadefinujeme hodnotu bind-address=0.0.0.0 v souboru /etc/my.cnf.d/mariadb-server.cnf v sekci [mysqld]. Po změně konfigurace musíme restartovat server:

$ sudo systemctl restart mariadb

Vytvoření databáze a uživatele pro aplikaci

Běží nám tedy pro vývoj rozumně zabezpečený démon MariaDB a máme root přístup. Nicméně ten nechceme použít v aplikaci -- nechceme přeci nechat útočníkovi, který by našel skulinu v kódu aplikace, víc přístupu i v databázi, než je nutné. Vytvoříme tedy uživatele s heslem a vlastní databází, ve které může pracovat s daty, ale nesmí měnit jejich strukturu.

Pro práci s uživateli a databázemi se připojíme jako root, nyní již musíme zadat heslo:

$ mysql -u root -p

Nejdříve vytvoříme databázi:

MariaDB [(none)]> CREATE DATABASE `appdb`;
Query OK, 1 row affected (0.00 sec)

A nyní uživatele, který se bude autentizovat heslem 'secretpass':

MariaDB [(none)]> CREATE USER `franta`@`localhost` IDENTIFIED BY 'secretpass';
Query OK, 0 rows affected (0.01 sec)
MariaDB [(none)]> GRANT SELECT,INSERT,UPDATE,DELETE ON appdb.* TO `franta`@`localhost`;
Query OK, 0 rows affected (0.00 sec)

Můžeme i vytvořit tabulky, neboť uživatel appuser na to nebude mít práva:

MariaDB [(none)]> CREATE TABLE `appdb`.`employees` (id INT, name VARCHAR(128));
Query OK, 0 rows affected (0.01 sec)

Nyní řekneme serveru, aby si znovu načetl tabulky s právy a opustíme konzoli:

MariaDB [(none)]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> quit
Bye

Nyní můžeme vyzkoušet, zda vše proběhlo, jak má, tedy zda uživatel franta může pracovat s daty:

$ mysql -u franta -p appdb

MariaDB [appdb]> INSERT INTO `employees` VALUES (1, "Honza");
Query OK, 1 row affected (0.01 sec)

MariaDB [appdb]> SELECT * from `employees`;
+------+-------+
| id   | name  |
+------+-------+
|    1 | Honza |
+------+-------+
1 row in set (0.00 sec)

Vše v pořádku, takže nyní stačí v aplikaci použít správné přístupové údaje a je to hotové. Ledaže bychom chtěli mít čistou databázi pro každou aplikaci zvlášť, to by se nám hodil nějaký kontejner.

MariaDB v Docker kontejneru

Docker kontejnery jsou stále více a více oblíbené mezi vývojáři, takže není překvapení, že MariaDB a MySQL kontejnery postavené na Fedořích balících jsou k dispozici a to i na [Docker Hubu](https://hub.docker.com). Jejich zdroje jsou k dispozici v repozitáři [Fedora-dockerfiles](https://github.com/fedora-cloud/Fedora-Dockerfiles) a kontejnery jsou na Docker Hubu k dispozici jako fedora/mysql a fedora/mariadb.

Takový kontejner s MariaDB databází můžeme použít právě zejména pro vývoj, místo konfigurování databázového serveru, jak jsme to udělali výše. Nemusíme totiž instalovat balíky a ovlivňovat prostředí celého systému, což může být kontraproduktivní nebo alespoň zbytečné. Vše, co je potřeba udělat, jsou následující kroky:

Nainstalovat a spustit Docker démon:

$ sudo dnf install docker
$ sudo systemctl start docker

Nahrát obraz s požadovanou databází z Docker hubu:

$ sudo docker pull fedora/mariadb

Připravíme adresář pro data:

$ sudo mkdir data
$ sudo chown 27:27 data
$ sudo chcon -t svirt_sandbox_file_t data

A nyní můžeme nastartovat kontejner s několika argumenty, které zařídí spuštění s vytvořením shodného uživatele a databáze, jako jsme viděli u klasického démona výše.

$ sudo docker run -v "`pwd`/data:/var/lib/mysql/data:Z" \
  -e MYSQL_USER=franta -e MYSQL_PASSWORD=secretpass \
  -e MYSQL_DATABASE=appdb -d -p 13306:3306 fedora/mariadb

Nyní máme spuštěný kontejner s MariaDB databází, která ukládá svoje data do lokálního adresáře data a exportuje port 3306 zevnitř kontejneru ven jako 13306 na hostující systém. Pro připojení k takové databázi musíme akorát použít síťový socket, neboť unix socket není samozřejmě kontejnerem vytvořen.

$ mysql -h 127.0.0.1 -P 13306 -u franta -p appdb

To je vše a jak je vidět, zejména pro vývoj může být použití kontejneru velmi efektivní cestou, jak se dostat k rozběhnuté databázi. Více o Docker kontejnerech na Fedoře se dozvíte ve článcích, které tu vyšly nedávno (https://mojefedora.cz/zaciname-s-dockerem-na-fedore/).