The parent project for OpenZiti. Here you will find the executables for a fully zero trust, application embedded, programmable network @OpenZiti
APACHE-2.0 License
Bot releases are visible (Hide)
true limit 5
you could have just limit 5
. Or instead of true sort by name
you could have sort by name
To enable:
events:
jsonLogger:
subscriptions:
- type: fabric.routers
Example JSON output:
{
"namespace": "fabric.routers",
"event_type": "router-online",
"timestamp": "2021-04-22T11:26:31.99299884-04:00",
"router_id": "JAoyjafljO",
"router_online": true
}
{
"namespace": "fabric.routers",
"event_type": "router-offline",
"timestamp": "2021-04-22T11:26:41.335114358-04:00",
"router_id": "JAoyjafljO",
"router_online": false
}
Add workaround for bbolt bug which caused some data to get left behind when deleting identities, seen when turning off tunneler capability on edge routers
Remove deprecated ziti-enroller command. Enrollement can be done using the ziti-tunnel, ziti-router and ziti commands
Fix UDP intercept handling
The host.v1 service configuration type has been changed as follows:
dialIntercepted*
properties to forwardProtocol
, forwardAddress
, forwardPort
for better consistency with non-tunneler client applications.allowedProtocols
, allowedAddresses
, and allowedPortRanges
properties to whitelist destinations that are dialed via forward*
. The allowed*
properties are required for any corresponding forward*
property that is true
.allowedSourceAddresses
, which serves as a whitelist for source IPs/CIDRs and informs the hosting tunneler of the local routes to establish when hosting a service.Ziti Controller will now report service posture query policy types (Dial/Bind)
Ziti Controller now supports enrollment extension for routers
Ziti Router now support forcing enrollment extension via run -e
Ziti Routers will now automatically extend their enrollment before their certificates expire
ziti edge enroll
with a UPDB JWT now confirms and properly sets the password supplied
Caveats:
allowedSourceAddresses
, but the routes are not consistently cleaned up when ziti-tunnel
exits. This issue will be addressed in a future release.isSystem
flag for system managed policiesPreviously support was adding for setting the default cost and precedence that an identity would use when hosting services. Now, in addition to setting default values, costs and precedences can be set per-service. These are exposed as maps keyed by service. There is one map for costs and another for precedences. There is also CLI support for setting these values.
Example creating an identity:
ziti edge create identity service test2 --default-hosting-cost 10 --default-hosting-precedence failed --service-costs loop=20,echo=30 --service-precedences loop=default,echo=required
When viewing the identity, these values can be seen:
"id": "-qJRZFqV8t",
"tags": {},
"updatedAt": "2021-04-05T16:54:42.763Z",
"authenticators": {},
"defaultHostingCost": 10,
"defaultHostingPrecedence": "failed",
"envInfo": {},
"hasApiSession": false,
"hasEdgeRouterConnection": false,
"isAdmin": false,
"isDefaultAdmin": false,
"isMfaEnabled": false,
"name": "test2",
"roleAttributes": null,
"sdkInfo": {},
"serviceHostingCosts": {
"vH3QndzRYt": 20,
"wAnuyO3PmI": 30
},
"serviceHostingPrecedences": {
"vH3QndzRYt": "default",
"wAnuyO3PmI": "required"
},
Note that this mechanism replaces setting cost and precedence via the host.v1/host.v2 config types listenOptions
. Those values will be ignored, and may in future be removed from the schemas.
We have an existing tags mechanism, which can be used by system administrators to annotate ziti entities in whatever is useful to them. Tags are an administrator function and are not meant to be visible to SDKs and SDK applications. If an administrator wants to provide custom data for services to the SDK they can use config types and configs for that purpose. Up until now however, there hasn't been a means to annotate identities and edge routers, which are the other two entities visible to SDKs, with data that the SDKs can consume.
0.19.9 introduces appData
on identities and edge-routers. appData
has the same structure as tags
, but is intended to allow administrators to push custom data on identities and edge routers to SDKs. An example use is for tunnelers. The sourceIp
can contain template information, which can refer back to the appData
for the tunneler's identity.
The CLI supports setting appData on identities and edge routers.
ziti edge create identity service myIdentity --tags office=Regional5,device=Laptop --app-data ip=1.1.1.1,QoS=voip
See the Transwarp beta_1 guide here.
ziti-router can now run with the tunneler embedded. It has the same capabilities as ziti-tunnel. As ziti-tunnel gains new features, the combined ziti-router/tunnel should maintain feature parity.
This is a beta release. It should be relatively feature complete and bug-free for hosting services but intercept support is still nascent. Some features are likely to be changed based on user feedback.
Like ziti-tunnel, tproxy
mode will only work on linux. proxy
and host
modes should work on all operating systems.
The converged tunneler/router does not support running in tun mode. This mode may be deprecated for ziti-tunnel as well at some point in the future if no advantages over tproxy mode are evident.
The following configurations are supported:
ziti-tunneler-client.v1
ziti-tunneler-server.v1
host.v1
(updated)host.v2
(new)Support for intercept.v1
will be added in a follow-up release.
When an edge router is marked as being tunneler enabled, a matching identity will be created, of type Router, as well as an edge router policy. The edge router policy ensures that the identity always
has access to the edge router. The identity allows the router to be included in service policies, to configure which services will intercepted/hosted.
edge-router-<edge-router-id>-system
, where <edge-router-id>
is replaced by the id of the edge router.system
entity, and cannot be updated and cannot deleted except by the system when the associated router is deleted.In order for a router instance to host a tunneler, it must meet the following criteria:
isTunnelerEnabled
must be set to trueedge:
config section must be present. NOTE: The edge listener does not need to be enabled.The ziti CLI can be used to enable/disable tunneler support on edge routers. When creating an edge router, the -t
flag can be passed in to enable running the tunneler.
ziti edge create edge-router myEdgeRouter --tunneler-enabled
or
ziti edge create edge-router myEdgeRouter -t
An existing edge router can be marked as tunneler enabled as follows:
ziti edge update edge-router myEdgeRouter --tunneler-enabled
or
ziti edge update edge-router myEdgeRouter -t
An existing edge router can be marked as not supporting the tunneler as follows:
ziti edge update edge-router myEdgeRouter -t=false
or
ziti edge update edge-router myEdgeRouter --tunneler-enabled=false
listeners:
- binding: tunnel
options:
mode: tproxy # mode to run in. Valid values [tproxy, host, proxy]. Default: tproxy
svcPollRate: 15s # How often to poll for service changes. Default: 15s
resolver: udp://127.0.0.1:53 # DNS resolve. Default: udp://127.0.0.1:53 for tproxy, blank for others
dnsSvcIpRange: 100.64.0.1/10 # cidr to use when assigning IPs to unresolvable intercept hostnames (default "100.64.0.1/10")
services: # services to intercept in proxy mode. Default: none
- echo:1977
lanIf: tun1 # if specified, INPUT rules for intercepted service addresses are assigned to this interface. Defaults to unspecified.
Health checks now have a new trigger option change
. This will trigger the action whenever the health state changes from pass to fail or fail to pass.
There's now a new action, send event
, which will send a health event to the controller. This will be reported via the recently introduced service events.
The change
option is designed to be sued with send event
as a way to send events only when the state changes, rather than sending every single pass/fail.
An example configuration:
{
"address": "localhost",
"port": 8171,
"protocol": "tcp",
"portChecks": [
{
"address": "localhost:8171",
"interval": "5s",
"timeout": "100ms",
"actions": [
{
"trigger": "change",
"action": "send event"
}
]
}
]
}
What the service events look like:
{
"namespace": "service.events",
"event_type": "service.health_check.failed",
"service_id": "vH3QndzRYt",
"count": 2,
"interval_start_utc": 1616703360,
"interval_length": 60
}
{
"namespace": "service.events",
"event_type": "service.health_check.failed",
"service_id": "vH3QndzRYt",
"count": 1,
"interval_start_utc": 1616703720,
"interval_length": 60
}
{
"namespace": "service.events",
"event_type": "service.health_check.passed",
"service_id": "vH3QndzRYt",
"count": 2,
"interval_start_utc": 1616703720,
"interval_length": 60
}
The host.v1 config type now support health checks. The configuration is the same for ziti-tunneler-server-v1
.
See here: https://github.com/openziti/edge/blob/v0.19.54/tunnel/entities/host.v1.json for the full schema
There is a new host configuration, host.v2
, which should supercede host.v1
. The primary difference from host.v1
is that it supports multiple terminators. This means that when a service is hosted by a router, it can connect to multiple service instances if the service is horizontally scaled, or in a primary/failover setup.
Each terminator definition is the same as a host.v1
configuration, which one exception: listOptions.connectTimeoutSeconds
is now listenOptions.connectTimeout
and is specified as a duration (5s
, 2500ms
, etc).
Example:
{
"terminators": [
{
"address": "localhost",
"port": 8171,
"protocol": "tcp",
"listenOptions": {
"cost": 50,
"precedence": "required"
},
"portChecks": [
{
"address": "localhost:8171",
"interval": "5s",
"timeout": "100ms",
"actions": [
{
"trigger": "change",
"action": "send event"
},
{
"trigger": "fail",
"action": "increase cost 25"
},
{
"trigger": "pass",
"action": "decrease cost 10"
}
]
}
]
},
{
"address": "localhost",
"port": 8172,
"protocol": "tcp",
"listenOptions": {
"cost": 51,
"precedence": "required"
},
"portChecks": [
{
"address": "localhost:8172",
"interval": "5s",
"timeout": "100ms",
"actions": [
{
"trigger": "change",
"action": "send event"
},
{
"trigger": "fail",
"action": "increase cost 25"
},
{
"trigger": "pass",
"action": "decrease cost 10"
}
]
}
]
}
]
}
The following router configuration stanza controls idle route garbage collection:
forwarder:
#
# After how many milliseconds of inactivity is a forwarding table entry considered idle?
#
idleSessionTimeout: 60000
#
# How frequently will we confirm idle sessions with the controller?
#
idleTxInterval: 60000
The following router configuration stanza controls Xgress dial "dwell time". You probably don't want
to use this unless you're debugging a timing-related issue in the overlay:
forwarder:
#
# (Debugging) Xgress dial "dwell time". When dialing, the Xgress framework will wait this number of milliseconds
# before responding in the affirmative to the controller.
#
xgressDialDwellTime: 0
Enable database tracing using the dbTrace
controller configuration directive:
dbTrace: true
This will result in log output that describes the entrance into and exit from transactional
functions operating against the underlying database:
[ 0.003] INFO fabric/controller/db.traceUpdateEnter: Enter Update (tx:18) [github.com/openziti/fabric/controller/db.createRoots]
[ 0.003] INFO fabric/controller/db.traceUpdateExit: Exit Update (tx:18) [github.com/openziti/fabric/controller/db.createRoots]
[ 0.006] INFO fabric/controller/db.traceUpdateEnter: Enter Update (tx:19) [github.com/openziti/foundation/storage/boltz.(*migrationManager).Migrate.func1]
[ 0.006] INFO foundation/storage/boltz.(*migrationManager).Migrate.func1: fabric datastore is up to date at version 4
[ 0.006] INFO fabric/controller/db.traceUpdateExit: Exit Update (tx:19) [github.com/openziti/foundation/storage/boltz.(*migrationManager).Migrate.func1]
With the Ziti Controller shutdown, it is now possible to clear out all API Sessions and Edge
Sessions that were persisted prior to the controller being stopped. All connecting identities will
need to re-authenticate when the controller is restarted.
This command is useful in situations where the number of sessions is large and the database is being
copied and/or used for debugging.
Example Command:
ziti-controller delete-sessions
Example Output:
[ 0.017] INFO ziti/ziti-controller/subcmd.deleteSessions: {go-version=[go1.16] revision=[local] build-date=[2020-01-01 01:01:01] os=[windows] arch=[amd64] version=[v0.0.0]} removing API Sessions and Edge Sessions from ziti-controller
[ 9.469] INFO ziti/ziti-controller/subcmd.deleteSessions.func2: existing api Sessions: 2785
[ 18.274] INFO ziti/ziti-controller/subcmd.deleteSessions.func2: edge sessions bucket does not exist, skipping, count is: 4035
[ 47.104] INFO ziti/ziti-controller/subcmd.deleteSessions.func3: done removing api Sessions
[ 55.866] INFO ziti/ziti-controller/subcmd.deleteSessions.func3: done removing api session indexes
[ 58.325] INFO ziti/ziti-controller/subcmd.deleteSessions.func3: done removing edge session indexes
In previous versions heartbeats from REST API usage and discrete Edge Router connection would all cause writes
for the same API Session as they were encountered. In situations where one or more REST API requests were issues and/or one or more
Edge Router connections were held by a ZitI Application, multiple simultaneous heartbeats could occur for no apparent benefit
and consume disk write I/O.
Heartbeats are now aggregated over a window of time in a cache and written to disk on an interval. The write interval defaults to 90s
and the batch size (for write transactions) to 250. Additionally, all heartbeats are flush to disk when the controller is properly shut down.
These settings can be defined in the edge.api
section for the Ziti Controller configuration.
Example:
edge:
api:
...
#(optional, default 90s) Alters how frequently heartbeat and last activity values are persisted
activityUpdateInterval: 90s
#(optional, default 250) The number of API Sessions updated for last activity per transaction
activityUpdateBatchSize: 250
...
When a Ziti Identity (endpoint) requests a service that is provided via a Service Policy with
Posture Checks associated with it, failure to meet the Posture Check requirements results in an
error message with a code of INVALID_POSTURE
and data elaborating on what Service Policies ids and
Posture Check ids failed. Additionally, now the controller will log the most recent requests and
provide detailed error output for administrators.
The output will show every Service Policy that was checked for access and every Posture Check that
failed. The failed Posture Checks include the Posture Data that was available for the identity and
the requirements defined in the Posture Check at the time of the Edge Session request.
New Endpoint: GET /identities/{id}/failed-service-requests
Example Output:
{
"data": [
{
"apiSessionId": "ckmgcom680002cc61hggmcy1n",
"policyFailures": [
{
"policyId": "eqggCQlBm",
"policyName": "alldial",
"checks": [
{
"actualValue": {
"hash": "123",
"isRunning": true,
"signerFingerprints": [
"834f29a60152ce36eb54af37ca5f8ec029eccf01",
"123248b9e8b0dd41938018a871a13dd92bed4456"
]
},
"expectedValue": {
"hashes": [
"3af35956a71c2afefbfe356f86c9139725eeecb15f0de7d98557d4d696c434f51fbc2fa5f7543aef4f5f1afb83caa4a43619973bae52e1f4f92ec10c39b039e8"
],
"osType": "Windows",
"path": "C:\\Program Files\\TestApp\\test.exe",
"signerFingerprint": "834f29a60152ce36eb54af37ca5f8ec029eccf01"
},
"postureCheckId": "UF9aOqlD3",
"postureCheckName": "processCheck",
"postureCheckType": "PROCESS"
},
{
"actualValue": {
"type": "Windows",
"version": "6.0.18364"
},
"expectedValue": [
{
"type": "Windows",
"versions": [
">=10.0.18364 <=10.0.19041"
]
}
],
"postureCheckId": "fK0aOQFD3",
"postureCheckName": "osCheck",
"postureCheckType": "OS"
},
{
"actualValue": "wrong.com",
"expectedValue": [
"right.com"
],
"postureCheckId": "i2wgOQlBm",
"postureCheckName": "domainCheck",
"postureCheckType": "DOMAIN"
}
]
}
],
"serviceId": "ll-aOqFDm",
"serviceName": "test-service",
"sessionType": "Dial",
"when": "2021-03-19T09:41:10.117-04:00"
}
],
"meta": {}
}
There are new events emitted for service, with statistics for how many dials are successful, failed,
timed out, or fail for non-dial related reasons. Stats are aggregated per-minute, similar to usage
statistics. They can be enabled in the controller config as follows:
events:
jsonLogger:
subscriptions:
- type: services
handler:
type: file
format: json
path: /tmp/ziti-events.log
Example of the events JSON output:
{
"namespace": "service.events",
"event_type": "service.dial.fail",
"service_id": "HSfgHzIom",
"count": 8,
"interval_start_utc": 1615400160,
"interval_length": 60
}
{
"namespace": "service.events",
"event_type": "service.dial.success",
"service_id": "HSfgHzIom",
"count": 29,
"interval_start_utc": 1615400160,
"interval_length": 60
}
Event types:
service.dial.success
service.dial.fail
service.dial.timeout
service.dial.error_other
15s
Example stanza from router config file:
metrics:
reportInterval: 15s
messageQueueSize: 10
Control the link latency probe timeout parameter with the following router configuration syntax:
forwarder:
#
# After how many milliseconds does the link latency probe timeout?
# (default 10000)
#
latencyProbeTimeout: 10000
Specify the dial timeout for Xgress dialers using the following syntax:
dialers:
- binding: transport
options:
connectTimeout: 2s
You will need to specify Xgress options for each dialer binding that you want to use with your
configuration.
Each now gets its own event. Here are two example events:
{
"metric": "xgress.tx_write_time",
"metrics": {
"xgress.tx_write_time.count": 0,
"xgress.tx_write_time.m1_rate": 0,
"xgress.tx_write_time.mean": 0,
"xgress.tx_write_time.p99": 0
},
"namespace": "metrics",
"source_event_id": "62c31ab9-e0ed-48f5-9907-2d2e8c76f393",
"source_id": "pTF3hzUQI",
"timestamp": "2021-02-23T19:33:39.017329033Z"
}
{
"metric": "link.rx.msgsize",
"metrics": {
"link.rx.msgsize.count": 3,
"link.rx.msgsize.mean": 0,
"link.rx.msgsize.p99": 0
},
"namespace": "metrics",
"source_entity_id": "8VEJ",
"source_event_id": "62c31ab9-e0ed-48f5-9907-2d2e8c76f393",
"source_id": "pTF3hzUQI",
"timestamp": "2021-02-23T19:33:39.017329033Z"
}
Changes of note:
source_event_id
which can be used to link together all the metrics that weresource_entity_id
field.Edge Session Validation
Ziti CLI now has 'Let's Encrypt' PKI support to facilitate TLS connections to Controller from
BrowZer-based apps that use the ziti-sdk-js
.
New command to Register a Let's Encrypt account, then create and install a certificate
Usage:
ziti pki le create -d domain -p path-to-where-data-is-saved [flags]
Flags:
-a, --acmeserver string ACME CA hostname (default "https://acme-v02.api.letsencrypt.org/directory")
-d, --domain string Domain for which Cert is being generated (e.g. me.example.com)
-e, --email string Email used for registration and recovery contact (default "[email protected]")
-h, --help help for create
-k, --keytype EC256|EC384|RSA2048|RSA4096|RSA8192 Key type to use for private keys (default RSA4096)
-p, --path string Directory to use for storing the data
-o, --port string Port to listen on for HTTP based ACME challenges (default "80")
-s, --staging Enable creation of 'staging' Certs (instead of production Certs)
New command to Display Let's Encrypt certificates and accounts information
Usage:
ziti pki le list -p path-to-where-data-is-saved [flags]
Flags:
-a, --accounts Display Account info
-h, --help help for list
-n, --names Display Names info
-p, --path string Directory where data is stored
New command to Renew a Let's Encrypt certificate
Usage:
ziti pki le renew -d domain -p path-to-where-data-is-saved [flags]
Flags:
-a, --acmeserver string ACME CA hostname (default "https://acme-v02.api.letsencrypt.org/directory")
--days int The number of days left on a certificate to renew it (default 14)
-d, --domain string Domain for which Cert is being generated (e.g. me.example.com)
-e, --email string Email used for registration and recovery contact (default "[email protected]")
-h, --help help for renew
-k, --keytype EC256|EC384|RSA2048|RSA4096|RSA8192 Key type to use for private keys (default RSA4096)
-p, --path string Directory where data is stored
-r, --reuse-key Used to indicate you want to reuse your current private key for the renewed certificate (default true)
-s, --staging Enable creation of 'staging' Certs (instead of production Certs)
New command to Revoke a Let's Encrypt certificate
Usage:
ziti pki le revoke -d domain -p path-to-where-data-is-saved [flags]
Flags:
-a, --acmeserver string ACME CA hostname (default "https://acme-v02.api.letsencrypt.org/directory")
-d, --domain string Domain for which Cert is being generated (e.g. me.example.com)
-e, --email string Email used for registration and recovery contact (default "[email protected]")
-h, --help help for revoke
-p, --path string Directory where data is stored
-s, --staging Enable creation of 'staging' Certs (instead of production Certs)
Parallel Routing
for additional details.router-disconnect
and router-reconnect
, which disconnects/reconnects theziti-router
on startup.Before 0.19, edge sessions (note: network sessions, not API sessions) would be sent to edge routers
after they were created. When the edge router received a dial or bind request it would verify that
the session was valid, then request the controller to create a fabric session.
This approach has two downsides.
Since the edge router makes a request to the controller anyway, we can pass the session token and
fingerprints up to the controller and do the verification there. This allows us to minimize the
amount of state the edge router needs to keep synchronized with the controller and removes the race
condition.
Prior to 0.19, the Ziti controller would send a Route
message to the terminating router first, to establish terminator endpoint connectivity. If the destination endpoint was unreachable, the entire session setup would be abandoned. If the terminator responded successfully, the controller would then proceed to work through the chain of routers sending Route
messages and creating the appropriate forwarding table entries. This all happened sequentially.
In 0.19 route setup for session creation now happens in parallel. The controller sends Route
commands to all of the routers in the chain (including the terminating router), and waits for responses and/or times out those responses. If all of the participating routers respond affirmatively within the timeout period, the entire session creation succeeds. If any participating router responds negatively, or the timeout period occurs, the session creation attempt fails, updating configured termination weights. Session creation will retry up to a configured number of attempts. Each attempt will perform a fresh path selection to ensure that failed terminators can be excluded from subsequent attempts.
The terminationTimeoutSeconds
timeout parameter has been removed and will be ignored. The routeTimeoutSeconds
controls the timeout for each route attempt.
#network:
#
# routeTimeoutSeconds controls the number of seconds the controller will wait for a route attempt to succeed.
#
#routeTimeoutSeconds: 10
You'll want to ensure that your participating routers' getSessionTimeout
in the Xgress options is configured to a suitably large enough value to support the configured number of routing attempts, at the configured routing attempt timeout. In the router configuration, the getSessionTimeout
value is configured for your Xgress listeners like this:
listeners:
# basic ssh proxy
- binding: proxy
address: tcp:0.0.0.0:1122
service: ssh
options:
getSessionTimeout: 120s
The new parallel routing implementation also supports a configurable number of session creation attempts. Prior to 0.19, the number of attempts was hard-coded at 3. In 0.19, the number of retries is controlled by the createSessionRetries
parameter, which defaults to 3.
network:
#
# createSessionRetries controls the number of retries that will be attempted to create a circuit (and terminate it)
# for new sessions.
#
createSessionRetries: 5
Prior to 0.19 API Sessions were only capable of being synchronized with connecting/reconnecting
edge routers in a single manner. In 0.19 and forward improvements allow for multiple strategies to be defined
within the same code base. Future releases will be able to introduce configurable and negotiable
strategies.
The default strategy from prior releases, now named 'instant', has been improved to
fix issues that could arise during edge router reconnects where API Sessions would become invalid
on the reconnecting edge router. In addition, the instant strategy now allows for invalid
synchronization detection, resync requests, enhanced logging, and synchronization statuses for edge routers.
The GET /edge-routers
list and GET /edge-routers/<id>
detail responses now include a syncStatus
field. This value is updated during the lifetime of the edge router's connection to the controller
and will provide insight on its status.
The possible syncStatus
values are as follows:
sessionStartTimeout
3m
ziti ps route <optional target> <session> <src-address> <dest-address>
ziti ps dump-routes <optional target>
--lanIf
option to automatically add rules to accept incomingziti-sdk-js
. Edge Routers support various configurations including a single tls
binding, aws
binding, or having both tls
and ws
bindings simultaneously. If both binding types# Example Edge Router config snippet (note new `ws` address type):
listeners:
- binding: edge
address: ws:0.0.0.0:3021
options:
advertise: curt-edge-ws-router:3021
- binding: edge
address: tls:0.0.0.0:3022
options:
advertise: curt-edge-ws-router:3022
A new endpoint has been added which will display the list of Edge Routers an authenticated session
has access to via any policy. The records will indicate whether the router is online, its hostname,
and its supported protocols. This endpoint will not return Edge Routers that have not completed
enrollment. Edge Routers that are offline will not have hostname and supported protocol information.
Endpoint: GET /current-identity/edge-routers
Example Output:
{
"data": [
{
"createdAt": "2021-01-27T20:13:18.599Z",
"id": "LolSlAQMq",
"tags": {},
"updatedAt": "2021-01-27T20:13:19.762Z",
"hostname": "",
"isOnline": false,
"name": "er1",
"supportedProtocols": {}
},
{
"createdAt": "2021-01-27T20:13:19.308Z",
"id": "oVzRl6kCq",
"tags": {},
"updatedAt": "2021-01-27T20:13:19.901Z",
"hostname": "127.0.0.1:5002",
"isOnline": true,
"name": "er2",
"supportedProtocols": {
"tls": "tls://127.0.0.1:5002",
"wss": "wss://127.0.0.1:5002"
}
}
],
"meta": {
"filterableFields": [
"id",
"createdAt",
"updatedAt",
"name",
],
"pagination": {
"limit": 10,
"offset": 0,
"totalCount": 2
}
}
}
xgressCloseCheckInterval
, which dictates for how long data flowlimit none
for Edge API Rest requests is now properly limited to 500 elements on list endpointsserver
is now populated on all responses with ziti-controller/vX.Y.Z
Note: This feature is only available if both controller and router are on 0.18.7 or higher.
The control channels between the controller and routers now generate metrics, including:
ctrl.<router id>.latency
ctrl.<router id>.tx.bytesrate
ctrl.<router id>.tx.msgrate
ctrl.<router id>.tx.msgsize
ctrl.<router id>.rx.bytesrate
ctrl.<router id>.rx.msgrate
ctrl.<router id>.rx.msgsize
There is a new controller config file setting:
ctrlChanLatencyIntervalSeconds
which controls how often the latency probe is sent. Defaultziti use
command to work with main branchEndpoint MFA is available that is based on RFC 4226 (HOTP: An HMAC-Based One-Time Password
Algorithm) and RFC 6238 (TOTP: Time-Based One-Time Password Algorithm). These standards are
compatible with standard "Authenticator" apps such as Google Authenticator and Authy. MFA is
suggested to be used in situations where human operators are involved and additional security is
desired.
Services can now have a Posture Check of type MFA that can be created and associated with a Service
Policy. Service Policies that are associated with an MFA Posture Check will restrict access to
services if a client has not enrolled in MFA and passed an MFA check on each login.
MFA Posture Checks support only the basic Posture Check fields:
Example:
POST /posture-checks
{
"name": "Any MFA",
"typeId": "MFA",
"roleAttributes": ["mfa"]
}
Admins of the Ziti Edge API can remove MFA from any user. However, they cannot enroll on behalf of
the client. The client will have to initiate MFA enrollment via their client.
Endpoints:
DELETE /identities/<id>/mfa
- remove MFA from an identityGET /identities
- has a new field isMfaEnabled
that is true/false based on the identity's MFAGET /identities/<id>/posture-data
- now includes a sessionPostureData
field which is a map ofExample Posture Data:
{
"mac": ["03092ac3bc69", "2b6df1dc52d9"],
"domain": "mycorp.com",
"os": {
...
},
processes: [
...
],
sessionPostureData: {
"xV1442s": {
"mfa": {
"passedMfa": true
}
}
}
}
Clients must individually enroll in MFA as the enrollment process includes exchanging a symmetric
key. During MFA enrollment the related MFA endpoints will return different data and HTTP status
codes based upon the state of MFA enrollment (enrollment not started, enrollment started, enrolled).
The general MFA enrollment flow is:
POST /authenticate
POST /current-identity/mfa
GET /current-identity/mfa
GET /current-identity/mfa/qr-code
POST /current-identity/mfa/verify
with the code incode
field {"code": "someCode"}
This section is an overview for the endpoints. Each endpoint may return errors depending on in input
and MFA status.
GET /current-identity/mfa
- returns the current state of MFA enrollment or 404 Not FoundPOST /current-identity/mfa
- initiates MFA enrollment or 409 ConflictDELETE /current-identity/mfa
- remove MFA enrollment, requires a valid TOTP or recovery codeGET /current-identity/mfa/recovery-codes
- returns the current recovery codes, requires a validPOST /current-identity/mfa/recovery-codes
- regenerates recovery codes, requires a valid TOTPPOST /current-identity/mfa/verify
- allows MFA enrollment to be completed, requires a valid TOTPGET /current-identity/mfa/qr-code
- returns a QR code for use with QR code scanner, MFAPOST /authenticate/mfa
- allows MFA authentication checks to be completed, requires a valid TOTPMFA Enrollment Not Started:
GET /current-identity/mfa
- returns HTTP status 404POST /current-identity/mfa
- start MFA enrollment, 200 OkDELETE /current-identity/mfa
- returns 404 Not FoundGET /current-identity/mfa/recovery-codes
- returns 404 Not FoundPOST /current-identity/mfa
- returns 404 Not FoundPOST /current-identity/mfa/verify
- returns 404 Not FoundGET /current-identity/mfa/qr-code
- returns 404 Not FoundMFA Enrollment Started:
GET /current-identity/mfa
- returns the current MFA enrollment and recovery codesPOST /current-identity/mfa
- returns 409 ConflictDELETE /current-identity/mfa
- aborts the current enrollment, a blank code
may be suppliedGET /current-identity/mfa/recovery-codes
- returns 404 Not FoundPOST /current-identity/mfa
- returns HTTP status 409 ConflictPOST /current-identity/mfa/verify
- validates the supplied code
GET /current-identity/mfa/qr-code
- returns a QR code for use with QR code scanner in PNG formatMFA Completed:
GET /current-identity/mfa
- returns the current MFA enrollment, but not recovery codesPOST /current-identity/mfa
- returns 409 ConflictDELETE /current-identity/mfa
- removes MFA, a valid TOTP or recovery code must be suppliedGET /current-identity/mfa/recovery-codes
- shows the current recovery codes, a valid TOTP codePOST /current-identity/mfa
- returns HTTP status 409 ConflictPOST /current-identity/mfa/verify
- returns HTTP status 409 ConflictGET /current-identity/mfa/qr-code
- returns 404 Not FoundClient MFA recovery codes are generated during enrollment and can be regenerated at any time with a
valid TOTP code. Twenty codes are generated and are one time use only. Generating new codes replaces
all existing recovery codes.
To view:
GET /current-identity/mfa/recovery-codes
{
"code": "123456"
}
To Generate new codes:
POST /current-identity/mfa/recovery-codes
{
"code": "123456"
}
During API Session authentication a new authQuery
field is returned. This field will indicate if
there are any outstanding authentication Posture Queries that need to be fulfilled before
authentication is considered complete.
When MFA authentication is required a field will now appear as an
authQuery
with the following format:
{
...
"token": "c68a187a-f4af-490c-a9dd-a09076511419",
"authQueries": [
...,
{
"typeId": "MFA",
"provider": "ZITI",
"httpMethod": "POST",
"httpUrl": "./authenticate/mfa",
"minLength": 4,
"maxLength": 6,
"format": "alphaNumeric"
},
...
]
}
ziti ps set-log-level
, allows you to set the application wide log level atAn Edge SDK client will create and api session and session with the controller first, then attempt
to use those sessions at an edge router. The controller will push session information to routers as
quickly as it can, but clients may still connect to the edge router before the client can. We
previously would wait up to 5 seconds for session to arrive before declaring a session invalid, but
would not wait for api-sessions.
We can now wait for both api-sessions and sessions. Both timeouts are configurable. They are
configured in the router config file under listeners options.
lookupApiSessionTimeout
lookupSessionTimeout
Example router config file stanza:
listeners:
- binding: edge
address: tls:0.0.0.0:6342
options:
advertise: 127.0.0.1:6432
lookupApiSessionTimeout: 5s
lookupSessionTimeout: 5s