Skip to content

Latest commit

 

History

History
303 lines (187 loc) · 17.5 KB

SECURITY_SETUP.md

File metadata and controls

303 lines (187 loc) · 17.5 KB

Domoticz Security Setup

Applies to version: 2022.2 Beta's (14706) and up

This document describes the security options within Domoticz.

By default, any Domoticz installation gets a default User/Password for an admin user as basic protection for the netwerk it is placed in.

NOTE: First thing to do is changing the default password into something else!

Usually that network would be someone's private network at home, work, school, barn, car, etc. And for many, if not most, use-cases that is sufficient and what we want. The goal is to measure and control things within the local environment.

But it is a bad idea to connect any installation directly to the internet, as that would mean anyone anywhere can access Domoticz and control connected devices. Could be fun in some edge-cases, but most likely not what anyone would want.

The same applies for larger networks, for example a school or an office, where you do not want just anyone that has access to the network, also get access to Domoticz. Schoolkids would probably love it, but teacher and staff probably not :)

There are a number of 'components'/'functions' involved when it comes to Domoticz security:

  • Users
  • Trusted networks
  • Clients
  • Domoticz
    • The Domoticz User Interface (or website. The UI should be regarded as a client)
    • The Domoticz Resource server (core server that does all the magic)
    • The Domoticz 'IAM server' (Identity & Access Management) (actually part of the core server at the moment)
A graphical representation looks like this: (_Assuming the __Mermaid__ graph is rendered nicely_)
  flowchart TB
  subgraph sUI["User Interface's"]
    direction LR
    subgraph UIs
      DUI[Domoticz Web Interface]
      OUI(Any Other Web Interface)
      APP(Any Domoticz capable App)
    end
  end
  subgraph sCORE[Domoticz Core Services]
    direction LR
    subgraph Services
      RSRV[Resource Server]
      IAM[IAM Server]
    end
    DB[(DataBase)] -.- Services
  end
  sUI -- "Use, but only with valid Token!" --> sCORE
  subgraph exIAM[External IAM Services]
    IM(Identity Managemement)
    AM(Authorization Management)
  end
  sUI -. "Could use to request access Token" .-> exIAM
  exIAM -. "Has trust relation with" .- sCORE
Loading

Isn't Domoticz just 1 Application?

Yes and No :)

From a User perspective; often Domoticz is considered as a single application. Until the point where users start using alternative 'tools' to access/control their Domoticz setup.

For example when using an alternative- and/or additional Dashboard. An additional 'application' gets installed and is connected to the existing Domoticz installation.

Same goes for example when a user starts to use a (native) mobile app. The Users installs an additional app on a mobile device and connects it to the Domoticz installation.

In all these case, the Resource server stays the same, but we change the UI. Or just add more UI's that can be used depending on the situation.

From a development architectural perspective; different parts of the Domoticz project/installation are used in different ways and situations.

The core part, the Resource server is always used. It is the heart of the system that holds and controls all devices and data.

