Hi everyone!
I am really interested in security issues and remote access to Nerves devices, because I am working in a project in which we are going to have many devices in different locations and I would like if it would be possible to provide support in a safe way.
At this moment the system I am developing consists in two parts:
- An Elixir application in a server that runs a
iex
shell with a node, a security cookie and TLS enabled. - A support system in the Nerves devices, part of the application, in which I supervised the starting of a node (start, set the cookie and check TLS is working) and its connection with the server’s node.
So I can access to this server, check which nodes are connected and apply RPC calls and even open a remote iex
shell. It is a very comfortable system, because I can manage the devices, give support, update firmware, etc., without many complications.
However, as far as I know from what I read, epmd
still manages the communications between the nodes in an unencrypted way.
In the blog post Erlang Elixir Node Security Flaws, @Andrei suggest some solutions:
- Setting up Erlang to use TLS/SSL.
- Using SSH.
I already configured the first point in both parts of the system, the application in the server and the Nerves device. But I am still thinking about how to setup a reverse SSH tunnel from the Nerves device to the remote server.
I have tried a lot and the result is a lot of dirty code hehe! But I am still looking for a good way to do it.
I am trying to use :ssh
module and the functions :ssh.connect/3
and :ssh.tcpip_tunnel_to_server/5
to setup the tunnel. Just like a test (not as part of the Elixir application in the Nerves device), I tried to run in the Nerves iex
shell these commands:
iex(device_node@nerves-hostname)7> {:ok, ssh_conn} = :ssh.connect(ip_address, 22, [user: user, password: pass])
{:ok, #PID<0.1826.0>}
iex(device_node@nerves-hostname)8> {:ok, tunnel} = :ssh.tcpip_tunnel_to_server(ssh_conn, 0, "localhost", 4369, "localhost", 4369)
** (MatchError) no match of right hand side value: {:error, :bad_connect_to_address}
(stdlib 4.2) erl_eval.erl:496: :erl_eval.expr/6
iex:8: (file)
I think that the main possibility is that I don’t know how to setup and work with SSH tunnels with Elixir and Erlang. Even just with ssh
command I have many to learn yet. Thus I want to ask you for help about this topic: what would be the best way to set up an SSH tunnel from the Nerves device to the remote server?
In addition, what do you think about this approach to provide remote support to Nerves devices from a server?
I am really interested in this topic and all the related aspects, but especially in the matter of security.
Regards,
Iván