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

shahryarjb
Hello, I get Persian date from my client and convert it to normal calendar like this: def jalali_string_to_miladi_english_number(persi...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 record...
New
tduccuong
Hi, is there any work on GUI with Elixir, that is similar to Electron/Javascript? My idea is to bundle Phoenix and BEAM into a single se...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
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
chewm
Hi guys, nice to meet you to the whole forum, I’m new here, I’m trying to configure visual studio code for elixir, right now the intellis...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New

Other popular topics Top

Tee
can someone please explain to me how Enum.reduce works with maps
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
sergio
I couldn’t find any guides that worked well with Phoenix 1.6.0 and esbuild. I hope this helps people test the waters and eases you into t...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
chensan
I have a User schema with a :from_id field set to type :string: defmodule TweetBot.Repo.Migrations.CreateUsers do use Ecto.Migration ...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
Nvim
Elixir appears to be a superior language to Python. I don’t see any advantage of Python over Elixir. Are there any?
New

We're in Beta

About us Mission Statement