Skip to content

Commit

Permalink
Merge branch 'master' into typos_in_docs
Browse files Browse the repository at this point in the history
  • Loading branch information
Mallets authored Sep 10, 2024
2 parents a654f55 + 05656a9 commit ac32aac
Show file tree
Hide file tree
Showing 19 changed files with 2,481 additions and 82 deletions.
8 changes: 5 additions & 3 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ menu:
- identifier: "APIs"
name: "API"
weight: 4000
- identifier: "migration"
name: "Migration guides"
- identifier: "migration_0.5_to_0.6"
name: "Migration guides v0.5.x → v0.6.x"
weight: 5000

- identifier: "migration_1.0"
name: "Migration guides v0.11 → v1.0 "
weight: 6000
6 changes: 3 additions & 3 deletions content/docs/getting-started/deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Zenoh applications in `peer` mode join multicast group `224.0.0.224` on UDP port
enabled: true,
address: "224.0.0.224:7446",
interface: "auto",
autoconnect: { peer: "router|peer" },
autoconnect: { router: [], peer: ["router", "peer"] },
listen: true,
},
},
Expand All @@ -49,7 +49,7 @@ Zenoh applications in `peer` mode join multicast group `224.0.0.224` on UDP port

**Gossip scouting**

Zenoh applications in `peer` mode forward all local applications and routers they have already discovered to newly scouted applications. This is useful when multicast communications are not available. But applications need to connect to a first entry point to discover the rest of the system. This entry point is typically one or several Zenoh routers but can also be one or several other peers. Those entry points are configured through the `connect` section of the configuration.
Zenoh applications in `peer` mode forward all local applications and routers that they already discovered to newly scouted applications. This is useful when multicast communications are not available. But applications need to connect first to an entry point to discover the rest of the system. This entry point is typically one or several Zenoh routers but can also be one or several other peers. Those entry points are configured through the `connect` section of the configuration.

**Configuration**
```
Expand All @@ -62,7 +62,7 @@ Zenoh applications in `peer` mode forward all local applications and routers the
gossip: {
enabled: true,
multihop: false,
autoconnect: { peer: "router|peer" },
autoconnect: { router: [], peer: ["router", "peer"] },
},
},
}
Expand Down
13 changes: 7 additions & 6 deletions content/docs/getting-started/first-app.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ Now we need a subscriber, `z_subscriber.py` that can receive the measurements:
import zenoh, time

def listener(sample):
print(f"Received {sample.kind} ('{sample.key_expr}': '{sample.payload.decode('utf-8')}')")

print(f"Received {sample.kind} ('{sample.key_expr}': '{sample.payload.deserialize(str)}')")
if __name__ == "__main__":
session = zenoh.open()
sub = session.declare_subscriber('myhome/kitchen/temp', listener)
Expand Down Expand Up @@ -108,14 +108,15 @@ import zenoh

if __name__ == "__main__":
session = zenoh.open()
replies = session.get('myhome/kitchen/temp', zenoh.ListCollector())
for reply in replies():
replies = session.get('myhome/kitchen/temp')
for reply in replies:
try:
print("Received ('{}': '{}')"
.format(reply.ok.key_expr, reply.ok.payload.decode("utf-8")))
.format(reply.ok.key_expr, reply.ok.payload.deserialize(str)))
except:
print("Received (ERROR: '{}')"
.format(reply.err.payload.decode("utf-8")))
.format(reply.err.payload.decode(str)))

session.close()
```
## Other examples
Expand Down
110 changes: 47 additions & 63 deletions content/docs/getting-started/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,68 +91,52 @@ $ zenohd --help
You should see the following output on your console:

