merge 5.1 into 5.2

This commit is contained in:
Evan Tschannen 2018-04-18 20:44:31 -07:00
commit 57d650062a
14 changed files with 400 additions and 52 deletions

View File

@ -158,7 +158,7 @@ You can add new machines to a cluster at any time:
5) If you have previously :ref:`excluded <removing-machines-from-a-cluster>` a machine from the cluster, you will need to take it off the exclusion list using the ``include <ip>`` command of fdbcli before it can be a full participant in the cluster.
.. note:: Addresses have the form ``IP``:``PORT``.
.. note:: Addresses have the form ``IP``:``PORT``. This form is used even if TLS is enabled.
.. _removing-machines-from-a-cluster:
@ -188,7 +188,7 @@ To temporarily or permanently remove one or more machines from a FoundationDB cl
``exclude`` can be used to exclude either machines (by specifiying an IP address) or individual processes (by specificying an ``IP``:``PORT`` pair).
.. note:: Addresses have the form ``IP``:``PORT``.
.. note:: Addresses have the form ``IP``:``PORT``. This form is used even if TLS is enabled.
Excluding a server doesn't shut it down immediately; data on the machine is first moved away. When the ``exclude`` command completes successfully (by returning control to the command prompt), the machines that you specified are no longer required to maintain the configured redundancy mode. A large amount of data might need to be transferred first, so be patient. When the process is complete, the excluded machine or process can be shut down without fault tolerance or availability consequences.
@ -210,6 +210,11 @@ Moving a cluster
The procedures for adding and removing machines can be combined into a recipe for :doc:`moving an existing cluster to new machines <moving-a-cluster>`.
Converting an existing cluster to use TLS
=========================================
A FoundationDB cluster has the option of supporting :doc:`Transport Layer Security (TLS) <tls>`. To enable TLS on an existing, non-TLS cluster, see :ref:`Converting a running cluster <converting-existing-cluster>`.
.. _administration-monitoring-cluster-status:
Monitoring cluster status

View File

@ -236,6 +236,34 @@
It is an error to set these options after the first call to |open-func| or |init-func| anywhere in your application.
.. |tls-options-burb| replace::
The following options are only used when connecting to a :doc:`TLS-enabled cluster <tls>`.
.. |option-tls-plugin-blurb| replace::
Sets the :ref:`TLS plugin <configuring-tls-plugin>` to load. This option, if used, must be set before any other TLS options.
.. |option-tls-cert-path-blurb| replace::
Sets the path for the file from which the :ref:`certificate chain <tls-certificate-file>` will be loaded.
.. |option-tls-key-path-blurb| replace::
Sets the path for the file from which to load the :ref:`private key <tls-key-file>` corresponding to your own certificate.
.. |option-tls-verify-peers-blurb| replace::
Sets the :ref:`peer certificate field verification criteria <tls-verify-peers>`.
.. |option-tls-cert-bytes| replace::
Sets the certificate chain.
.. |option-tls-key-bytes| replace::
Set the private key corresponding to your own certificate.
.. |option-disable-multi-version-client-api| replace::
Disables the :ref:`multi-version client API <multi-version-client-api>` and instead uses the local client directly. Must be set before setting up the network.

View File

@ -149,6 +149,32 @@ After importing the ``fdb`` module and selecting an API version, you probably wa
|option-external-client-directory|
.. note:: |tls-options-burb|
.. method :: fdb.options.set_tls_plugin(plugin_path_or_name)
|option-tls-plugin-blurb|
.. method :: fdb.options.set_tls_cert_path(path_to_file)
|option-tls-cert-path-blurb|
.. method :: fdb.options.set_tls_key_path(path_to_file)
|option-tls-key-path-blurb|
.. method :: fdb.options.set_tls_verify_peers(criteria)
|option-tls-verify-peers-blurb|
.. method :: fdb.options.set_tls_cert_bytes(bytes)
|option-tls-cert-bytes|
.. method :: fdb.options.set_tls_key_bytes(bytes)
|option-tls-key-bytes|
Cluster objects
===============

View File

