Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Erlang client set ssh key

I'm using the :client API to connect to an external node and use code there remotely, the thing though is that I'm using Dokku for deployment and it would be really nice if I could specify a ssh key at runtime.

Right now my code looks something like this:

def start(host) do
  allow_boot to_char_list(host)
  {:ok, slave} = :slave.start(to_char_list(host), :slave, inet_loader_args)
  load_paths(slave)
  {:ok, slave}
end

inet_loader_args == ' -rsh ssh -loader inet -hosts #{master_node_ip} -setcookie #{:erlang.get_cookie}'

I've tried something like setting the -rsh argument to be "-rsh ssh -i /path/to/id_rsh" but it seems to ignore this entirely, I'm not exactly sure how it's implemented and the Erlang docs for :client are a little hard to understand for me (I can see it uses :ssh underneath somewhere, and that can take a "user_dir" argument which can contain a key file, but I'm not sure how to set that from :client)

Any ideas?

like image 909
Zen Avatar asked Nov 29 '15 18:11

Zen


1 Answers

The -rsh option is intended to point to a different executable:

%% Alternative, if the master was started as
%% 'erl -sname xxx -rsh my_rsh...', then 'my_rsh' will be used instead
%% of 'rsh' (this is useful for systems where the rsh program is named
%% 'remsh').

These days people use ssh instead of rsh. (About 10 years ago the security team on a previous job required ssh even when both machines are on the same isolated network.) Since the command line interface is compatible, just pointing to a new executable generally works once you have the keys set up properly. So it makes sense to use the -rsh option to point to ssh instead.

It also seem logical that the argument could be used to pass other parameters to the ssh command as you attempted. However, the code assumes the string passed is the name of an executable in your PATH. It uses os:find_executable to look for an executable and ssh -i /path/to/id_rsh probably doesn't exist.

However, you can take advantage of this feature to point to any executable including a shell script. For instance, you could write a ssh-wrapper that looks something like:

#!/usr/bin/env ksh
exec ssh -i /path/to/id_rsh $@

Then use -rsh /path/to/my/ssh-wrapper so that :slave.start uses your wrapper with the proper ssh options specified. I've found the wrapper technique also makes future maintenance easier as the connection logic stays in one place.


Hat tip to this comment from Martin S.

like image 178
Jon Ericson Avatar answered Oct 21 '22 08:10

Jon Ericson