ewpa / LibSSH-ESP32

Libssh SSH client & server port to ESP32 Arduino library
https://www.ewan.cc/node/157
Other
268 stars 36 forks source link

Is it possible to establish SSH connection while using softAP ? #9

Open GeorgeFlorian opened 3 years ago

GeorgeFlorian commented 3 years ago

I am interested in establishing a SSH connection with a server. I want the server the be connected to the ESP using softAP(). Is this possible ?

I've went to the https://github.com/ewpa/LibSSH-ESP32/tree/master/examples folder but I have no idea what to use from there.

One thing to point out from the example files is that there are a lot of duplicate includes. For example in exec example:

#include "examples_common.h" // is declared 4 times
#include <libssh/libssh.h> // is declared 4 times
#include <stdio.h> // is declared 3 times
// and so on
ewpa commented 3 years ago

Hi George, is your requirement that the server will get its IP address from the ESP32 and then the ESP32 makes an SSH connection to the server? Or that the ESP32 is a server and can be reached from connecting devices as an AP?

The multiple includes are a result of porting the example code from upstream 'as-is'.

GeorgeFlorian commented 3 years ago

Hi George, is your requirement that the server will get its IP address from the ESP32 and then the ESP32 makes an SSH connection to the server? Or that the ESP32 is a server and can be reached from connecting devices as an AP?

Hello. Thank you for your prompt reply.

The PC server will be connected to a network. Also, the same PC server should connect to the ESP32's AP on Wireless to enable communication between them.

I am trying to connect to the ESP using softAP to try and eliminate the need for a switch between the PC Server and the ESP32.

I am basically trying to shutdown a Linux server using SSH. What do you think ?

The multiple includes are a result of porting the example code from upstream 'as-is'.

Got it. Thanks. I am not very good at networking so can you please help me with some answers ?

Inside exec example there are multiple functions doing different things:

/*
 * knownhosts.c
 * This file contains an example of how verify the identity of a
 * SSH server using libssh
 */
int verify_knownhost(ssh_session session):

/*
 * authentication.c
 * This file contains an example of how to do an authentication to a
 * SSH server using libssh
 */
int authenticate_kbdint(ssh_session session, const char *password):
static int auth_keyfile(ssh_session session, char* keyfile);
int authenticate_console(ssh_session session)

/*
 * connect_ssh.c
 * This file contains an example of how to connect to a
 * SSH server using libssh
 */
ssh_session connect_ssh(const char *host, const char *user,int verbosity):
int ex_main(int argc, char **argv);

There are basically 3 examples doing 3 different things in regards to a SSH connection. To establish the type of connection that I need, what functions do I have to use ?

Do I need all of them as these are the needed steps in order to establish SSH connection ?

ewpa commented 3 years ago

The examples to try to run the ESP32 as an SSH server are firstly keygen2. This will create the SSH host key on the ESP32. Secondly, samplesshd-kbdint. This runs a sample SSH server on the ESP32. Once this is working that sketch can be enhanced to use AP mode. Have a look through those examples first, especially the second example which runs the server.

GeorgeFlorian commented 3 years ago

The examples to try to run the ESP32 as an SSH server are firstly keygen2. This will create the SSH host key on the ESP32. Secondly, samplesshd-kbdint. This runs a sample SSH server on the ESP32. Once this is working that sketch can be enhanced to use AP mode. Have a look through those examples first, especially the second example which runs the server.

I don't think that I need the ESP32 to run a SSH Server. I just need the ESP to send one command to the PC using SSH. How should I breakdown the code for this ? What is the client code ? After the client code comes the client's private key, right ? Something like this: https://www.tecmint.com/ssh-passwordless-login-using-ssh-keygen-in-5-easy-steps/

ewpa commented 3 years ago

Yes, seems exec example is the closest to what you need to SSH to your server that connects to the ESP32 as AP. The verify_knownhost ensures you connect to only a server you already know. auth_keyfile is probably the best way to authenticate. You store an SSH public key in SPIFFS on the ESP32 and no coded password is needed. My wrapper around the example code from libssh is ex_main. This just allows me to copy/paste the code as-is. Is that enough information to get you going?