```text
The Zenoh router v0.6.0-beta.X
USAGE:
zenohd [OPTIONS]
OPTIONS:
-c, --config [<FILE>...]
The configuration file. Currently, this file must be a valid JSON5 or YAML file.
--cfg <KEY:VALUE>
Allows arbitrary configuration changes as column-separated KEY:VALUE pairs, where:
- KEY must be a valid config path.
- VALUE must be a valid JSON5 string that can be deserialized to the expected type for
the KEY field.
Examples:
--cfg='startup/subscribe:["demo/**"]'
--cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'
-e, --connect [<ENDPOINT>...]
A peer locator this router will try to connect to.
Repeat this option to connect to several peers.
-h, --help
Print help information
-i, --id [<HEX_STRING>]
The identifier (as an hexadecimal string, with odd number of chars - e.g.: 0A0B23...)
that zenohd must use. If not set, a random UUIDv4 will be used.
WARNING: this identifier must be unique in the system and must be 16 bytes maximum (32
chars)!
-l, --listen [<ENDPOINT>...]
A locator on which this router will listen for incoming sessions.
Repeat this option to open several listeners.
--no-multicast-scouting
By default zenohd replies to multicast scouting messages for being discovered by peers
and clients. This option disables this feature.
--no-timestamp
By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't
already one. This option disables this feature.
-P, --plugin [<PLUGIN>...]
A plugin that MUST be loaded. You can give just the name of the plugin, zenohd will
search for a library named 'libzplugin_<name>.so' (exact name depending the OS). Or you
can give such a string: "<plugin_name>:<library_path>".
Repeat this option to load several plugins. If loading failed, zenohd will exit.
--plugin-search-dir [<DIRECTORY>...]
A directory where to search for plugins libraries to load.
Repeat this option to specify several search directories.
--rest-http-port [<SOCKET>]
Configures HTTP interface for the REST API (enabled by default). Accepted values:
- a port number
- a string with format `<local_ip>:<port_number>` (to bind the HTTP server to a
specific interface)
- `none` to disable the REST API
[default: 8000]
-V, --version
Print version information
2024-08-12T13:27:29.724708Z INFO main ThreadId(01) zenohd: zenohd v0.11.0-dev-965-g764be602d built with rustc 1.75.0 (82e1608df 2023-12-21)
The zenoh router
Usage: zenohd [OPTIONS]
Options:
-c, --config <PATH>
The configuration file. Currently, this file must be a valid JSON5 or YAML file
-l, --listen <ENDPOINT>
Locators on which this router will listen for incoming sessions. Repeat this option to open several listeners
-e, --connect <ENDPOINT>
A peer locator this router will try to connect to. Repeat this option to connect to several peers
-i, --id <ID>
The identifier (as an hexadecimal string, with odd number of chars - e.g.: A0B23...) that zenohd must use. If not set, a random unsigned 128bit integer will be used. WARNING: this identifier must be unique in the system and must be 16 bytes maximum (32 chars)!
-P, --plugin <PLUGIN>
A plugin that MUST be loaded. You can give just the name of the plugin, zenohd will search for a library named 'libzenoh_plugin_\<name\>.so' (exact name depending the OS). Or you can give such a string: "\<plugin_name\>:\<library_path\>" Repeat this option to load several plugins. If loading failed, zenohd will exit
--plugin-search-dir <PATH>
Directory where to search for plugins libraries to load. Repeat this option to specify several search directories
--no-timestamp
By default zenohd adds a HLC-generated Timestamp to each routed Data if there isn't already one. This option disables this feature
--no-multicast-scouting
By default zenohd replies to multicast scouting messages for being discovered by peers and clients. This option disables this feature
--rest-http-port <SOCKET>
Configures HTTP interface for the REST API (enabled by default on port 8000). Accepted values: - a port number - a string with format `<local_ip>:<port_number>` (to bind the HTTP server to a specific interface) - `none` to disable the REST API
--cfg <CFG>
Allows arbitrary configuration changes as column-separated KEY:VALUE pairs, where: - KEY must be a valid config path. - VALUE must be a valid JSON5 string that can be deserialized to the expected type for the KEY field.
Examples: - `--cfg='startup/subscribe:["demo/**"]'` - `--cfg='plugins/storage_manager/storages/demo:{key_expr:"demo/example/**",volume:"memory"}'`
--adminspace-permissions <[r|w|rw|none]>
Configure the read and/or write permissions on the admin space. Default is read only
-h, --help
Print help (see a summary with '-h')
-V, --version
Print version
```

3 changes: 2 additions & 1 deletion content/docs/getting-started/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ To check this look for such logs:
[2022-03-28T15:23:36Z INFO zenohd] Successfully started plugin storage_manager from "/Users/test/.zenoh/lib/libzplugin_storage_manager.dylib"
[2022-03-28T15:23:36Z INFO zenohd] Successfully started plugin webserver from "/Users/test/.zenoh/lib/libzplugin_webserver.dylib"
```
Here you can see all the plugins libraries that have been loaded by `zenohd` at startup. You must check if each of those are using the same Zenoh version as dependency than `zenohd`.
Here you can see all the plugins libraries that have been loaded by `zenohd` at startup.
You must check if each of the plugins are using the same Zenoh version as dependency than `zenohd` and Rust compiler version as the `zenohd` instance.
To assess which one is causing troubles, you can also move or rename all the libraries but one and test if `zenohd` is correctly loading this one. Then repeat the process for each library.


Expand Down
201 changes: 201 additions & 0 deletions content/docs/manual/access-control.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
---
title: "Access Control"
weight : 3900
menu:
docs:
parent: manual
---

*NOTE: This documentation covers the Zenoh 1.0 ACL config. For Zenoh 0.11 ACL config,
please refer to the [Zenoh 0.11 Access Control Rules RFC](https://github.com/eclipse-zenoh/roadmap/blob/ca841fe219890bf73289089b520271d70ded89b6/rfcs/ALL/Access%20Control%20Rules.md)*

*Access control* enables Zenoh instances to filter (allow or deny) messages,
depending on certain characteristics of individual messages and their respective source or destination.
*Authentication* on the other hand allows Zenoh instances to identify certain characteristics in other instances they connect to,
which are used to match the remote instances with configured subjects in the ACL policies and apply the rules accordingly on the exhanged messages.

The configuration of access control policies is done via a [configuration file](../configuration).

---------
## ACL configuration

ACL configuration mainly consists of three components: `rules`, `subjects` and `policies`, to which is added the `default_permission` (`allow` or `deny`) to be applied on messages that do not match the configured policies.

The `enabled` boolean field allows to enable and disable ACL. Note that ACL config cannot be updated at runtime, and requires a restart of the instance to reflect the changes.

Below is the example config we will be analyzing in this documentation.

```json5
{
access_control: {
"enabled": true,
"default_permission": "allow",

"rules": [
{
"id": "deny pub/sub",
"permission": "deny",
"flows": ["ingress", "egress"],
"messages": [
"declare_subscriber",
"put",
"delete",
],
"key_exprs": [
"demo/example/**",
],
}
],

"subjects": [
{
"id": "example subject",
"interfaces": [
"lo0",
"en0",
],
"cert_common_names": [
"example.zenoh.io"
],
"usernames": [
"zenoh-example1",
"zenoh-example2",
],
}
],

"policies": [
{
"rules": [
"deny pub/sub"
],
"subjects": [
"example subject"
],
},
]
}
}
```

### rules

Each rule within the `rules` list is identified by a unique `id` string. Rules apply on matched messages based on their individual characteristics:

- `messages`: types of messages to apply the rule on. Supported message types are the following:
- Declare Subscriber (`declare_subscriber`)
- Publication (`put`)
- Delete (`delete`)
- Declare Queryable (`declare_queryable`)
- Query (`query`)
- Reply (`reply`)
- `flows`: applies rule on incoming messages (`ingress`), outgoing messages (`egress`), or both directions. If this field is not provided in the config, the rule will apply to both directions by default.
- `key_exprs`: the rule applies on messages for which the key matches one of the given key expressions. For more details on key expression matching, see [Key Expressions](https://zenoh.io/docs/manual/abstractions/#key-expression).

Matched messages are filtered based on the rule's `permission`: `allow` or `deny`.

For instance, the following rule denies all incoming and outgoing subscriptions, publications and deletions on key expressions matching `demo/example/**`:

```json5
{
"id": "deny pub/sub",
"permission": "deny",
"flows": ["ingress", "egress"],
"messages": [
"declare_subscriber",
"put",
"delete",
],
"key_exprs": [
"demo/example/**",
],
}
```

### subjects

Each subject configuration is identified by a unique `id` string. Subject configuration combines `interfaces`, `cert_common_names` and `usernames` to match with configurations of connecting Zenoh instances.

- `interfaces`: list of local network interfaces through which the configured instance communicates with the remote instance to be matched.
- `cert_common_names`: list of certificate common names which are matched with the respective certificate content of the remote instance using TLS or QUIC transport. For details on certificate configuration refer to [TLS authentication](../tls) and [QUIC transport](../quic).
- `usernames`: list of usernames to be matched with the authentication config of remote instances. Refer to [User-Password authentication](../user-password) for how to setup this authentication mechanism.

To produce all possible combinations that characterize a subject configuration, the Cartesian product of the `interfaces`, `cert_common_names` and `usernames` lists is calculated. This allows for items within the same list to be considered a logical `OR`, and items across different lists to be considered a logical `AND`.
To demonstrate these logical combinations, below is an example of a subject configuration and its internal representation.

```json5
{
"id": "example subject",
"interfaces": [
"lo0",
"en0",
],
"cert_common_names": [
"example.zenoh.io"
],
"usernames": [
"zenoh-example1",
"zenoh-example2",
],
// This instance translates internally to this filter:
// (interface="lo0" AND cert_common_name="example.zenoh.io" AND username="zenoh-example1") OR
// (interface="lo0" AND cert_common_name="example.zenoh.io" AND username="zenoh-example2") OR
// (interface="en0" AND cert_common_name="example.zenoh.io" AND username="zenoh-example1") OR
// (interface="en0" AND cert_common_name="example.zenoh.io" AND username="zenoh-example2")
}
```

Note that any of the three lists presented above can be ommited, and will be interpreted as a wildcard (i.e matches with all possible values of that authentication method). This implies that the empty subject below is a wildcard that will match any Zenoh instance.

```json5
{
"id": "subject that matches all zenoh instances",
}
```

### policies

The `policies` list associates configured rules to configured subjects based on their unique `id`s. For example, the policy below applies the `deny pub/sub` rule on the `example subject` subject declared above. Note that in a policy object, `rules` and `subjects` are lists, which conveniently allows to apply multiple rules to multiple subjects within the same policy object.

```json5
{
"rules": [
"deny pub/sub"
],
"subjects": [
"example subject"
],
}
```

---------

## Guidelines for configuring ACL

Designing ACL policies can be quite the challenge, especially when considering the potential impact that a subomptimal configuration can have on performance.
For you convenience, we've compiled below some guidelines and common mistakes to look out for when configuring ACL.

- The first step to consider is which of the two ACL models to use: set `"default_permission": "deny"` and define `allow` rules, or the opposite.
This choice can have an impact on performance if the number of rules to verify per message is too high.
Therefore, it is considered best practice in most cases to pick the model that yields the least amount of rules, with regards to your application and desired filters.
- When defining subjects and applying rules on them, avoid having two different subjects that can match the same instance and have the same rule apply on them, as this could lead to a double verification of said rule in this case, which yields a loss in performance.
- Defining rules that apply on both `ingress` and `egress` flows can cause a double verification of messages, which leads to performance loss.
Avoid defining rules that respectively apply on both flows, unless the affected messages are *generated* or *consumed* by the instance, and do not pass through it. Consider the following examples:
- A router receives `put` messages and routes them, which applies both of its matching `ingress` and `egress` rules on them.
- A client running a subscriber receives and *consumes* `put` messages, only applying its matching `ingress` rules on them.
- A client publisher *generates* `put` messages and so only applies its matching `egress` rules on them.
- A client running both a publisher and a subscriber *generates* and *consumes* `put` messages,
but only applies either of its matching `ingress` or `egress` rules on each individual message.
- Depending on your rules, conflicting decisions on the same message can occur (`allow` and `deny` from different rules).
In this case, it is important to know decision priority to predict the outcome: **explicit deny rule** > **explicit allow rule** > **default_permission rule**.
For more details on decision priority, please refer to the [*Priority* section of the Access Control Rules RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Access%20Control%20Rules.md#priority).
- Key expression matching when applying rules on messages can have a substantial impact on performance, depending on how the rules are constructed.
When possible, avoid using wildcards and DSL (eg: `"**"`, `"example/*"`, `"example/t$*"`) and prefer keys (eg: `example/test`) which are much faster to match.
- Look out for supersets and partial overlap between rule key expressions and message key, which are not considered valid matches and therefore will not apply said ACL rule on said message.
For more details on this regard, please refer to the [*Key-Expression Matching* section of the Access Control Rules RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Access%20Control%20Rules.md#key-expression-matching).
- When filtering queryable messages, keep in mind that a `reply` does not necessarily have the same key expression as its associated `query`.
- Bare in mind that the effectiveness of ACL policies is highly dependent of your Zenoh network topology and how much control you have over it. The topology can evolve in unpredictable ways in certain scenarios when combined with configuration options like `scouting` and `gossip`, which is complicated further when factoring the mobility of Zenoh clients in certain use-cases.

---------

For a more technical analysis of the ACL feature, please refer to the [Access Control Rules RFC](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Access%20Control%20Rules.md).
Loading

0 comments on commit ac32aac

Please sign in to comment.