diff --git a/nixos/modules/services/databases/foundationdb.nix b/nixos/modules/services/databases/foundationdb.nix index 22acddc8ca91..443cc6d5e456 100644 --- a/nixos/modules/services/databases/foundationdb.nix +++ b/nixos/modules/services/databases/foundationdb.nix @@ -35,6 +35,13 @@ let memory = ${cfg.memory} storage_memory = ${cfg.storageMemory} + ${optionalString (cfg.tls != null) '' + tls_plugin = ${pkgs.foundationdb}/libexec/plugins/FDBLibTLS.so + tls_certificate_file = ${cfg.tls.certificate} + tls_key_file = ${cfg.tls.key} + tls_verify_peers = ${cfg.tls.allowedPeers} + ''} + ${optionalString (cfg.locality.machineId != null) "locality_machineid=${cfg.locality.machineId}"} ${optionalString (cfg.locality.zoneId != null) "locality_zoneid=${cfg.locality.zoneId}"} ${optionalString (cfg.locality.datacenterId != null) "locality_dcid=${cfg.locality.datacenterId}"} @@ -188,6 +195,43 @@ in ''; }; + tls = mkOption { + default = null; + description = '' + FoundationDB Transport Security Layer (TLS) settings. + ''; + + type = types.nullOr (types.submodule ({ + options = { + certificate = mkOption { + type = types.str; + description = '' + Path to the TLS certificate file. This certificate will + be offered to, and may be verified by, clients. + ''; + }; + + key = mkOption { + type = types.str; + description = "Private key file for the certificate."; + }; + + allowedPeers = mkOption { + type = types.str; + default = "Check.Valid=1,Check.Unexpired=1"; + description = '' + "Peer verification string". This may be used to adjust which TLS + client certificates a server will accept, as a form of user + authorization; for example, it may only accept TLS clients who + offer a certificate abiding by some locality or organization name. + + For more information, please see the FoundationDB documentation. + ''; + }; + }; + })); + }; + locality = mkOption { default = { machineId = null; @@ -331,27 +375,30 @@ in touch ${cfg.pidfile} && \ chown -R ${cfg.user}:${cfg.group} ${cfg.pidfile} - for x in "${cfg.logDir}" "${cfg.dataDir}" /etc/foundationdb; do - [ ! -d "$x" ] && mkdir -m 0700 -vp "$x" && chown -R ${cfg.user}:${cfg.group} "$x"; + for x in "${cfg.logDir}" "${cfg.dataDir}"; do + [ ! -d "$x" ] && mkdir -m 0700 -vp "$x"; + chown -R ${cfg.user}:${cfg.group} "$x"; done + [ ! -d /etc/foundationdb ] && \ + mkdir -m 0775 -vp /etc/foundationdb && \ + chown -R ${cfg.user}:${cfg.group} "/etc/foundationdb" + if [ ! -f /etc/foundationdb/fdb.cluster ]; then cf=/etc/foundationdb/fdb.cluster desc=$(tr -dc A-Za-z0-9 /dev/null | head -c8) rand=$(tr -dc A-Za-z0-9 /dev/null | head -c8) echo ''${desc}:''${rand}@${initialIpAddr}:${builtins.toString cfg.listenPortStart} > $cf - chmod 0660 $cf && chown -R ${cfg.user}:${cfg.group} $cf + chmod 0664 $cf && chown -R ${cfg.user}:${cfg.group} $cf touch "${cfg.dataDir}/.first_startup" fi ''; - script = '' - exec fdbmonitor --lockfile ${cfg.pidfile} --conffile ${configFile}; - ''; + script = "exec fdbmonitor --lockfile ${cfg.pidfile} --conffile ${configFile}"; postStart = '' if [ -e "${cfg.dataDir}/.first_startup" ]; then - fdbcli --exec "configure new single ssd" + fdbcli --exec "configure new single memory" rm -f "${cfg.dataDir}/.first_startup"; fi ''; diff --git a/nixos/modules/services/databases/foundationdb.xml b/nixos/modules/services/databases/foundationdb.xml index 0a96203e0551..045193f4b75b 100644 --- a/nixos/modules/services/databases/foundationdb.xml +++ b/nixos/modules/services/databases/foundationdb.xml @@ -192,6 +192,44 @@ to a new node in order to connect, if it is not part of the cluster. +
Client authorization and TLS + +By default, any user who can connect to a FoundationDB process with the +correct cluster configuration can access anything. FoundationDB uses a +pluggable design to transport security, and out of the box it supports a +LibreSSL-based plugin for TLS support. This plugin not only does in-flight +encryption, but also performs client authorization based on the given +endpoint's certificate chain. For example, a FoundationDB server may be +configured to only accept client connections over TLS, where the client TLS +certificate is from organization Acme Co in the +Research and Development unit. + +Configuring TLS with FoundationDB is done using the + options in order to control the peer +verification string, as well as the certificate and its private key. + +Note that the certificate and its private key must be accessible to the +FoundationDB user account that the server runs under. These files are also NOT +managed by NixOS, as putting them into the store may reveal private +information. + +After you have a key and certificate file in place, it is not enough to +simply set the NixOS module options -- you must also configure the +fdb.cluster file to specify that a given set of coordinators +use TLS. This is as simple as adding the suffix :tls to your +cluster coordinator configuration, after the port number. For example, assuming +you have a coordinator on localhost with the default configuration, simply +specifying: + + +XXXXXX:XXXXXX@127.0.0.1:4500:tls + + +will configure all clients and server processes to use TLS from now +on. + +
+
Backups and Disaster Recovery The usual rules for doing FoundationDB backups apply on NixOS as written @@ -245,9 +283,6 @@ FoundationDB is not new software, but the NixOS compilation and integration has only undergone fairly basic testing of all the available functionality. - TLS plugin support is compiled in, but it's currently not - possible to specify the set of TLS certificate options in - services.foundationdb There is no way to specify individual parameters for individual fdbserver processes. Currently, all server processes inherit all the global fdbmonitor settings.