|
|
This page describes a design for RBAC implementation in Kea.
|
|
|
|
|
|
[[_TOC_]]
|
|
|
|
|
|
This design aims to fulfill the [requirements](https://gitlab.isc.org/isc-projects/kea/-/wikis/designs/rbac-tls-requirements) related to RBAC and TLS.
|
|
|
|
|
|
# 1. RBAC Hook Design
|
|
|
|
|
|
As the native TLS implementation is now complete (released in 1.9.x), we are be able to implement an RBAC hook that will have access to basic HTTP headers and TLS certs data. The hooks will take advantage of those different channels.
|
|
|
|
|
|
The existing Control Agent (CA) hook point `auth` will be extended with additional parameters:
|
|
|
|
|
|
- `tls` - boolean parameter that specifies if a command was received over TLS connection (true) or plain http (false)
|
|
|
- `tls-common-name` will specify the COMMON NAME field of the client certificate used for establishing the TLS connection (or empty if plain http was used)
|
|
|
|
|
|
The code will also take advantage of the already existing `request` parameter which contains HTTP headers.
|
|
|
|
|
|
The hook will conduct the following operations:
|
|
|
|
|
|
1. on start-up:
|
|
|
- load ACL file. The loaded ACL entries will be stored in vector container.
|
|
|
- register commands (`acl-reload` for now)
|
|
|
|
|
|
2. on command reception:
|
|
|
- will iterate over all ACL entries. Since there are wildcards, it's difficult to optimize this.
|
|
|
- if match is found, true will be returned (meaning the client's API call is accepted)
|
|
|
- if match is not found, false will be returned (meaning the client's API call is rejected)
|
|
|
|
|
|
3. on unload:
|
|
|
- unregister commands
|
|
|
|
|
|
# 2. Access Control Lists
|
|
|
|
|
|
There is a need to define ACL. The ACL applies to REST API commands only, not to normal DHCP traffic.
|
|
|
|
|
|
The basic access control would be based on usernames:
|
|
|
```javascript
|
|
|
{
|
|
|
// username alice is allowed to use config-set command
|
|
|
"username": ["alice"], "scope": ["config-set"]
|
|
|
},
|
|
|
{
|
|
|
// users bob and charlie are allowed to call shutdown command
|
|
|
"username": ["bob","charlie"], "scope": ["shutdown"]
|
|
|
}
|
|
|
```
|
|
|
|
|
|
Wildcards are allowed in all fields:
|
|
|
```javascript
|
|
|
{
|
|
|
// junior user is allowed to use only read-only (get) commands
|
|
|
"username": ["junior"],
|
|
|
"scope":["*-get"]
|
|
|
},
|
|
|
{
|
|
|
// any username that starts with adm is allowed to call write commands
|
|
|
"username": ["adm*"],
|
|
|
"scope": ["*-write"]
|
|
|
},
|
|
|
{
|
|
|
// any authenticated user is allowed to use any command. This effectively
|
|
|
// sets the default policy to accept everything.
|
|
|
"username": ["*"],
|
|
|
"scope": ["*"]
|
|
|
}
|
|
|
```
|
|
|
|
|
|
The authorization can also use fields of TLS certs. For the time being only subject common name is expected, but that list may be expanded in the future (e.g. to add issuer common name and other certificate fields):
|
|
|
|
|
|
```javascript
|
|
|
{
|
|
|
// client that use valid TLS certificate with common name equal to delta,
|
|
|
// is allowed to use all set commands
|
|
|
"tls-subject": ["delta"],
|
|
|
"scope": "*-set"
|
|
|
}
|
|
|
```
|
|
|
|
|
|
_OPTIONAL_: In the future, this may also be based on IP address.
|
|
|
|
|
|
```javascript
|
|
|
{
|
|
|
// client connecting from IP address 192.0.2.1 is allowed to
|
|
|
"ip": ["192.0.2.1"],
|
|
|
"scope": ["subnet4-add"]
|
|
|
}
|
|
|
```
|
|
|
|
|
|
Requirements and targets can be comma separated, e.g.
|
|
|
|
|
|
```javascript
|
|
|
{
|
|
|
// users echo and foxtrot are allowed to use several commands
|
|
|
"username": ["echo","foxtrot"],
|
|
|
"scope": ["subnet4*","subnet6-del","subnet6-add"]
|
|
|
}
|
|
|
```
|
|
|
|
|
|
_OPTIONAL_: Requirements can be mixed. If multiple requirements are specific, all must be met:
|
|
|
|
|
|
```javascript
|
|
|
{
|
|
|
// client connecting using TLS cert assigned to guliet is able to
|
|
|
// write config, but only if connects from 192.0.2.1
|
|
|
"tls-common-name": ["golf"],
|
|
|
"ip": ["192.0.2.1"],
|
|
|
"scope": ["config-write"]
|
|
|
}
|
|
|
```
|
|
|
|
|
|
# 3. ACL Management
|
|
|
|
|
|
Initially, the ACL will be stored in a file as a plain text. In the future, additional backends may be defined. MySQL and PostgreSQL are natural solutions, but more specific systems, such as LDAP could be considered.
|
|
|
|
|
|
Configuration of the ACL would be done using the following syntax:
|
|
|
|
|
|
```javascript
|
|
|
"Control-agent": {
|
|
|
"authentication": {
|
|
|
"clients": [
|
|
|
{ "user": "admin", "password": "1234" },
|
|
|
],
|
|
|
"acl-backend": {
|
|
|
"type": "file",
|
|
|
"name": "/etc/kea/acl.txt"
|
|
|
}
|
|
|
},
|
|
|
}
|
|
|
```
|
|
|
|
|
|
## ACL Management
|
|
|
|
|
|
The following commands will be supported:
|
|
|
|
|
|
- `acl-reload` - instructs Kea to reload the content of the ACL lists from disk (in the future, also from a DB)
|
|
|
|
|
|
_OPTIONAL_: In the future, additional commands for managing the ACLs could be designed.
|
|
|
|
|
|
## ACL groups
|
|
|
|
|
|
Proper role-based access control requires roles, i.e. ability to add users to certain groups and control access based on those groups. For the time being, this functionality will not be implemented.
|
|
|
|
|
|
Once we decide to implement groups, the following syntax could be used:
|
|
|
|
|
|
```javascript
|
|
|
"groups": [
|
|
|
// Users alpha, beta and charlie belong to group readers.
|
|
|
// Note that user can belong to multiple groups (e.g. charlie is both in
|
|
|
// readers and writers.
|
|
|
"readers": [ "alpha", "beta", "charlie" ],
|
|
|
"writers": [ "charlie", "echo", "foxtrot" ]
|
|
|
],
|
|
|
"acl": [
|
|
|
{
|
|
|
"group": ["readers"],
|
|
|
"scope": ["*-get"]
|
|
|
},
|
|
|
{
|
|
|
"group": ["writers"],
|
|
|
"scope": ["*-set", "*-del", "*-update"]
|
|
|
}
|
|
|
]
|
|
|
```
|
|
|
|
|
|
## Fine-grained control over subnets
|
|
|
|
|
|
_OPTIONAL_: So far, the design discussed how to limit access on a per call basis. However, some operations, such as subnets modifications, likely will require more fine grained control, e.g. some users are allowed to manage only some subnets. This will be done with `param` operator. If `param` is specified in the ACL, it must be present in the API call for the rule to apply.
|
|
|
|
|
|
```javascript
|
|
|
{
|
|
|
// users echo and foxtrot are allowed to use several commands. All
|
|
|
// of those commands need to have "subnet-id": 5 parameter defined.
|
|
|
// This effectively will limit the scope to one subnet.
|
|
|
"username": ["echo","foxtrot"],
|
|
|
"scope": ["subnet4*","subnet6-del","subnet6-update"],
|
|
|
"param": {
|
|
|
"id": 5
|
|
|
}
|
|
|
}
|
|
|
```
|
|
|
|
|
|
This mechanism could be generic (if `param` is specified, for each entry on its list check if the parameter is present in the API call being considered. If all of the are, we can apply the rule).
|
|
|
|
|
|
# 4. Obsolete pages
|
|
|
|
|
|
- [initial wrapper discussion](https://gitlab.isc.org/isc-projects/kea/-/wikis/designs/https-wrapper-for-control-agent-discussion) - this was the initial discussion page back when we still considered writing a wrapper around Kea. It's obsolete, because #1619 proved that native TLS implementation using Boost.SSL library is viable.
|
|
|
|
|
|
- [wrapper impl discussion](https://gitlab.isc.org/isc-projects/kea/-/wikis/designs/https-wrapper-for-control-agent-solution) - obsolete. See #1619 explanation above.
|
|
|
|
|
|
# 5. Native TLS Implementation (done)
|
|
|
|
|
|
The implementation takes use of Boost.SSL library, providing nice ASIO layer abstraction above OpenSSL. The following tasks will be needed to complete this goal:
|
|
|
|
|
|
1. #1619 - experimental PoC implementation.
|
|
|
1. #1644 - preliminary cleanup of existing ASIO code to be able to support upcoming TLS socket
|
|
|
2. #1661 - TLS socket implementation, including asiolink and libhttp updates
|
|
|
3. #1662 - CA code extension (including parsers update, ability to open TLS sockets, load certs, etc.)
|
|
|
4. #1663 - extension of kea-shell to be able to establish both http and TLS sockets.
|
|
|
5. #1665 - attempt to extend the code to work with Botan.
|
|
|
6. #1664 - documentation (both ARM and developer's guide). The dev guide is particularly important, so other devs that are not experts in security could understand how to use the code and possibly extend it in the future.
|
|
|
|
|
|
Once those tickets are completed, Kea will be able to accept TLS connection using CA, while still offering legacy http connection for those who don't want to deploy TLS. The libhttp changes are particularly well suited adaptation in other areas, such as implementing http(s) capability in DHCP daemons (see experiments in #1315 and their follow ups). |