Cannot configure openHAB docker to use port 80

Hi,
I’ve been using openHAB for around 2 years now, and I am very happy with it.
Currently, I am running into a problem which I cannot get sorted out myself, but maybe one of you can give me a hint.

I am running openHAB as a docker container.
I am running that container connected to a macvlan docker network. This assigns a distinct mac address (and IP) to the container and in turn I can assign that container a distinct name through my router.
So far so good: I can access http://openhab.local.net:8080 from my browser.

Now the tricky bit: I want to get rid of the port number.
I can control the port numbers by the environment variables of the docker run command:

docker run \
 --name=openhabTESTBED \
 --net=mymacvlan \
 --ip=192.168.2.197 \
 -e OPENHAB_HTTP_PORT=80 \
 -e OPENHAB_HTTPS_PORT=8444 \
 -v /etc/localtime:/etc/localtime:ro \
 -v /etc/timezone:/etc/timezone:ro \
 -d \
 openhab/openhab:2.4.0-amd64-debian

This works, but only as long as I don’t assign port number below 1024:
For the example above, I can open https://openhab.local.net:8444in my browser, but http://openhab.local.net just gives no connection.
I believe, this due to the fact, that these ports are considered “priviledged” and the executable trying to open such a port, needs special rights.

In order to give these rights, I tried two approaches. Both are based on building a new docker image from the official one, which allows me to run extra commands in the dockerfile.

  1. using “setcap”
FROM openhab/openhab:2.4.0-amd64-debian

RUN apt-get update && \
    apt-get install -y libcap2-bin && \
    setcap CAP_NET_BIND_SERVICE=+ep /openhab/runtime/bin/karaf && \
    apt-get clean
  1. using “authbind”
FROM openhab/openhab:2.4.0-amd64-debian

RUN apt-get update && \
    apt-get install -y authbind && \
    touch /etc/authbind/byport/80 /etc/authbind/byport/443 && \
    chmod 777 /etc/authbind/byport/80 /etc/authbind/byport/443 && \
    apt-get clean

Both approaches failed. When I run my individual image, I cannot connect to the server on port 80 (which is what I configured via the environment variable).

With approach 1., I presume that maybe karaf is not the executable, which needs to bind to the port - but which executable is it?

With approach 2., I have no clue why it is not working.

Uhh, yes. I wanted to go to bed after posting to the forum, but I prodded around a little bit more with approach 1.

FROM openhab/openhab:2.4.0-amd64-debian

RUN apt-get update && apt-get install -qq -y libcap2-bin && \
    apt-get autoremove -y && \
    setcap 'cap_net_bind_service=+eip' /usr/bin/tini && \
    setcap 'cap_net_bind_service=+eip' /openhab/runtime/bin/karaf && \
    getcap /openhab/runtime/bin/karaf /usr/bin/tini

The output from the docker build verified, that the capabilities are set, as they should be - this is the output from the docker build - the part with the response from getcap:

...
/openhab/runtime/bin/karaf = cap_net_bind_service+eip
/usr/bin/tini = cap_net_bind_service+eip
...

But once the docker is running, the karaf has not capabilities any more:

$ docker exec -it openhabTRY bash
root@f00a4f144eae:/openhab# getcap /openhab/runtime/bin/karaf /usr/bin/tini
/usr/bin/tini = cap_net_bind_service+eip

Is karaf modified when the container starts up?

Stupid question, but why don’t you just use “-p” to publish your port? something like

-p 80:8080

in your “docker run” should allow you accessing your OH instance without explicit port in the URL, and inside the container, the karaf process will not know of any change.

Hi Hakan - it would be great if it was that easy :slight_smile:. When using a macvlan network for a docker container, using -p port mappings is not possible. The reason I want to keep using the macvlan network, is that it allows me to have my own internal domain to access the service.

The ENTRYPOINT script recursively sets ownership on the /openhab directory which removes the setcap permissions previously set: https://github.com/openhab/openhab-docker/blob/b460365ce1fce91e044b3dd7e7dbdd2502d8b975/2.4.0/debian/entrypoint.sh#L140.

As a stop-gap so I could get Echo device discovery working via the Hue emulation add-on, I created a volume, mapped it to /etc/cont-init.d, and created a simple script:

apt-get update
apt-get install -y iptables
apt-get autoremove -y

iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
1 Like

Aaah, in that case we could move the “chown” step before the s6 init scripts. That way, one could create an init script that adds the setcap permissions back again after the chown…

I’ll try to come up with a pull request and an example for the setpcap in the README on monday or so. Ping me please if I forget it.

1 Like

Hey all,
I had time to do some further tests. Here are my (interim) results:

rgd. approach 2. “authbind”
I cannot get authbind to work as it should. I must be missing something. I create a 80 file in /etc/authbind/byport and no matter how freely (777) or restrictively (user:group openhab:openhab, 500) I configure permissions, OH UI never shows up on port 80.

rgd. approach 1. “setcap”
More luck here :smile:.

  • I found out, that giving capabilities to karaf does not help (I did this by adding it in the entrypoint.sh after the chown). OH UI does not come up on port 80, even when the capabilities are set for karaf.
  • What works though (and what it probably not at all good security-wise) is to give capabilites to the java runtime:
    setcap 'cap_net_bind_service=+ep' /usr/lib/java-8/bin/java
    I have build my own tiny dockerfile, which adds this step as another layer on top of the original OH image, so it gets quickly reproducible:
FROM openhab/openhab:2.4.0-amd64-debian

RUN apt-get update && apt-get install -qq -y libcap2-bin && \
    apt-get autoremove -y && \
    setcap 'cap_net_bind_service=+ep' /usr/lib/java-8/bin/java

:warning: I have not yet tried my new “port 80” image productively. I have only seen the web UI come up and am hoping everything else will work as well.
I will give an update, once I have gathered more experience.

Nevertheless I would like to understand why authbind is not working for me. In case anyone has any pointers for that - it is greatly appreciated.
Also, feel free to comment if some of the things I did are not recommendable or make no sense.

Cheers,
-bastian

Just created a PR moving the chown step to an earlier place. Now, you should be able to add your setpcap just as an continuation script. You would still need to either have your own tiny dockerfile or have /etc/cont-init.d as a volume mount though. I don’t feel that it is very safe to distribute an image the by default gives those permissions to the JDK :grin:

1 Like

I don’t feel that it is very safe to distribute an image the by default gives those permissions to the JDK

I absolutely agree :slight_smile: