Skip to content
Boris Lovosevic edited this page Jan 21, 2018 · 14 revisions

SSH module

This module uses libssh2 to implement ssh, scp and sftp protocols to connect to the SSH server.

Features

  • list files on remote server, both short and long lists are supported. Uses sftp protocol.
  • mkdir, create directory on remote server. Uses sftp protocol.
  • Download or Upload file to the remote ssh server. Uses SCP protocol.
  • execute any command on remote ssh server, wait and collect the result output.

Security

Module supports both password and public key authentication.

In conventional password authentication, you prove you are who you claim to be by proving that you know the correct password. The only way to prove you know the password is to tell the server what you think the password is. This means that if the server has been hacked, or spoofed, an attacker can learn your password.
Public key authentication solves this problem. You generate a key pair, consisting of a public key (which everybody is allowed to know) and a private key (which you keep secret and do not give to anybody). The private key is able to generate signatures. A signature created using your private key cannot be forged by anybody who does not have that key; but anybody who has your public key can verify that a particular signature is genuine.

To use a public key authentication, you have to generate public/private key pair on your PC and store it on the MicroPython file system.

Note:
The module uses mbedTLS and more memory is required.
If not using psRAM, you may need to lower the MicroPython heap (72 KB will usually be enough).
You may try to set
→ Component config → mbedTLS → TLS maximum message content length
to a lower value than default 16 kB, for example to 4 kB. It will usually work, but The TLS may fail if the server side does not support TLS Maximum Fragment Length Negotiation Extension.



Methods


ssh.options(print, verbose, progress, timeout, maxfsize, hdrlen, bodylen, trace)

Get or set ssh options.
All arguments are optional. All, except ṗrint, arguments are *kw arguments and must be entered in arg=value format.

Arg Description
print Default: True; print the current options.
False can be used when setting the option(s) from Python script
verbose if True, collects the ssh operation results which can be examined after the operation is finished
progress if True, prints the progress during the file upload/download
timeout Default: 8 sek; set the timeout for ssh socket operations in seconds. Allowed range is 2 ~ 30 seconds
maxfsize Default: 300000
Maximum download file size. If the requested file size is bigger, the whole file will be downloaded, but the file on filesystem will be truncated at that value.
hdrlen Default: 512 or 1024 if psRAM is used
The size of the header buffer. Header buffer is returned as the 2nd item in ssh operations result and contains the ssh operation messages
bodylen Default: 1024 or 4096 if psRAM is used
The size of the body buffer. Body buffer is returned as 3rd item in ssh operations result and contains the response from the ssh server
trace Enable individual libssh2 trace messages.
The trace options can be combined (added or or-ed)
The following constants can be used:
ssh.TRACE_TRANS, ssh.TRACE_KEX, ssh.TRACE_AUTH
ssh.TRACE_CONN, ssh.TRACE_SCP, ssh.TRACE_SFTP
ssh.TRACE_ERROR, ssh.TRACE_PUBLICKEY
ssh.TRACE_NONE, ssh.TRACE_ALL
>>> import ssh
>>> ssh.options()
SSH options(
  Verbose: False, Progress: 0, Timeout: 8 s, Max fsize: 300000, Header len: 1024, Body len: 4096, Trace: False (0x000)
)

ssh.list(url, user, password, key, port)

List the files on the remote server directory.
url, user and password are mandatory arguments, other arguments are optional and must be used as kw arguments, arg=value

url argument must be given in the format server_domain/dir_path or server_IP_address/dir_path

If the password authentication is used, password is the ssh server password for the specified user.
If the public key authentication is used, password is the key's password if used, otherwise None.

key, if used, is the path to the private key file on your MicroPython file system.
public key file with the same name and extension .pub must be available on the same location.

port is the ssh server's port. Defaults to 22 if not entered.

The method returns tuple of 3 items: (res_code, msgs, response)
On succes res_code will have the value 0, on fail the error code.

