1 { lib, pkgs, config, ... }:
3 cfg = config.myServices.databases.mariadb;
5 options.myServices.databases = {
7 enable = lib.mkOption {
10 description = "Whether to enable mariadb database";
11 type = lib.types.bool;
13 package = lib.mkOption {
14 type = lib.types.package;
15 default = pkgs.mariadb;
17 Mariadb package to use.
20 credentials = lib.mkOption {
22 description = "Credentials";
23 type = lib.types.attrsOf lib.types.str;
25 ldapConfig = lib.mkOption {
26 description = "LDAP configuration to allow PAM identification via LDAP";
27 type = lib.types.submodule {
29 host = lib.mkOption { type = lib.types.str; };
30 base = lib.mkOption { type = lib.types.str; };
31 dn = lib.mkOption { type = lib.types.str; };
32 password = lib.mkOption { type = lib.types.str; };
33 filter = lib.mkOption { type = lib.types.str; };
37 dataDir = lib.mkOption {
38 type = lib.types.path;
39 default = "/var/lib/mysql";
41 The directory where Mariadb stores its data.
45 socketsDir = lib.mkOption {
46 type = lib.types.path;
47 default = "/run/mysqld";
49 The directory where Mariadb puts sockets.
52 sockets = lib.mkOption {
53 type = lib.types.attrsOf lib.types.path;
55 mysqld = "${cfg.socketsDir}/mysqld.sock";
65 config = lib.mkIf cfg.enable {
66 networking.firewall.allowedTCPPorts = [ 3306 ];
68 # for adminer, ssl is implemented with mysqli only, which is
69 # currently disabled because it’s not compatible with pam.
70 # Thus we need to generate two users for each 'remote': one remote
71 # with SSL, and one localhost without SSL.
72 # User identified by LDAP:
73 # CREATE USER foo@% IDENTIFIED VIA pam USING 'mysql' REQUIRE SSL;
74 # CREATE USER foo@localhost IDENTIFIED VIA pam USING 'mysql';
77 package = cfg.package;
78 dataDir = cfg.dataDir;
80 ssl_ca = ${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt
81 ssl_key = ${config.security.acme.directory}/mysql/key.pem
82 ssl_cert = ${config.security.acme.directory}/mysql/fullchain.pem
86 users.users.mysql.extraGroups = [ "keys" ];
87 security.acme.certs."mysql" = config.myServices.databasesCerts // {
90 plugins = [ "fullchain.pem" "key.pem" "account_key.json" ];
91 domain = "db-1.immae.eu";
93 systemctl restart mysql.service
99 dest = "mysql/mysqldump";
100 permissions = "0400";
106 password = ${cfg.credentials.root}
111 permissions = "0400";
114 text = with cfg.ldapConfig; ''
129 30 1,13 * * * root ${cfg.package}/bin/mysqldump --defaults-file=${config.secrets.location}/mysql/mysqldump --all-databases > ${cfg.dataDir}/backup.sql
134 security.pam.services = let
135 pam_ldap = "${pkgs.pam_ldap}/lib/security/pam_ldap.so";
140 # https://mariadb.com/kb/en/mariadb/pam-authentication-plugin/
141 auth required ${pam_ldap} config=${config.secrets.location}/mysql/pam
142 account required ${pam_ldap} config=${config.secrets.location}/mysql/pam