OBSOLETE We abandoned the wrapper concept and decided to go with native TLS implementation. See here.
Current base model is:
client ^ ^ | http | V -- border between Internet + and server machine + control agent | ^ | | unix socket | V V DHCP server
The extended model which protects external communication is:
client ^ ^ | https | V -- border between Internet + and server machine + reverse proxy | ^ | | http | V | control agent | ^ | | unix socket | V V DHCP server
The proposed model is the same with a new function in the reverse proxy in addition of the https <-> http translation:
- a role is assigned to each client
- according to the role the query and the response are filtered
The control agent and DHCP server are left unchanged.
The proposal adds a few requirements to the reverse proxy:
- access to query and response bodies
- use of the JSON library to handle the JSON value in these bodies
- access to client credentials in order to assign a role
- use of command descriptions to implement per role policies
The first two points are trivial with any reverse proxy code. The last one requires some extensions to the command description file format: the work started in #1240 (closed) by the addition of a read/write access attribute.
#1240 (closed) read/write access enough?question 1: is
Today the only planned extension to commands is the read/write access. Perhaps it is enough? Note adding a new attribute to all commands make sense only for a generic attribute (generic means here which applies to many commands).
As the current command description files have the hook name (for hook commands) a per hook handling does not require any extension.
So a priori the answer is yes, read/write access is enough.
Tomek: This is what we initially thought, but the user most vitally interested in this asked for several roles. See support#15938, comment from Jan 31
Prototype feedback: the read/write is enough but is only a part of the access. The prototype builds a positive (named accept) and a negative (named reject) access list from boolean operations from the known commands and:
- an access property (so read or write)
- a hook name
- an explicit list of commands
with in addition two flags saying what to do with commands in both lists and what to do with commands which are in no lists. So it is possible to express anything.
question 2: what to use for credentials?
Authorization requires authentication or with other words if it is trivial to impersonate a client the access control is useless.
In the security model this translates into TLS (the s in https) must be setup to provide mutual authentication (mutual means both client and server: many TLS setups provide only the server authentication). It is not strictly required but the usual way is to use public key certificates and a public key infrastructure. Note when the authentication used for the access control is not bound to the TLS authentication the protocol is open to man-in-the-middle attacks as the EAP-TLS protocol disaster showed.
This can open an indirect issue at the client which should provide a certificate and have access to the private key. It is handled by browsers but it is more complex when clients are programs.
So the usual answer is the client credential is the client certificate.
tomek: Yes, the client certificate looks good to me.
question 3: what to use in credentials to assign a role?
It is related to the way the public key infrastructure is organized:
- in the simplest setup clients use self-signed certificates and the server is configured by a list of certificates associated to a role.
- if the public key infrastructure has sub certificate authority a simple scheme is to associate an issuer to each role.
- any attribute or any part of an attribute can be used: in fact to assign a role the only needed function is equality so even opaque fields work.
So even I like the issuer idea we really need guidance here.
Prototype feedback: The Python SSL library partially decode the peer certificate but it is possible to get it in raw (DER) format and to use another tool to extract undecided fields. The code has an access to the TLS session too including for instance the peer IP address.
question 4: what to use for the reverse proxy base code?
The requirements on the reverse proxy base code are pretty low. In addition of the functional requirements already detailed we need:
- open source
- programming language easy to check (unit tests) and to review
- reasonable performance
- either base code easy to adapt or accepting plugins / hooks / etc
I investigate the Python 3 solutions and the standard HTTP(S) server with the request library (not standard but used by sphinx so not a real new dependency) does the job.
(Implemented in a prototype as a premium tool in #1263 where its documentation is attached).
To summary there are a lot of possible solutions and we must reduce the choice before going further.
- #1120 - original ticket, useful discussion there
- #1240 (closed) - extend JSON files to have access parameter
- #1248 (closed) - doc/sphinx/Makefile uses GNU make specific features
- #1263 - ticket for RBAC (Role Based Access Control) - list of roles proposed
- #1304 (closed) - basic HTTP auth
- support#15938 - support ticket, some suggestions (like use RESTFul methods other than POST for read-only commands)