330 lines
9.2 KiB
Markdown
330 lines
9.2 KiB
Markdown
EMQX configuration files are in [HOCON](https://github.com/emqx/hocon) format.
|
|
HOCON, or Human-Optimized Config Object Notation is a format for human-readable data,
|
|
and a superset of JSON.
|
|
|
|
## Layered
|
|
|
|
EMQX configuration consists of two layers.
|
|
From bottom up:
|
|
|
|
1. Cluster-synced configs: `$EMQX_NODE__DATA_DIR/configs/cluster.hocon`.
|
|
2. Local node configs: `emqx.conf` + `EMQX_` prefixed environment variables.
|
|
|
|
:::tip Tip
|
|
Prior to v5.0.23 and e5.0.3, the cluster-synced configs are stored in
|
|
`cluster-override.conf` which is applied on top of the local configs.
|
|
|
|
If upgraded from an earlier version, as long as `cluster-override.conf` exists,
|
|
`cluster.hocon` will not be created, and `cluster-override.conf` will stay on
|
|
top of the overriding layers.
|
|
:::
|
|
|
|
When environment variable `$EMQX_NODE__DATA_DIR` is not set, config `node.data_dir`
|
|
is used.
|
|
|
|
The `cluster.hocon` file is overwritten at runtime when changes
|
|
are made from Dashboard, management HTTP API, or CLI. When clustered,
|
|
after EMQX restarts, it copies the file from the node which has the greatest `uptime`.
|
|
|
|
:::tip Tip
|
|
To avoid confusion, don't add the same keys in both `cluster.hocon` and `emqx.conf`.
|
|
:::
|
|
|
|
For detailed override rules, see [Config Overlay Rules](#config-overlay-rules).
|
|
|
|
## Syntax
|
|
|
|
In config file the values can be notated as JSON like objects, such as
|
|
```
|
|
node {
|
|
name = "emqx@127.0.0.1"
|
|
cookie = "mysecret"
|
|
}
|
|
```
|
|
|
|
Another equivalent representation is flat, such as
|
|
|
|
```
|
|
node.name = "127.0.0.1"
|
|
node.cookie = "mysecret"
|
|
```
|
|
|
|
This flat format is almost backward compatible with EMQX's config file format
|
|
in 4.x series (the so called 'cuttlefish' format).
|
|
|
|
It is not fully compatible because the often HOCON requires strings to be quoted,
|
|
while cuttlefish treats all characters to the right of the `=` mark as the value.
|
|
|
|
e.g. cuttlefish: `node.name = emqx@127.0.0.1`, HOCON: `node.name = "emqx@127.0.0.1"`.
|
|
|
|
Strings without special characters in them can be unquoted in HOCON too,
|
|
e.g. `foo`, `foo_bar` and `foo_bar_1`.
|
|
|
|
For more HOCON syntax, please refer to the [specification](https://github.com/lightbend/config/blob/main/HOCON.md)
|
|
|
|
## Schema
|
|
|
|
To make the HOCON objects type-safe, EMQX introduced a schema for it.
|
|
The schema defines data types, and data fields' names and metadata for config value validation
|
|
and more.
|
|
|
|
::: tip Tip
|
|
The configuration document you are reading now is generated from schema metadata.
|
|
:::
|
|
|
|
### Complex Data Types
|
|
|
|
There are 4 complex data types in EMQX's HOCON config:
|
|
|
|
1. Struct: Named using an unquoted string, followed by a predefined list of fields.
|
|
Only lowercase letters and digits are allowed in struct and field names.
|
|
Alos, only underscore can be used as word separator.
|
|
1. Map: Map is like Struct, however the fields are not predefined.
|
|
1. Union: `MemberType1 | MemberType2 | ...`
|
|
1. Array: `[ElementType]`
|
|
|
|
::: tip Tip
|
|
If map field name is a positive integer number, it is interpreted as an alternative representation of an `Array`.
|
|
For example:
|
|
```
|
|
myarray.1 = 74
|
|
myarray.2 = 75
|
|
```
|
|
will be interpreated as `myarray = [74, 75]`, which is handy when trying to override array elements.
|
|
:::
|
|
|
|
### Primitive Data Types
|
|
|
|
Complex types define data 'boxes' which may contain other complex data
|
|
or primitive values.
|
|
There are quite some different primitive types, to name a few:
|
|
|
|
* `atom()`.
|
|
* `boolean()`.
|
|
* `string()`.
|
|
* `integer()`.
|
|
* `float()`.
|
|
* `number()`.
|
|
* `binary()`, another format of string().
|
|
* `emqx_schema:duration()`, time duration, another format of integer()
|
|
* ...
|
|
|
|
::: tip Tip
|
|
The primitive types are mostly self-describing, so there is usually not a lot to document.
|
|
For types that are not so clear by their names, the field description is to be used to find the details.
|
|
:::
|
|
|
|
### Config Paths
|
|
|
|
If we consider the whole EMQX config as a tree,
|
|
to reference a primitive value, we can use a dot-separated names form string for
|
|
the path from the tree-root (always a Struct) down to the primitive values at tree-leaves.
|
|
|
|
Each segment of the dotted string is a Struct field name or Map key.
|
|
For Array elements, 1-based index is used.
|
|
|
|
below are some examples
|
|
|
|
```
|
|
node.name = "emqx.127.0.0.1"
|
|
zone.zone1.max_packet_size = "10M"
|
|
authentication.1.enable = true
|
|
```
|
|
|
|
### Environment variables
|
|
|
|
Environment variables can be used to define or override config values.
|
|
|
|
Due to the fact that dots (`.`) are not allowed in environment variables, dots are
|
|
replaced with double-underscores (`__`).
|
|
|
|
And the `EMQX_` prefix is used as the namespace.
|
|
|
|
For example `node.name` can be represented as `EMQX_NODE__NAME`
|
|
|
|
Environment variable values are parsed as HOCON values, this allows users
|
|
to even set complex values from environment variables.
|
|
|
|
For example, this environment variable sets an array value.
|
|
|
|
```
|
|
export EMQX_LISTENERS__SSL__L1__AUTHENTICATION__SSL__CIPHERS='["TLS_AES_256_GCM_SHA384"]'
|
|
```
|
|
However, this also means a string value should be quoted if it happens to contain special
|
|
characters such as `=` and `:`.
|
|
|
|
For example, a string value `"localhost:1883"` would be
|
|
parsed into object (struct): `{"localhost": 1883}`.
|
|
|
|
To keep it as a string, one should quote the value like below:
|
|
|
|
```
|
|
EMQX_BRIDGES__MQTT__MYBRIDGE__CONNECTOR_SERVER='"localhost:1883"'
|
|
```
|
|
|
|
::: tip Tip
|
|
Unknown root paths are silently discarded by EMQX, for example `EMQX_UNKNOWN_ROOT__FOOBAR` is
|
|
silently discarded because `unknown_root` is not a predefined root path.
|
|
|
|
Unknown field names in environment variables are logged as a `warning` level log, for example:
|
|
|
|
```
|
|
[warning] unknown_env_vars: ["EMQX_AUTHENTICATION__ENABLED"]
|
|
```
|
|
|
|
because the field name is `enable`, not `enabled`.
|
|
:::
|
|
|
|
|
|
### Config Overlay Rules
|
|
|
|
HOCON objects are overlaid, in general:
|
|
|
|
- Within one file, objects defined 'later' recursively override objects defined 'earlier'
|
|
- When layered, 'later' (higher layer) objects override objects defined 'earlier' (lower layer)
|
|
|
|
Below are more detailed rules.
|
|
|
|
#### Struct Fields
|
|
|
|
Later config values overwrites earlier values.
|
|
For example, in below config, the last line `debug` overwrites `error` for
|
|
console log handler's `level` config, but leaving `enable` unchanged.
|
|
```
|
|
log {
|
|
console_handler{
|
|
enable=true,
|
|
level=error
|
|
}
|
|
}
|
|
|
|
## ... more configs ...
|
|
|
|
log.console_handler.level=debug
|
|
```
|
|
|
|
#### Map Values
|
|
|
|
Maps are like structs, only the files are user-defined rather than
|
|
the config schema. For instance, `zone1` in the example below.
|
|
|
|
```
|
|
zone {
|
|
zone1 {
|
|
mqtt.max_packet_size = 1M
|
|
}
|
|
}
|
|
|
|
## The maximum packet size can be defined as above,
|
|
## then overridden as below
|
|
|
|
zone.zone1.mqtt.max_packet_size = 10M
|
|
```
|
|
|
|
#### Array Elements
|
|
|
|
Arrays in EMQX config have two different representations
|
|
|
|
* list, such as: `[1, 2, 3]`
|
|
* indexed-map, such as: `{"1"=1, "2"=2, "3"=3}`
|
|
|
|
Dot-separated paths with number in it are parsed to indexed-maps
|
|
e.g. `authentication.1={...}` is parsed as `authentication={"1": {...}}`
|
|
|
|
This feature makes it easy to override array element values. For example:
|
|
|
|
```
|
|
authentication=[{enable=true, backend="built_in_database", mechanism="password_based"}]
|
|
# we can disable this authentication provider with:
|
|
authentication.1.enable=false
|
|
```
|
|
|
|
::: warning Warning
|
|
List arrays is a full-array override, but not a recursive merge, into indexed-map arrays.
|
|
e.g.
|
|
|
|
```
|
|
authentication=[{enable=true, backend="built_in_database", mechanism="password_based"}]
|
|
## below value will replace the whole array, but not to override just one field.
|
|
authentication=[{enable=true}]
|
|
```
|
|
:::
|
|
|
|
#### TLS/SSL ciphers
|
|
|
|
Starting from v5.0.6, EMQX no longer pre-populates the ciphers list with a default
|
|
set of cipher suite names.
|
|
Instead, the default ciphers are applied at runtime when starting the listener
|
|
for servers, or when establishing a TLS connection as a client.
|
|
|
|
Below are the default ciphers selected by EMQX.
|
|
|
|
For tlsv1.3:
|
|
```
|
|
ciphers =
|
|
[ "TLS_AES_256_GCM_SHA384", "TLS_AES_128_GCM_SHA256",
|
|
"TLS_CHACHA20_POLY1305_SHA256", "TLS_AES_128_CCM_SHA256",
|
|
"TLS_AES_128_CCM_8_SHA256"
|
|
]
|
|
```
|
|
|
|
For tlsv1.2 or earlier
|
|
|
|
```
|
|
ciphers =
|
|
[ "ECDHE-ECDSA-AES256-GCM-SHA384",
|
|
"ECDHE-RSA-AES256-GCM-SHA384",
|
|
"ECDHE-ECDSA-AES256-SHA384",
|
|
"ECDHE-RSA-AES256-SHA384",
|
|
"ECDH-ECDSA-AES256-GCM-SHA384",
|
|
"ECDH-RSA-AES256-GCM-SHA384",
|
|
"ECDH-ECDSA-AES256-SHA384",
|
|
"ECDH-RSA-AES256-SHA384",
|
|
"DHE-DSS-AES256-GCM-SHA384",
|
|
"DHE-DSS-AES256-SHA256",
|
|
"AES256-GCM-SHA384",
|
|
"AES256-SHA256",
|
|
"ECDHE-ECDSA-AES128-GCM-SHA256",
|
|
"ECDHE-RSA-AES128-GCM-SHA256",
|
|
"ECDHE-ECDSA-AES128-SHA256",
|
|
"ECDHE-RSA-AES128-SHA256",
|
|
"ECDH-ECDSA-AES128-GCM-SHA256",
|
|
"ECDH-RSA-AES128-GCM-SHA256",
|
|
"ECDH-ECDSA-AES128-SHA256",
|
|
"ECDH-RSA-AES128-SHA256",
|
|
"DHE-DSS-AES128-GCM-SHA256",
|
|
"DHE-DSS-AES128-SHA256",
|
|
"AES128-GCM-SHA256",
|
|
"AES128-SHA256",
|
|
"ECDHE-ECDSA-AES256-SHA",
|
|
"ECDHE-RSA-AES256-SHA",
|
|
"DHE-DSS-AES256-SHA",
|
|
"ECDH-ECDSA-AES256-SHA",
|
|
"ECDH-RSA-AES256-SHA",
|
|
"ECDHE-ECDSA-AES128-SHA",
|
|
"ECDHE-RSA-AES128-SHA",
|
|
"DHE-DSS-AES128-SHA",
|
|
"ECDH-ECDSA-AES128-SHA",
|
|
"ECDH-RSA-AES128-SHA"
|
|
]
|
|
```
|
|
|
|
For PSK enabled listeners
|
|
|
|
```
|
|
ciphers =
|
|
[ "RSA-PSK-AES256-GCM-SHA384",
|
|
"RSA-PSK-AES256-CBC-SHA384",
|
|
"RSA-PSK-AES128-GCM-SHA256",
|
|
"RSA-PSK-AES128-CBC-SHA256",
|
|
"RSA-PSK-AES256-CBC-SHA",
|
|
"RSA-PSK-AES128-CBC-SHA",
|
|
"PSK-AES256-GCM-SHA384",
|
|
"PSK-AES128-GCM-SHA256",
|
|
"PSK-AES256-CBC-SHA384",
|
|
"PSK-AES256-CBC-SHA",
|
|
"PSK-AES128-CBC-SHA256",
|
|
"PSK-AES128-CBC-SHA"
|
|
]
|
|
```
|