Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC for remote clients #50976

Closed
wants to merge 5 commits into from
Closed
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 132 additions & 0 deletions rfcs/remote-client.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
- Feature Name: Remote Client
- Start Date: 2018-12-24
- RFC PR: (leave this empty)
- Salt Issue: (leave this empty)

# Summary
[summary]: #summary

This feature allows for people using the `salt` CLI tool to connect remotely to
any Salt master and to issue commands as though they were on the master itself.

It removes the limitation for the CLI tool to have access to a stored key on the
master and replaces that method with a public-key authentication system.

# Motivation
[motivation]: #motivation

At present, if a person wishes to publish commands to a minion, they most often
achieve this by logging into a master directly and then using the provided
`salt` CLI tool. Altneratively, they may issue commands to a master by using
`salt-api` which provides a series of REST endpoints which may be accessed
natively, or by using an alternative CLI designed specifically for use
with `salt-api`, which is known as `pepper`.

However, even between these option, there remain several serious drawbacks:

* A user cannot use either the `salt` tool or the `pepper` tool to send
commands to a mix of API- and non-API- endpoints.

* Using `pepper`, there is no way to target a given master from the
cachedout marked this conversation as resolved.
Show resolved Hide resolved
command-line.

* The only way to use Salt outputters is via the `salt` CLI tool, but
as mentioned, this is limited to a single, local master. This is
a noteable competitive disadvantage when comparing Salt to other
tools which allow for remote infrastructure control.

* Salt could have a richer ecosystem of third-party client tool and
libraries to interact with Salt masters if this limitation were removed.
These could include smartphone clients, as well as a much easier
path for Salt libraries which could interact with a Salt master
in a direct manner.

# Design
[design]: #detailed-design

At present, the Salt LocalClient communicates with the master by sending
commands to the RequestServer which listens on TCP/4506. The LocalClient
proves that it is local to the host by accessing a special token which
is generated by the mater on start and is stored by default in
`/var/cache/salt/master/.root_key`.

The goal of this RFC is to remove the dependency on access to the
key in question and to replace or augment it with public-key
authentication.

Luckily, such a system is _already_ built into Salt and is used for the
authentication process for minions which connect to a master in order to
have a shared AES key securely transmitted to them.

As such, this proposal suggests that the existing public-key authentication
system simply be extended to accomodate clients.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 makes sense to me


Therefore, in addition to directories already present in `/etc/salt/master/pki`
which are presently prefixed with `minions_`, such as
`/etc/salt/master/pki/minions` for accepted minion public keys or
`/etc/salt/master/pki/`, we recommend the addition of directories prefixed by
the word `clients`, such as `/etc/salt/master/clients`.

The authentication system would be modified to accept a second type of
authentication which would be of the type `client`. Clients presenting
a key which is present in the master's PKI store would be allowed access.

This allows, in turn, for the use of the `salt-key` tooling to control client
access.

The LocalClient would then have the option of either presenting a stored
`root_key` to preserve existing behavior, or of negotiating public-key
authentication with the master.

Obvious modifications would also need to be made to the CLI parser to
support the addition of a `-m` flag to indicate a master or list of masters
to publish to.

As such, a sample command to access a remote master via the Salt CLI might
be:

`salt -m my_remote_master '*' test.ping`

## Alternatives

There are, of course, other ways we might accomplish this. These include:

* Enhancing support for a master to be controlled via events on the master event
bus. This might make integration with a reactive architecture substantially
more robust.

* Simply creating a special kind of minion that has rights on the existing
minion-publish system. However, in the author's view, the overhead of this
in terms of performance and start-up speed for a client would be too severe.

* Create a unified client which can publish commands seamlessly between salt-api
instances and local salt masters. This could potentially be extetended to
`salt-ssh` as well. Though, the goals of this are not necessarily orthoginal
to this RFC.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this option a lot, if we could expand saltnado to be have more feature parity with rest_cherrypy, and then build a client that uses the websocket stream of the event bus in order to watch for events in a similar way to how LocalClient looks for them now, we could also remove the restriction of having the localclient call in the api wait for the events to return, and would also allow for more robust integration in other programming languages.

Also expanding saltnado has the benefit that it doesn't add any extra dependencies, and we can remove the requirement for cherrypy for the api endpoint.


## Unresolved questions

This breaks the existing assumption that a client will be dealing with a single
master and as such, the names of minions which return are expected to be
unique. However, this assumption has long been broken by the introduction of
syndics. This might well make that problem worse though and the handling of
"duplicate" returns would need to be addressed more thoroughly.

If adopted, we would need to determine whether to remove the `root_key`
system or whether to allow it to continue as an option.

# Drawbacks
[drawbacks]: #drawbacks

First and most obviously, an administrator might now wish to allow remote
access. As such, it is recommended that a `client_remote_access` option be
added to the master configuration option allowing this feature to be easily
disabled and to return to the existing behavior of requiring a `root_key`
to be presented. However, in cases where this functionality is being provided
by salt-api using tokens, there are a diminished set of reasons as to why
one approach would be more secure than another, though in certain cases
they may exist and be important to consider.

Additionally, this system might be slower or even _substantially_ slower
than the existing system, which would degrade client performance.