X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=modules%2Fprivate%2Fdatabases%2Fmariadb.nix;fp=modules%2Fprivate%2Fdatabases%2Fmariadb.nix;h=21f4359957f8be4225f070d5bd52f8a2e4c57a7b;hb=182ae57f53731be220075bc87aff4d47a35563b8;hp=0000000000000000000000000000000000000000;hpb=6c97d2d715620a1cdc3b8a785174590ec0dafb98;p=perso%2FImmae%2FConfig%2FNix.git diff --git a/modules/private/databases/mariadb.nix b/modules/private/databases/mariadb.nix new file mode 100644 index 0000000..21f4359 --- /dev/null +++ b/modules/private/databases/mariadb.nix @@ -0,0 +1,125 @@ +{ lib, pkgs, config, myconfig, ... }: +let + cfg = config.myServices.databases.mariadb; +in { + options.myServices.databases = { + mariadb = { + enable = lib.mkOption { + default = cfg.enable; + example = true; + description = "Whether to enable mariadb database"; + type = lib.types.bool; + }; + dataDir = lib.mkOption { + type = lib.types.path; + default = "/var/lib/mysql"; + description = '' + The directory where Mariadb stores its data. + ''; + }; + # Output variables + socketsDir = lib.mkOption { + type = lib.types.path; + default = "/run/mysqld"; + description = '' + The directory where Mariadb puts sockets. + ''; + }; + sockets = lib.mkOption { + type = lib.types.attrsOf lib.types.path; + default = { + mysqld = "${cfg.socketsDir}/mysqld.sock"; + }; + readOnly = true; + description = '' + Mariadb sockets + ''; + }; + }; + }; + + config = lib.mkIf cfg.enable { + networking.firewall.allowedTCPPorts = [ 3306 ]; + + # for adminer, ssl is implemented with mysqli only, which is + # currently disabled because it’s not compatible with pam. + # Thus we need to generate two users for each 'remote': one remote + # with SSL, and one localhost without SSL. + # User identified by LDAP: + # CREATE USER foo@% IDENTIFIED VIA pam USING 'mysql' REQUIRE SSL; + # CREATE USER foo@localhost IDENTIFIED VIA pam USING 'mysql'; + services.mysql = { + enable = true; + package = pkgs.mariadb; + dataDir = cfg.dataDir; + extraOptions = '' + ssl_ca = ${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt + ssl_key = /var/lib/acme/mysql/key.pem + ssl_cert = /var/lib/acme/mysql/fullchain.pem + ''; + }; + + users.users.mysql.extraGroups = [ "keys" ]; + security.acme.certs."mysql" = config.myServices.databasesCerts // { + user = "mysql"; + group = "mysql"; + plugins = [ "fullchain.pem" "key.pem" "account_key.json" ]; + domain = "db-1.immae.eu"; + postRun = '' + systemctl restart mysql.service + ''; + }; + + secrets.keys = [ + { + dest = "mysql/mysqldump"; + permissions = "0400"; + user = "root"; + group = "root"; + text = '' + [mysqldump] + user = root + password = ${myconfig.env.databases.mysql.systemUsers.root} + ''; + } + { + dest = "mysql/pam"; + permissions = "0400"; + user = "mysql"; + group = "mysql"; + text = with myconfig.env.databases.mysql.pam; '' + host ${myconfig.env.ldap.host} + base ${myconfig.env.ldap.base} + binddn ${dn} + bindpw ${password} + pam_filter ${filter} + ssl start_tls + ''; + } + ]; + + services.cron = { + enable = true; + systemCronJobs = [ + '' + 30 1,13 * * * root ${pkgs.mariadb}/bin/mysqldump --defaults-file=${config.secrets.location}/mysql/mysqldump --all-databases > ${cfg.dataDir}/backup.sql + '' + ]; + }; + + security.pam.services = let + pam_ldap = "${pkgs.pam_ldap}/lib/security/pam_ldap.so"; + in [ + { + name = "mysql"; + text = '' + # https://mariadb.com/kb/en/mariadb/pam-authentication-plugin/ + auth required ${pam_ldap} config=${config.secrets.location}/mysql/pam + account required ${pam_ldap} config=${config.secrets.location}/mysql/pam + ''; + } + ]; + + }; +} +