summaryrefslogtreecommitdiffstats
path: root/krebs/2configs/nameserver.nix
blob: 4c6b95516967458f1c21e4ae75e6c28a3b99eed0 (plain)
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
{ config, lib, pkgs, ... }: let
  acmeChallenge =
    { domain
    , nameserver
    , adminEmail
    , serial ? 0
    , refresh ? 3600
    , retry ? 900
    , expire ? 604800
    , minimum ? 180
    }:
    pkgs.writeText "${domain}.zone" /* bindzone */ ''
      $TTL 60
      @ IN SOA ${lib.concatStringsSep " " [
        "${nameserver}."
        "${lib.replaceStrings ["@"] ["."] adminEmail}."
        (toString serial)
        (toString refresh)
        (toString retry)
        (toString expire)
        (toString minimum)
      ]}
      @ IN NS ${nameserver}.
    '';
in {
  networking.firewall.allowedTCPPorts = [
    53 # domain for AXFR
  ];
  networking.firewall.allowedUDPPorts = [
    53 # domain
  ];

  krebs.systemd.services.knot.restartIfCredentialsChange = true;
  systemd.services.knot.serviceConfig.LoadCredential = [
    "keys.conf:/var/src/secrets/knot-keys.conf"
  ];

  services.knot = {
    enable = true;
    keyFiles = [
      "/run/credentials/knot.service/keys.conf"
    ];
    extraConfig = /* yaml */ ''
      server:
        udp-max-payload: 4096
        listen: [ 127.0.0.53@2, ${
          lib.concatMapStringsSep ", "
            (addr: "${addr}@53")
            (
              config.krebs.build.host.nets.internet.addrs or []
              ++
              # This is required for hosts at OCI because the default route
              # provided by DHCP is using the private address.
              config.krebs.build.host.nets.intranet.addrs or []
            )
        } ]

      log:
        - target: syslog
          any: debug

      remote:
        - id: henet_ns1
          address: 216.218.130.2

        - id: krebscode_ni
          address: ${config.krebs.hosts.ni.nets.internet.ip4.addr}
          key: krebs_transfer_notify_key

      acl:
        - id: acme_acl
          key: acme
          action: update

        - id: dane_acl
          key: dane
          action: update

        - id: transfer_to_henet_secondary
          key: henet_transfer_key
          address: [ 216.218.133.2, 2001:470:600::2 ]
          action: transfer

        - id: transfer_to_krebscode_secondary
          key: krebs_transfer_notify_key
          action: transfer

      mod-rrl:
        - id: default
          rate-limit: 200   # Allow 200 resp/s for each flow
          slip: 2           # Every other response slips

      policy:
        - id: rsa2k
          algorithm: rsasha256
          ksk-size: 4096
          zsk-size: 2048

      template:
        - id: default
          global-module: mod-rrl/default
          semantic-checks: on
          zonefile-sync: -1
          zonefile-load: difference-no-serial
          journal-content: all

      zone:
        - domain: krebsco.de
          file: ${pkgs.krebs.zones."krebsco.de"}
          dnssec-signing: on
          dnssec-policy: rsa2k
          notify: henet_ns1
          notify: krebscode_ni
          acl: transfer_to_henet_secondary
          acl: transfer_to_krebscode_secondary
          acl: dane_acl

        - domain: _acme-challenge.krebsco.de
          file: ${acmeChallenge {
            domain = "_acme-challenge.krebsco.de";
            nameserver = "ns1.krebsco.de";
            adminEmail = "spam@krebsco.de";
          }}
          acl: acme_acl

        - domain: r
          file: ${pkgs.krebs.zones.r}

        - domain: w
          file: ${pkgs.krebs.zones.w}
    '';
  };

  systemd.services."knsupdate-krebsco.de" = {
    serviceConfig = {
      Type = "oneshot";
      SyslogIdentifier = "knsupdate-krebsco.de";
      ExecStart = pkgs.writeDash "knsupdate-krebsco.de" /* sh */ ''
        set -efu

        mk_certificate_association_data() {
          ${pkgs.openssl}/bin/openssl x509 -noout -fingerprint -sha256 < "$1" |
          ${pkgs.coreutils}/bin/cut -d= -f2 |
          ${pkgs.coreutils}/bin/tr -d :
        }

        certfile=/var/lib/acme/krebsco.de/cert.pem
        certificate_association_data=$(mk_certificate_association_data "$certfile")
        keyfile=/var/src/secrets/dane.tsig

        script=$(${pkgs.coreutils}/bin/mktemp -t knsupdate.XXXXXXXX)
        trap 'rm "$script"' EXIT
        (
          exec >"$script"
          echo server krebsco.de.
          echo zone krebsco.de.
          echo origin krebsco.de.
          echo add _25._tcp.ni 60 IN TLSA 3 0 1 $certificate_association_data
          echo add _443._tcp.ni 60 IN TLSA 3 0 1 $certificate_association_data
          echo show
          echo send
          echo answer
          echo quit
        )
        ${pkgs.knot-dns}/bin/knsupdate -k "$keyfile" "$script"
      '';
    };
  };
}