--- /dev/null
+{ lib, pkgs, config, myconfig, mylibs, ... }:
+let
+ cfg = config.services.myDatabases;
+in {
+ options.services.myDatabases = {
+ mariadb = {
+ enable = lib.mkOption {
+ default = cfg.enable;
+ example = true;
+ description = "Whether to enable mariadb database";
+ type = lib.types.bool;
+ };
+ };
+ };
+
+ config = lib.mkIf cfg.enable {
+ nixpkgs.config.packageOverrides = oldpkgs: rec {
+ mariadb = mariadbPAM;
+ mariadbPAM = oldpkgs.mariadb.overrideAttrs(old: rec {
+ cmakeFlags = old.cmakeFlags ++ [ "-DWITH_AUTHENTICATION_PAM=ON" ];
+ buildInputs = old.buildInputs ++ [ pkgs.pam ];
+ });
+ };
+
+ networking.firewall.allowedTCPPorts = [ 3306 ];
+
+ # for adminer, ssl is implemented with mysqli only, which is
+ # currently disabled because it’s not compatible with pam.
+ # Thus we need to generate two users for each 'remote': one remote
+ # with SSL, and one localhost without SSL.
+ # User identified by LDAP:
+ # CREATE USER foo@% IDENTIFIED VIA pam USING 'mysql' REQUIRE SSL;
+ # CREATE USER foo@localhost IDENTIFIED VIA pam USING 'mysql';
+ services.mysql = rec {
+ enable = cfg.mariadb.enable;
+ package = pkgs.mariadb;
+ extraOptions = ''
+ ssl_ca = ${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt
+ ssl_key = /var/lib/acme/mysql/key.pem
+ ssl_cert = /var/lib/acme/mysql/fullchain.pem
+ '';
+ };
+
+ security.acme.certs."mysql" = config.services.myCertificates.certConfig // {
+ user = "mysql";
+ group = "mysql";
+ plugins = [ "fullchain.pem" "key.pem" "account_key.json" ];
+ domain = "db-1.immae.eu";
+ postRun = ''
+ systemctl restart mysql.service
+ '';
+ };
+
+ security.pam.services = let
+ pam_ldap = "${pkgs.pam_ldap}/lib/security/pam_ldap.so";
+ pam_ldap_mysql = with myconfig.env.databases.mysql.pam;
+ pkgs.writeText "mysql.conf" ''
+ host ${myconfig.env.ldap.host}
+ base ${myconfig.env.ldap.base}
+ binddn ${dn}
+ bindpw ${password}
+ pam_filter ${filter}
+ ssl start_tls
+ '';
+ in [
+ {
+ name = "mysql";
+ text = ''
+ # https://mariadb.com/kb/en/mariadb/pam-authentication-plugin/
+ auth required ${pam_ldap} config=${pam_ldap_mysql}
+ account required ${pam_ldap} config=${pam_ldap_mysql}
+ '';
+ }
+ ];
+
+ };
+}
+