User creation/management on initial start of openHAB on Docker/Kubernetes

Dear community,
I’m pretty old openhab user (since 1st version) and for a long time I’m using Docker version on top of my Kubernetes cluster (Rancher’s K3S). For some time I’ve been trying to improve all the automation as much as possible (all of my configs are done via files, stored in git, secrets/configs are being manipulated via executing scripts before openhab starts). Basically I can completely destroy even whole cluster and could bring back everything via running a single command (there’s bunch of other stuff running on cluster and I’ve been able to automate everything except two workloads, openhab is one of those :slight_smile:). Only thing that I’m currently missing and I can’t find a proper way to achieve that - initial users creation, since karaf is not running when init scripts are executed / users.json is not existing yet, etc. I understand, that this is not applicable to all users and this is kind of advanced setup which is definitely not a priority and I fully understand that evolution of openhab is moving towards having everything configured via UI and supporting textual configuration is not in priority as well.
I’d really didn’t wanted to have custom image and use either init-containers or upper mentioned option for customization. Does anyone face the same issue, has solution for such case?

P.S> If you guys are interested to get more regarding my setup - feel free to ask, I’m not planning to publish everything yet, cause just dropping multiple thousands lines of yaml/python/bash would create more questions then answers :smiley:

Hi @ypyly,

the K8s approach might be quite challenging … but I’m interested in you results.

Regards, Guenther

results are already in-place - I’m running openhab on kubernetes for more than two years now :slight_smile:, started with 2 and migrated to 3 (approx a year ago), now I’m trying to improve my overall configurations, since I’ve moved abroad and left most of my hardware at my home country, so building automation almost from scratch (except rules :wink: )

1 Like

Well, the opeHAB users are stored in jsondb/users.json, problem is: password is hashed and salted.
If karaf is already running, you can use it to create the user:

openhab:users add <your username> <the password> administrator

where administrator is the role of the main user.
You might add some other more restricted users with the same command but role user instead.

Hi @Udo_Hartmann , thanks for the suggestion, I’m aware about the way of adding users/api keys etc via karaf, the problem is, that during init scripts karaf is not yet running and on the first run jsondb/users.json doesn’t exist yet.
to get jsondb/users.json created, you still need to run initial setup via UI and I’d prefer to get it configured without a single manual interaction, so even I would be able to properly hash and salt the password, it wouldn’t still be in use before manual init setup via UI.
one of the ideas that I was considering is to create additional kubernetes job which will connect to karaf, check users/api keys and propagate it with necessary objects if needed, but for this approach, I’ll need to open karaf to the cluster/namespace, which is insecure and I’d prefer to avoid it :confused:

Ah.

But you can use secure login to karaf as well.

You will need to delete the openhab user for login (at least I haven’t found a way to restrict login to karaf to publicKey in another way)

In file $OPENHAB_USERDATA/etc/keys.properties add a line like this:

karaf=AAAAB3NzaC1kc3MAAACBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAAAAFQCXYFCPFSMLzLKSuYKi64QL8Fgc9QAAAIEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoAAACBAKKSU2PFl/qOLxIwmBZPPIcJshVe7bVUpFvyl3BbJDow8rXfskl8wO63OzP/qLmcJM0+JbcRU/53JjTuyk31drV2qxhIOsLDC9dGCWj47Y7TyhPdXh/0dthTRBy6bqGtRPxGa7gJov1xm/UuYYXPIUR/3x9MAZvZ5xvE0kYXO+rx,_g_:admingroup


_g_\:admingroup = group,admin,manager,viewer,systembundles,ssh

karaf is the user, = is delimiter to public key, AAA...+rx is the public key, , is delimiter to permissions, _g_:admingroup is the actual group for this user.
Be aware of the last line, were the group is defined.

In file $OPENHAB_USERDATA/etc/keys.properties delete the line for user openhab (or give it an ridicoulously complex password)
Open the karaf to ssh from remote in file $OPENHAB_USERDATA/etc/org.apache.karaf.shell.cfg by setting sshHost to 0.0.0.0

After starting karaf, it should be possible to login with the private key.

1 Like

that’s one of the options I was thinking about, still, karaf is available only after the openhab is started, which a bit contradicts with the idea of having pre-start configuration adjustments like using scripts in /etc/cont-init.d (which I kind of like).
to be honest, my current ideas are:

  1. override entrypoint with copy of the current one + direct calls to karaf for users/groups/keys propagation after full startup of openhab
  2. build custom openhab image with all I need straight away included
  3. create kubernetes job that will be from time to time monitor upper mentioned resources and adjust it if needed via karaf/bash
  4. create a sidecar, that will be doing same stuff as 3. constantly
    I don’t like any of those options tbh as they are a bit overkill :slight_smile:
    Since I haven’t found any other native method, I thought I might be missing something.
    Anyway, if I’ll succeed with entrypoint, I’ll potentially rise a PR that would not disrupt any of the startup processes, but will just add a user/credentials using karaf based on the existence of env variable (not sure if it will going to work or it will still request initial setup from the UI, but I’ll check it up soon)
    In case you know any other native method that could be completed on initial setup (not after the container is already running) please let me know, thank you in advance

I’ve created an init script which will just copy the json file to the destination.

if [ ! -e /openhab/userdata/jsondb/users.json ]
then
    mkdir -p /openhab/userdata/jsondb
    cp /etc/files/users.json /openhab/userdata/jsondb/users.json
fi

The users.json file in etc/files is just a copy of a one time manual setup I did in a local docker container so I could get out the correct hash and salt

{
  "pi": {
    "class": "org.openhab.core.auth.ManagedUser",
    "value": {
      "name": "pi",
      "passwordHash": "***",
      "passwordSalt": "***",
      "roles": [
        "administrator"
      ],
      "sessions": [],
      "apiTokens": []
    }
  }
}

thanx for the suggestion, however openhab fully ignores users.json, until first user is created via UI.
Just tried it once again:

  1. Freshly installed openhab
  2. users in-place:
    2022-12-27 14_06_38-Lens
  3. users are not present in karaf (and not able to do anything)
    2022-12-27 14_07_26-Lens

Did you reboot or restart openHAB? I’m pretty sure that users.json is not checked for changes.

I just did a fresh install on a new SD card and the first time I started the Docker image, my script ran, copied the users.json and I was able to log in using that user.

sorry for bringing the old topic back to life, unfortunately I’m not having too much time lately for my hobbies
that approach was not working for me, however, here’s the one that worked (part of my init-scripts):

    if [ ! -e /openhab/userdata/users.check ]
    then
      /bin/bash /openhab/runtime/bin/start
      sleep 40
      ssh -o "StrictHostKeyChecking=no" -i ${KEY_LOCATION} karaf@${OH_HOST} -p 8101 "openhab:users add ${OH_USERNAME} ${OH_PASSWORD} administrator"
      touch /openhab/userdata/users.check
      /bin/bash /openhab/runtime/bin/stop || true > /dev/null 2>&1
      sleep 40
    fi

sorry for being lazy and using sleeps instead of loops and checks of the processes running/ready/stopped, hope it might help some folks that are having same approach as I do :slight_smile: