Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

host mode node red #391

Closed
swiss-R-user opened this issue Aug 17, 2021 · 2 comments
Closed

host mode node red #391

swiss-R-user opened this issue Aug 17, 2021 · 2 comments

Comments

@swiss-R-user
Copy link

Hi. I have a question regarding the "host mode" in node red. I plan to use the host mode in node red to access the bluetooth of my raspi in the future. I wanted to ask if there is any security threat using node red in the host mode (regarding the acessibility of my homenetwork from outside ).
Thanky for your answers.

@Paraphraser
Copy link

Here are some references that might help:

These days, the first part of the Dockerfile template is laid out as:

FROM nodered/node-red:latest-12 
USER root
RUN apk update && apk add --no-cache eudev-dev
USER node-red

Doing the update and add in a single RUN statement is more efficient.

Setting the user back to node-red fixes a bug introduced by PR70.


With that as background, let me try to answer your question.

When you run a container in non-host mode, it behaves like an independent computer. It has its own TCP/IP stack, IP address and listens to the container's ports. Traffic reaches the container's ports by arriving at one of the Raspberry Pi's network interfaces, is heard by Docker which is listening to mapped ports on the container's behalf, and is then routed (layer three) across the internal bridged network using Network Address Translation rules.

Using Node-RED as the example, the lines in its service definition:

ports:
  - "1880:1880"

are better viewed as:

ports:
  - "external:internal"

Docker is listening to the external (ie the Raspberry Pi's) port 1880 while the Node-RED process running inside the container is listening to the internal (ie the container's) port 1880.

When Docker receives a packet on port 1880 it gets the new destination port from the right hand side (the "internal" port), and figures out the destination IP of the container by inference (you can only have one external port 1880 at a time). The packet gets rewritten with the new destination IP and port, and is routed to the container.

When you take that same container and run it in host mode, the idea of the "independent computer" with its own IP stack and IP address disappears. The Node-RED process running inside the container attaches to the external (Raspberry Pi's) port 1880. Docker stays out of the way and no network address translation is involved. Up-to-date versions of docker-compose reinforce this by complaining if you try to use host-mode and port mappings in the same service definition.

There are swings and roundabouts:

  • If two containers want the same external port, only one can have it so using "host mode" for both containers loses the ability to resolve the port conflict using a Docker port mapping. You have to figure out how to tell one of the containers to use a different port.
  • Inter-container traffic can be slightly less efficient. For example, if Node-RED is in host mode while Mosquitto is in non-host mode then traffic between the two has to be routed and NATted. Conversely, if both containers are in non-host mode, they communicate directly across the internal bridged network in exactly the same manner as two computers in the same subnet connected to a common layer two switch.
  • Other issues like 127.0.0.1 which means "this container" when a container is in non-host mode, but "this Raspberry Pi" when a container is in host mode. A Node-RED container in host-mode will address Mosquitto as 127.0.0.1:1883. When both containers are in non-host mode, Node-RED will address Mosquitto as mosquitto:1883 where mosquitto is a host-name-to-IP-lookup mapping provided by Docker.

Now, why am I telling you all this? Because that's all that host-mode does. In particular, putting a container into host-mode doesn't give the container any particular privileges for other Raspberry Pi hardware such as Bluetooth. The changes introduced by PR70 definitely afford access to Bluetooth from the non-host-mode Node-RED container. The first reference link above shows that in action. Host mode will do nothing to change that.

There are good reasons for running a container in host mode. The one that comes up most frequently is if the container needs to participate in multicast traffic, and the most common example of that is multicast DNS (ie names like "raspberrypi.local"). Docker doesn't forward multicast traffic across the internal bridged network so, if a container needs to listen to or originate multicast packets, the only way to do that is host mode. HomeAssistant is a good example.

Some less-than-well-behaved containers also like to run in host mode so they can "sniff" the network interfaces to hear broadcast traffic. My personal view is that such things are "hacks" and, if that's the answer to your problem, you're asking the wrong question. But that's just me.

If a container does need access to particular hardware, there are ways to achieve it but there's a lot to wrap your brain around. See this gist for an example. The most I will claim for the content of that gist is that "it works" in the sense that my Octoprint container follows my 3D printer and that I have a rough idea of what is going on, but whether I really understand all the nuances is a very very open question.

In terms of security, containers are (supposedly) sandboxed and only have access to the things granted in their service definitions. But I'm no security guru so maybe processes running inside containers can be set up to break containment. If we imagine a worst-case scenario where someone manages to plant a trojan horse inside a container image on Dockerhub and that trojan is able to break containment and the overall effect is to expose parts of your home network to the outside world, then I honestly can't see it making any material difference whether the container is running in host-mode or non-host-mode.

I hope something in this helps you.

@swiss-R-user
Copy link
Author

Hi Phill
Thank you very much for your detailed answer. It helped a lot. I understand the whole host-thing now much better.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants