]> git.immae.eu Git - perso/Immae/Config/Nix.git/blob - modules/private/databases/mariadb.nix
Use acme directory config rather than hardcoding the value
[perso/Immae/Config/Nix.git] / modules / private / databases / mariadb.nix
1 { lib, pkgs, config, myconfig, ... }:
2 let
3 cfg = config.myServices.databases.mariadb;
4 in {
5 options.myServices.databases = {
6 mariadb = {
7 enable = lib.mkOption {
8 default = cfg.enable;
9 example = true;
10 description = "Whether to enable mariadb database";
11 type = lib.types.bool;
12 };
13 dataDir = lib.mkOption {
14 type = lib.types.path;
15 default = "/var/lib/mysql";
16 description = ''
17 The directory where Mariadb stores its data.
18 '';
19 };
20 # Output variables
21 socketsDir = lib.mkOption {
22 type = lib.types.path;
23 default = "/run/mysqld";
24 description = ''
25 The directory where Mariadb puts sockets.
26 '';
27 };
28 sockets = lib.mkOption {
29 type = lib.types.attrsOf lib.types.path;
30 default = {
31 mysqld = "${cfg.socketsDir}/mysqld.sock";
32 };
33 readOnly = true;
34 description = ''
35 Mariadb sockets
36 '';
37 };
38 };
39 };
40
41 config = lib.mkIf cfg.enable {
42 networking.firewall.allowedTCPPorts = [ 3306 ];
43
44 # for adminer, ssl is implemented with mysqli only, which is
45 # currently disabled because it’s not compatible with pam.
46 # Thus we need to generate two users for each 'remote': one remote
47 # with SSL, and one localhost without SSL.
48 # User identified by LDAP:
49 # CREATE USER foo@% IDENTIFIED VIA pam USING 'mysql' REQUIRE SSL;
50 # CREATE USER foo@localhost IDENTIFIED VIA pam USING 'mysql';
51 services.mysql = {
52 enable = true;
53 package = pkgs.mariadb;
54 dataDir = cfg.dataDir;
55 extraOptions = ''
56 ssl_ca = ${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt
57 ssl_key = ${config.security.acme.directory}/mysql/key.pem
58 ssl_cert = ${config.security.acme.directory}/mysql/fullchain.pem
59 '';
60 };
61
62 users.users.mysql.extraGroups = [ "keys" ];
63 security.acme.certs."mysql" = config.myServices.databasesCerts // {
64 user = "mysql";
65 group = "mysql";
66 plugins = [ "fullchain.pem" "key.pem" "account_key.json" ];
67 domain = "db-1.immae.eu";
68 postRun = ''
69 systemctl restart mysql.service
70 '';
71 };
72
73 secrets.keys = [
74 {
75 dest = "mysql/mysqldump";
76 permissions = "0400";
77 user = "root";
78 group = "root";
79 text = ''
80 [mysqldump]
81 user = root
82 password = ${myconfig.env.databases.mysql.systemUsers.root}
83 '';
84 }
85 {
86 dest = "mysql/pam";
87 permissions = "0400";
88 user = "mysql";
89 group = "mysql";
90 text = with myconfig.env.databases.mysql.pam; ''
91 host ${myconfig.env.ldap.host}
92 base ${myconfig.env.ldap.base}
93 binddn ${dn}
94 bindpw ${password}
95 pam_filter ${filter}
96 ssl start_tls
97 '';
98 }
99 ];
100
101 services.cron = {
102 enable = true;
103 systemCronJobs = [
104 ''
105 30 1,13 * * * root ${pkgs.mariadb}/bin/mysqldump --defaults-file=${config.secrets.location}/mysql/mysqldump --all-databases > ${cfg.dataDir}/backup.sql
106 ''
107 ];
108 };
109
110 security.pam.services = let
111 pam_ldap = "${pkgs.pam_ldap}/lib/security/pam_ldap.so";
112 in [
113 {
114 name = "mysql";
115 text = ''
116 # https://mariadb.com/kb/en/mariadb/pam-authentication-plugin/
117 auth required ${pam_ldap} config=${config.secrets.location}/mysql/pam
118 account required ${pam_ldap} config=${config.secrets.location}/mysql/pam
119 '';
120 }
121 ];
122
123 };
124 }
125