>>> res = ssh.list('loboris.eu/home', 'usrname', 'password')
>>> res[0]
0
>>> print(res[1])
* DNS lookup succeeded. IP=82.196.4.208
* Connected
* SSH session created
* SSH session established
* Fingerprint (SHA256): [1880B86E21ECABD2C21DD039FA1C6FD01BEAE0C739CACB1DB32A8B51BAA1B553]
* Authentication by password succeed.

>>> print(res[2])
D	26	.
D	4096	..
D	1222	boris
D	24	ftpusers
>>> res = ssh.list('loboris.eu/home', 'usrname', None, key='id_rsa')
>>> res[0]
0
>>> print(res[1])
* DNS lookup succeeded. IP=82.196.4.208
* Connected
* SSH session created
* SSH session established
* Fingerprint (SHA256): [1880B86E21ECABD2C21DD039FA1C6FD01BEAE0C739CACB1DB32A8B51BAA1B553]
* Authentication by public key succeed.

ssh.llist(url, user, password, key, port)

List the files on the remote server directory in long format.

>>> res = ssh.llist('loboris.eu/home', 'usrname', None, key='id_rsa')
>>> print(res[2])
drwxr-xr-x    1 root     root           26 Mar  5  2016 .
drwxr-xr-x   26 root     root         4096 May 23  2015 ..
drwxr-xr-x    1 boris    boris        1222 Jan 18 23:52 boris
drwxr-xr-x    1 ftpuser  ftpgroup       24 Apr 26  2017 ftpusers

ssh.get(url, user, password, key, file, port)

Download the file from remote ssh server.

url must contain the full path to the file on remote server to be downloaded

file argument is optional, if not used, the file will be downloaded into response buffer (and truncated to its size).
If used, the remote file will be downloaded to the file on MicroPython file system.

>>> res = ssh.get('loboris.eu/var/www/ESP32/info.txt', 'usrname', None, key='id_rsa')
>>> res[0]
0
>>> print(res[1])
* DNS lookup succeeded. IP=82.196.4.208
* Connected
* SSH session created
* SSH session established
* Fingerprint (SHA256): [1880B86E21ECABD2C21DD039FA1C6FD01BEAE0C739CACB1DB32A8B51BAA1B553]
* Authentication by public key succeed.
* Received: 385 bytes in 0.0 sec (8.952 KB/s)

>>> print(res[2])
================
Welcome to ESP32
================

The ESP32 is a low cost, low power microcontroller
with integrated Wi-Fi & dual-mode Bluetooth,
which employs a dual-core
Tensilica Xtensa LX6 microprocessor.

ESP32 is created and developed by Espressif Systems,
a Shanghai-based Chinese company,
and is manufactured by TSMC using their 40 nm process.

---------
2017 LoBo
---------

>>> 
>>> res = ssh.get('loboris.eu/var/www/ESP32/info.txt', 'usrname', None, key='id_rsa', file='remote.txt')
>>> print(res[1])
* DNS lookup succeeded. IP=82.196.4.208
* Connected
* SSH session created
* SSH session established
* Fingerprint (SHA256): [1880B86E21ECABD2C21DD039FA1C6FD01BEAE0C739CACB1DB32A8B51BAA1B553]
* Authentication by public key succeed.
* Received: 385 bytes in 0.0 sec (7.673 KB/s)

>>> os.listdir()
['boot.py', 'main.py', 'id_rsa', 'id_rsa.pub', 'remote.txt']
>>> os.stat('remote.txt')
(33279, 0, 0, 0, 0, 0, 385, 0, 1516554118, 0)
>>> 

ssh.put(url, user, password, key, file, port)

Upload the file to remote ssh server.

url must contain the full path to the file on remote server to which to upload the local file

file argument is mandatory, the file name on MicroPython file system to be uploaded.

See the example below.


ssh.mkdir(url, user, password, key, port)

Create the directory on remote server.

url must contain the full path to the directory on remote server to be created

