mirage / awa-ssh

Purely functional SSH library in ocaml.
ISC License
104 stars 12 forks source link

SSH Client question #27

Closed dgjustice closed 3 years ago

dgjustice commented 3 years ago

I am interested in trying some network automation with OCaml. Is this library a good candidate for a general-purpose client to connect to network switches and routers, or is it specifically designed to be used only inside of Mirage? Thanks!

hannesm commented 3 years ago

Hi @dgjustice, thanks for your question. This library is well-suited for connecting to network switches and routers. The current state is:

The client implementation does not handle multiple channels (should be fine for your use case), neither interactive session (instead, only executing a single remote command), nor key rollover (required if you transfer lots of data). The implementation is pure (within lib/), an effectful MirageOS layer is implemented in mirage/awa_mirage.ml. In order to use it on unix without the MirageOS stack, you'd need to reimplement that part within lwt/ (likely without any functors - since a monotonic clock and the socket stack are available out of the box on Unix). We're happy to help you with that, and eager to merge such code to this repository.

To start, you could as well look into test/awa_test_client.ml (dune build test/awa_test_client.exe) and see whether you're able to connect to your network routers and switches.

The client implementation does not support password authentication yet, only public key authentication. Eventually this is needed for your scenario. Please reach out if you need more guidance, I'm happy to collaborate on getting awa-ssh used for your use case.

dgjustice commented 3 years ago

Hannes, thank you for the quick, detailed response! I will attempt what you have suggested and reach out if I run into issues.

palainp commented 3 years ago

Hi @dgjustice do you managed to connect ? I have some troubles for the moment, I can connect with the classic ssh client and a private key, the server side seems ok:

$ ssh awa@127.0.0.1 -i ~/awa-ssh/test/data/awa_test_rsa
Last login: Sat Aug  7 08:55:19 2021 from 127.0.0.1
[awa@localhost ~]$ 

But I couldn't get a connection with private key using awa_test_client (I think I need to use some specific format for the authenticator argument, I have the warning telling me that, and the authenticator_of_string starts to try with no authentication if the authenticator is empty, but none of my tests have matched so far):

$ dune build test/awa_test_client.exe && ./_build/default/test/awa_test_client.exe --user awa --keytype rsa -vvv
[....]
awa_test_client.exe: [INFO] verified kexdh_reply!
awa_test_client.exe: [DEBUG] >>> Msg_newkeys
awa_test_client.exe: [DEBUG] rotating ctos keys
awa_test_client.exe: [DEBUG] <<< Msg_newkeys
awa_test_client.exe: [DEBUG] rotating stoc keys
awa_test_client.exe: [DEBUG] >>> (Msg_service_request ssh-userauth)
awa_test_client.exe: [DEBUG] read 44 bytes
awa_test_client.exe: [DEBUG] <<< (Msg_service_accept ssh-userauth)
awa_test_client.exe: [DEBUG] >>> (Msg_userauth_request (awa ssh-connection Authnone))
awa_test_client.exe: [DEBUG] read 76 bytes
awa_test_client.exe: [DEBUG] <<< (Msg_userauth_failure ((publickey gssapi-keyex gssapi-with-mic) false))
awa_test_client.exe: [DEBUG] >>> (Msg_userauth_request
 (awa ssh-connection (Pubkey ("Hostkey.sexp_of_pub rsa: TODO" ()))))
awa_test_client.exe: [DEBUG] read 76 bytes
awa_test_client.exe: [DEBUG] <<< (Msg_userauth_failure ((publickey gssapi-keyex gssapi-with-mic) false))
awa_test_client.exe: [DEBUG] >>> (Msg_userauth_request
 (awa ssh-connection (Pubkey ("Hostkey.sexp_of_pub rsa: TODO" ()))))
awa_test_client.exe: [DEBUG] read 76 bytes
awa_test_client.exe: [DEBUG] <<< (Msg_userauth_failure ((publickey gssapi-keyex gssapi-with-mic) false))
[...]
awa_test_client.exe: [DEBUG] unexpected (Msg_disconnect
 (DISCONNECT_PROTOCOL_ERROR "Too many authentication failures" ""))
awa_test_client: unexpected state and message
$
dgjustice commented 3 years ago

I have not had time to work on this yet. I will try to take a look this week.

hannesm commented 3 years ago

Dear @palainp, if I understand you correctly, you have the following setup:

