-{ lib, pkgs, config, myconfig, ... }:
+{ lib, pkgs, config, ... }:
let
cfg = config.myServices.databases.mariadb;
in {
options.myServices.databases = {
mariadb = {
enable = lib.mkOption {
- default = cfg.enable;
+ default = false;
example = true;
description = "Whether to enable mariadb database";
type = lib.types.bool;
};
+ package = lib.mkOption {
+ type = lib.types.package;
+ default = pkgs.mariadb;
+ description = ''
+ Mariadb package to use.
+ '';
+ };
+ credentials = lib.mkOption {
+ default = {};
+ description = "Credentials";
+ type = lib.types.attrsOf lib.types.str;
+ };
+ ldapConfig = lib.mkOption {
+ description = "LDAP configuration to allow PAM identification via LDAP";
+ type = lib.types.submodule {
+ options = {
+ host = lib.mkOption { type = lib.types.str; };
+ base = lib.mkOption { type = lib.types.str; };
+ dn = lib.mkOption { type = lib.types.str; };
+ password = lib.mkOption { type = lib.types.str; };
+ filter = lib.mkOption { type = lib.types.str; };
+ };
+ };
+ };
+ replicationLdapConfig = lib.mkOption {
+ description = "LDAP configuration to allow replication";
+ type = lib.types.submodule {
+ options = {
+ host = lib.mkOption { type = lib.types.str; };
+ base = lib.mkOption { type = lib.types.str; };
+ dn = lib.mkOption { type = lib.types.str; };
+ password = lib.mkOption { type = lib.types.str; };
+ };
+ };
+ };
dataDir = lib.mkOption {
type = lib.types.path;
default = "/var/lib/mysql";
# User identified by LDAP:
# CREATE USER foo@% IDENTIFIED VIA pam USING 'mysql' REQUIRE SSL;
# CREATE USER foo@localhost IDENTIFIED VIA pam USING 'mysql';
+
+ # To create a user (host) for replication:
+ # CREATE USER 'host'@'%' IDENTIFIED VIA pam USING 'mysql_replication' REQUIRE SSL;
+ # GRANT REPLICATION SLAVE, REPLICATION CLIENT, RELOAD, LOCK TABLES, SELECT, SHOW VIEW ON *.* TO 'host'@'%';
+ # (the lock/select grant permits to let the replication host handle
+ # the initial fetch of the database)
+ # % should be valid for both localhost (for cron dumps) and the origin host.
services.mysql = {
enable = true;
- package = pkgs.mariadb;
+ package = cfg.package;
dataDir = cfg.dataDir;
extraOptions = ''
ssl_ca = ${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt
ssl_key = ${config.security.acme.directory}/mysql/key.pem
ssl_cert = ${config.security.acme.directory}/mysql/fullchain.pem
+
+ # for replication
+ log-bin=mariadb-bin
+ server-id=1
'';
};
text = ''
[mysqldump]
user = root
- password = ${myconfig.env.databases.mysql.systemUsers.root}
+ password = ${cfg.credentials.root}
'';
}
{
permissions = "0400";
user = "mysql";
group = "mysql";
- text = with myconfig.env.databases.mysql.pam; ''
- host ${myconfig.env.ldap.host}
- base ${myconfig.env.ldap.base}
+ text = with cfg.ldapConfig; ''
+ host ${host}
+ base ${base}
binddn ${dn}
bindpw ${password}
pam_filter ${filter}
ssl start_tls
- '';
+ '';
+ }
+ {
+ dest = "mysql/pam_replication";
+ permissions = "0400";
+ user = "mysql";
+ group = "mysql";
+ text = with cfg.replicationLdapConfig; ''
+ host ${host}
+ base ${base}
+ binddn ${dn}
+ bindpw ${password}
+ pam_login_attribute cn
+ 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 [
account required ${pam_ldap} config=${config.secrets.location}/mysql/pam
'';
}
+ {
+ name = "mysql_replication";
+ text = ''
+ auth required ${pam_ldap} config=${config.secrets.location}/mysql/pam_replication
+ account required ${pam_ldap} config=${config.secrets.location}/mysql/pam_replication
+ '';
+ }
];
};
}
-