Skip to content
This repository has been archived by the owner on Jul 18, 2023. It is now read-only.

Node: Added TLS trust modes and workdir option; misc refactoring #57

Merged
merged 13 commits into from
Nov 21, 2017

Conversation

patrickmn
Copy link
Contributor

@patrickmn patrickmn commented Nov 17, 2017

The main feature of this is a hybrid CA/tofu (openssh) TLS model that works out of the box with existing setups (even without Letsencrypt or other CAs in the mix), and uses only reasonably secure defaults for TLS (1.2+, mutually authenticated, only AEAD ciphersuites).

From CHANGELOG.md:

  • Node API: The from parameter to /send is now optional. If unset,
    the first public key listed in publickeys will be used.

  • Argon2id is now the default for password-based key locking.

  • workdir command line and configuration option to set the directory
    in which files specified in other command-line arguments, as well as
    auto-generated files, will be placed.

  • TLS certificate auto-generation and mutual authentication using a
    whitelist, certificate authority, or trust-on-first-use model.

From sample.conf:

## TLS status. Options:
##
##   - strict: All connections to and from this node must use TLS with mutual
##     authentication. See the documentation for tlsservertrust and
##     tlsclienttrust below.
##   - off: Mutually authenticated TLS is not used for in- and outbound
##     connections, although unauthenticated connections to HTTPS hosts are
##     still possible. This should only be used if another transport security
##     mechanism like WireGuard is in place.
##
## Default: strict
tls = "strict"

## Path to a file containing the server's TLS certificate in Apache format.
## This is used to identify this node to other nodes in the network when they
## connect to the public API.
##
## This file will be auto-generated if it doesn't exist.
##
## Default: "tls-server-cert.pem"
tlsservercert = "tls-server-cert.pem"

## List of files that constitute the CA trust chain for the server certificate.
## This can be empty for auto-generated/non-PKI-based certificates.
##
## Default: []
tlsserverchain = []

## The private key file for the server TLS certificate.
##
## This file will be auto-generated if it doesn't exist.
##
## Default: "tls-server-key.pem"
tlsserverkey = "tls-server-key.pem"

## TLS trust mode for the server. This decides who's allowed to connect to it.
## Options:
##
##   - whitelist: Only nodes that have previously connected to this node and
##     been added to the tlsknownclients file below will be allowed to connect.
##     This mode will not add any new clients to the tlsknownclients file.
##
##   - tofu: (Trust-on-first-use) Only the first node that connects identifying
##     as a certain host will be allowed to connect as the same host in the
##     future. Note that nodes identifying as other hosts will still be able
##     to connect -- switch to whitelist after populating the tlsknownclients
##     list to restrict access.
##
##   - ca: Only nodes with a valid certificate and chain of trust to one of
##     the system root certificates will be allowed to connect. The folder
##     containing trusted root certificates can be overriden with the
##     SYSTEM_CERTIFICATE_PATH environment variable.
##
##   - ca-or-tofu: A combination of ca and tofu: If a certificate is valid,
##     it is always allowed and added to the tlsknownclients list. If it is
##     self-signed, it will be allowed only if it's the first certificate this
##     node has seen for that host.
##
##   - insecure-no-validation: Any client can connect, however they will still
##     be added to the tlsknownclients file.
##
## Default: "tofu"
tlsservertrust = "tofu"

## TLS known clients file for the server. This contains the fingerprints of
## public keys of other nodes that are allowed to connect to this one.
##
## Default: "tls-known-clients"
tlsknownclients = "tls-known-clients"

## Path to a file containing the client's TLS certificate in Apache format.
## This is used to identify this node to other nodes in the network when it is
## connecting to their public APIs.
##
## This file will be auto-generated if it doesn't exist.
##
## Default: "tls-client-cert.pem"
tlsclientcert = "tls-client-cert.pem"

## List of files that constitute the CA trust chain for the client certificate.
## This can be empty for auto-generated/non-PKI-based certificates.
##
## Default: []
tlsclientchain = []

## The private key file for the client TLS certificate.
##
## This file will be auto-generated if it doesn't exist.
##
## Default: "tls-client-key.pem"
tlsclientkey = "tls-client-key.pem"

## TLS trust mode for the client. This decides which servers it will connect to.
## Options:
##
##   - whitelist: This node will only connect to servers it has previously seen
##     and added to the tlsknownclients file below. This mode will not add
##     any new servers to the tlsknownservers file.
##
##   - tofu: (Trust-on-first-use) This node will only connect to the same
##     server for any given host. (Similar to how OpenSSH works.)
##
##   - ca: The node will only connect to servers with a valid certificate and
##     chain of trust to one of the system root certificates. The folder
##     containing trusted root certificates can be overriden with the
##     SYSTEM_CERTIFICATE_PATH environment variable.
##
##   - ca-or-tofu: A combination of ca and tofu: If a certificate is valid,
##     it is always allowed and added to the tlsknownservers list. If it is
##     self-signed, it will be allowed only if it's the first certificate this
##     node has seen for that host.
##
##   - insecure-no-validation: This node will connect to any server, regardless
##     of certificate, however it will still be added to the tlsknownservers
##     file.
##
## Default: "ca-or-tofu"
tlsclienttrust = "ca-or-tofu"

## TLS known servers file for the client. This contains the fingerprints of
## public keys of other nodes that this node has encountered.
##
## Default: "tls-known-servers"
tlsknownservers = "tls-known-servers"

Resolves #24

@joelburget
Copy link

Nice -- GHC gives no warnings except to complain about deprecated EitherT.

@joelburget
Copy link

Odd -- I get this error when testing (cabal new-test):

test/Constellation/Util/Logging/Test.hs:12:9: error:
    • Variable not in scope: testGroup :: [Char] -> [a0] -> TestTree
    • Perhaps you want to add ‘testGroup’ to the import list
      in the import of ‘Test.Tasty’
      (test/Constellation/Util/Logging/Test.hs:7:1-28).
   |
12 | tests = testGroup "Util.Logging" []

@patrickmn
Copy link
Contributor Author

Ah. I'm using stack only. I guess new cabal compiles that module even if it's not actually imported?

@patrickmn
Copy link
Contributor Author

Try now.

Migrating EitherT to ExceptT should be easy... just need a replacement for hoistEither in Util.Either.

@bts
Copy link
Contributor

bts commented Nov 17, 2017

@patrickmn I'll replace EitherT with ExceptT, and I also have a refactor for sendPayload that uses it.

@bts
Copy link
Contributor

bts commented Nov 17, 2017

I put the two commits on the send-payload-refactor branch. Feel free to pull them into this PR

@patrickmn
Copy link
Contributor Author

@bts This (with the default settings) could be another reason to use different loopback addresses when spinning up local clusters since tofu only allows one cert per hostname.

@patrickmn
Copy link
Contributor Author

Think this is mergeable. Any objections?

@joelburget
Copy link

@patrickmn not from me

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants