Eclipse Zenoh 1.10.2
Overview
Eclipse Zenoh is a pub/sub, query and storage protocol for robotics, IoT, edge and cloud. Applications publish values under key expressions (paths such as fleet/robot-7/battery), subscribe with wildcards (fleet/**), answer queries with queryables and keep values in storages.
This guide covers launching and using the Eclipse Zenoh 1.10.2 on Ubuntu 24.04 AMI from SecureAnyCloud on Amazon EC2. The image runs zenohd, the Zenoh router: the infrastructure node that your clients and peers connect to. It is one version of the SecureAnyCloud streaming and messaging listing on AWS Marketplace, and you choose it as the software version when you subscribe and launch.
What you get:
- TLS only. The router's only network listener is
tls/0.0.0.0:7447, and Zenoh's protocol whitelist accepts TLS and nothing else: plaintcp/, UDP, QUIC, WebSocket and unix-socket sessions are refused. (The upstream package listens on plaintcp/[::]:7447, where every sample, query and reply crosses the network unencrypted.) QUIC stays off. - A certificate generated on your instance. At first boot the router gets a TLS key and an end-entity certificate for this instance's own names and addresses. The certificate can vouch only for this router and can never sign other certificates. You pin it in your clients (Step 5). When the instance's addresses change (an EC2 stop and start gives a new public IP), the certificate is re-issued on the same key, so clients that pinned it keep connecting.
- Mandatory logins and no default account. Upstream's package accepts any client with no authentication. Every session here must log in with a user name and password (Zenoh's HMAC challenge, inside TLS). First boot creates two logins unique to your instance: SecureAnyCloud, the administrator, and sac-app, a least-privilege application identity. No password is ever placed on a command line.
- Deny-by-default access control. SecureAnyCloud may use every key expression and read the router's admin space. sac-app may use sac/app/** and nothing else. The sudo zenoh-user add command creates more scoped users.
- No discovery traffic. Multicast and gossip scouting are off and the router connects to nothing on its own, so it never announces itself on your network or joins one by accident.
- The REST API on the loopback address. The REST plugin runs inside the router and is not subject to the access control, so it listens on
127.0.0.1:8000only. You reach it through an SSH tunnel (Step 10). - Fail-closed start. A configuration gate checks the router's effective configuration before every start and refuses to start it after an unsafe change (a plain-tcp listener, scouting on, access control off, the REST API off loopback, a short or published password, and more). A listener check stops the router if it ever listens beyond its configuration. The router runs as an unprivileged user in a systemd sandbox and cannot reach the instance metadata service.
- A pinned supply chain. zenohd, the REST and storage-manager plugins and the filesystem storage backend come from the official 1.10.2 release archives, each checked against its published SHA-256. The official
eclipse-zenoh1.10.2 Python client is installed from its hash-pinned wheel, with every file checked against the wheel's own record. Ubuntu 24.04 LTS is fully patched at build time with unattended security upgrades on, and SSH accepts keys only.
What is on the image: zenohd 1.10.2 with zenoh-plugin-rest, zenoh-plugin-storage-manager and zenoh-backend-filesystem 1.10.2 (from the Eclipse Zenoh release packages), the eclipse-zenoh 1.10.2 Python client in /usr/local/lib/sac/zenoh-venv, the SecureAnyCloud helpers zenoh-probe, zenoh-user, zenoh-selfcheck, zenoh-set-hostname and zenoh-install-cert, cloud-init and the AWS Systems Manager agent. No compiler toolchain is installed.
Default user: ubuntu | Architecture: x86_64 | Recommended instance type: m5.large
Prerequisites
- An AWS account subscribed to the listing, an EC2 key pair and a VPC subnet with a route to the internet (or a private route that you use for management).
- A security group that allows TCP 22 (SSH) from your admin network and TCP 7447 (Zenoh over TLS) from the networks that your clients, sensors or other routers connect from. Nothing else needs to be open. The REST API (port 8000) listens on the loopback address only and refuses connections from other machines, even if a security group allows them.
Launch the instance
In the AWS Marketplace listing, choose Continue to Subscribe, then Continue to Configuration. Select Eclipse Zenoh 1.10.2 on Ubuntu 24.04 as the software version, select your Region, and choose Launch through EC2. Pick m5.large (or a larger size for many sessions or high message rates), your key pair and a security group as described above.
To launch with the AWS CLI instead, replace the values in angle brackets:
aws ec2 run-instances --region <region> --image-id <ami-id-from-the-listing> \
--instance-type m5.large --key-name <your-key-pair> \
--security-group-ids <your-security-group> --subnet-id <your-subnet> \
--metadata-options HttpTokens=required,HttpEndpoint=enabled \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=zenoh-router}]'The image requires IMDSv2 (session tokens). First boot takes under a minute after the instance is running. The boot service creates the logins and the certificate, and then the router starts.
Connect to your instance
Connect to Eclipse Zenoh 1.10.2 on Ubuntu 24.04 as the SSH user ubuntu, with the key pair you chose at launch:
ssh -i <your-key.pem> ubuntu@<public-ip>The login banner summarises where everything is.
Check the services and the listening set
systemctl is-active zenoh-metadata-names zenohd-firstboot zenohd
sudo ss -tlnp | grep -E ':(22|7447|8000) '
sudo ss -ulnp | grep zenohd || echo 'no UDP socket'active active active LISTEN 0 128 127.0.0.1:8000 0.0.0.0:* users:(("zenohd",pid=1049,fd=12)) LISTEN 0 4096 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=1071,fd=3),("systemd",pid=1,fd=58)) LISTEN 0 1024 0.0.0.0:7447 0.0.0.0:* users:(("zenohd",pid=1049,fd=22)) LISTEN 0 4096 [::]:22 [::]:* users:(("sshd",pid=1071,fd=4),("systemd",pid=1,fd=59)) no UDP socketzenoh-metadata-names reads this instance's EC2 names for the certificate, zenohd-firstboot prepares the logins and the certificate, and zenohd is the router: TLS on 7447 for everyone, the REST API on 127.0.0.1:8000 for this instance only, no UDP at all.
Your endpoint, logins and client configurations
Everything generated for your instance is in /root/zenoh-credentials.txt (readable by root only). View it all with sudo cat /root/zenoh-credentials.txt; the non-secret lines are:
sudo grep -E '^ZENOH_(HOST|ENDPOINT|ADMIN_USER|APP_USER|APP_PREFIX|TLS_CERT_SHA256|TLS_PUBKEY_SHA256)=' /root/zenoh-credentials.txtZENOH_HOST=18.209.60.217 ZENOH_ENDPOINT=tls/18.209.60.217:7447 ZENOH_ADMIN_USER=sac ZENOH_APP_USER=sac-app ZENOH_APP_PREFIX=sac/app ZENOH_TLS_CERT_SHA256=37:D8:1C:44:AF:06:7A:DB:73:93:20:94:8F:24:36:1E:E2:4E:42:44:66:07:F2:B4:15:07:1A:49:65:74:81:4A ZENOH_TLS_PUBKEY_SHA256=e0fd471e8065003514ad528a0519bc1653932033ddda1fc9bdc90b1fc669abd0The file also holds ZENOH_ADMIN_PASSWORD and ZENOH_APP_PASSWORD. First boot also wrote two ready-to-use Zenoh client configurations (root only, mode 0600): /root/zenoh-client-admin.json5 for the administrator and /root/zenoh-client-app.json5 for the application identity. Each holds the endpoint, the certificate to pin and the login, so your client code reads the password from a file and never from its command line. Here is the application one with its password masked:
sudo sed -E 's/password: "[^"]*"/password: "<app-password>"/' /root/zenoh-client-app.json5// Zenoh client configuration for the application identity (sac; generated on this instance at first boot). // Allowed keys: sac/app/**. On another machine, copy /etc/zenohd/tls/zenohd.crt there and set // root_ca_certificate to its path (this pins the router certificate). Keep this file secret: it holds the password. { mode: "client", connect: { endpoints: ["tls/18.209.60.217:7447"] }, scouting: { multicast: { enabled: false, listen: false }, gossip: { enabled: false } }, transport: { link: { tls: { root_ca_certificate: "/etc/zenohd/tls/zenohd.crt" } }, auth: { usrpwd: { user: "sac-app", password: "<app-password>" } }, }, }Give applications the sac-app login or a scoped user (Step 8), not the administrator's.
Check the certificate and pin it in your client
The router's certificate is self-signed, made on your instance:
openssl x509 -in /etc/zenohd/tls/zenohd.crt -noout -subject -fingerprint -sha256 -ext subjectAltName,basicConstraints
openssl s_client -connect 127.0.0.1:7447 </dev/null 2>/dev/null | openssl x509 -noout -fingerprint -sha256subject=CN = zenoh-router, O = sac sha256 Fingerprint=37:D8:1C:44:AF:06:7A:DB:73:93:20:94:8F:24:36:1E:E2:4E:42:44:66:07:F2:B4:15:07:1A:49:65:74:81:4A X509v3 Subject Alternative Name: IP Address:18.209.60.217, DNS:ec2-18-209-60-217.compute-1.amazonaws.com, IP Address:172.31.87.224, DNS:ip-172-31-87-224.ec2.internal, IP Address:127.0.0.1, DNS:localhost X509v3 Basic Constraints: critical CA:FALSE sha256 Fingerprint=37:D8:1C:44:AF:06:7A:DB:73:93:20:94:8F:24:36:1E:E2:4E:42:44:66:07:F2:B4:15:07:1A:49:65:74:81:4AOn each client machine, copy the certificate and compare what the router serves with ZENOH_TLS_CERT_SHA256 before you trust it:
scp -i <your-key.pem> ubuntu@<public-ip>:/etc/zenohd/tls/zenohd.crt ./zenohd.crt openssl s_client -connect <public-ip>:7447 </dev/null 2>/dev/null | openssl x509 -noout -fingerprint -sha256Then pin it in that client's own Zenoh configuration: set transport.link.tls.root_ca_certificate to the path of the copied zenohd.crt. This makes the client accept this router's certificate for this connection only. Do not add the certificate to your operating system's or browser's trust store. A client without the pin is refused (invalid peer certificate: UnknownIssuer), and the router's name or address must be one of the certificate's names (the client checks it).
The certificate is re-issued on the same key and subject when the instance's addresses change, so its SHA-256 fingerprint changes but ZENOH_TLS_PUBKEY_SHA256 stays the same, and a client that pinned the original zenohd.crt keeps connecting. To use a DNS name, see Step 11.
Connect a client from another machine
Copy the application client configuration and the certificate to the client machine (keep the configuration file private: it holds the password), then point root_ca_certificate at the copied certificate:
ssh -i <your-key.pem> ubuntu@<public-ip>
sudo cat /root/zenoh-client-app.json5 > zenoh-client-app.json5 chmod 600 zenoh-client-app.json5 sed -i "s#/etc/zenohd/tls/zenohd.crt#$PWD/zenohd.crt#" zenoh-client-app.json5
# on macOS: sed -i ''Python (3.9 or later): install the official client of the same release, python3 -m venv zenoh-env && zenoh-env/bin/pip install eclipse-zenoh==1.10.2, then save this as zenoh_demo.py:
# zenoh_demo.py - publish, subscribe and query through your sac Eclipse Zenoh router.
# Usage:
python3 zenoh_demo.py zenoh-client-app.json5
# The client configuration file holds the endpoint (tls/<router>:7447), the certificate to pin and the login,
# so no password ever appears on the command line. import sys import time import zenoh zenoh.init_log_from_env_or("error") conf = zenoh.Config.from_file(sys.argv[1]) with zenoh.open(conf) as session: received = [] sub = session.declare_subscriber("sac/app/demo/**", lambda s: received.append((str(s.key_expr), s.payload.to_string()))) qbl = session.declare_queryable("sac/app/demo/status", lambda q: q.reply(q.key_expr, "ready")) time.sleep(1) session.put("sac/app/demo/temperature", "21.5") time.sleep(1) for key, value in received: print("received", key, "=", value) for reply in session.get("sac/app/demo/status"): if reply.ok is not None: print("reply ", reply.ok.key_expr, "=", reply.ok.payload.to_string())zenoh-env/bin/python zenoh_demo.py zenoh-client-app.json5received sac/app/demo/temperature = 21.5 reply sac/app/demo/status = ready(This output is from a client on a second EC2 instance connecting to the router over TLS with the sac-app login and the pinned certificate.)
Rust: add zenoh = "1.10.2" and tokio (with the macros and rt-multi-thread features) to Cargo.toml and load the same file:
#[tokio::main] async fn main() { let config = zenoh::Config::from_file("zenoh-client-app.json5").unwrap(); let session = zenoh::open(config).await.unwrap(); session.put("sac/app/demo/from-rust", "hello").await.unwrap(); let replies = session.get("sac/app/demo/status").await.unwrap(); while let Ok(reply) = replies.recv_async().await { if let Ok(sample) = reply.result() { println!("{} = {}", sample.key_expr().as_str(), sample.payload().try_to_string().unwrap()); } } }The upstream Zenoh examples take the same file with -c, for example cargo run --example z_sub -- -c zenoh-client-app.json5 -k 'sac/app/**' in a checkout of the zenoh 1.10.2 repository.
Keep the client's log level at error, warn or info: at RUST_LOG=debug Zenoh clients log their whole configuration, the password included.
Pub/sub, queries and storage on the instance
zenoh-probe is a small client on the image (run with sudo so it can read the credentials file; --identity admin or --identity app picks the login). Each command is its own Zenoh session, so these are two independent clients talking through the router:
sudo zenoh-probe subscribe --identity app --key 'sac/app/demo/**' --count 1 --duration 10 & sleep 2
sudo zenoh-probe publish --identity app --key sac/app/demo/temperature --payload 21.5 waitSUBSCRIBER_READY SAMPLE sac/app/demo/temperature 21.5 RECEIVED_COUNT 1 PUBLISHED sac/app/demo/temperatureA queryable answering a get:
sudo zenoh-probe queryable --identity app --key sac/app/demo/status --payload ready --duration 6 & sleep 2
sudo zenoh-probe get --identity admin --key sac/app/demo/status waitQUERYABLE_READY REPLY sac/app/demo/status ready REPLY_COUNT 1 QUERYABLE_DONEStorage. The storage manager keeps everything published under sac/store/** on disk (the filesystem backend, under /var/lib/zenohd/storage), so it survives a router restart or a reboot; a get on the key answers from the storage:
sudo zenoh-probe publish --identity admin --key sac/store/demo/greeting --payload 'hello from sac'
sudo zenoh-probe get --identity admin --key 'sac/store/demo/**'PUBLISHED sac/store/demo/greeting REPLY sac/store/demo/greeting hello from sac REPLY_COUNT 1The storage directory ships empty. Size the instance's EBS volume for the data you keep there. The storage is reachable by the administrator only until you give a user access to sac/store/** (Step 8).
Access control, logins and scoped users
The router refuses a session without credentials, and a wrong password:
sudo zenoh-probe session --identity anonymous2026-10-29T21:58:27.725050Z ERROR ThreadId(04) zenoh_transport::unicast::establishment::open: Received a close message (reason 0) in response to an InitSyn on: tls/127.0.0.1:50512 => tls/127.0.0.1:7447 at ... SESSION_REFUSED Unable to connect to any of [Single(tls/127.0.0.1:7447)]! at ...A wrong password is closed one step later, in response to an OpenSyn. The test logins that Eclipse Zenoh publishes in its own source (for example routername/routerpasswd) are refused too, and the router will not even start with one of them in its dictionary.
What a login may do is decided by the access_control section of /etc/zenohd/zenohd.json5, which defaults to deny:
The administrator login, SecureAnyCloud, may use every key expression (**) and may read the router admin space (@/**). The application login, sac-app, may use sac/app/** only.
A message outside a login's keys is dropped by the router. Here sac-app publishes twice and the administrator, subscribed to sac/**, receives only the allowed one:
sudo zenoh-probe subscribe --identity admin --key 'sac/**' --duration 6 & sleep 2
sudo zenoh-probe publish --identity app --key sac/private/x --payload denied
sudo zenoh-probe publish --identity app --key sac/app/x --payload allowed waitSUBSCRIBER_READY PUBLISHED sac/private/x PUBLISHED sac/app/x SAMPLE sac/app/x allowed RECEIVED_COUNT 1Scoped users. zenoh-user adds a user with its own password (generated on the instance) and a rule allowing one key prefix, writes that user's ready-to-use client configuration to /root/zenoh-user-<name>.json5 and restarts the router (sessions reconnect). The password is never printed:
sudo zenoh-user add sensor-17 fleet/sensors/17
sudo zenoh-user listzenoh-user: added sensor-17 (keys fleet/sensors/17/**); its client configuration, password included, is /root/zenoh-user-sensor-17.json5 sac every key (administrator) sac-app sac/app/** sensor-17 fleet/sensors/17/**sensor-17 may now use fleet/sensors/17/** and nothing else. Remove a user with sudo zenoh-user remove sensor-17. To give a login more than one prefix, edit the rule zenoh-user added in /etc/zenohd/zenohd.json5 (a line ending // zenoh-user:<name>) and sudo systemctl restart zenohd; the configuration gate checks the file before the router starts.
The admin space
The router's admin space (@/<router-id>/...) describes the router, its plugins and its sessions. It is read-only, and only the administrator may read it:
sudo zenoh-probe get --identity admin --key '@/*/router' | cut -c1-200REPLY @/d9074bfd276bd6c55a57f20d1a024b62/router {"locators":["tls/172.31.87.224:7447"],"metadata":null,"plugins":{"rest":{"name":"rest","path":"/usr/lib/libzenoh_plugin_rest.so"},"storage_manager":{"n REPLY_COUNT 1sac-app receives nothing from it.
The REST API (through an SSH tunnel)
The REST plugin maps HTTP to Zenoh: GET /<key-expr> is a Zenoh get (it can reach storages and queryables), PUT /<key> publishes and DELETE /<key> deletes. It runs inside the router and is not subject to the access control, which is why it listens on 127.0.0.1:8000 only. On the instance:
curl -s 'http://127.0.0.1:8000/sac/store/demo/**'; echo[{"key":"sac/store/demo/greeting","value":"aGVsbG8gZnJvbSBjbG91ZGltZw==","encoding":"zenoh/bytes","timestamp":"7702212529998757696/d9074bfd276bd6c55a57f20d1a024b62"}](value is base64.) From your workstation, open a tunnel and use http://127.0.0.1:8000 there:
ssh -i <your-key.pem> -N -L 8000:127.0.0.1:8000 ubuntu@<public-ip>Anyone with a shell on the instance can use the REST API without a Zenoh login, so keep shell access to people who may administer the router. Do not change http_port to a public address: the configuration gate refuses it.
Use your own name or a CA-issued certificate
If clients reach the router by a DNS name (or an Elastic IP), add it to the certificate. The key stays the same, so existing pins keep working:
sudo zenoh-set-hostname zenoh.example.comzenoh-set-hostname: clients connect to tls/zenoh.example.com:7447 zenoh-set-hostname: certificate SHA-256 69:E6:C8:C4:4B:19:C9:03:21:99:A8:E8:65:71:35:1D:21:CE:9F:D4:F0:F5:D6:2D:0E:C3:E3:48:A4:11:A8:54; public key SHA-256 e0fd471e8065003514ad528a0519bc1653932033ddda1fc9bdc90b1fc669abd0It updates the endpoint in /root/zenoh-credentials.txt and in the client configurations, and restarts the router.
To use a certificate from your own CA (or a public CA), install the chain (server certificate first) and its unencrypted key:
sudo zenoh-install-cert /path/to/chain.pem /path/to/key.pem zenoh.example.comClients then set root_ca_certificate to your CA's certificate (or leave it unset for a certificate from a public CA). The boot-time renewal never replaces an installed certificate; sudo zenoh-set-hostname <name> goes back to a new self-signed one.
Mutual TLS (optional). To require a client certificate as well as the login, copy the certificate of the CA that signs your client certificates to /etc/zenohd/tls/client-ca.crt, then in the router's transport.link.tls section of /etc/zenohd/zenohd.json5 change enable_mtls: false to true and add the CA:
enable_mtls: true, root_ca_certificate: "/etc/zenohd/tls/client-ca.crt",Give each client enable_mtls: true, connect_certificate and connect_private_key in its own transport.link.tls section (next to its root_ca_certificate pin), and restart with sudo systemctl restart zenohd. A client without a certificate from that CA is then refused even with a valid login. Access-control subjects can also match cert_common_names.
Connecting other routers to this one. Another Zenoh router (or peer) joins this one the same way a client does: create it a scoped login with sudo zenoh-user add, and in that router's own configuration add tls/<this-host>:7447 to its connect.endpoints, the login under transport.auth.usrpwd and the pinned certificate under transport.link.tls.root_ca_certificate. Its traffic is then limited to the login's key prefix. This router does not dial out by default: connect.endpoints is empty, it accepts TLS endpoints only, and the configuration gate refuses a user/password in the router's own configuration, so links to a remote router that itself requires a login are made from that remote router's side.
Why scouting is off, and the metadata block
Zenoh's default multicast scouting makes a router answer, and connect to, anything that announces itself on the local network, and gossip scouting propagates what routers learn about each other. On a cloud network that means joining or exposing a bus you did not plan. Both are off here and the router connects to nothing unless you list it in connect.endpoints. Clients find the router by its endpoint.
The router and its boot service cannot reach the EC2 instance metadata service, where instance-role credentials live, so even a compromised router cannot read them. Only the small zenoh-metadata-names service may, and it reads nothing but this instance's names and addresses for the certificate:
systemctl show -p IPAddressDeny zenohd zenohd-firstbootIPAddressDeny=fd00:ec2::254/128 169.254.169.254/32 ::ffff:169.254.169.254/128 168.63.129.16/32 ::ffff:168.63.129.16/128 IPAddressDeny=::ffff:169.254.169.254/128 168.63.129.16/32 169.254.169.254/32 ::ffff:168.63.129.16/128 fd00:ec2::254/128Re-verify the appliance
zenoh-selfcheck proves pub/sub, queries, storage across a router restart, every refusal, the access control, the listening set, the metadata block and the certificate on your instance (it restarts the router once):
sudo zenoh-selfcheckok pub/sub: sac-app published, a separate administrator subscriber received it byte for byte; a non-matching subscriber received nothing ok query: a get from one process was answered by a queryable in another ok storage: sac/store/** is written to disk (filesystem backend) and survived a router restart ok refused: no credentials (closed at InitSyn) ok refused: wrong passwords and Eclipse Zenoh's published test logins (routername/routerpasswd, client1name/client1passwd, client2name/client2passwd, sac/routerpasswd) closed at OpenSyn ok refused: plain tcp to 7447; TLS without the pinned certificate (invalid peer certificate: UnknownIssuer) ok control: the administrator and sac-app logins open TLS sessions right after the refusals ok access control: sac-app was denied put, subscribe and get outside sac/app/** and the router admin space @/ce3de20f.../** (0 deliveries / 0 replies), in the same run as its allowed publish and the administrator's deliveries and replies ok listeners: zenohd.service listens exactly on 0.0.0.0:7447 127.0.0.1:8000 (tcp) and holds no udp socket; REST answers on 127.0.0.1:8000 and is refused on 172.31.87.224:8000 while 172.31.87.224:7447 opens a TLS session ok metadata: 169.254.169.254 (v4 and v4-mapped) and 168.63.129.16 unreachable from inside zenohd.service; loopback control 200 ok certificate: 7447 serves /etc/zenohd/tls/zenohd.crt (SHA-256 37:D8:1C:44:AF:06:7A:DB...), an end-entity server certificate, as recorded in the credentials file SELFCHECK OKLogs and service management
The router logs to the journal:
sudo journalctl -u zenohd -b -o cat --no-pager | grep -E 'zenohd v|config-gate|reached at|assert-listeners' | tail -4zenohd-config-gate: OK (TLS-only listeners, user/password auth, access control default deny, scouting off, REST on loopback) 2026-10-29T21:57:13.909399Z INFO main ThreadId(01) zenohd: zenohd v1.10.2 built with rustc 1.97.1 (8bab26f4f 2026-07-14) 2026-10-29T21:57:17.419591Z INFO main ThreadId(01) zenoh::net::runtime::orchestrator: Zenoh can be reached at: tls/172.31.87.224:7447 zenoh-assert-listeners: zenohd.service listens exactly on 0.0.0.0:7447 127.0.0.1:8000 (tcp) and holds no udp socketIf the router refuses to start after you edit /etc/zenohd/zenohd.json5, journalctl -u zenohd shows the gate's reason (zenohd-config-gate: REFUSED: ...). The router runs as the unprivileged zenohd user and may write only its storage directory:
systemctl show -p User,NoNewPrivileges,ProtectSystem,ReadWritePaths zenohdUser=zenohd ReadWritePaths=/var/lib/zenohd/storage ProtectSystem=strict NoNewPrivileges=yesSecurity notes
- Protect the credentials. Keep
/root/zenoh-credentials.txtand the client configuration files secret. Give each application or device its own scoped user (Step 8) instead of the administrator login. - Restrict the network. Limit port 7447 in the security group to the networks your clients connect from, and limit port 22 to your admin network.
- Treat the REST API as privileged. It is unauthenticated and bypasses the access control by design because it runs inside the router. For that reason it listens on the loopback address only (Step 10).
- Mind client log levels. Run clients at log level
error,warnorinfo. Atdebugthey log their configuration, password included.
What changed since the Azure image (Eclipse Zenoh 1.9.0)
The SecureAnyCloud Azure Marketplace image of Eclipse Zenoh ships 1.9.0 with user/password logins and access control, but its router listens on plain tcp/0.0.0.0:7447, so every sample, query and reply crosses the network unencrypted. This AWS image runs 1.10.2 (which fixes a QUIC listener denial of service; QUIC stays off here), accepts TLS sessions only with a per-instance certificate, turns gossip scouting off too, makes the admin space readable by the administrator only, checks the configuration before every start and blocks the instance metadata service.
Support
SecureAnyCloud provides support for this image by email at sales@secureanycloud.com. Eclipse Zenoh is open source software under the Eclipse Public License 2.0 or the Apache License 2.0; this image is not affiliated with or endorsed by the Eclipse Foundation or the Eclipse Zenoh project.
Deploy on AWS
Launch Eclipse Zenoh 1.10.2 on Ubuntu 24.04 on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com