nixos: add TLS support to FoundationDB module, and tweak setup a bit

Signed-off-by: Austin Seipp <aseipp@pobox.com>
This commit is contained in:
Austin Seipp 2018-05-01 00:35:10 -05:00
parent ed5cbbbc44
commit 55eec81118
2 changed files with 92 additions and 10 deletions

View file

@ -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/urandom 2>/dev/null | head -c8)
rand=$(tr -dc A-Za-z0-9 </dev/urandom 2>/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
'';

View file

@ -192,6 +192,44 @@ to a new node in order to connect, if it is not part of the cluster.</para>
</section>
<section><title>Client authorization and TLS</title>
<para>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 <emphasis>Acme Co</emphasis> in the
<emphasis>Research and Development</emphasis> unit.</para>
<para>Configuring TLS with FoundationDB is done using the
<option>services.foundationdb.tls</option> options in order to control the peer
verification string, as well as the certificate and its private key.</para>
<para>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.</para>
<para>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
<command>fdb.cluster</command> file to specify that a given set of coordinators
use TLS. This is as simple as adding the suffix <command>:tls</command> to your
cluster coordinator configuration, after the port number. For example, assuming
you have a coordinator on localhost with the default configuration, simply
specifying:</para>
<programlisting>
XXXXXX:XXXXXX@127.0.0.1:4500:tls
</programlisting>
<para>will configure all clients and server processes to use TLS from now
on.</para>
</section>
<section><title>Backups and Disaster Recovery</title>
<para>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.</para>
<itemizedlist>
<listitem><para>TLS plugin support is compiled in, but it's currently not
possible to specify the set of TLS certificate options in
<command>services.foundationdb</command></para></listitem>
<listitem><para>There is no way to specify individual parameters for
individual <command>fdbserver</command> processes. Currently, all server
processes inherit all the global <command>fdbmonitor</command> settings.