Configuration Files

Description of the structure and contents of the "foxmq.d/" directory

FoxMQ's commands all use a single configuration directory, which by default is foxmq.d/ in the current working directory of your shell. Each command has a flag (--output-dir for address-book and user, a trailing positional argument for run) which allows you to change this if you choose.

Using a directory with separate files for configuring different components allows FoxMQ to add more functionality in the future without affecting existing configurations.

FoxMQ uses the TOML format for its configuration files.

address-book.toml

This file contains knowledge of all nodes in the FoxMQ cluster which is necessary to drive the consensus algorithm.

It exists as a separate file to allow copying verbatim to other nodes in a multi-party cluster without having to search for and remove private information (such as login credentials) from it.

Normally, it is expected to be generated by the foxmq address-book command as shown in the Quick Start guide, but it can be created manually. You can use OpenSSL or another tool to generate the required cryptographic keys yourself if you prefer (though demonstrating how to do so is out of scope for this documentation).

The contents of this file must be identical for all nodes in the cluster, or they will be unable to synchronize with each other. If this happens, FoxMQ will log warnings to the console from the tashi_consensus_engine component. Set RUST_LOG=warn as an environment variable to see this output.

Example: 2 Nodes

The following is an annotated example of an address-book.toml file with 2 nodes generated by foxmq address-book.

Note: it will not work to directly copy this file as it does not include the corresponding private key files. It is not secure to use cryptographic private keys you found on the Internet. See the Quick Start guide for how to use the foxmq address-book command to generate this file as well as new, securely random private keys for each node.

# An address book file is simply a list of entries in the `addresses` array.
# The `foxmq address-book` subcommand adds comments above each entry
# telling you which private key file corresponds to which node.

# The entry for the first node.
# key_0.pem
[[addresses]]
# The key string is the PEM encoded public key for the node.
# Since PEM is a multi-line format, TOML's support for multi-line strings
# comes in really handy here.
#
# If manually generating an address book, 
# note that FoxMQ currently only supports ECDSA keypairs using the P-256 curve.
key = """
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE48VTK97faW815TQKbU/OY/ENsLmw
9M4D46bz8T/MfSlfErjKW6aMmB+armT2Fg5/5+T53ezUUlwP1ELP/GpUog==
-----END PUBLIC KEY-----
"""
# The UDP socket address (IP:port) that the node will be listening on
# for cluster connections. 
#
# Corresponds to `--cluster-addr`, or a socket address that connects to it
# when using `0.0.0.0` for the IP address.
addr = "172.16.238.2:19793"

# The entry for the second node.
# key_1.pem
[[addresses]]
# Note that each node's key and cluster address must be unique within the address book.
key = """
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEdJH/jhJEJ8zJfnYbu1gXZnSJ7a+g
K6BC6pGyzxP6tCQ75PX13XDaV9jdhAWvHt+gKOg+0u2nCikv8dfTOe6aTw==
-----END PUBLIC KEY-----
"""
addr = "172.16.238.3:19793"

users.toml

This file specifies sets of login credentials for MQTT clients to use to connect.

This file may be copied to other nodes in the cluster if you intend to allow the same users to log in to any node, but should not be shared with other nodes in a multi-party cluster for security.

As a security precaution, FoxMQ requires that you either specify at least one set of login credentials, or explicitly allow anonymous logins. FoxMQ will exit with an error if this condition is not satisfied.

Passwords in this file are hashed with a random salt (using Argon2 as of writing). When an MQTT client sends user credentials, FoxMQ will hash the supplied password and check if it matches the stored hash. Because of this hashing, there is no real security concern with storing passwords on disk. However, this also means it is not possible to recover a password that has been forgotten; it must be changed to a new password instead (by deleting the entry and re-generating it).

This file is expected to be generated by the foxmq user command as shown in the Quick Start guide. It is not expected for you to create entries manuallly, though deleting entries must be done manually.

Example: Allow Anonymous Login

You may copy this example users.toml if you wish to allow MQTT clients to log in anonymously. This can also be found in both Quick Start guides.

This corresponds to the --allow-anonymous-login flag of foxmq run.

[auth]
allow-anonymous-login = true

This may be added to a file with existing login credentials to allow an MQTT client to either log in anonymously or with explicit credentials (though it's usually going to be one or the other).

Example: 2 Users

The following is an annotated example of a users.toml file with 2 users generated by foxmq user add.

Note: it will not work to directly copy this file as it does not include the corresponding plaintext passwords to send from the MQTT client; these would be the first passwords that someone looking to attack a FoxMQ deployment would try. See the Quick Start guide for how to use the foxmq user add command to generate this file with your chosen password (or to let FoxMQ generate one for you).

# This file is just a list of entries in the `users` table.
#
# The rules of the TOML format forbid two table entries with the same name.
# FoxMQ will exit with an error if an entry is duplicated.

# Entry for the user `foxmq`.
[users.foxmq]
# The password is stored as a hash so it cannot be recovered from disk.
# This is the PHC string format, which includes the hash algorithm used and its parameters:
# https://github.com/P-H-C/phc-string-format/blob/5f1e4ec633845d43776849f503f8ce8314b5290c/phc-sf-spec.md
password-hash = "$argon2id$v=19$m=19456,t=2,p=1$MSUEbSAUyQXrOMYSooedPA$m1eGcWE5+lykZwLP6XIsqwcIhELMUn2pdH4ZZHTLAmE"

# Entry for the user `foxmq.local`.
# The username may be any UTF-8 string allowed by the MQTT specification:
# https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_UTF-8_Encoded_String
#
# However, the TOML format requires it to be specified in quotes if it contains 
# anything but the following:
# * letters (A-Z, a-z)
# * digits (0-9)
# * underscores (_)
# * dashes (-)
#
# A dot in this case would define a subkey of `users.foxmq` which is not what we want.
[users."foxmq.local"]
# Note that the password used to generate this entry is actually the same as above,
# but the hash is completely different thanks to the random salt.
#
# This makes a direct attack on the password hash infeasible,
# e.g. a rainbow table or a hash stolen from a database leak.
#
# The only option is brute-force, but Argon2 is designed to be 
# incredibly costly to conduct a brute-force attack on.
password-hash = "$argon2id$v=19$m=19456,t=2,p=1$tI+FqCiXlzdZ8BKQmBXFDQ$xz21APffxSLde8Iv7SzzrWrfYfuUYUBSrcUNiwiQktc"

Last updated