Hardening OH2 as a service on Windows 10

Im am running OH 2.2 as a service on a Windows 10 Pro box. My objective is to prevent bugs in OH or in Java to allow execution of code that would compromise my server box. It is probably not always possible to prevent execution of malicious code (e.g. with a DDOS payload), but I would like to prevent changes to my server that would persist through a restart of the OH service.

By default, the Windows service is created to run with LocalSystem rights. This would be akin to running OH (and java) as root on a linux box. Therefore, I have set it to run under the Localservice account. This is an account tailored for services to run with minimal rights. So far, so good. Seems to run OK.

I have my setup defined in .cfg files. Does OH need any file/directory write/create rights on its directory structure in this configuration?

Does running OH as LocalService secure my server against above mentioned potential vulnerabilities?

OH needs read write permissions on the userdata folder and it needs read permissions on the conf folder. I think that is it.

I don’t know as much about Windows permissions so can’t say definitively whether this would mitigate those vulnerabilities or not. I do know that depending on what bindings you use you may need higher level permissions as OH will need permission to read/write to COM ports and the like.

Once you get this working right it would be great if you wrote a tutorial in the Examples and Tutorials section.

[quote=“rlkoshak, post:2, topic:37434, full:true”]
OH needs read write permissions on the userdata folder and it needs read permissions on the conf folder.[/quote]
I am not so sure whether I even want to give it write permissions to the whole userdata folder. I think that would allow configuration through the front end, including installing the exec binding and that way opening up the execution of arbitrary code on the server. Since the front end is not secured, I think I would want to block front end configuration. I am not running it on a public network, but it is in a network with some IOT devices that haven’t seen updates for years (max! heating, energenie). I have a separate subnet for my IOT devices, assuming that they all can be vulnerable. That’s also where my OH server lives, I have a separate home server in a trusted subnet that handles backups etc.

I think windows permissions are not as granular as that it would control access to com ports. I have a zigbee usb stick on a virtual com port and that still works ok.

I guess I’ll just peek at the logs regularly to see what fails due to missing write privileges. If anyone knows about specific parts of the userdata folder that need write access other than for changing the configuration, let me know. For now I will just continue to run it a LocalService, in case it would need write access somewhere, I would need to configure a custom user account.

I found out that actually, the LocalService account doesn’t restrict the service to the extent that I would like. In particular, the service can still read and write at will. I noticed the events.log was still being maintained, and I could still install bindings from PaperUI. For now, I left it at LocalService, since I don’t see any reason why it should run as LocalSystem.

Restricting access further would require making a custom user group and user for OH. And then troubleshoot in case it (or Java) wouldn’t run. That was more hassle than I was willing to go through. So I decided on a different approach.

I decided to have the firewall block inbound connections to OpenHab from the network, and use Internet Information Services to set up a reverse proxy with authentication. I think this is only available on windows professional or better. So from “Programs and Features”, “Turn Windows features on or off”, I activated Internet Information Services. By default, not all components are installed, so I had to drill down into “security” and additionally activate “Windows Authentication”. From the web, I additionally installed URLRewrite and Application Request Routing.

In the configuration for the default server, I clicked the Application Request Routing icon, and under “server proxy settings” in the right pane, I clicked “activate proxy”. Below, I activated “reverse proxy” with the address of my server and port 80 (e.g 168.192.0.100:80). Then, in the default site configuration, I clicked the Authentication Icon, deactivated anonymous authentication and activated windows authentication. Under “server farms” I created a new server farm and set the server with the advanced configuration to 127.0.0.1 port 8080 (where openhab presents its web interface).

So now I am presented with a login screen whenever I want to go to the openhab web interface (on standard http port 80 now). Credentials are the same as my windows server user account. BTW, I never had Karaf available to the network, I only use it via remote desktop and a local terminal application. So now, Openhab and it’s web server are no longer openly exposed to the network, they are now proxied through IIS which presents a login screen. So any security flaws are not exploitable unless one passes the proxy, and I don’t have to prohibit configuration from the web interface since it is now password protected.

Optionally, one could also activate SSL encryption to further secure the session. I am leaving that out for now.

If you want to still use visual studio code remotely this is possible. For that, also basic authentication has to be installed and activated in IIS. In visual studio, you have to change the user settings to use the rest API for code completion and store the username and password. Note that (when not using SSL) credentials are then transmitted in cleartext over the network, so this is less secure.

Logs for one are in userdata on Windows.

An alternative approach would be to put OH into some sort of sandbox. Probably the easiest would be to run it on a VM which can give you more opportunities to isolate OH from the rest of the host. One can also use Docker (I’m pretty sure you need Windows 10 to run Docker though) which lets you very precisely control how things can connect and how they get exposed.

For example, You can set up the reverse proxy running in one Docker container and set up OH running in another one and only allow access to OH from the Reverse Proxy container and even prevent access from localhost.

There are lots of ways to do this sort of lockdown.