-{ lib, config, ... }:
+{ lib, config, myconfig, ... }:
let
cfg = config.myServices.databases;
in
description = "Default databases configurations for certificates as accepted by acme";
};
};
+
+ config.nixpkgs.overlays = lib.mkIf cfg.enable [ (self: super: {
+ postgresql = self.postgresql_11_custom;
+ }) ];
+
config.myServices.databases = lib.mkIf cfg.enable {
- mariadb.enable = true;
- openldap.enable = true;
- postgresql.enable = true;
+ mariadb = {
+ enable = true;
+ ldapConfig = {
+ inherit (myconfig.env.ldap) host base;
+ inherit (myconfig.env.databases.mysql.pam) dn filter password;
+ };
+ credentials.root = myconfig.env.databases.mysql.systemUsers.root;
+ };
+
+ openldap = {
+ accessFile = "${myconfig.privateFiles}/ldap.conf";
+ baseDn = myconfig.env.ldap.base;
+ rootDn = myconfig.env.ldap.root_dn;
+ rootPw = myconfig.env.ldap.root_pw;
+ enable = true;
+ };
+
+ postgresql = {
+ ldapConfig = {
+ inherit (myconfig.env.ldap) host base;
+ inherit (myconfig.env.databases.postgresql.pam) dn filter password;
+ };
+ replicationLdapConfig = {
+ inherit (myconfig.env.ldap) host base password;
+ dn = myconfig.env.ldap.host_dn;
+ };
+ authorizedHosts = {
+ immaeEu = [{
+ ip4 = [
+ myconfig.env.servers.immaeEu.ips.main.ip4
+ myconfig.env.servers.immaeEu.ips.alt.ip4
+ ];
+ }];
+ };
+ replicationHosts = {
+ backup-1 = {
+ ip4 = [myconfig.env.servers.backup-1.ips.main.ip4];
+ ip6 = myconfig.env.servers.backup-1.ips.main.ip6;
+ };
+ };
+ enable = true;
+ };
+
redis.enable = true;
};
}
-{ lib, pkgs, config, myconfig, ... }:
+{ lib, pkgs, config, ... }:
let
cfg = config.myServices.databases.mariadb;
in {
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; };
+ };
+ };
+ };
dataDir = lib.mkOption {
type = lib.types.path;
default = "/var/lib/mysql";
# CREATE USER foo@localhost IDENTIFIED VIA pam USING 'mysql';
services.mysql = {
enable = true;
- package = pkgs.mariadb;
+ package = cfg.package;
dataDir = cfg.dataDir;
extraOptions = ''
ssl_ca = ${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt
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
- '';
+ '';
}
];
enable = true;
systemCronJobs = [
''
- 30 1,13 * * * root ${pkgs.mariadb}/bin/mysqldump --defaults-file=${config.secrets.location}/mysql/mysqldump --all-databases > ${cfg.dataDir}/backup.sql
+ 30 1,13 * * * root ${cfg.package}/bin/mysqldump --defaults-file=${config.secrets.location}/mysql/mysqldump --all-databases > ${cfg.dataDir}/backup.sql
''
];
};
-{ lib, pkgs, config, myconfig, ... }:
+{ lib, pkgs, config, ... }:
let
cfg = config.myServices.databases.openldap;
ldapConfig = let
moduleload memberof
database hdb
- suffix "${myconfig.env.ldap.base}"
- rootdn "${myconfig.env.ldap.root_dn}"
+ suffix "${cfg.baseDn}"
+ rootdn "${cfg.rootDn}"
include ${config.secrets.location}/ldap/password
directory ${cfg.dataDir}
overlay memberof
description = "Whether to enable ldap";
type = lib.types.bool;
};
+ baseDn = lib.mkOption {
+ type = lib.types.str;
+ description = ''
+ Base DN for LDAP
+ '';
+ };
+ rootDn = lib.mkOption {
+ type = lib.types.str;
+ description = ''
+ Root DN
+ '';
+ };
+ rootPw = lib.mkOption {
+ type = lib.types.str;
+ description = ''
+ Root (Hashed) password
+ '';
+ };
+ accessFile = lib.mkOption {
+ type = lib.types.path;
+ description = ''
+ The file path that defines the access
+ '';
+ };
dataDir = lib.mkOption {
type = lib.types.path;
default = "/var/lib/openldap";
permissions = "0400";
user = "openldap";
group = "openldap";
- text = "rootpw ${myconfig.env.ldap.root_pw}";
+ text = "rootpw ${cfg.rootPw}";
}
{
- dest = "ldap/access ";
+ dest = "ldap/access";
permissions = "0400";
user = "openldap";
group = "openldap";
- text = builtins.readFile "${myconfig.privateFiles}/ldap.conf";
+ text = builtins.readFile "${cfg.accessFile}";
}
];
users.users.openldap.extraGroups = [ "keys" ];
-{ lib, pkgs, config, myconfig, ... }:
+{ lib, pkgs, config, ... }:
let
cfg = config.myServices.databases.postgresql;
in {
description = "Whether to enable postgresql database";
type = lib.types.bool;
};
+ package = lib.mkOption {
+ type = lib.types.package;
+ default = pkgs.postgresql;
+ description = ''
+ Postgresql package to use.
+ '';
+ };
+ 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; };
+ };
+ };
+ };
+ authorizedHosts = lib.mkOption {
+ default = {};
+ description = "Hosts to allow connections from";
+ type = lib.types.attrsOf (lib.types.listOf (lib.types.submodule {
+ options = {
+ method = lib.mkOption {
+ default = "md5";
+ type = lib.types.str;
+ };
+ username = lib.mkOption {
+ default = "all";
+ type = lib.types.str;
+ };
+ database = lib.mkOption {
+ default = "all";
+ type = lib.types.str;
+ };
+ ip4 = lib.mkOption {
+ default = [];
+ type = lib.types.listOf lib.types.str;
+ };
+ ip6 = lib.mkOption {
+ default = [];
+ type = lib.types.listOf lib.types.str;
+ };
+ };
+ }));
+ };
+ replicationHosts = lib.mkOption {
+ default = {};
+ description = "Hosts to allow replication from";
+ type = lib.types.attrsOf (lib.types.submodule {
+ options = {
+ ip4 = lib.mkOption {
+ type = lib.types.listOf lib.types.str;
+ };
+ ip6 = lib.mkOption {
+ type = lib.types.listOf lib.types.str;
+ };
+ };
+ });
+ };
# Output variables
socketsDir = lib.mkOption {
type = lib.types.path;
};
config = lib.mkIf cfg.enable {
- nixpkgs.overlays = [ (self: super: rec {
- postgresql = self.postgresql_11_custom;
- }) ];
-
networking.firewall.allowedTCPPorts = [ 5432 ];
security.acme.certs."postgresql" = config.myServices.databasesCerts // {
SupplementaryGroups = "keys";
RuntimeDirectory = cfg.systemdRuntimeDirectory;
};
- services.postgresql = rec {
+ services.postgresql = {
enable = true;
- package = pkgs.postgresql;
+ package = cfg.package;
enableTCPIP = true;
extraConfig = ''
max_connections = 100
ssl_cert_file = '${config.security.acme.directory}/postgresql/fullchain.pem'
ssl_key_file = '${config.security.acme.directory}/postgresql/key.pem'
'';
- authentication = ''
+ authentication = let
+ hosts = builtins.concatStringsSep "\n" (
+ lib.lists.flatten (lib.mapAttrsToList (k: vs: map (v:
+ map (ip6: "hostssl ${v.database} ${v.username} ${ip6}/128 ${v.method}") v.ip6
+ ++ map (ip4: "hostssl ${v.database} ${v.username} ${ip4}/32 ${v.method}") v.ip4
+ ) vs) cfg.authorizedHosts
+ ));
+ replication = builtins.concatStringsSep "\n" (
+ lib.lists.flatten (lib.mapAttrsToList (k: v:
+ map (ip6: "hostssl replication ${k} ${ip6}/128 pam pamservice=postgresql_replication") v.ip6
+ ++ map (ip4: "hostssl replication ${k} ${ip4}/32 pam pamservice=postgresql_replication") v.ip4
+ ) cfg.replicationHosts
+ ));
+ in ''
local all postgres ident
local all all md5
- hostssl all all 188.165.209.148/32 md5
- hostssl all all 178.33.252.96/32 md5
+ ${hosts}
hostssl all all all pam
- hostssl replication backup-1 2001:41d0:302:1100::9:e5a9/128 pam pamservice=postgresql_replication
- hostssl replication backup-1 54.37.151.137/32 pam pamservice=postgresql_replication
+ ${replication}
'';
};
permissions = "0400";
group = "postgres";
user = "postgres";
- text = with myconfig.env.databases.postgresql.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}
permissions = "0400";
group = "postgres";
user = "postgres";
- text = ''
- host ${myconfig.env.ldap.host}
- base ${myconfig.env.ldap.base}
- binddn ${myconfig.env.ldap.host_dn}
- bindpw ${myconfig.env.ldap.password}
+ text = with cfg.replicationLdapConfig; ''
+ host ${host}
+ base ${base}
+ binddn ${dn}
+ bindpw ${password}
pam_login_attribute cn
ssl start_tls
'';
-{ lib, config, myconfig, ... }:
+{ lib, config, ... }:
let
cfg = config.myServices.databases.redis;
in {