ruslansavenok

ruslansavenok

Distillery node defaults - should I be concerned about security?

I have a phoenix app deployed as distillery release.

By default, distillery sets node name to app_name@127.0.0.1 and cookie to app_name.

Do I need to be concerned about security here? Can anybody connect to the node and execute commands on my production machine?

From what I understand, in order to connect to such node, one should explicitly setup ssh tunnel to app_name@127.0.0.1 is this correct?

Marked As Solved

voltone

voltone

No, this is not correct. When starting the Erlang VM with a node name (short or long), a TCP listener is created on all network interfaces (unless you set inet_dist_use_interface; see below). You should assume that anyone who can reach that TCP port, from the local network or beyond, can try to connect. If they know, guess or brute-force the cookie, they gain complete control over the VM.

To harden your deployment:

  • If you are not using Erlang distribution at all, disable it altogether by not setting a node name
  • If you are only using Erlang distribution locally on the machine, e.g. to run Observer, set {inet_dist_use_interface, {127, 0, 0, 1}} in the Kernel app configuration; also set a strong cookie value, out of an abundance of caution
  • If you do plan to use Erlang distribution from other hosts (e.g. your dev machine), set it up for local use as described above and use an SSH tunnel with port forwarding

Also Liked

voltone

voltone

This is not about SSH tunnels. The issue is that the node name gives the false impression that the Erlang distribution protocol is only reachable over the loopback interface. In reality, the node is reachable on a randomly allocated TCP port through all other network interfaces as well.

Of course that does not mean the port is exposed to the Internet: I assume you only open up selected ports in your firewall. But a firewall only provides perimeter defense. The Erlang distribution protocol is too powerful to be protected only by a TCP port filter.

As for actually connecting to the node, e.g. from another machine in the local network: it is not trivial, but definitely possible. A normal iex -remsh will fail, because it will try to look up the node with the local EPMD on that machine (because of the ‘127.0.0.1’). But EPMD can be spoofed, and the part of the node name after “@” is only used to locate the node’s EPMD server, but is ignored during the node-to-node connection authentication.

EDIT: Correction, the domain part of the node name is used to discover the EPMD server and also in the handshake between the nodes; it is not used by EPMD, which only cares about the part before the “@”.

voltone

voltone

Actually, that issue was in the node itself, not EPMD (which is written in C, and therefore does not deal with atoms).

And no, the issue was not resolved. In OTP 21 the node whitelist (:net_kernel.allow/1; docs) will now be checked prior to creating an atom for the remote node name. But no whitelist is active by default, and use of a whitelist may not be practical in many cases.

Earlier, in OTP 20, a check was added to look for a “@” character inside the node name prior to conversion to an atom. Due to this, the code examples in my original blog post on the topic no longer work as-is, but it’s trivial to work around that, of course.

So that’s a DoS risk, which is another reason to disable the distribution protocol, or at least bind it to the loopback interface only.

ruslansavenok

ruslansavenok

@Qqwy when you build release, it shows you a warning if you don’t set a cookie.

With distillery, you can’t disable distributed erlang, because it uses it to start/restart node & other commands. So the only option you have is to setup firewall and use inet_dist_use_interface

In my case, I’m using docker container and there’s no need to adjust firewall, since the only port I expose is 80.

I’ve also added this to my config.exs and increased cookie length as @voltone blog post suggests.

config :kernel, inet_dist_use_interface: {127, 0, 0, 1}

Where Next?

Popular in Questions Top

Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call th...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lis...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
Exadra37
Sometimes I want to check if the input into a function is not a blank string. My first approach: defmodule Example do def do_stuff(s...
New
Mooodi
Given a string, how can I get access to its character by index? Enum.at("my_string", 2) doesn't work. Or rather, not char, but a substr...
New
wernerlaude
In AR this is so simple @articles = current_user.articles How to do in Ecto? def index(conn, _params) do current_user = conn.assig...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers' Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New

Other popular topics Top

peerreynders
Manning 2016 Halloween weekend sale via Deal of the Day Friday, October 28 - Half off all MEAPs - code WM102816LT Saturday, October 29 ...
326 29600 154
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? https://hexdocs.pm/ecto/Ecto.Repo.h...
New
AstonJ
We’ve put together this wiki for Phoenix LiveView - please feel free to add any info you feel is worth including. What is Phoenix LiveV...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
magnetic
Hey :wave:t3: Elixir community, I’ve been learning Elixir, and working on some side projects. My editor of choice is VSCode, and althoug...
New

We're in Beta

About us Mission Statement