]> git.immae.eu Git - perso/Immae/Config/Nix.git/blob - nixops/modules/databases/mysql.nix
a9ca8d326d1db8df00d21419c2586cdb7569af59
[perso/Immae/Config/Nix.git] / nixops / modules / databases / mysql.nix
1 { lib, pkgs, config, myconfig, mylibs, ... }:
2 let
3 cfg = config.services.myDatabases;
4 in {
5 options.services.myDatabases = {
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 };
14 };
15
16 config = lib.mkIf cfg.enable {
17 nixpkgs.overlays = [ (self: super: rec {
18 mariadb = mariadbPAM;
19 mariadbPAM = super.mariadb.overrideAttrs(old: rec {
20 cmakeFlags = old.cmakeFlags ++ [ "-DWITH_AUTHENTICATION_PAM=ON" ];
21 buildInputs = old.buildInputs ++ [ self.pam ];
22 });
23 }) ];
24
25 networking.firewall.allowedTCPPorts = [ 3306 ];
26
27 # for adminer, ssl is implemented with mysqli only, which is
28 # currently disabled because it’s not compatible with pam.
29 # Thus we need to generate two users for each 'remote': one remote
30 # with SSL, and one localhost without SSL.
31 # User identified by LDAP:
32 # CREATE USER foo@% IDENTIFIED VIA pam USING 'mysql' REQUIRE SSL;
33 # CREATE USER foo@localhost IDENTIFIED VIA pam USING 'mysql';
34 services.mysql = rec {
35 enable = cfg.mariadb.enable;
36 package = pkgs.mariadb;
37 extraOptions = ''
38 ssl_ca = ${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt
39 ssl_key = /var/lib/acme/mysql/key.pem
40 ssl_cert = /var/lib/acme/mysql/fullchain.pem
41 '';
42 };
43
44 users.users.mysql.extraGroups = [ "keys" ];
45 security.acme.certs."mysql" = config.services.myCertificates.certConfig // {
46 user = "mysql";
47 group = "mysql";
48 plugins = [ "fullchain.pem" "key.pem" "account_key.json" ];
49 domain = "db-1.immae.eu";
50 postRun = ''
51 systemctl restart mysql.service
52 '';
53 };
54
55 mySecrets.keys = [
56 {
57 dest = "mysql/mysqldump";
58 permissions = "0400";
59 user = "root";
60 group = "root";
61 text = ''
62 [mysqldump]
63 user = root
64 password = ${myconfig.env.databases.mysql.systemUsers.root}
65 '';
66 }
67 {
68 dest = "mysql/pam";
69 permissions = "0400";
70 user = "mysql";
71 group = "mysql";
72 text = with myconfig.env.databases.mysql.pam; ''
73 host ${myconfig.env.ldap.host}
74 base ${myconfig.env.ldap.base}
75 binddn ${dn}
76 bindpw ${password}
77 pam_filter ${filter}
78 ssl start_tls
79 '';
80 }
81 ];
82
83 services.cron = {
84 enable = true;
85 systemCronJobs = [
86 ''
87 30 1,13 * * * root ${pkgs.mariadb}/bin/mysqldump --defaults-file=/var/secrets/mysql/mysqldump --all-databases > /var/lib/mysql/backup.sql
88 ''
89 ];
90 };
91
92 security.pam.services = let
93 pam_ldap = "${pkgs.pam_ldap}/lib/security/pam_ldap.so";
94 in [
95 {
96 name = "mysql";
97 text = ''
98 # https://mariadb.com/kb/en/mariadb/pam-authentication-plugin/
99 auth required ${pam_ldap} config=/var/secrets/mysql/pam
100 account required ${pam_ldap} config=/var/secrets/mysql/pam
101 '';
102 }
103 ];
104
105 };
106 }
107