aboutsummaryrefslogtreecommitdiff
path: root/nixops/modules
diff options
context:
space:
mode:
authorIsmaël Bouya <ismael.bouya@normalesup.org>2019-05-17 00:49:27 +0200
committerIsmaël Bouya <ismael.bouya@normalesup.org>2019-05-17 01:31:05 +0200
commit182ae57f53731be220075bc87aff4d47a35563b8 (patch)
tree79b523057406db394668bbfd720660d6a1e24094 /nixops/modules
parent6c97d2d715620a1cdc3b8a785174590ec0dafb98 (diff)
downloadNix-182ae57f53731be220075bc87aff4d47a35563b8.tar.gz
Nix-182ae57f53731be220075bc87aff4d47a35563b8.tar.zst
Nix-182ae57f53731be220075bc87aff4d47a35563b8.zip
Move databases configs to modules
Diffstat (limited to 'nixops/modules')
-rw-r--r--nixops/modules/certificates.nix1
-rw-r--r--nixops/modules/databases/default.nix14
-rw-r--r--nixops/modules/databases/immae.schema167
-rw-r--r--nixops/modules/databases/mysql.nix99
-rw-r--r--nixops/modules/databases/openldap.nix104
-rw-r--r--nixops/modules/databases/postgresql.nix120
-rw-r--r--nixops/modules/databases/redis.nix35
7 files changed, 1 insertions, 539 deletions
diff --git a/nixops/modules/certificates.nix b/nixops/modules/certificates.nix
index d648ff7..9a9974e 100644
--- a/nixops/modules/certificates.nix
+++ b/nixops/modules/certificates.nix
@@ -16,6 +16,7 @@
16 16
17 config = { 17 config = {
18 services.websitesCerts = config.services.myCertificates.certConfig; 18 services.websitesCerts = config.services.myCertificates.certConfig;
19 myServices.databasesCerts = config.services.myCertificates.certConfig;
19 20
20 security.acme.preliminarySelfsigned = true; 21 security.acme.preliminarySelfsigned = true;
21 22
diff --git a/nixops/modules/databases/default.nix b/nixops/modules/databases/default.nix
deleted file mode 100644
index be549b1..0000000
--- a/nixops/modules/databases/default.nix
+++ /dev/null
@@ -1,14 +0,0 @@
1{ lib, pkgs, config, myconfig, ... }:
2let
3 cfg = config.services.myDatabases;
4in {
5 imports = [
6 ./mysql.nix
7 ./openldap.nix
8 ./postgresql.nix
9 ./redis.nix
10 ];
11 options.services.myDatabases = {
12 enable = lib.mkEnableOption "my databases service";
13 };
14}
diff --git a/nixops/modules/databases/immae.schema b/nixops/modules/databases/immae.schema
deleted file mode 100644
index f5ee5d5..0000000
--- a/nixops/modules/databases/immae.schema
+++ /dev/null
@@ -1,167 +0,0 @@
1# vim: set filetype=slapd:
2objectIdentifier Immaeroot 1.3.6.1.4.1.50071
3
4objectIdentifier Immae Immaeroot:2
5objectIdentifier ImmaeattributeType Immae:3
6objectIdentifier ImmaeobjectClass Immae:4
7
8# TT-RSS
9attributetype ( ImmaeattributeType:1 NAME 'immaeTtrssLogin'
10 DESC 'login for TTRSS'
11 EQUALITY caseIgnoreMatch
12 SUBSTR caseIgnoreSubstringsMatch
13 SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
14
15objectclass ( ImmaeobjectClass:1 NAME 'immaeTtrssClass'
16 DESC 'Expansion of the existing object classes for ttrss'
17 SUP top AUXILIARY
18 MUST ( immaeTtrssLogin ) )
19
20# FTP
21attributetype ( ImmaeattributeType:2 NAME 'immaeFtpDirectory'
22 DESC 'home directory for ftp'
23 EQUALITY caseExactIA5Match
24 SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
25
26attributetype ( ImmaeattributeType:3 NAME 'immaeFtpUid'
27 DESC 'user id for ftp'
28 EQUALITY integerMatch
29 SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
30
31attributetype ( ImmaeattributeType:4 NAME 'immaeFtpGid'
32 DESC 'group id for ftp'
33 EQUALITY integerMatch
34 SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
35
36objectclass ( ImmaeobjectClass:2 NAME 'immaeFtpClass'
37 DESC 'Expansion of the existing object classes for ftp'
38 SUP top AUXILIARY
39 MUST ( immaeFtpDirectory $ immaeFtpGid $ immaeFtpUid ) )
40
41
42# SSH keys
43attributetype ( ImmaeattributeType:5 NAME 'immaeSshKey'
44 DESC 'OpenSSH Public key'
45 EQUALITY octetStringMatch
46 SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
47
48objectClass ( ImmaeobjectClass:3 NAME 'immaeSshClass'
49 DESC 'OpenSSH class'
50 SUP top AUXILIARY
51 MAy ( immaeSSHKey ) )
52
53# Specific access
54attributetype (ImmaeattributeType:6 NAME 'immaeAccessDn'
55 EQUALITY distinguishedNameMatch
56 SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
57
58attributetype (ImmaeattributeType:17 NAME 'immaeAccessWriteDn'
59 EQUALITY distinguishedNameMatch
60 SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
61
62attributetype (ImmaeattributeType:18 NAME 'immaeAccessReadSubtree'
63 EQUALITY distinguishedNameMatch
64 SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
65
66objectClass ( ImmaeobjectClass:4 NAME 'immaeAccessClass'
67 DESC 'Access class'
68 SUP top AUXILIARY
69 MAY ( immaeAccessDn $ immaeAccessWriteDn $ immaeAccessReadSubtree ) )
70
71# Xmpp uid
72attributetype ( ImmaeattributeType:7 NAME 'immaeXmppUid'
73 DESC 'user part for Xmpp'
74 EQUALITY caseIgnoreMatch
75 SUBSTR caseIgnoreSubstringsMatch
76 SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
77
78objectclass ( ImmaeobjectClass:5 NAME 'immaeXmppClass'
79 DESC 'Expansion of the existing object classes for XMPP'
80 SUP top AUXILIARY
81 MUST ( immaeXmppUid ) )
82
83# Postfix accounts
84attributetype ( ImmaeattributeType:8 NAME 'immaePostfixAddress'
85 DESC 'the dovecot address to match as username'
86 EQUALITY caseIgnoreIA5Match
87 SUBSTR caseIgnoreIA5SubstringsMatch
88 SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
89
90attributetype ( ImmaeattributeType:9 NAME 'immaePostfixHome'
91 DESC 'the postfix home directory'
92 EQUALITY caseExactIA5Match
93 SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
94
95attributetype ( ImmaeattributeType:10 NAME 'immaePostfixMail'
96 DESC 'the dovecot mail location'
97 EQUALITY caseExactIA5Match
98 SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
99
100attributetype ( ImmaeattributeType:11 NAME 'immaePostfixUid'
101 DESC 'the dovecot uid'
102 EQUALITY caseExactIA5Match
103 SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
104
105attributetype ( ImmaeattributeType:12 NAME 'immaePostfixGid'
106 DESC 'the dovecot gid'
107 EQUALITY caseExactIA5Match
108 SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
109
110objectclass ( ImmaeobjectClass:6 NAME 'immaePostfixClass'
111 DESC 'Expansion of the existing object classes for Postfix'
112 SUP top AUXILIARY
113 MUST ( immaePostfixAddress $ immaePostfixHome $
114 immaePostfixMail $ immaePostfixUid $ immaePostfixGid )
115 )
116
117# Tinc informations
118# Domaine = une classe a part ou une partie du dn ?
119# attributetype ( ImmaeattributeType:13 NAME 'immaeTincIpSegment'
120# DESC 'the internal ip segment in tinc'
121# EQUALITY caseIgnoreIA5Match
122# SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
123#
124# attributetype ( ImmaeattributeType:14 NAME 'immaeTincSubdomain'
125# DESC 'the host subdomain'
126# EQUALITY caseIgnoreIA5Match
127# SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
128#
129# attributetype ( ImmaeattributeType:15 NAME 'immaeTincHostname'
130# DESC 'the host name'
131# EQUALITY caseIgnoreIA5Match
132# SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
133#
134# objectclass ( ImmaeobjectClass:7 NAME 'immaeTincHostClass'
135# DESC 'Expansion of the existing object classes for Tinc'
136# SUP top AUXILIARY
137# MUST ( immaeTincInternalIp $ immaeTincSubdomain $
138# immaeTincHostname )
139# )
140
141attributetype (ImmaeattributeType:16 NAME 'immaePuppetJson'
142 DESC 'Puppet hiera json'
143 EQUALITY octetStringMatch
144 SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
145
146objectclass ( ImmaeobjectClass:8 NAME 'immaePuppetClass'
147 DESC 'Expansion of the existing object classes for Puppet'
148 SUP top AUXILIARY
149 MUST ( immaePuppetJson )
150 )
151
152attributetype (ImmaeattributeType:19 NAME 'immaeTaskId'
153 DESC 'Taskwarrior server Org:Name:Key'
154 EQUALITY caseIgnoreMatch
155 SUBSTR caseIgnoreSubstringsMatch
156 SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
157
158objectclass ( ImmaeobjectClass:9 NAME 'immaeTaskClass'
159 DESC 'Expansion of the existing object classes for Task'
160 SUP top AUXILIARY
161 MUST ( immaeTaskId )
162 )
163
164# Last:
165# attributetype (ImmaeattributeType:19 NAME 'immaeTaskId'
166# objectclass ( ImmaeobjectClass:9 NAME 'immaeTaskClass'
167
diff --git a/nixops/modules/databases/mysql.nix b/nixops/modules/databases/mysql.nix
deleted file mode 100644
index 6739aaa..0000000
--- a/nixops/modules/databases/mysql.nix
+++ /dev/null
@@ -1,99 +0,0 @@
1{ lib, pkgs, config, myconfig, ... }:
2let
3 cfg = config.services.myDatabases;
4in {
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 networking.firewall.allowedTCPPorts = [ 3306 ];
18
19 # for adminer, ssl is implemented with mysqli only, which is
20 # currently disabled because it’s not compatible with pam.
21 # Thus we need to generate two users for each 'remote': one remote
22 # with SSL, and one localhost without SSL.
23 # User identified by LDAP:
24 # CREATE USER foo@% IDENTIFIED VIA pam USING 'mysql' REQUIRE SSL;
25 # CREATE USER foo@localhost IDENTIFIED VIA pam USING 'mysql';
26 services.mysql = rec {
27 enable = cfg.mariadb.enable;
28 package = pkgs.mariadb;
29 extraOptions = ''
30 ssl_ca = ${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt
31 ssl_key = /var/lib/acme/mysql/key.pem
32 ssl_cert = /var/lib/acme/mysql/fullchain.pem
33 '';
34 };
35
36 users.users.mysql.extraGroups = [ "keys" ];
37 security.acme.certs."mysql" = config.services.myCertificates.certConfig // {
38 user = "mysql";
39 group = "mysql";
40 plugins = [ "fullchain.pem" "key.pem" "account_key.json" ];
41 domain = "db-1.immae.eu";
42 postRun = ''
43 systemctl restart mysql.service
44 '';
45 };
46
47 secrets.keys = [
48 {
49 dest = "mysql/mysqldump";
50 permissions = "0400";
51 user = "root";
52 group = "root";
53 text = ''
54 [mysqldump]
55 user = root
56 password = ${myconfig.env.databases.mysql.systemUsers.root}
57 '';
58 }
59 {
60 dest = "mysql/pam";
61 permissions = "0400";
62 user = "mysql";
63 group = "mysql";
64 text = with myconfig.env.databases.mysql.pam; ''
65 host ${myconfig.env.ldap.host}
66 base ${myconfig.env.ldap.base}
67 binddn ${dn}
68 bindpw ${password}
69 pam_filter ${filter}
70 ssl start_tls
71 '';
72 }
73 ];
74
75 services.cron = {
76 enable = true;
77 systemCronJobs = [
78 ''
79 30 1,13 * * * root ${pkgs.mariadb}/bin/mysqldump --defaults-file=/var/secrets/mysql/mysqldump --all-databases > /var/lib/mysql/backup.sql
80 ''
81 ];
82 };
83
84 security.pam.services = let
85 pam_ldap = "${pkgs.pam_ldap}/lib/security/pam_ldap.so";
86 in [
87 {
88 name = "mysql";
89 text = ''
90 # https://mariadb.com/kb/en/mariadb/pam-authentication-plugin/
91 auth required ${pam_ldap} config=/var/secrets/mysql/pam
92 account required ${pam_ldap} config=/var/secrets/mysql/pam
93 '';
94 }
95 ];
96
97 };
98}
99
diff --git a/nixops/modules/databases/openldap.nix b/nixops/modules/databases/openldap.nix
deleted file mode 100644
index ff97fb3..0000000
--- a/nixops/modules/databases/openldap.nix
+++ /dev/null
@@ -1,104 +0,0 @@
1{ lib, pkgs, config, myconfig, ... }:
2let
3 cfg = config.services.myDatabases;
4 ldapConfig = let
5 kerberosSchema = pkgs.fetchurl {
6 url = "https://raw.githubusercontent.com/krb5/krb5/master/src/plugins/kdb/ldap/libkdb_ldap/kerberos.schema";
7 sha256 = "17fnkkf6s3lznsl7wp6914pqsc78d038rh38l638big8z608ksww";
8 };
9 puppetSchema = pkgs.fetchurl {
10 url = "https://raw.githubusercontent.com/puppetlabs/puppet/master/ext/ldap/puppet.schema";
11 sha256 = "11bjf5zfvqlim7p9vddcafs0wiq3v8ys77x8h6fbp9c6bdfh0awh";
12 };
13 in ''
14 include ${pkgs.openldap}/etc/schema/core.schema
15 include ${pkgs.openldap}/etc/schema/cosine.schema
16 include ${pkgs.openldap}/etc/schema/inetorgperson.schema
17 include ${pkgs.openldap}/etc/schema/nis.schema
18 include ${puppetSchema}
19 include ${kerberosSchema}
20 include ${./immae.schema}
21
22 pidfile /run/slapd/slapd.pid
23 argsfile /run/slapd/slapd.args
24
25 moduleload back_hdb
26 backend hdb
27
28 moduleload memberof
29 database hdb
30 suffix "${myconfig.env.ldap.base}"
31 rootdn "${myconfig.env.ldap.root_dn}"
32 include /var/secrets/ldap/password
33 directory /var/lib/openldap
34 overlay memberof
35
36 TLSCertificateFile /var/lib/acme/ldap/cert.pem
37 TLSCertificateKeyFile /var/lib/acme/ldap/key.pem
38 TLSCACertificateFile /var/lib/acme/ldap/fullchain.pem
39 TLSCACertificatePath ${pkgs.cacert.unbundled}/etc/ssl/certs/
40 #This makes openldap crash
41 #TLSCipherSuite DEFAULT
42
43 sasl-host kerberos.immae.eu
44 include /var/secrets/ldap/access
45 '';
46in {
47 options.services.myDatabases = {
48 ldap = {
49 enable = lib.mkOption {
50 default = cfg.enable;
51 example = true;
52 description = "Whether to enable ldap";
53 type = lib.types.bool;
54 };
55 };
56 };
57
58 config = lib.mkIf cfg.enable {
59 secrets.keys = [
60 {
61 dest = "ldap/password";
62 permissions = "0400";
63 user = "openldap";
64 group = "openldap";
65 text = "rootpw ${myconfig.env.ldap.root_pw}";
66 }
67 {
68 dest = "ldap/access ";
69 permissions = "0400";
70 user = "openldap";
71 group = "openldap";
72 text = builtins.readFile "${myconfig.privateFiles}/ldap.conf";
73 }
74 ];
75 users.users.openldap.extraGroups = [ "keys" ];
76 networking.firewall.allowedTCPPorts = [ 636 389 ];
77
78 services.cron = {
79 systemCronJobs = [
80 ''
81 35 1,13 * * * root ${pkgs.openldap}/bin/slapcat -v -b "dc=immae,dc=eu" -f ${pkgs.writeText "slapd.conf" ldapConfig} -l /var/lib/openldap/backup.ldif | ${pkgs.gnugrep}/bin/grep -v "^# id=[0-9a-f]*$"
82 ''
83 ];
84 };
85
86 security.acme.certs."ldap" = config.services.myCertificates.certConfig // {
87 user = "openldap";
88 group = "openldap";
89 plugins = [ "fullchain.pem" "key.pem" "cert.pem" "account_key.json" ];
90 domain = "ldap.immae.eu";
91 postRun = ''
92 systemctl restart openldap.service
93 '';
94 };
95
96 services.openldap = {
97 enable = config.services.myDatabases.ldap.enable;
98 dataDir = "/var/lib/openldap";
99 urlList = [ "ldap://" "ldaps://" ];
100 extraConfig = ldapConfig;
101 };
102 };
103}
104
diff --git a/nixops/modules/databases/postgresql.nix b/nixops/modules/databases/postgresql.nix
deleted file mode 100644
index de0820f..0000000
--- a/nixops/modules/databases/postgresql.nix
+++ /dev/null
@@ -1,120 +0,0 @@
1{ lib, pkgs, config, myconfig, ... }:
2let
3 cfg = config.services.myDatabases;
4in {
5 options.services.myDatabases = {
6 postgresql = {
7 enable = lib.mkOption {
8 default = cfg.enable;
9 example = true;
10 description = "Whether to enable postgresql database";
11 type = lib.types.bool;
12 };
13 };
14 };
15
16 config = lib.mkIf cfg.enable {
17 nixpkgs.overlays = [ (self: super: rec {
18 postgresql = self.postgresql_11_custom;
19 }) ];
20
21 networking.firewall.allowedTCPPorts = [ 5432 ];
22
23 security.acme.certs."postgresql" = config.services.myCertificates.certConfig // {
24 user = "postgres";
25 group = "postgres";
26 plugins = [ "fullchain.pem" "key.pem" "account_key.json" ];
27 domain = "db-1.immae.eu";
28 postRun = ''
29 systemctl reload postgresql.service
30 '';
31 };
32
33 systemd.services.postgresql.serviceConfig.SupplementaryGroups = "keys";
34 systemd.services.postgresql.serviceConfig.RuntimeDirectory = "postgresql";
35 services.postgresql = rec {
36 enable = cfg.postgresql.enable;
37 package = pkgs.postgresql;
38 enableTCPIP = true;
39 extraConfig = ''
40 max_connections = 100
41 wal_level = logical
42 shared_buffers = 512MB
43 work_mem = 10MB
44 max_wal_size = 1GB
45 min_wal_size = 80MB
46 log_timezone = 'Europe/Paris'
47 datestyle = 'iso, mdy'
48 timezone = 'Europe/Paris'
49 lc_messages = 'en_US.UTF-8'
50 lc_monetary = 'en_US.UTF-8'
51 lc_numeric = 'en_US.UTF-8'
52 lc_time = 'en_US.UTF-8'
53 default_text_search_config = 'pg_catalog.english'
54 ssl = on
55 ssl_cert_file = '/var/lib/acme/postgresql/fullchain.pem'
56 ssl_key_file = '/var/lib/acme/postgresql/key.pem'
57 '';
58 authentication = ''
59 local all postgres ident
60 local all all md5
61 hostssl all all 188.165.209.148/32 md5
62 hostssl all all 178.33.252.96/32 md5
63 hostssl all all all pam
64 hostssl replication backup-1 2001:41d0:302:1100::9:e5a9/128 pam pamservice=postgresql_replication
65 hostssl replication backup-1 54.37.151.137/32 pam pamservice=postgresql_replication
66 '';
67 };
68
69 secrets.keys = [
70 {
71 dest = "postgresql/pam";
72 permissions = "0400";
73 group = "postgres";
74 user = "postgres";
75 text = with myconfig.env.databases.postgresql.pam; ''
76 host ${myconfig.env.ldap.host}
77 base ${myconfig.env.ldap.base}
78 binddn ${dn}
79 bindpw ${password}
80 pam_filter ${filter}
81 ssl start_tls
82 '';
83 }
84 {
85 dest = "postgresql/pam_replication";
86 permissions = "0400";
87 group = "postgres";
88 user = "postgres";
89 text = ''
90 host ${myconfig.env.ldap.host}
91 base ${myconfig.env.ldap.base}
92 binddn ${myconfig.env.ldap.host_dn}
93 bindpw ${myconfig.env.ldap.password}
94 pam_login_attribute cn
95 ssl start_tls
96 '';
97 }
98 ];
99
100 security.pam.services = let
101 pam_ldap = "${pkgs.pam_ldap}/lib/security/pam_ldap.so";
102 in [
103 {
104 name = "postgresql";
105 text = ''
106 auth required ${pam_ldap} config=/var/secrets/postgresql/pam
107 account required ${pam_ldap} config=/var/secrets/postgresql/pam
108 '';
109 }
110 {
111 name = "postgresql_replication";
112 text = ''
113 auth required ${pam_ldap} config=/var/secrets/postgresql/pam_replication
114 account required ${pam_ldap} config=/var/secrets/postgresql/pam_replication
115 '';
116 }
117 ];
118 };
119}
120
diff --git a/nixops/modules/databases/redis.nix b/nixops/modules/databases/redis.nix
deleted file mode 100644
index 75c69a6..0000000
--- a/nixops/modules/databases/redis.nix
+++ /dev/null
@@ -1,35 +0,0 @@
1{ lib, pkgs, config, myconfig, ... }:
2let
3 cfg = config.services.myDatabases;
4in {
5 options.services.myDatabases = {
6 redis = {
7 enable = lib.mkOption {
8 default = cfg.enable;
9 example = true;
10 description = "Whether to enable redis database";
11 type = lib.types.bool;
12 };
13 };
14 };
15
16 config = lib.mkIf cfg.enable {
17 ids.uids.redis = myconfig.env.users.redis.uid;
18 ids.gids.redis = myconfig.env.users.redis.gid;
19 users.users.redis.uid = config.ids.uids.redis;
20 users.groups.redis.gid = config.ids.gids.redis;
21 services.redis = rec {
22 enable = config.services.myDatabases.redis.enable;
23 bind = "127.0.0.1";
24 unixSocket = myconfig.env.databases.redis.socket;
25 extraConfig = ''
26 unixsocketperm 777
27 maxclients 1024
28 '';
29 };
30 systemd.services.redis.serviceConfig.RuntimeDirectory =
31 assert myconfig.env.databases.redis.socket == "/run/redis/redis.sock";
32 "redis";
33 };
34}
35