@ -117,8 +117,6 @@ After requiring the ``FDB`` gem and selecting an API version, you probably want
|option-trace-roll-size-blurb|
.. method :: FDB.options.set_disable_multi_version_client_api() -> nil
|option-disable-multi-version-client-api|
.. method :: FDB.options.set_callbacks_on_external_threads() -> nil
@ -133,6 +131,34 @@ After requiring the ``FDB`` gem and selecting an API version, you probably want
|option-external-client-directory|
.. note:: |tls-options-burb|
.. method :: FDB.options.set_tls_plugin(plugin_path_or_name) -> nil
|option-tls-plugin-blurb|
.. method :: FDB.options.set_tls_cert_path(path_to_file) -> nil
|option-tls-cert-path-blurb|
.. method :: FDB.options.set_tls_key_path(path_to_file) -> nil
|option-tls-key-path-blurb|
.. method :: FDB.options.set_tls_verify_peers(criteria) -> nil
|option-tls-verify-peers-blurb|
.. method :: FDB.options.set_tls_cert_bytes(bytes) -> nil
|option-tls-cert-bytes|
.. method :: FDB.options.set_tls_key_bytes(bytes) -> nil
|option-tls-key-bytes|
.. method :: FDB.options.set_disable_multi_version_client_api() -> nil
Cluster objects
===============

View File

@ -41,6 +41,8 @@ Choose a machine to be the starting machine for your cluster. The database on th
user@host1$ sudo /usr/lib/foundationdb/make_public.py
/etc/foundationdb/fdb.cluster is now using address 10.0.1.1
.. note:: A FoundationDB cluster has the option of supporting :doc:`Transport Layer Security (TLS) <tls>` for all connections (between server processes and between clients and servers). To enable TLS on a new cluster, see :ref:`Enabling TLS <enable-TLS>`.
By default, the script will pick a local network interface that can access the internet. To specify the address manually, use the ``-a`` flag and choose an address that is accessible by all machines in the cluster as well as by all intended clients.::
user@host1$ sudo /usr/lib/foundationdb/make_public.py -a 10.0.1.1

View File

