Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Short Circuit Erlang Port Mapper Daemon

Given a known TCP port and name for a remote beam.smp service, as well as a known cookie, is it possible to short circuit the Erlang Port Mapper Daemon handshake phase of the Erlang distribution protocol and establish an Erlang shell directly to the target beam.smp service?

The protocol is documented here:

http://erlang.org/doc/apps/erts/erl_dist_protocol.html

And here:

https://github.com/blackberry/Erlang-OTP/blob/master/lib/kernel/internal_doc/distribution_handshake.txt

But it is not clear to me if the recv_challenge/send_challenge authentication occurs via the Erlang Port Mapper Daemon or the beam.smp service bound to a specific port.

Thank you for your time.

like image 461
Anthony Roe Avatar asked Oct 02 '22 16:10

Anthony Roe


1 Answers

Authentication occurs between Erlang VMs (beam or beam.smp). epmd only handles port registration. Simply short-circuiting epmd is not extremely easy, and other approaches might be more appropriate to your actual need.

Unfortunately, epmd is not an option for the default distribution protocol (inet_tcp_dist) or for its SSL counterpart. There are two undocumented options that look like you can disable epmd (-no_epmd) or provide an alternative implementation (epmd_module). However, the dependency of the distribution protocols on epmd is hard-coded and does not depend on these options.

So you could:

  • override the erl_epmd module at the code server level (probably the dirtiest approach);
  • provide an alternative distribution protocol which would copy (or call) inet_tcp_dist except for the parts where erl_epmd is called. Mainly, you need to provide your own implementation of setup/5.

If you don't want the shell node to connect to epmd for registering its name, you will also need to override listen/1. In this case, you can pass -no_epmd to the command line.

Alternatively, you can connect to epmd to register the listening node in order to create a shell connection using the default protocol.

This approach is particularly useful if epmd lost track of a node (e.g. it was killed, unfortunately epmd is a single point of failure). To do so:

  1. Create a TCP connection to epmd and send a packet to register the lost node with its known port and name. Keep the TCP connection open or epmd will unregister the node.
  2. Connect a new shell to the lost node using the name used in previous step.
  3. You can then close the connection established in (1) and eventually re-register the lost node to epmd by calling erl_epmd:register_node/2 (and sending well-crafted tcp_closed message if required).
like image 178
Paul Guyot Avatar answered Oct 07 '22 18:10

Paul Guyot