How to connect via :ssh module using an id_ed25519 private key string

I spent more than a day trying to figure out how to connect via ssh using a private key but without a result… all languages some to have an example when it comes to ssh except erlang/elixir which I don’t know why it’s that hard.

The only example I can find is using username/password, but I want to ssh to another machine using username and private ssh key (id_ed25519),

Any idea?

If you are using OTP, it’s always worth checking out the official documentation. Here is how to configure custom keypairs for servers and the next paragraph is for clients: ssh — ssh v5.2.1

The parameters that can be sent to the client/daemon are also clearly documented, take a look through them: ssh — ssh v5.2.1

1 Like

Ok I believe this is so easy for you so please just add that one line or 2 missing lines where I have put a placeholder for completion (my private key is located in /home/me/.ssh/id_ed25519)

ssh_options = [
      {:user, user},
      {:silently_accept_hosts, true},
      {:user_interaction, false},
      # ====== please just fill in here those easy missing lines ======
    ]

{:ok, conn} <- :ssh.connect(ip, port, ssh_options, 5000)

BTW I am really newbie to OTP, but I am sure you an experienced on these stuff.

1 Like

I am still waiting for the “it’s easy to do” guy to answer, but unfortunately the easy things are not easy. Said is always easier than Done. Anyway!

You can PM me and I’ll hand you the consulting prices, then you won’t have to wait anymore :slight_smile: .

1 Like

For the record, I re-read the comment you are referring to three times and hereby I admit it does not have wording “it is easy to do.”

It suggests reading docs. Which is the great advice, btw. You might also read something about SSH in a nutshell, because your attempt to pass the username alongside with the file hints you are not quite familiar with it.

1 Like

As far as I can tell the only way to do this is to implement a ssh_client_key_api callback.
The default is to look for the key files in the .ssh folder, this you can override with user_dir option.

I have never used it myself, but saw a reference to a package called librarian that seems to support it.
If you want to write it yourself, you can look at how they do it.

A good starting point IMO is the example in the :ssh user guide.

That shows the general shape of things (connect/session_channel/exec) but doesn’t really use the messages, or answer your original question.

For the “using the messages” part, take a look at how SSHEx does it - the whole file is worth reading, but this is where the actual {:ssh_cm, ...} messages get handled:

For the second half, there are two behaviours that :ssh depends on but the one we care about is :ssh_client_key_api. That’s implemented by two modules supplied with :ssh, :ssh_file and :ssh_agent which use either files or the SSH agent. :ssh_file is the default, but you can pass an alternative implementation via the :key_cb option to :ssh.connect.

HOWEVER

:ssh_client_key_api has more moving parts than just “here is a key”, it also deals with known hosts. SSHEx includes an implementation you could use / model after:

2 Likes