@ -110,7 +110,7 @@ We're going to rely on the powerful guarantees of transactions to help keep all
@fdb.transactional
def add_class(tr, c):
tr[course.pack((c,))] = bytes(100)
tr[course.pack((c,))] = fdb.tuple.pack((100,))
:py:func:`@fdb.transactional <fdb.transactional>` is a Python decorator that makes a normal function a transactional function. All functions decorated this way *need to have a parameter named* ``tr``. This parameter is passed the transaction that the function should use to do reads and writes.
@ -180,7 +180,7 @@ We finally get to the crucial function. A student has decided on a class (by nam
@fdb.transactional
def signup(tr, s, c):
rec = attends.pack((s, c))
tr[rec] = ''
tr[rec] = b''
We simply insert the appropriate record (with a blank value).
@ -212,7 +212,7 @@ Let's go back to the data model. Remember that we stored the number of seats in
@fdb.transactional
def available_classes(tr):
return [course.unpack(k)[0] for k, v in tr[course.range(())]
if int(v)]
if fdb.tuple.unpack(v)[0]]
This is easy -- we simply add a condition to check that the value is non-zero. Let's check out ``signup`` next:
@ -224,11 +224,11 @@ This is easy -- we simply add a condition to check that the value is non-zero. L
rec = attends.pack((s, c))
if tr[rec].present(): return # already signed up
seats_left = int(tr[course.pack((c,))])
seats_left = fdb.tuple.unpack(tr[course.pack((c,))])[0]
if not seats_left: raise Exception('No remaining seats')
tr[course.pack((c,))] = bytes(seats_left - 1)
tr[rec] = ''
tr[course.pack((c,))] = fdb.tuple.pack((seats_left - 1,))
tr[rec] = b''
We now have to check that we aren't already signed up, since we don't want a double sign up to decrease the number of seats twice. Then we look up how many seats are left to make sure there is a seat remaining so we don't push the counter into the negative. If there is a seat remaining, we decrement the counter.
@ -259,7 +259,7 @@ Let's finish up the limited seats feature by modifying the drop function:
def drop(tr, s, c):
rec = attends.pack((s, c))
if not tr[rec].present(): return # not taking this class
tr[course.pack((c,))] = bytes(int(tr[course.pack((c,))]) + 1)
tr[course.pack((c,))] = fdb.tuple.pack((fdb.tuple.unpack(tr[course.pack((c,))])[0] + 1,))
del tr[rec]
This case is easier than signup because there are no constraints we can hit. We just need to make sure the student is in the class and to "give back" one seat when the student drops.
@ -277,14 +277,14 @@ Of course, as soon as our new version of the system goes live, we hear of a tric
rec = attends.pack((s, c))
if tr[rec].present(): return # already signed up
seats_left = int(tr[course.pack((c,))])
seats_left = fdb.tuple.unpack(tr[course.pack((c,))])[0]
if not seats_left: raise Exception('No remaining seats')
classes = tr[attends.range((s,))]
if len(list(classes)) == 5: raise Exception('Too many classes')
tr[course.pack((c,))] = bytes(seats_left - 1)
tr[rec] = ''
tr[course.pack((c,))] = fdb.tuple.pack((seats_left - 1,))
tr[rec] = b''
Fortunately, we decided on a data model that keeps all of the attending records for a single student together. With this approach, we can use a single range read in the ``attends`` subspace to retrieve all the classes that a student is signed up for. We simply throw an exception if the number of classes has reached the limit of five.
@ -331,8 +331,10 @@ Appendix: SchedulingTutorial.py
Here's the code for the scheduling tutorial::
import itertools
import traceback
import fdb
import fdb.tuple
fdb.api_version(510)
@ -352,7 +354,7 @@ Here's the code for the scheduling tutorial::
@fdb.transactional
def add_class(tr, c):
tr[course.pack((c,))] = bytes(100)
tr[course.pack((c,))] = fdb.tuple.pack((100,))
# Generate 1,620 classes like '9:00 chem for dummies'
levels = ['intro', 'for dummies', 'remedial', '101',
@ -378,7 +380,7 @@ Here's the code for the scheduling tutorial::
@fdb.transactional
def available_classes(tr):
return [course.unpack(k)[0] for k, v in tr[course.range(())]
if int(v)]
if fdb.tuple.unpack(v)[0]]
@fdb.transactional
@ -386,21 +388,21 @@ Here's the code for the scheduling tutorial::
rec = attends.pack((s, c))
if tr[rec].present(): return # already signed up
seats_left = int(tr[course.pack((c,))])
seats_left = fdb.tuple.unpack(tr[course.pack((c,))])[0]
if not seats_left: raise Exception('No remaining seats')
classes = tr[attends.range((s,))]
if len(list(classes)) == 5: raise Exception('Too many classes')
tr[course.pack((c,))] = bytes(seats_left - 1)
tr[rec] = ''
tr[course.pack((c,))] = fdb.tuple.pack((seats_left - 1,))
tr[rec] = b''
@fdb.transactional
def drop(tr, s, c):
rec = attends.pack((s, c))
if not tr[rec].present(): return # not taking this class
tr[course.pack((c,))] = bytes(int(tr[course.pack((c,))]) + 1)
tr[course.pack((c,))] = fdb.tuple.pack((fdb.tuple.unpack(tr[course.pack((c,))])[0] + 1,))
del tr[rec]
@ -446,7 +448,8 @@ Here's the code for the scheduling tutorial::
my_classes.remove(old_c)
my_classes.append(new_c)
except Exception as e:
print e, "Need to recheck available classes."
traceback.print_exc()
print("Need to recheck available classes.")
all_classes = []
def run(students, ops_per_student):
@ -455,9 +458,9 @@ Here's the code for the scheduling tutorial::
for i in range(students)]
for thr in threads: thr.start()
for thr in threads: thr.join()
print "Ran", students * ops_per_student, "transactions"
print("Ran {} transactions".format(students * ops_per_student))
if __name__ == "__main__":
init(db)
print "initialized"
print("initialized")
run(10, 10)

View File

@ -263,6 +263,7 @@ Contains default parameters for all fdbserver processes on this machine. These s
* ``locality_dcid``: Data center identifier key. All processes physically located in a data center should share the id. No default value. If you are depending on data center based replication this must be set on all processes.
* ``locality_data_hall``: Data hall identifier key. All processes physically located in a data hall should share the id. No default value. If you are depending on data hall based replication this must be set on all processes.
* ``io_trust_seconds``: Time in seconds that a read or write operation is allowed to take before timing out with an error. If an operation times out, all future operations on that file will fail with an error as well. Only has an effect when using AsyncFileKAIO in Linux. If unset, defaults to 0 which means timeout is disabled.
.. note:: In addition to the options above, TLS settings as described for the :ref:`TLS plugin <configuring-tls-plugin>` can be specified in the [fdbserver] section.
``[fdbserver.<ID>]`` section(s)
---------------------------------