>>> res = ssh.llist('loboris.eu/home/boris/esp32test', 'usrname', None, key='id_rsa')
>>> print(res[1])
* DNS lookup succeeded. IP=82.196.4.208
* Connected
* SSH session created
* SSH session established
* Fingerprint (SHA256): [1880B86E21ECABD2C21DD039FA1C6FD01BEAE0C739CACB1DB32A8B51BAA1B553]
* Authentication by public key succeed.
Unable to open dir with SFTP
# !!! Directory not found on remote server

>>> res = ssh.mkdir('loboris.eu/home/boris/esp32test', 'usrname', None, key='id_rsa')
>>> res = ssh.llist('loboris.eu/home/boris/esp32test', 'usrname', None, key='id_rsa')
>>> print(res[2])
drwxr-xr-x    1 boris    boris           0 Jan 21 18:09 .
drwxr-xr-x    1 boris    boris        1240 Jan 21 18:09 ..

>>> res = ssh.put('loboris.eu/home/boris/esp32test/main.py', 'usrname', None, key='id_rsa', file='main.py')
>>> res = ssh.llist('loboris.eu/home/boris/esp32test', 'usrname', None, key='id_rsa')
>>> print(res[2])
drwxr-xr-x    1 boris    boris          32 Jan 21 18:12 .
drwxr-xr-x    1 boris    boris        1240 Jan 21 18:09 ..
-r-xr-xr-x    1 boris    boris        1880 Jan 21 18:12 main.py

>>> 

ssh.exec(url, user, password, key, port)

Login to the server, execute any command, wait and return the rusult.

If the command is not in the server's PATH, url must contain the full path to the program on the remote server

The working directory after login is the user's home directory.

>>> res = ssh.exec('loboris.eu/ls *.jpg', 'usrname', None, key='id_rsa')
>>> print(res[2])
test1.jpg
tiger.jpg

>>> res = ssh.exec('loboris.eu/ls -l *.jpg', 'usrname', None, key='id_rsa')
>>> print(res[2])
-rw-r--r-- 1 boris boris 97543 Kol 15 15:04 test1.jpg
-r-xr-xr-x 1 boris boris 97543 Kol 16 18:20 tiger.jpg

>>> res = ssh.exec('loboris.eu/uname -a', 'usrname', None, key='id_rsa')
>>> print(res[2])
Linux loboris 3.16.0-37-generic #51~14.04.1-Ubuntu SMP Wed May 6 15:23:14 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux

>>> res = ssh.exec('loboris.eu/df', 'usrname', None, key='id_rsa')
>>> print(res[2])
Filesystem     1K-blocks     Used Available Use% Mounted on
udev             1013616       12   1013604   1% /dev
tmpfs             204980      588    204392   1% /run
/dev/vda1       51473020 26027264  22808036  54% /
none                   4        0         4   0% /sys/fs/cgroup
none                5120        0      5120   0% /run/lock
none             1024896        0   1024896   0% /run/shm
none              102400        0    102400   0% /run/user
/dev/loop0      20480000  5040524  13520884  28% /.bdisk
/dev/loop0      20480000  5040524  13520884  28% /home
/dev/loop0      20480000  5040524  13520884  28% /Baze
/dev/loop0      20480000  5040524  13520884  28% /Podaci
/dev/loop0      20480000  5040524  13520884  28% /Backup
/dev/loop0      20480000  5040524  13520884  28% /var/www

>>> res = ssh.exec('loboris.eu/cat /var/www/ESP32/info.txt', 'usrname', None, key='id_rsa')
>>> print(res[2])
================
Welcome to ESP32
================

The ESP32 is a low cost, low power microcontroller
with integrated Wi-Fi & dual-mode Bluetooth,
which employs a dual-core
Tensilica Xtensa LX6 microprocessor.

ESP32 is created and developed by Espressif Systems,
a Shanghai-based Chinese company,
and is manufactured by TSMC using their 40 nm process.

---------
2017 LoBo
---------

>>>