aboutsummaryrefslogtreecommitdiff
path: root/modules/private/databases/postgresql.nix
blob: 8c36d84e0ccbab15e68b555c4d46008861fd5ffc (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
{ lib, pkgs, config, myconfig,  ... }:
let
    cfg = config.myServices.databases.postgresql;
in {
  options.myServices.databases = {
    postgresql = {
      enable = lib.mkOption {
        default = cfg.enable;
        example = true;
        description = "Whether to enable postgresql database";
        type = lib.types.bool;
      };
      # Output variables
      socketsDir = lib.mkOption {
        type = lib.types.path;
        default = "/run/postgresql";
        description = ''
          The directory where Postgresql puts sockets.
          '';
        readOnly = true;
      };
      systemdRuntimeDirectory = lib.mkOption {
        type = lib.types.str;
        # Use ReadWritePaths= instead if socketsDir is outside of /run
        default = assert lib.strings.hasPrefix "/run/" cfg.socketsDir;
          lib.strings.removePrefix "/run/" cfg.socketsDir;
        description = ''
        Adjusted Postgresql sockets directory for systemd
        '';
        readOnly = true;
      };
    };
  };

  config = lib.mkIf cfg.enable {
    nixpkgs.overlays = [ (self: super: rec {
      postgresql = self.postgresql_11_custom;
    }) ];

    networking.firewall.allowedTCPPorts = [ 5432 ];

    security.acme.certs."postgresql" = config.myServices.databasesCerts // {
      user = "postgres";
      group = "postgres";
      plugins = [ "fullchain.pem" "key.pem" "account_key.json" ];
      domain = "db-1.immae.eu";
      postRun = ''
        systemctl reload postgresql.service
      '';
    };

    systemd.services.postgresql.serviceConfig = {
      SupplementaryGroups = "keys";
      RuntimeDirectory = cfg.systemdRuntimeDirectory;
    };
    services.postgresql = rec {
      enable = true;
      package = pkgs.postgresql;
      enableTCPIP = true;
      extraConfig = ''
        max_connections = 100
        wal_level = logical
        shared_buffers = 512MB
        work_mem = 10MB
        max_wal_size = 1GB
        min_wal_size = 80MB
        log_timezone = 'Europe/Paris'
        datestyle = 'iso, mdy'
        timezone = 'Europe/Paris'
        lc_messages = 'en_US.UTF-8'
        lc_monetary = 'en_US.UTF-8'
        lc_numeric = 'en_US.UTF-8'
        lc_time = 'en_US.UTF-8'
        default_text_search_config = 'pg_catalog.english'
        ssl = on
        ssl_cert_file = '${config.security.acme.directory}/postgresql/fullchain.pem'
        ssl_key_file = '${config.security.acme.directory}/postgresql/key.pem'
        '';
      authentication = ''
        local	all	postgres				ident
        local	all	all					md5
        hostssl	all	all	188.165.209.148/32		md5
        hostssl	all	all	178.33.252.96/32		md5
        hostssl	all	all	all				pam
        hostssl	replication	backup-1	2001:41d0:302:1100::9:e5a9/128	pam pamservice=postgresql_replication
        hostssl	replication	backup-1	54.37.151.137/32		pam pamservice=postgresql_replication
      '';
    };

    secrets.keys = [
      {
        dest = "postgresql/pam";
        permissions = "0400";
        group = "postgres";
        user = "postgres";
        text =  with myconfig.env.databases.postgresql.pam; ''
          host ${myconfig.env.ldap.host}
          base ${myconfig.env.ldap.base}
          binddn ${dn}
          bindpw ${password}
          pam_filter ${filter}
          ssl start_tls
        '';
      }
      {
        dest = "postgresql/pam_replication";
        permissions = "0400";
        group = "postgres";
        user = "postgres";
        text = ''
          host ${myconfig.env.ldap.host}
          base ${myconfig.env.ldap.base}
          binddn ${myconfig.env.ldap.host_dn}
          bindpw ${myconfig.env.ldap.password}
          pam_login_attribute cn
          ssl start_tls
        '';
      }
    ];

    security.pam.services = let
      pam_ldap = "${pkgs.pam_ldap}/lib/security/pam_ldap.so";
    in [
      {
        name = "postgresql";
        text = ''
          auth    required ${pam_ldap} config=${config.secrets.location}/postgresql/pam
          account required ${pam_ldap} config=${config.secrets.location}/postgresql/pam
          '';
      }
      {
        name = "postgresql_replication";
        text = ''
          auth    required ${pam_ldap} config=${config.secrets.location}/postgresql/pam_replication
          account required ${pam_ldap} config=${config.secrets.location}/postgresql/pam_replication
          '';
      }
    ];
  };
}