View File

@ -10,38 +10,38 @@ macOS
The macOS installation package is supported on macOS 10.7+. It includes the client and (optionally) the server.
* `FoundationDB-5.1.6.pkg <https://www.foundationdb.org/downloads/5.1.6/macOS/installers/FoundationDB-5.1.6.pkg>`_
* `FoundationDB-5.1.7.pkg <https://www.foundationdb.org/downloads/5.1.7/macOS/installers/FoundationDB-5.1.7.pkg>`_
Ubuntu
------
The Ubuntu packages are supported on 64-bit Ubuntu 12.04+, but beware of the Linux kernel bug in Ubuntu 12.x.
* `foundationdb-clients-5.1.6-1_amd64.deb <https://www.foundationdb.org/downloads/5.1.6/ubuntu/installers/foundationdb-clients_5.1.6-1_amd64.deb>`_
* `foundationdb-server-5.1.6-1_amd64.deb <https://www.foundationdb.org/downloads/5.1.6/ubuntu/installers/foundationdb-server_5.1.6-1_amd64.deb>`_ (depends on the clients package)
* `foundationdb-clients-5.1.7-1_amd64.deb <https://www.foundationdb.org/downloads/5.1.7/ubuntu/installers/foundationdb-clients_5.1.7-1_amd64.deb>`_
* `foundationdb-server-5.1.7-1_amd64.deb <https://www.foundationdb.org/downloads/5.1.7/ubuntu/installers/foundationdb-server_5.1.7-1_amd64.deb>`_ (depends on the clients package)
RHEL/CentOS EL6
---------------
The RHEL/CentOS EL6 packages are supported on 64-bit RHEL/CentOS 6.x.
* `foundationdb-clients-5.1.6-1.el6.x86_64.rpm <https://www.foundationdb.org/downloads/5.1.6/rhel6/installers/foundationdb-clients-5.1.6-1.el6.x86_64.rpm>`_
* `foundationdb-server-5.1.6-1.el6.x86_64.rpm <https://www.foundationdb.org/downloads/5.1.6/rhel6/installers/foundationdb-server-5.1.6-1.el6.x86_64.rpm>`_ (depends on the clients package)
* `foundationdb-clients-5.1.7-1.el6.x86_64.rpm <https://www.foundationdb.org/downloads/5.1.7/rhel6/installers/foundationdb-clients-5.1.7-1.el6.x86_64.rpm>`_
* `foundationdb-server-5.1.7-1.el6.x86_64.rpm <https://www.foundationdb.org/downloads/5.1.7/rhel6/installers/foundationdb-server-5.1.7-1.el6.x86_64.rpm>`_ (depends on the clients package)
RHEL/CentOS EL7
---------------
The RHEL/CentOS EL7 packages are supported on 64-bit RHEL/CentOS 7.x.
* `foundationdb-clients-5.1.6-1.el7.x86_64.rpm <https://www.foundationdb.org/downloads/5.1.6/rhel7/installers/foundationdb-clients-5.1.6-1.el7.x86_64.rpm>`_
* `foundationdb-server-5.1.6-1.el7.x86_64.rpm <https://www.foundationdb.org/downloads/5.1.6/rhel7/installers/foundationdb-server-5.1.6-1.el7.x86_64.rpm>`_ (depends on the clients package)
* `foundationdb-clients-5.1.7-1.el7.x86_64.rpm <https://www.foundationdb.org/downloads/5.1.7/rhel7/installers/foundationdb-clients-5.1.7-1.el7.x86_64.rpm>`_
* `foundationdb-server-5.1.7-1.el7.x86_64.rpm <https://www.foundationdb.org/downloads/5.1.7/rhel7/installers/foundationdb-server-5.1.7-1.el7.x86_64.rpm>`_ (depends on the clients package)
Windows
-------
The Windows installer is supported on 64-bit Windows XP and later. It includes the client and (optionally) the server.
* `foundationdb-5.1.6-x64.msi <https://www.foundationdb.org/downloads/5.1.6/windows/installers/foundationdb-5.1.6-x64.msi>`_
* `foundationdb-5.1.7-x64.msi <https://www.foundationdb.org/downloads/5.1.7/windows/installers/foundationdb-5.1.7-x64.msi>`_
API Language Bindings
=====================
@ -58,18 +58,18 @@ On macOS and Windows, the FoundationDB Python API bindings are installed as part
If you need to use the FoundationDB Python API from other Python installations or paths, download the Python package:
* `foundationdb-5.1.6.tar.gz <https://www.foundationdb.org/downloads/5.1.6/bindings/python/foundationdb-5.1.6.tar.gz>`_
* `foundationdb-5.1.7.tar.gz <https://www.foundationdb.org/downloads/5.1.7/bindings/python/foundationdb-5.1.7.tar.gz>`_
Ruby 1.9.3/2.0.0+
-----------------
* `fdb-5.1.6.gem <https://www.foundationdb.org/downloads/5.1.6/bindings/ruby/fdb-5.1.6.gem>`_
* `fdb-5.1.7.gem <https://www.foundationdb.org/downloads/5.1.7/bindings/ruby/fdb-5.1.7.gem>`_
Java 8+
-------
* `fdb-java-5.1.6.jar <https://www.foundationdb.org/downloads/5.1.6/bindings/java/fdb-java-5.1.6.jar>`_
* `fdb-java-5.1.6-javadoc.jar <https://www.foundationdb.org/downloads/5.1.6/bindings/java/fdb-java-5.1.6-javadoc.jar>`_
* `fdb-java-5.1.7.jar <https://www.foundationdb.org/downloads/5.1.7/bindings/java/fdb-java-5.1.7.jar>`_
* `fdb-java-5.1.7-javadoc.jar <https://www.foundationdb.org/downloads/5.1.7/bindings/java/fdb-java-5.1.7-javadoc.jar>`_
Go 1.1+
-------

