Architecture Design Record - Event publishing authorization¶
Problem¶
Elos is designed to publish events from elos-clients or scanner-plugins to interested subscribers. How to ensure only authorized client can publish certain events?
Goals¶
avoid exploitation of the event logging system to trigger certain system behavior by unprivileged access.
i.e. Provides a wrong system view by injecting events
trace and/or detect possible intrusion
Assumptions¶
Tcp/Ip is required as API-Interface
Unix Domain Sockets are possible as further API-Interface (i.e. earlier available as Tcp/Ip when it comes to booting things up)
remote access to elosd API is required in future
a third party authentication instance is possible, identity service
incoming events via internal scanner-plugin-API are treated as trust-able.
Rationale: scanners are loaded as
*.so
files into the elosd process. Hence they have full access to any data of the process and further protection is pointless.
Excluded¶
How to ensure only authorized subscribers can subscribe to certain events?
This ADR does not cover handling of sensitive data that need a confidentiality protection (i.e. keys in coredumps, syslog entries with security sensitive data). This aspect is left to another ADR.
in this ADR we assume that any one can read every event
Transport Layer Security
communication can be plain text
this ADR consider no efforts in encryption of communication channels
no authentication of subscribers
Remote event transfer
in this ADR it is assumed that elos handles only local events. No event is crossing the network wires. This would be part of another ADR.
Solution¶
For elos we divide the publishing clients in “privileged” and “normal” clients. Each event has a classification field which can be used by the integrator to mark critical events. ( Hint: The idea is to mark critical events as such by the publisher and expect the subscriber to subscribe or at least to check for the appropriate classification flags in an event.) Elosd gets configured to blacklist all events matching a certain event filter to drop all attempts of publishing events marked as critical from an non secured channel.
So if a client tries to publish a critical message elos will only dispatch it if the channel is secured. Subscribers can rely on the fact that events with security classification flags are only published from privileged and authorized clients.
Privileged Client¶
Privileged client must be authorized and hence needs some authentication. To permit publishing of black listed events a client must be authorized and therefore the communication is treated as secured.
On a secured communication it is allowed to send any event, no blackList will be applied. In a later development stage it could be allowed to send only configured events. This could be done by RPN-filter rules per client like AccessControlList for events.
To assume a secured communication a client must be authenticated. Currently the following three approaches are thinkable: A) Trusted channel: authenticate the local client process connected via UnixDomain socket / localhost tcp/ip ( only system local) B) Certificate: authentication via public private keys (allow remote systems) C) Token: A third party (identification service) takes over the authentication and authorization (allow remote systems)
Trusted channel¶
Trusted channel is the working title for a authentication / authorization method, that tries to identify the connecting process. This approach only works on local system as it assumes integrity of the channel and reliable detection of endpoints. The goal is to gather the following set of information about the connecting process:
UID -> effective user id of the connecting client
GID -> effective group id of the connecting client
PID -> current process id of the connecting client
determined at runtime during connecting and is necessary to identify the process in procfs
with
/proc/${PID}/*
-> many additional information about the connecting process which can be used to authorize the connecting process. In example the name of the process or the link to the original executable file.
The method to obtain the necessary process information differs for the two considered interface types Tcp/IP and Unix domain sockets.
Unix-sockets¶
For STREAM Unix socket bound to a path name we can use the following options for authorization:
The Linux sock_diag module via netlink API to query UID,GID and PID. With the
getsockopt
call this can be simplified togetsockopt(clientSocket, SOCK_STREAM, SO_PEERCRED, &creds, &creds_length);
.Unfortunately this is very Linux specific, but until nothing other is specified we can use it by enabling
_GNU_SOURCE
for this part.The Unix socket must be bound to a path, for unnamed or abstract Unix socket this setup will probably not work.
local Tcp/ip (loopback interface)¶
To authorize local Tcp/Ip connections we need also to identify the connecting process.
This requires:
root privileges for elos or a process to make the actual lookup for elos
The peer address must be bound to a local interface (127.0.0.1) , in a later stage also the public interface could be allowed if necessary
The actual process lookup is can be done by either calling netstat
or ss
or
any equivalent tool. But preferably the kernel interface used by tools like
netstat
shall be used directly. See therefore /proc/net
and sock_diag
.
Final step¶
Now it is possible to match the process information against a set of rule set defined in the configuration:
"trustedProcesses" : {
"<client name | identifier>": {
"uid": 0,
"gid":0 ,
"executable": "/bin/crinit"
}
}
Or by reuseing RPN-Filter:
"trustedProcesses" : {
"<nameOfExecutable>": [
".uid 0 EQ .exec '/bin/crinit' STRCMP AND",
".uid 0 EQ .gid 0 EQ AND"
]
}
and decide if the client can be treated as privileged.
Conclusion¶
pro:
Can be done without changing the protocol or adding any overhead to it cons:
the lookup could be time consuming
Rational: but usually only one lookup per connection should be feasable
works only for local processes
authorization via certificates¶
To authorize a connecting client it shall be sufficient to know that the client can prove its identity. This can be done by using certificates. Common certificate based socket communication protocols focuses on the tcp/ip interface, but it shall be possible to use them also via unix domain sockets.
The authorized entity is the process which have access to the certificate and key. Thus a successful handshake and established secure connection proves that the client is authorized to publish classified events. Certificates usually authenticate a certain domain name, this can be used to distinguish between different clients. The configuration for cetificate based authorization would be based on domain names and could look like:
"trustedProcesses": {
"com.emlix.asecureapp":{
"cert": "/etc/elos/client_certs/asecureapp.crt"
},
"com.elektrobit.an.evenmore.secureapp":{
"cert": "/etc/elos/client_certs/amoresecureapp.crt"
}
}
how to authorize a publisher¶
Usualy certificate based authorization comes with encrypted connections and a special connection. This requires a second socket, where elos expects to create a secured connection. The process of authorization shall be as follows:
client connect to secure Tcp/Ip or Unix socket i.e 128.0.0.1:5432 instead of 127.0.0.1:54321 or /run/elosd.ssock instead of /run/elosd.sock
elosd accepts incoming connection and initiate handshake (https://wiki.openssl.org/index.php/Simple_TLS_Server) 3a. if successful flag connection as secured and trustable and if needed store domain name 3b. if unsuccessful drop the connection and issue an appropriate event
start communication as usual but be sure to use ssl_read/ssl_write methods
continue until connection is closed
Summary¶
pro:
with TLS this uses commonly used technology, proven in use
less complicated to implement and to prove security then secure channel approach
allows to authenticate and authorize remote clients
cons:
needs two sockets (secure and unsecure)
needs rework of current connection handling in elos
due to the encryption a overhead can be expected in for event publishing as for connecting to elosd
probably increased start time due to loading of certificates
needs certificate and private key infrastructure.
How to issue them
How to revoke them
How to deploy them
How to store keys securely
authorization via token¶
Regardless of the actual choosen implementation of a token based authorization it would work the following way. The token based approach extends the elos protocol by an additional field containg a token, which was created by a third party service. The client previously proves its authentiy against some identity service and got the token in exchange. The identity service and elosd shares some common secret. This way elosd can decode the token and verify the client has authorized itself on some identification service.
The token can contain additonal information see JWT (JSON WebToken JWT.io) for example.
Elosd needs to manage at least one key to verify the tokens. A configuration could look like:
"eventAuthKey" : "/path/to|or directly the key"
Summary¶
pro:
implementations like JWT are proven in use
allows to authenticate and authorize remote clients
allows to store costom additional information in a token
cons:
elos protocol must be changed
needs rework of current connection handling in elos
overhead of token length in each elosd paket
needs additional infrastructure.
identity service
How to revoke tokens
How to store keys securely
Normal Clients (current status)¶
Normal clients doesn’t need any authentication or authorization. All connections of normal clients are treated as non-secure and hence need filtering of black listed events.
Configurable elements¶
To manage privileged an normal clients two configuration items are necessary:
for secure clients: (Certs, Token) or a tuple of (UID, GID, ELF-Path)
"trustedProcesses" : {
"<client name | identifier>": {
"uid": 0,
"gid":0 ,
"executable": "/bin/crinit"
"cert": "/etc/elos/client_certs/..."
"token": "yxzkjlsdj87238..."
}
}
for normal clients: a BlackList defined as RPN-Filter i.e. blacklist all as ‘Security’ classified events:
"EventBlacklist" : ".event.classification 0x4 EQ"
The blacklist filtering¶
For the blacklist filtering approach there are to variants possible, when to check for a privileged clients.
check on establishing of connection
If the client connection is authorized, the blacklist check can be skipped. If the client is not authorized (normal client) a black list check must be performed on each incoming event. If the client is not authorized and the event hits the blacklist, the event is dropped.
check on receive of blacklisted event
Each event is checked if matches the blacklist and if the blacklist matches it is checked if the client is privileged, otherwise the event is dropped.
The attempt of sending a classified event from a normal client will create a new event tirggered by elos it self to broadcast the insident:
{
"date": [42,0],
"source": {
"appName": "elosd",
"pid": 1234
},
"severity": 3,
"hardwareid": "<hardwareid>",
"classification": 324,
"messageCode": 8007
}
The value classification
value is a concatenation of the flags elos|Security|IPC
.
Decision:¶
In both cases we have to match all incoming events from normal clients (not secure) against the blacklist. So the first solution gives us a little advantage in processing speed by skipping the blacklist check entirely for privileged clients (secure).
Thus we choose option 1 to implement the blacklist check. For client authentication approach A of privilieged clients is choosen.