Sockets from balenaOS container

hello all folks,

I’d like to know how can I access a couple of unix sockets from inside a container.
I have a process which creates two unix sockets on /tmp on the balenaOS and I want to make them accesible to a container.

I have tested this approch in my dockerfile:

version: "2"
volumes: 
  tmp:
services:
  balena-owasys-pollux-gps:
    build: .
    privileged: true
    volumes: 
      - '/tmp:/tmp'
    labels:
      io.balena.features.balena-socket: '1'
      io.balena.features.dbus: '1'
      io.balena.features.sysfs: '1'
      io.balena.features.procfs: '1'
      io.balena.features.kernel-modules: '1'
    environment:
      - 'DBUS_SYSTEM_BUS_ADDRESS=unix:path=/host/run/dbus/system_bus_socket'

but I got an error saying that bind mounts are not possible.

any help would be much appreciated.

Thanks!

Any ideas on this?

I’ve also tested this approach to mount /tmp without success:

    services:
      myservice:
        volumes:
          - hosttmp:/tmp
    volumes:
      hosttmp:
        driver_opts:
          type: none
          o: bind
          device: /tmp

Hi, which process’ sockets you need to access?

BalenaOS is a lightweight hypervisor OS which tries hard to isolate the hostOS from the containers apps. There are standard interfaces for applications to access a selected set of hostOS functionality (dbus and feature labels), and bind mounts is not one of them.

If you explain your use case with details we will very likely be able to suggest what the right approach is.

Hello, thanks Alex.

I’ve got a couple of unix sockets created on /tmp by a process needed by our owa5X. This sockets are the gateway for a power manager process to communicate with a little uC that handles power features on the HW.

Besides, some others non-mandatory processes of ours also need those sockets and I’m trying to use them from a balena container.

Thanks

Also, I’m just simply unable to run a container in local mode as Privileged.
When I examine the created container with

balena inspect contander_id

I just see Privileged false

Any thoughts on this?

BR

I’ve got a couple of unix sockets created on /tmp by a process needed by our owa5X

The first thing that comes to mind would be modifying the process to expose a local socket instead that could be accessed from a container running in the host network. Or using socat or similar to proxy the unit socket to a network socket.

If that does not work, as you are the maintainers of that device type, you could PR the bind mounting of that specific unix socket into containers.

I’m just simply unable to run a container in local mode as Privileged

Let me look into that and come back to you.

I think PR those bind mounting would be the best option for us. Is there any reference of that kind of PR to be able to look at?

Thanks Alex!

I think PR those bind mounting would be the best option for us. Is there any reference of that kind of PR to be able to look at?

Actually that’s not going to be an option. You could PR a hostOS bind mount, but you actually need an application bind mount which the supervisor would need to provide.

So, if modifying the service to use local/network sockets is not an option, the only other bad technical solution which would introduce security concerns would be to use the engine socket to access the unix socket on the host, or to directly mount the physical device where the unix socket is located from a container with enough privileges to do so.

I’m just simply unable to run a container in local mode as Privileged

That’s not something I can reproduce. If I push a multicontainer application with a privileged service in local mode, the service remains privileged.

Could you maybe provide reproduction steps with a simple app like the one in the getting started?

I am attaching the output of balena inspect frontend multicontainer example and the container unable to be ran in privileged mode.

Do you see smth interesting?
multicontainer-frontend-inspect.log (11.6 KB)
pollux-gps-inspect.log (9.7 KB)

Hello!

We are still in the dark with this issue. Could you elaborate on using the engine socket to access the unix socket on the host?
Any example, reference or use case that I can take a look at?
Do you mean using socket labels in the docker-compose file?

We’ve got customers awaiting a solution for this.

Thanks in advance

Hi,

Yes, using the socket label you can expose the engine socket to a privileged container in the application and use it to have root access to the hostOS.

An example service that runs commands on the hostOS can be:

  bootparams:
    image: docker:27.3.1-cli
    restart: on-failure
    cap_add:
      - SYS_ADMIN
    labels:
      io.balena.features.balena-socket: '1'
    entrypoint:
      - /bin/sh
      - -c
    command:
      - |
        set -ex
        HOST_CONTAINER_NAME=host-chroot

        function host_cmd() {
          if [ -z "$(docker ps -qf "NAME=$HOST_CONTAINER_NAME")" ]; then
            docker run \
              --interactive \
              --tty=true \
              --detach \
              --rm \
              --name="$HOST_CONTAINER_NAME" \
              --volume=/:/host \
              alpine
          fi
          HOST_CONTAINER_ID="$(docker ps -qf "NAME=$HOST_CONTAINER_NAME")"
          docker exec "$HOST_CONTAINER_ID" chroot /host bash -c "$*"
        }

        host_cmd echo "Running on host"
        docker stop "$(docker ps -qf "NAME=$HOST_CONTAINER_NAME")"

Be aware that root access to the hostOS is a security hazard. My advice would be to use it as a one time container to perform some initial configuration so that it is not running all the time.

As I mentioned before, the correct approach would be to modify the service to use local/network sockets, and this solution should only be used if that is not possible.