My experiments use an OpenSSH server where I add the public key (ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCz3x8pW/OpnOx7jlLLaod1gCu++4+y0RXUlhBOdGDIzC9CgDBSJvOBKGzy+tC7QGhTaB5gKHS4xmw7+7KW70ncw+KfzxI5xAdgAvM7LV7E6614ni/AbGewEpOt+rsyHI/u45rBrrn0IPpQbN8atsY9XINJjq4p/s7okuZGkMYXYkeDDrVAHxowuwdeX2UE9LH1oB7Lso8YZ0cDVMLpw3nEqTEI7MDV1y2Y9uK8urGrZTh159xAFkTFzjzIhc0gk2XE+cidr/af8K6hyWs10r4BfR6S4Q5kX5UwhVkvAXpHuNX8m4Z9M/0aht/3dpw2EUJd+PdMMgAvs3Ah/vvlYQOp -- as output by awa_test_client on startup) to ~/.ssh/authorized_keys.

The "authenticator" argument is for the client to verify the host key (and if you provide none, a warning is printed).

There may be interoperability issues between awa server and awa client (based on different development time, where my interest and usage was only with the client -- I don't use the server).

palainp commented 3 years ago

Thanks for your help, my server is an OpenSSH_8.0p1 with the default key test/data/awa_test_rsa.pub copied to .ssh/authorized_keys in the homedir of user awa, it looks like your setup. I have the output awa_test_client.exe: [INFO] using ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCz3x8pW/OpnOx7jlLLaod1gCu++4+y0RXUlhBOdGDIzC9CgDBSJvOBKGzy+tC7QGhTaB5gKHS4xmw7+7KW70ncw+KfzxI5xAdgAvM7LV7E6614ni/AbGewEpOt+rsyHI/u45rBrrn0IPpQbN8atsY9XINJjq4p/s7okuZGkMYXYkeDDrVAHxowuwdeX2UE9LH1oB7Lso8YZ0cDVMLpw3nEqTEI7MDV1y2Y9uK8urGrZTh159xAFkTFzjzIhc0gk2XE+cidr/af8K6hyWs10r4BfR6S4Q5kX5UwhVkvAXpHuNX8m4Z9M/0aht/3dpw2EUJd+PdMMgAvs3Ah/vvlYQOp Actually I'm still missing how to use a private key with awa_ssh_client :/ I will try to use the other combos (openssh client/awa server, awa client/awa server) after that.

hannesm commented 3 years ago

Ok, thanks for your information. Let's keep rolling with awa_test_client.exe and the existing OpenSSH server.

It turns out, the awa_test_client.exe uses a different RSA key, not the one in test/data/awa_test_rsa. This leads to the authentication failure you observe.

With https://github.com/mirage/awa-ssh/pull/28 I added a --key argument to awa_test_client.exe, would you mind to try with that PR/branch (git remote add hannesm https://github.com/hannesm/awa-ssh.git ; git fetch hannesm ; git checkout hannesm/improve-test-client) the execution of dune build test/awa_test_client.exe && ./_build/default/test/awa_test_client.exe --user awa --key data/test/awa_test_rsa -vv on your machine (with the OpenSSH server started, and the awa_test_rsa.pub added to the authorized keys of user awa), please? If this works fine for you, I'll go ahead and merge that.

hannesm commented 3 years ago

NB: the ssh-rsa ... output by the awa_test_client.exe on startup is which public key it uses -- this is what you could copy to ~awa/.ssh/authorized_keys -- unless you use the --key argument to use a (unencrypted!) OpenSSH (or pem encoded) private key.

palainp commented 3 years ago

After adding the correct public key in authorized_keys (in fact I didn't checked that the awa_rsa.pub was not the one generated by the default seed, sorry for the noise I could have realized it earlier) I can confirm that the client connects to the open ssh server. Thanks a lot ! After updating and upgrading to opam 4.12 (I was on 4.11.1) I can also confirm that the key argument connects with the private key of the awa_test_rsa repo. PR is ok for me. I will now continue the tests with the awa server part :)

hannesm commented 3 years ago

@palainp cool, thanks. The server part still lacks some features that I only implemented for the client (RFC 4492 - DH group exchange, curve 25519 RFC 8731, 8709 -- maybe others). I don't have the requirement nor the bandwidth to enhance the server side with these features, but PRs are welcome :)

hannesm commented 3 years ago

or maybe @haesbaert is up to improving the server side :)