honzasp / makiko

Asynchronous SSH client library in pure Rust
https://honzasp.github.io/makiko/
The Unlicense
39 stars 3 forks source link

Fails to connect to AWS EC2 instance #4

Closed rukai closed 1 year ago

rukai commented 1 year ago

I ran this code against an amazon EC2 instance running ubuntu.

        let (client, mut client_rx, client_fut) = Client::open(
            tokio::net::TcpStream::connect((address, 22)).await.unwrap(),
            ClientConfig::default(),
        )
        .unwrap();

        tokio::task::spawn(async move {
            if let Err(err) = client_fut.await {
                tracing::error!("Error while driving ssh connection: {err}");
            }
        });

        tokio::task::spawn(async move {
            loop {
                // Wait for the next event.
                let event = client_rx
                    .recv()
                    .await
                    .expect("Error while receiving client event");

                // Normally a client would perform TOFU authentication (known_hosts file) against the server here.
                // But that would be pointless for us since we only connect to each server once.

                if event.is_none() {
                    // connection is closed
                    return;
                }
            }
        });

        let privkey = makiko::keys::decode_pem_privkey_nopass(private_key.as_bytes())
            .expect("Could not decode a private key from PEM")
            .privkey()
            .cloned()
            .expect("Private key is encrypted");

        let auth_res = client
            .auth_pubkey("ubuntu".to_owned(), privkey, &SSH_ED25519)
            .await
            .expect("Error when trying to authenticate");

I can connect to this instance fine with russh and I am passing in the same public ip and private ED25519 key that I use with russh. The final .expect fails with: 'Error when trying to authenticate: AuthAborted' And I also get a tracing error: Error while driving ssh connection: server public key was not accepted

honzasp commented 1 year ago

Hi, the problem here is that you need to verify and accept the server public key. This key is returned in ClientEvent::ServerPubkey; in your code, it seems that this event is ignored and dropped, so Makiko treats the key as rejected and aborts the connection with the server public key was not accepted error. You always need to handle this event, even if you plan to accept all server keys unconditionally.

You can read more about this in chapter 1 of the tutorial (here is the code for the tutorial).

rukai commented 1 year ago

Oh, I see, I carelessly deleted this line from the example https://github.com/honzasp/makiko/blob/master/examples/tutorial_4.rs#L46C24-L46C24 I missed the accept() call and thought I was just deleting a println. Sorry for the erroneous issue.

honzasp commented 1 year ago

No problem! I'm happy to help, feel free to open another issue if you hit some other problem :)