VIP Authentication¶
VIP (VOLTTRON Interconnect Protocol) authentication is
implemented in the auth module
and extends
the ZeroMQ Authentication Protocol
ZAP to VIP by including the ZAP
User-Id in the VIP payload, thus allowing peers to authorize access
based on ZAP credentials. This document does not cover ZAP in any
detail, but its understanding is fundamental to securely configuring
ZeroMQ. While this document will attempt to instruct on securely
configuring VOLTTRON for use on the Internet, it is recommended that the
ZAP documentation also be consulted.
Default Encryption¶
By default, ZeroMQ operates in plain-text mode, without any sort of encryption. While this is okay for in-process and interprocess communications, via UNIX domain sockets, it is insecure for any kind of inter-network communications, especially when traffic must traverse the Internet. Therefore, VOLTTRON automatically generates an encryption key and enables CurveMQ by default on all TCP connections.
To see VOLTTRON’s public key run the vctl auth serverkey
command.
For example:
(volttron)[user@home]$ volttron-ctl auth serverkey
FSG7LHhy3v8tdNz3gK35G6-oxUcyln54pYRKu5fBJzU
Authentication Implementation¶
Authentication is handled on the server and client sides. The server authentication handles the setup and monitoring of incoming connection authentication. This verifies that the authentication method matches the appropriate auth protocol that has been implemented. The client authentication creates a connection address that contains all the necessary authentication meta data to allow an agent to connect to a server. While the default authentication implementation is for Zap ZMQ, it is possible to develop new authentication client and server designs. The server implementation is handled by the auth service, and client authentication is handled by the agent core.
Client Authentication: * create_authenticated_address
Server Authentication: * setup_authentication * handle_authentication * stop_authentication * unbind_authentication
Peer Authentication¶
ZAP defines a method for verifying credentials exchanged when a connection is initially established. The authentication mechanism provides three main pieces of information useful for authentication:
domain: a name assigned to a locally bound address (to which peers connect)
address: the remote address of the peer
credentials: includes the authentication method and any associated credentials
During authentication, VOLTTRON checks these pieces against a list of
accepted peers defined in a file, called the “auth file” in this
document. This JSON-formatted file is located at
$VOLTTRON_HOME/auth.json
and must have a matching entry in the allow
list for remote connections to be accepted.
The auth file should not be modified directly.
To change the auth file, use vctl auth
subcommands: add
,
list
, remove
, and update
. (Run vctl auth --help
for more details and see the
authentication commands documentation.)
Here are some example entries:
(volttron)[user@home]$ vctl auth list
INDEX: 0
{
"domain": null,
"user_id": "platform",
"roles": [],
"enabled": true,
"mechanism": "CURVE",
"capabilities": [],
"groups": [],
"address": null,
"credentials": "k1C9-FPRAVjL-cH1iQqAJaCHUNVXaAlkVc7EqK0u9mI",
"comments": "Automatically added by platform on start"
}
INDEX: 2
{
"domain": null,
"user_id": "platform.sysmon",
"roles": [],
"enabled": true,
"mechanism": "CURVE",
"capabilities": [],
"groups": [],
"address": null,
"credentials": "5UD_GTk5dM2g4pk8d1-wM-BYgt4RAKiHf4SnT_YU6jY",
"comments": "Automatically added on agent install"
}
Note: If using regular expressions in the “address” portion, denote this with “/”. Backslashes must be escaped “\”.
This is a valid regular expression: "/192\\.168\\.1\\..*/"
These are invalid:
"/192\.168\.1\..*/", "/192\.168\.1\..*", "192\\.168\\.1\\..*"
When authenticating, the credentials are checked. If they don’t exist or don’t match, authentication fails. Otherwise, if domain and address are not present (or are null), authentication succeeds. If address and/or domain exist, they must match as well for authentication to succeed.
CURVE credentials include the remote peer’s public key. Watching the INFO level log output of the auth module can help determine the required values for a specific peer.
Configuring Agents¶
A remote agent must know the platform’s public key (also called the
server key) to successfully authenticate. This server key can be
passed to the agent’s __init__
method in the serverkey
parameter, but in most scenarios it is preferable to add the server key
to the known-hosts file.
URL-style Parameters¶
VOLTTRON extends ZeroMQ’s address scheme by supporting URL-style parameters for configuration. The following parameters are supported when connecting:
serverkey: encoded public key of remote server
secretkey: agent’s own private/secret key
publickey: agent’s own public key
ipv6: instructs ZeroMQ to attempt to use IPv6
Note: Although these parameters are still supported they should rarely need to be specified in the VIP-address URL. Agent key stores and the known-hosts file are automatically used when possible.
Platform Configuration¶
By default, the platform only listens on the local IPC VIP socket.
Additional addresses may be bound using the --vip-address
option,
which can be provided multiple times to bind multiple addresses. Each
VIP address should follow the standard ZeroMQ convention of prefixing
with the socket type (ipc:// or tcp://) and may include any of the
following additional URL parameters:
domain: domain name to associate with this endpoint (defaults to “vip”)
secretkey: alternate private/secret key (defaults to generated key for tcp://)
ipv6: instructs ZeroMQ to attempt to use IPv6
Example Setup¶
Suppose agent A
needs to connect to a remote platform B
.
First, agent A
must know platform B
’s public key
(the server key) and platform B
’s IP address (including port).
Also, platform B
needs to know agent A
’s public key
(let’s say it is HOVXfTspZWcpHQcYT_xGcqypBHzQHTgqEzVb4iXrcDg
).
Given these values, a user on agent A
’s platform adds platform
B
’s information to the known-hosts file.
At this point agent A
has all the infomration needed to connect to
platform B
, but platform B
still needs to add an authentication entry
for agent A
.
If agent A
tried to connect to platform B
at this point both parties
would see an error. Agent A
would see an error similar to:
No response to hello message after 10 seconds.
A common reason for this is a conflicting VIP IDENTITY.
Shutting down agent.
Platform B
(if started with -v or -vv) will show an error:
2016-10-19 14:21:20,934 () volttron.platform.auth INFO: authentication failure: domain='vip', address='127.0.0.1', mechanism='CURVE', credentials=['HOVXfTspZWcpHQcYT_xGcqypBHzQHTgqEzVb4iXrcDg']
Agent A
failed to authenticat to platform B
because the platform
didn’t have agent A
’s public in the authentication list.
To add agent A
’s public key, a user on platform B
runs:
(volttron)[user@platform-b]$ volttron-ctl auth add
domain []:
address []:
user_id []: Agent-A
capabilities (delimit multiple entries with comma) []:
roles (delimit multiple entries with comma) []:
groups (delimit multiple entries with comma) []:
mechanism [CURVE]:
credentials []: HOVXfTspZWcpHQcYT_xGcqypBHzQHTgqEzVb4iXrcDg
comments []:
enabled [True]:
Now if agent A
can successfully connect to platform B
, and platform
B
’s log will show:
2016-10-19 14:26:16,446 () volttron.platform.auth INFO: authentication success: domain='vip', address='127.0.0.1', mechanism='CURVE', credentials=['HOVXfTspZWcpHQcYT_xGcqypBHzQHTgqEzVb4iXrcDg'], user_id='Agent-A'
For a more details see the authentication walk-through.