]> git.immae.eu Git - perso/Immae/Config/Nix.git/blame - systems/eldiron/databases/mariadb.nix
Squash changes containing private information
[perso/Immae/Config/Nix.git] / systems / eldiron / databases / mariadb.nix
CommitLineData
4aac110f 1{ lib, pkgs, config, ... }:
4ff90563 2let
182ae57f 3 cfg = config.myServices.databases.mariadb;
4ff90563 4in {
182ae57f 5 options.myServices.databases = {
4ff90563
IB
6 mariadb = {
7 enable = lib.mkOption {
8415083e 8 default = false;
4ff90563
IB
9 example = true;
10 description = "Whether to enable mariadb database";
11 type = lib.types.bool;
12 };
4aac110f
IB
13 package = lib.mkOption {
14 type = lib.types.package;
15 default = pkgs.mariadb;
16 description = ''
17 Mariadb package to use.
18 '';
19 };
20 credentials = lib.mkOption {
21 default = {};
22 description = "Credentials";
23 type = lib.types.attrsOf lib.types.str;
24 };
25 ldapConfig = lib.mkOption {
26 description = "LDAP configuration to allow PAM identification via LDAP";
27 type = lib.types.submodule {
28 options = {
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; };
34 };
35 };
36 };
9f6a7862
IB
37 replicationLdapConfig = lib.mkOption {
38 description = "LDAP configuration to allow replication";
39 type = lib.types.submodule {
40 options = {
41 host = lib.mkOption { type = lib.types.str; };
42 base = lib.mkOption { type = lib.types.str; };
43 dn = lib.mkOption { type = lib.types.str; };
44 password = lib.mkOption { type = lib.types.str; };
45 };
46 };
47 };
182ae57f
IB
48 dataDir = lib.mkOption {
49 type = lib.types.path;
50 default = "/var/lib/mysql";
51 description = ''
52 The directory where Mariadb stores its data.
53 '';
54 };
55 # Output variables
56 socketsDir = lib.mkOption {
57 type = lib.types.path;
58 default = "/run/mysqld";
59 description = ''
60 The directory where Mariadb puts sockets.
61 '';
62 };
63 sockets = lib.mkOption {
64 type = lib.types.attrsOf lib.types.path;
65 default = {
66 mysqld = "${cfg.socketsDir}/mysqld.sock";
67 };
68 readOnly = true;
69 description = ''
70 Mariadb sockets
71 '';
72 };
4ff90563
IB
73 };
74 };
75
76 config = lib.mkIf cfg.enable {
1a64deeb 77 networking.firewall.allowedTCPPorts = [ config.myEnv.databases.mysql.port ];
4ff90563
IB
78
79 # for adminer, ssl is implemented with mysqli only, which is
80 # currently disabled because it’s not compatible with pam.
81 # Thus we need to generate two users for each 'remote': one remote
82 # with SSL, and one localhost without SSL.
83 # User identified by LDAP:
84 # CREATE USER foo@% IDENTIFIED VIA pam USING 'mysql' REQUIRE SSL;
85 # CREATE USER foo@localhost IDENTIFIED VIA pam USING 'mysql';
9f6a7862
IB
86
87 # To create a user (host) for replication:
88 # CREATE USER 'host'@'%' IDENTIFIED VIA pam USING 'mysql_replication' REQUIRE SSL;
89 # GRANT REPLICATION SLAVE, REPLICATION CLIENT, RELOAD, LOCK TABLES, SELECT, SHOW VIEW ON *.* TO 'host'@'%';
90 # (the lock/select grant permits to let the replication host handle
91 # the initial fetch of the database)
92 # % should be valid for both localhost (for cron dumps) and the origin host.
182ae57f
IB
93 services.mysql = {
94 enable = true;
4aac110f 95 package = cfg.package;
182ae57f 96 dataDir = cfg.dataDir;
258dd18b
IB
97 settings = {
98 mysqld = {
1a64deeb 99 port = config.myEnv.databases.mysql.port;
258dd18b
IB
100 ssl_ca = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt";
101 ssl_key = "${config.security.acme.certs.mysql.directory}/key.pem";
102 ssl_cert = "${config.security.acme.certs.mysql.directory}/fullchain.pem";
9f6a7862 103
258dd18b
IB
104 # for replication
105 log-bin = "mariadb-bin";
106 server-id = "1";
0907cf1b 107
258dd18b
IB
108 # this introduces a small delay before storing on disk, but
109 # makes it order of magnitudes quicker
110 innodb_flush_log_at_trx_commit = "0";
1a64deeb
IB
111
112 # This is necessary since the default ("dialog") is not
113 # supported by php's mysqlnd plugin (in mysqli). But with that
114 # change only regular login+password schemes can work (no
115 # "fancy" authentication methods like fprintd or keys)
116 pam_use_cleartext_plugin = true;
258dd18b
IB
117 };
118 };
4ff90563
IB
119 };
120
e1da84b0 121 users.users.mysql.extraGroups = [ "keys" ];
1a64deeb 122 security.acme.certs."mysql" = {
4ff90563 123 group = "mysql";
4ff90563
IB
124 domain = "db-1.immae.eu";
125 postRun = ''
126 systemctl restart mysql.service
127 '';
128 };
129
4c4652aa
IB
130 secrets.keys = {
131 "mysql/mysqldump" = {
e1da84b0
IB
132 permissions = "0400";
133 user = "root";
134 group = "root";
135 text = ''
85fe2b41
IB
136 [mysqldump]
137 user = root
4aac110f 138 password = ${cfg.credentials.root}
e1da84b0 139 '';
4c4652aa
IB
140 };
141 "mysql/pam" = {
e1da84b0
IB
142 permissions = "0400";
143 user = "mysql";
144 group = "mysql";
4aac110f
IB
145 text = with cfg.ldapConfig; ''
146 host ${host}
147 base ${base}
e1da84b0
IB
148 binddn ${dn}
149 bindpw ${password}
150 pam_filter ${filter}
151 ssl start_tls
4aac110f 152 '';
4c4652aa
IB
153 };
154 "mysql/pam_replication" = {
9f6a7862
IB
155 permissions = "0400";
156 user = "mysql";
157 group = "mysql";
158 text = with cfg.replicationLdapConfig; ''
159 host ${host}
160 base ${base}
161 binddn ${dn}
162 bindpw ${password}
163 pam_login_attribute cn
164 ssl start_tls
165 '';
4c4652aa
IB
166 };
167 };
e1da84b0 168
4ff90563
IB
169 security.pam.services = let
170 pam_ldap = "${pkgs.pam_ldap}/lib/security/pam_ldap.so";
258dd18b
IB
171 in {
172 mysql = {
4ff90563
IB
173 text = ''
174 # https://mariadb.com/kb/en/mariadb/pam-authentication-plugin/
da30ae4f
IB
175 auth required ${pam_ldap} config=${config.secrets.fullPaths."mysql/pam"}
176 account required ${pam_ldap} config=${config.secrets.fullPaths."mysql/pam"}
4ff90563 177 '';
258dd18b
IB
178 };
179 mysql_replication = {
9f6a7862 180 text = ''
da30ae4f
IB
181 auth required ${pam_ldap} config=${config.secrets.fullPaths."mysql/pam_replication"}
182 account required ${pam_ldap} config=${config.secrets.fullPaths."mysql/pam_replication"}
9f6a7862 183 '';
258dd18b
IB
184 };
185 };
4ff90563
IB
186
187 };
188}