Depending on the User(s) environment 1 of more different User Interfaces (UI's) are used to interact with the resource server. Each of those different UI's is called a client. And a standard Domoticz installation comes with a default client, the web UI.

When a Domoticz setup becomes either more complex, gets more users, needs connection to the Internet or other less- or insecure networks, it becomes neccessary to add SECURITY. This is where the functions and features of the IAM server comes into play.

IAM server

Domoticz has a build-in IAM service (part of the core server at the moment) that can be used to handle Identity (Authentication) and Access (Authorization) Management. Here we can define Users and their (access)rights for a (single) Domoticz installation.

But often in larger/complex environments, there usually already is a more centralized IAM service, for example a Windows AD (Active Directory) Server or KeyCloak or a Cloud based solution like AWS Incognito or Microsoft's Azure AD.

Also in modern (Hybrid) Cloud environments, a more centralized IAM service is often in place.

Using a centralized IAM service, instead of the internal IAM server of each Domoticz installation, makes it much easier the do the on-and offboarding of Users, granting and revoking rights, etc. Also Single Sign-On (SSO) to different applications including one- or more Domoticz installations becomes possible.

And thanks to modern (web)standards like OAuth2, OpenID Connect, etc. different IAM Services and servers become interchangable and interopperable, making the life of sysadmins a little easier.

Due to the now build in support of those standards, Domoticz can become integrated in such environments.


Add user-management

A first step is to further leverage 'User-Management'. User-Management add's a first layer of security by requiring possible users to identify themselves before they get access.

Using the menu 'Setup/Users', additional users can be added to the system.

NOTE: It is not a problem to remove the default admin user. But this means that when no other users have been defined, User Management is turned off an now anyone can access Domoticz and gets admin priveleges!

TIP: Start with creating a new admin User by giving the user Admin priveleges! So you always have a user to fall back upon if something goes wrong.

RESCUE TIP: In case that access to the UI has been lost because no valid (admin) User credentials are known, it is possible to regain access by stopping the Domoticz services and restart it with the -nowwwpwd option. Now the missing passwords can be reset. Make sure Domoticz is restarted once more but now without this option to re-activate User-Management.

Add trusted-networks

Users coming from a 'trusted network' do not need to identify themselves.

But when coming from 'outside' a trusted network, Domoticz will require the user to authenticate.

In 'Setup/Settings' on the security tab, there is a section called 'Local Networks' where IP-addresses and IP-ranges (with wild-cards) can be entered. This ; (semicolon) separated list is used by Domoticz to allow requests coming from clients with an IP-address that falls in one of the listed ranges, to access Domoticz without the need to provide valid credentials.

NOTE: Although this functionality seems very handy for easy access to Domoticz for example for scripting and connectivity reasons, it is easy to overlook the possible risks. It is prefered/safer to make sure that scripts, etc. use valid credentials. This has become easier with the use of tokens, so no need to store user credentials in scripts and pass them over the network with each request.

Add clients

(Applications/UI's that want to communicate with the Domoticz Server)

Next to normal User Management, it is also possible to register clients. Clients are 'applications' that would like to interact with the core Domoticz server to retrieve information and/or perform actions. These applications should/could do so on behalf of registered Users.

Examples of clients are web applications like Dashticz, Reacticz, mobile apps like Domoticz mobile (Xamarin or Android), Domotix, Pilot Home Control or SaaS services as myDomoticz.

Why do we need clients? Basically by having Users with a username/password, we created a way to secure the use of Domoticz resources. A given user can be restricted to do only a given number of actions. But the User uses a client (an application) to perform these actions on his/her behalf. The standard Domoticz UI being one of them.

When the Users wants to use other clients as well, the clients also need the Users username/password to perform actions on Domoticz resources (through interaction with the Domoticz resource server.)

The problem is 'how to trust all these clients?'. Putting your Domoticz User credentials into a nice app you just installed on your mobile or found as a SaaS service or installed yourself, etc. makes these credentials open to (un)intentional leakage. Once these credentials are leaked, they could be used by any random client.

Therefor it is better to tell the 'Domoticz resource server' which clients are allowed to ask for access on behalf of a User when providing User credentials.

Under 'Setup/More Options/Applications' it is possible to add/modify applications that Domoticz may trust to give access to resources on behalf of a user.

The information from an application is used by the IAM Service when handing out Tokens to clients (applications) on behalf of an (authorized) User.

Generating secrets for clients

To be able to generate and sign secure tokens, each client needs to have some kind of secret.

Such a secret is used to digitally sign the tokendata and is also used to validate if a token is valid.

It is possibe to specify a secret as a passphrase which will be used both for signing and validation. As both the IAM server (for signing) and the Resource server (for validation) need to know this secret, it is not considered the most safe option.

It is better to use a public/private keypair where the private key is used to sign the token (by the IAM server) while the public key is used to validate it (by the Resource server).

At the moment of writing (2022), an RSA-PSS (Probabilistic) based keypair using 3072 bits key generation is considered quite safe for the coming years.

See below how to generate such a keypair (in PEM format):

openssl genpkey -algorithm rsa-pss -pkeyopt rsa_keygen_bits:3072 > [_yourpemfile_].pem

openssl rsa -pubout -in [_yourpemfile_].pem >> [_yourpemfile_].pem

In cases where token generation and signing is done by an external IAM service, only the public key has to be made available for the client in Domoticz.

Connecting Domoticz to the Internet/Cloud

More and more, Users are looking into ways to control their Automated Home from a distance. So preferably through the Cloud. So the Domoticz setup somehow needs to be accesible outside the safe environment of the Home.

This means there is a need to have some kind of application (a client) that can access the resource server to perform actions or exchange data.

The resource server always has to be in the Home (local) as here it can safely be connected to the devices it controls. Putting the resource server in the Cloud would mean that all communication between Domoticz and the devices would have to go through the Cloud. That is not a wanted scenario as it poses numerous security risks that are almost impossible to mitigate. And probably not even possible with some/most hardware devices.

That leaves only the client as a candidate to make it accessible/run in the Cloud.

And to make sure that the client can safely interact with the (local) resource server, this communication has to be secured. Using Identity and Access Management (IAM) is a good way to secure interaction with the resource server.


Supporting web standards

Domoticz tries to leverage best practices and (RFC) standards where possible. Sometimes not all details of each standard are fully implemented or honoured, but we should be as close as possible and fitting with Domoticz as possible. Any diversion, etc. should be well documented (and explained probably).

OAuth2 support (RFC6749)

At the moment a few flows/grant_types are supported:

  • authorization_code
  • authorization_code with PKCE
  • password
  • refresh_token

The implicit flow is not implemented as it is not secure. But using authorization_code flow with the PKCE extension is also possible now. PKCE stands for Proof Key for Code Exchange.

We do not support client_credentials flow as we do not want 'anonymous' access by a client/application.

To see the details of what is supported by the current IAM Service, the specification can be requested through the well known OpenID Configuration endpoint at https://<yourdomoticz>/.well-known/openid-configuration which will return something like:

{
    "authorization_endpoint": "https://domoticz.local:8443/oauth2/v1/authorize",
    "code_challenge_methods_supported": [
        "S256"
    ],
    "grant_types_supported": [
        "authorization_code",
        "password",
        "refresh_token"
    ],
    "issuer": "https://domoticz.local:8443/",
    "response_types_supported": [
        "code"
    ],
    "token_endpoint": "https://domoticz.local:8443/oauth2/v1/token",
    "token_endpoint_auth_methods_supported": [
        "client_secret_basic"
    ],
    "token_endpoint_auth_signing_alg_values_supported": [
        "PS256",
        "RS256",
        "HS256",
        "HS384",
        "HS512"
    ]
}

Tokens

There are 3 types of tokens

  • authorization code
  • access_token
  • refresh_token

authorization_code flow (with PKCE)

This is the flow that should be used in almost all cases. Preferably using the PKCE extension as it is even more secure.

This flow returns an access_token and an refresh_token but only in the cases where the authorization_code has been given to an registered client application on behalf of an known users. If the authorization_code has been created based on only a registered User, no refresh_token is generated.

password flow

Using the password flow, one can get an access_token without the need to first obtain an authorization_code by just provider the username/password of a user.

The password flow does NOT return a refresh_token, only an access_token.

Although this flow is not really regarded as safe, as in essense it is as simple as a normal login by providing a username/password, it is offered especially for local automation use-cases. For example for having scripts, etc. being able to communicate with the Domoticz server without the need to send the username/password of a user with each individual request.

Instead it can provide a username/password once to obtain an access_token and than use this access_token till it expires. No need to provide the username/password in the meantime.

Proper scripts,etc. should behave like real clients and use the authorization_code flow instead.

TO-DO? Not implemented yet, but it probably better to limit the password flow only to 'users' (scripts, etc.) that are within in trusted network. Otherwise the password flow would also be available for use by 'users' that live outside trusted networks like the Internet.

Using refresh_tokens

The goal of refresh_tokens is to get a new access_token, for example when an access_token has expired, without the need for the User to authenticate again to get a new authorization_code to exchange for a new access_token.

Instead by providing a (valid) refresh_token, a new access_token and refresh_token are handed out immediatly.

A refresh_token also has an expiration date/time (24 hours), but that is much longer than the life-time of an access_token (which is 1 hour).

The use-case is for clients that keep communicating with Domoticz for a longer period of time, for example a Dashboard like Dashticz. Without a refresh_token, the Dasboard would require the user the re-login every hour. (Or in a bad implementation, store the users credentials and re-use them each time to re-login).

Now only at start-up, the Dashboard has to ask for the users credentials and provide these to obtain an authorization_code. After that the user credentials are never needed again. Unless the Dashboard has stopped working and the latest refresh_token has expired. Then the user has to re-login as a safety measure.

PKCE extension (RFC7636)

Proof Key Code Exchange (pronounced "pixy") More secure auth_code flow for public clients (alternative to depricated implicit flow).

OpenID Connect (OIDC) support

OpenID Connect adds additional best practices and standards on top of existing standards like OAuth2 and JWT.

At this moment, some OIDC parts are implementend, like support for

  • well-known end-point discovery

But other parts like ID Tokens for example are not. Also not everything is fully compliant (yet) with OIDC, but some useful pieces are available and can be leveraged.

JWT support (RFC7519)

The access_token returned is a so-called JWT (Json Web Token) containing all kind of relevant information and is tamper-proof because it has been digitally signed.

More reading

https://developer.okta.com/blog/2019/10/21/illustrated-guide-to-oauth-and-oidc

https://developer.okta.com/blog/2019/05/01/is-the-oauth-implicit-flow-dead

https://blog.postman.com/pkce-oauth-how-to/

https://datatracker.ietf.org/doc/html/rfc6749

https://datatracker.ietf.org/doc/html/rfc7636

https://datatracker.ietf.org/doc/html/rfc7519


Future developments and other options

Thanks to the support of open standards like OAuth, JWT, OIDC, etc. it becomes possible to use/integrate Domoticz into environments that use single-signon for example. Also it is possible to use external User Management for example by using an Azure AD, AWS Cognito, API Gateways or Microsoft Active Directy and Federation Services, Okta Identity or Red Hats KeyCloak (or FreeIPA), etc.

Scenario's where a central IAM system provides the User Management functionalities and hands-out the correct tokens, that than can be used by (local) Domoticz Servers. For example when managing multiple locations and installations of Domoticz.