View File

@ -16,6 +16,8 @@ Ready to operate an externally accessible FoundationDB cluster? You'll find what
* :doc:`mr-status` describes the JSON encoding of a cluster's status information.
* :doc:`tls` describes the Transport Layer Security (TLS) capabilities of FoundationDB, which enable security and authentication through a public/private key infrastructure.
* :doc:`backups` covers the FoundationDB backup tool, which provides an additional level of protection by supporting recovery from disasters or unintentional modification of the database.
* :doc:`platforms` describes issues on particular platforms that affect the operation of FoundationDB.
@ -30,5 +32,6 @@ Ready to operate an externally accessible FoundationDB cluster? You'll find what
administration
command-line-interface
mr-status
tls
backups
platforms

View File

@ -2,6 +2,14 @@
Release Notes
#############
5.1.7
=====
Fixes
-----
* fdbdr switch could take a long time to complete if the two clusters were not created at the same time. <rdar://problem/37551521>
5.1.6
=====

View File

@ -0,0 +1,235 @@
########################
Transport Layer Security
########################
.. include:: guide-common.rst.inc
Introduction
============
Transport Layer Security (TLS) and its predecessor, Secure Sockets Layer (SSL), are protocols designed to provide communication security over public networks. Users exchange a symmetric session key that is used to encrypt data exchanged between the parties.
By default, a FoundationDB cluster uses *unencrypted* connections among client and server processes. This document describes the `Transport Layer Security <http://en.wikipedia.org/wiki/Transport_Layer_Security>`_ (TLS) capabilities of FoundationDB, which enable security and authentication through a public/private key infrastructure. TLS is provided in FoundationDB via a plugin-based architecture. This document will describe the basic TLS capabilities of FoundationDB and document the default plugin, which is based on `LibreSSL <https://www.libressl.org/>`_. TLS-enabled servers will only communicate with other TLS-enabled servers and TLS-enabled clients. Therefore, a cluster's machines must all enable TLS in order for TLS to be used.
Setting Up FoundationDB to use TLS
==================================
.. _enable-TLS:
Enabling TLS in a new cluster
-----------------------------
To set a new cluster to use TLS, use the ``-t`` flag on ``make-public.py``::
user@host1$ sudo /usr/lib/foundationdb/make-public.py -t
/etc/foundationdb/fdb.cluster is now using address 10.0.1.1 (TLS enabled)
This will configure the new cluster to communicate with TLS.
.. note:: Depending on your operating system, version and configuration, there may be a firewall in place that prevents external access to certain ports. If necessary, please consult the appropriate documentation for your OS and ensure that all machines in your cluster can reach the ports configured in your :ref:`configuration file <foundationdb-conf>`.
.. _converting-existing-cluster:
Converting an existing cluster to use TLS
=========================================
Enabling TLS on an existing (non-TLS) cluster cannot be accomplished without downtime because all processes must have TLS enabled to communicate. At startup, each server process enables TLS if the addresses in its cluster file are TLS-enabled. As a result, server processes must be stopped and restarted to convert them to use TLS. To convert the cluster to TLS in the most conservative way:
1) Stop all FoundationDB clients and :ref:`server processes <administration-running-foundationdb>` in the cluster.
2) Change all cluster files to have the ``:tls`` suffix for each coordinator.
3) Restart the cluster and the clients.
.. _configuring-tls-plugin:
Configuring the TLS Plugin
==========================
The location and operation of the TLS plugin are configured through four settings. These settings can be provided as command-line options, client options, or environment variables, and are named as follows:
======================== ==================== ============================ ==================================================
Command-line Option Client Option Environment Variable Purpose
======================== ==================== ============================ ==================================================
``tls_plugin`` ``TLS_plugin`` ``FDB_TLS_PLUGIN`` Path to the file to be loaded as the TLS plugin
``tls_certificate_file`` ``TLS_cert_path`` ``FDB_TLS_CERTIFICATE_FILE`` Path to the file from which the local certificates
can be loaded, used by the plugin
``tls_key_file`` ``TLS_key_path`` ``FDB_TLS_KEY_FILE`` Path to the file from which to load the private
key, used by the plugin
``tls_verify_peers`` ``TLS_verify_peers`` ``FDB_TLS_VERIFY_PEERS`` The byte-string for the verification of peer
certificates and sessions, used by the plugin
======================== ==================== ============================ ==================================================
The value for each setting can be specified in more than one way. The actual valued used is determined in the following order:
1. An explicity specified value as a command-line option or client option, if one is given;
2. The value of the environment variable, if one has been set;
3. The default value
As with all other command-line options to ``fdbserver``, the TLS settings can be specified in the :ref:`[fdbserver] section of the configuration file <foundationdb-conf-fdbserver>`.
The settings for certificate file, key file, and peer verification are interpreted by the loaded plugin.
Default Values
--------------
Plugin default location
^^^^^^^^^^^^^^^^^^^^^^^
Similarly, if a value is not specified for the parameter ``tls_plugin``, the file will be specified by the environment variable ``FDB_TLS_PLUGIN`` or, if this variable is not set, the system-dependent location:
* Linux: ``/usr/lib/foundationdb/plugins/FDBLibTLS.so``
* macOS: ``/usr/local/foundationdb/plugins/FDBLibTLS.dylib``
* Windows: ``C:\Program Files\foundationdb\plugins\FDBLibTLS.dll``
On Windows, this location will be relative to the chosen installation location. The environment variable ``FOUNDATIONDB_INSTALL_PATH`` will be used in place of ``C:\Program Files\foundationdb\`` to determine this location.
Certificate file default location
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The default behavior when the certificate or key file is not specified is to look for a file named ``fdb.pem`` in the current working directory. If this file is not present, an attempt is made to load a file from a system-dependent location:
* Linux: ``/etc/foundationdb/fdb.pem``
* macOS: ``/usr/local/etc/foundationdb/fdb.pem``
* Windows: ``C:\ProgramData\foundationdb\fdb.pem``
Default Peer Verification
^^^^^^^^^^^^^^^^^^^^^^^^^
The default peer verification is the empty string.
Parameters and client bindings
------------------------------
When loading a TLS plugin from a non-default location when using a client binding, the ``TLS_PLUGIN`` network option must be specified before any other TLS option. Because a loaded TLS plugin is allowed to reject the values specified in the other options, the plugin load operation will be forced by specifying one of the other options, if it not already specified.
The default LibreSSL-based plugin
=================================
FoundationDB offers a TLS plugin based on the LibreSSL library. By default, it will be loaded automatically when participating in a TLS-enabled cluster.
For the plugin to operate, each process (both server and client) must have an X509 certificate, its corresponding private key, and potentially the certificates with which is was signed. When a process begins to communicate with a FoundationDB server process, the peer's certificate is checked to see if it is trusted and the fields of the peer certificate are verified. Peers must share the same root trusted certificate, and they must both present certificates whose signing chain includes this root certificate.
If the local certificate and chain is invalid, a FoundationDB server process bound to a TLS address will not start. In the case of invalid certificates on a client, the client will be able to start but will be unable to connect any TLS-enabled cluster.
Formats
-------
The LibreSSL plugin can read certificates and their private keys in base64-encoded DER-formatted X.509 format (which is known as PEM). A PEM file can contain both certificates and a private key or the two can be stored in separate files.
Required files
--------------
A single file can contain the information as described in both of the following sections.
.. _tls-certificate-file:
The certificate file
^^^^^^^^^^^^^^^^^^^^
A file must be supplied that contains an ordered list of certificates. The first certificate is the process' own certificate. Each following certificate must sign the one preceding it.
All but the last certificate are provided to peers during TLS handshake as the certificate chain.
The last certificate in the list is the trusted certificate. All processes that want to communicate must have the same trusted certificate.
.. note:: If the certificate list contains only one certificate, that certificate *must* be self-signed and will be used as both the certificate chain and the trusted certificate.
Each of these certificates must be in the form::
--------BEGIN CERTIFICATE--------
xxxxxxxxxxxxxxx
--------END CERTIFICATE--------
.. _tls-key-file:
The key file
^^^^^^^^^^^^
The key file must contain the private key corresponding to the process' own certificate. The private key must be in PKCS#8 format, which means that it must be surrounded by::
-----BEGIN PRIVATE KEY-----
xxxxxxxxxxxxxxx
-----END PRIVATE KEY-----
Certificate creation
--------------------
If your organization already makes use of certificates for access control and securing communications, you should ask your security expert for organizational procedure for obtaining and verifying certificates. If the goal of enabling TLS is to make sure that only known machines can join or access the FoundationDB cluster and for securing communications, then creating your own certificates can serve these purposes.
The following set of commands uses the OpenSSL command-line tools to create a self-signed certificate and private key. The certificate is then joined with the private key in the output ``fdb.pem`` file::
user@host:> openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout private.key -out cert.crt
user@host:> cat cert.crt private.key > fdb.pem
Peer verification
=================
A FoundationDB server or client will only communicate with peers that present a certificate chain that meets the verification requirements. By default, the only requirement is that the provided certificate chain ends in a certificate signed by the local trusted certificate.
.. _tls-verify-peers:
Certificate field verification
------------------------------
With a peer verification string, FoundationDB servers and clients can adjust what is required of the certificate chain presented by a peer. These options can make the certificate requirements more rigorous or more lenient.
Turning down the validation
^^^^^^^^^^^^^^^^^^^^^^^^^^^
If the default checking of the certificate chain is too stringent, the verification string can contain settings to weaken what certificates are accepted.
===================== =============================================================
Setting Result
===================== =============================================================
``Check.Valid=0`` Sets the current process to disable all further verification
of a peer certificate.
``Check.Unexpired=0`` Disables date checking of peer certificates. If the clocks in
the cluster and between the clients and servers are not to be
trusted, setting this value to ``0`` can allow communications
to proceed.
===================== =============================================================
Adding verification requirements
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Requirements can be placed on the fields of the Issuer and Subject DNs in the peer's own certificate. These reqirements take the form of a comma-separated list of conditions. Each condition takes the form of ``field=value``. Only certain fields from a DN can be matched against.
====== ===================
Field Well known name
====== ===================
``CN`` Common Name
``C`` County
``L`` Locality
``ST`` State
``O`` Organization
``OU`` Organizational Unit
====== ===================
The field of each condition may optionally have a DN prefix, which is otherwise considered to be for the Subject DN.
============================= ========
Prefix DN
============================= ========
``S.``, ``Subject.``, or none Subject
``I.``, or ``Issuer.`` Issuer
============================= ========
The value of a condition must be specified in a form derived from a subset of `RFC 4514 <http://www.ietf.org/rfc/rfc4514.txt>`_. Specifically, the "raw" notation (a value starting with the ``#`` character) is not accepted. Other escaping mechanisms, including specifying characters by hex notation, are allowed. The specified field's value must exactly match the value in the peer's certificate.
By default, the fields of a peer certificate's DNs are not examined.
Verification Examples
^^^^^^^^^^^^^^^^^^^^^
A verification string can be of the form::
Check.Unexpired=0,I.C=US,C=US,S.O=XYZCorp\, LLC
This verification string would:
* Skip the check on all peer certificates that the certificate is not yet expired
* Require that the Issuer have a Country field of ``US``
* Require that the Subject have a Country field of ``US``
* Require that the Subject have a Organization field of ``XYZCorp, LLC``

View File

@ -1510,19 +1510,6 @@ public:
TraceEvent("DBA_switchover_stopped");
try {
Void _ = wait( drAgent.submitBackup(backupAgent->taskBucket->src, tagName, backupRanges, false, addPrefix, removePrefix, true, true) );
} catch( Error &e ) {
if( e.code() != error_code_backup_duplicate )
throw;
}
TraceEvent("DBA_switchover_submitted");
int _ = wait( drAgent.waitSubmitted(backupAgent->taskBucket->src, tagName) );
TraceEvent("DBA_switchover_started");
state ReadYourWritesTransaction tr3(dest);
loop {
try {
@ -1544,6 +1531,19 @@ public:
TraceEvent("DBA_switchover_version_upgraded");
try {
Void _ = wait( drAgent.submitBackup(backupAgent->taskBucket->src, tagName, backupRanges, false, addPrefix, removePrefix, true, true) );
} catch( Error &e ) {
if( e.code() != error_code_backup_duplicate )
throw;
}
TraceEvent("DBA_switchover_submitted");
int _ = wait( drAgent.waitSubmitted(backupAgent->taskBucket->src, tagName) );
TraceEvent("DBA_switchover_started");
Void _ = wait( backupAgent->unlockBackup(dest, tagName) );
TraceEvent("DBA_switchover_unlocked");

View File

@ -845,8 +845,19 @@ void setupSimulatedSystem( vector<Future<Void>> *systemActors, std::string baseF
ASSERT( coordinatorAddresses.size() == coordinatorCount );
ClusterConnectionString conn(coordinatorAddresses, LiteralStringRef("TestCluster:0"));
g_simulator.extraDB = new ClusterConnectionString(coordinatorAddresses, ((extraDB==0 || (extraDB==1 && BUGGIFY)) ? LiteralStringRef("TestCluster:0") : LiteralStringRef("ExtraCluster:0")));
// If extraDB==0, leave g_simulator.extraDB as null because the test does not use DR.
if(extraDB==1) {
// The DR database can be either a new database or itself
g_simulator.extraDB = new ClusterConnectionString(coordinatorAddresses, BUGGIFY ? LiteralStringRef("TestCluster:0") : LiteralStringRef("ExtraCluster:0"));
} else if(extraDB==2) {
// The DR database is a new database
g_simulator.extraDB = new ClusterConnectionString(coordinatorAddresses, LiteralStringRef("ExtraCluster:0"));
} else if(extraDB==3) {
// The DR database is the same database
g_simulator.extraDB = new ClusterConnectionString(coordinatorAddresses, LiteralStringRef("TestCluster:0"));
}
*pConnString = conn;
TraceEvent("SimulatedConnectionString").detail("String", conn.toString()).detail("ConfigString", startingConfigString);
@ -887,7 +898,7 @@ void setupSimulatedSystem( vector<Future<Void>> *systemActors, std::string baseF
systemActors->push_back(reportErrors(simulatedMachine(conn, ips, sslEnabled,
localities, processClass, baseFolder, false, machine == useSeedForMachine, true ), "SimulatedMachine"));
if (extraDB) {
if (extraDB && g_simulator.extraDB->toString() != conn.toString()) {
std::vector<uint32_t> extraIps;
for (int i = 0; i < processesPerMachine; i++){
extraIps.push_back(4 << 24 | dc << 16 | g_random->randomInt(1, i + 2) << 8 | machine);

View File

@ -32,7 +32,7 @@
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>
<Product Name='$(var.Title)'
Id='{E0036E6A-8287-4BAD-A709-FBE032AF5415}'
Id='{2F0D2748-11CD-496F-B4B5-77FABB98E362}'
UpgradeCode='{A95EA002-686E-4164-8356-C715B7F8B1C8}'
Version='$(var.Version)'
Manufacturer='$(var.Manufacturer)'