GeorgeFlorian commented 3 years ago

Yes, seems exec example is the closest to what you need to SSH to your server that connects to the ESP32 as AP. The verify_knownhost ensures you connect to only a server you already know. auth_keyfile is probably the best way to authenticate. You store an SSH public key in SPIFFS on the ESP32 and no coded password is needed. My wrapper around the example code from libssh is ex_main. This just allows me to copy/paste the code as-is. Is that enough information to get you going?

I will try it. Thank you very much.

Isai-dc commented 2 years ago

Yes, seems exec example is the closest to what you need to SSH to your server that connects to the ESP32 as AP. The verify_knownhost ensures you connect to only a server you already know. auth_keyfile is probably the best way to authenticate. You store an SSH public key in SPIFFS on the ESP32 and no coded password is needed. My wrapper around the example code from libssh is ex_main. This just allows me to copy/paste the code as-is. Is that enough information to get you going?

I will try it. Thank you very much.

Hey, did you figure this out? I'm also trying to wirelessly connect to a ssh server to turn of a PC and can't seem to figure it out.

ewpa commented 2 years ago

Please try the following steps and let me know if it is useful.

Open the exec.ino example and make the following changes.

  1. Change YourWiFiSSID and YourWiFiPSK as appropriate to match your WiFi credentials.
  2. Find the line: session = connect_ssh("localhost", NULL, 0);
  3. Change localhost to your remote server, e.g. www.example.com.
  4. Change NULL to your username, e.g. "ewan".
  5. Increase 0 to 2 if you want more verbose output, e.g. session = connect_ssh("www.example.com", "ewan", 2);
  6. Find the line: rc = ssh_channel_request_exec(channel, "lsof");
  7. Change lsof to the command you wish to execute on the remote ssh server, e.g. rc = ssh_channel_request_exec(channel, "shutdown -r now");
  8. Compile the exec.ino example and upload it to your ESP32.
  9. Access the console at 115200bps and respond to the prompts as below.
E (10) uart: UART driver already installed
E (12) SPIFFS: mount failed, -10025
% No formatted SPIFFS filesystem found to mount.
% Format SPIFFS and mount now (NB. may cause data loss) [y/n]?

If you see the above message, press y and wait about 10 seconds.

% Formatting...
% Mounted SPIFFS used=0 total=1374476
% WiFi enabled with SSID=xxx
% IPv4 Address: xxx
% IPv6 Address: fe80:xxx
% IPv6 Address: 2001:xxx
% Execution in progress: exec

[1970/01/01 00:01:11.076398, 2] ssh_connect:  libssh 0.8.90 (c) 2003-2021 Aris Adamantiadis, Andreas Schneider and libssh contributors. Distributed under the LGPL, please refer to COPYING file for information about your rights, using threading threads_noop
[...]
The server is unknown. Do you trust the host key (yes/no)?
SHA256:xxx

Type yes[CR] into the console. You may receive a further prompt.

This new key will be written on disk for further usage. do you agree ?

Type y[CR] into the console.

[1970/01/01 00:00:42.122681, 2] ssh_userauth_publickey_auto:  Tried every public key, none matched
Automatic pubkey failed. Do you want to try a specific key? (y/n)

Type n[CR] into the console.

Password:

Type your password then [CR] into the console. The command will now execute on the remote ssh server. If not, review the verbose output.

[1970/01/01 00:01:22.053648, 2] channel_open:  Creating a channel 43 with 250 window and 32768 max packet

[...output...]

% Execution completed: rc=0
Isai-dc commented 2 years ago

Thanks a lot for your response ewpa, I did what you said and it works.

Now I am not that experienced in writing code so I am not really sure how to simplify your code.

But I'm looking for a way to simplify your code to where you just have to put in the WiFi credentials, the server ip adres, the user, the password and the cmd code. Where then the serial output would just tell you if a connection has been made or not.

In the end I want to make a physical enclosure for the esp32 with a couple buttons and LEDs to be able to turn my pc on / off.

ewpa commented 2 years ago

Hi @Isai-dc, it may be easier to start with a simple WiFi example of your own and add in chunks of the example code gradually.