Use case examples

This section describes typical NanoSSH Client use cases and explains how to build applicable TrustCore SDK example code:

Use NanoSSH client for shell (remote) access

The NanoSSH client shell provides a secured communication channel between two networked devices. The typical usage is to log in to a remote machine and execute commands, as shown below.

image

Before you begin

Add the NanoSSH client shell example code and supporting software (such as TrustCore SDK code) to the application’s development environment. Make sure to include the sshc_shell_example.c file. See Add TrustCore SDK code to your environment for more details.

Build the shell access example code

Standard Edition

  1. Configure login credentials
    • In the sshc_shell_example.c example code file, change the following login credential variable values to match the SSH server (such as NanoSSH server or any other SSH server):
      • sshc_exampleUserName[]
      • sshc_examplePassword[]
      • sshc_exampleIPAddress
  2. Set compilation flags
    • Specify which features to be included in the NanoSSH client executable by setting the appropriate compilation flags. For the NanoSSH client shell example code, the basic flags include:
      • __ENABLE_MOCANA_SSH_CLIENT__
      • __ENABLE_MOCANA_EXAMPLES__
      • __ENABLE_MOCANA_SSH_RSA_SUPPORT__
    • The following flag must not be defined:
      • __ENABLE_MOCANA_SSH_FTP_CLIENT__
  3. Build the executable
    • Create the object files and executable using the following commands:
      • make -f make/Makefile.<os> clean
      • make -f make/Makefile.<os> sshc
  4. Verify the NanoSSH client execution
    • Verify that the NanoSSH client example code executes successfully in the environment.
    • See Verifying Communication between the client Shell and the NanoSSH server, Verifying NanoSSH client Shell Communication with Any SSH server
  5. Repeat steps 4 to 6 as needed to add features one at a time.

Community Edition

Run the following commands from the root of the cloned repository:

  1. Generate build system and enable the shell example:
    cmake -DBUILD_SAMPLES=ON \
    -DENABLE_SSH_CLIENT_SHELL_EXAMPLE=ON \
    -B build -S .
    
  2. Compile everything (including object files and executable):
    cd build
    make
    
    The shell client executable is written to build/samples/bin/ssh_client.

Verify communication between NanoSSH client shell and NanoSSH server

After building the NanoSSH code, verify that it executes in the operating environment. Assuming that the NanoSSH client and NanoSSH server (and the example code) have been enabled, the loopback interface may be used to confirm that the client and server are able to communicate within the operating environment.

If using only the NanoSSH client but not the NanoSSH server, see Verifying NanoSSH client Shell Communication with Any SSH server.

To verify communication between the client shell and the NanoSSH server:

Standard Edition

  1. If necessary, open a command shell on the NanoSSH server (e.g., Cygwin).
  2. Change to the mss directory.
  3. Start the appropriate executable; for example, for NanoSSH server:
    bin/sshs.exe
    
    Messages are displayed as processes and methods start up and run.
  4. Open a second shell (the client), and enter the following command to request a connection for the admin user:
    ssh admin@127.0.0.1
    
    The system prompts for the corresponding password.
  5. When prompted for the corresponding password, enter the default password, secure.
  6. When prompted to enter a new password, type any password; for example, new.
  7. When prompted to confirm the password, type it again. The client echoes “Password changed” and “Password successfully changed”.
  8. In the client window, press any keys. If they are echoed to the client window (i.e., if you can see what you are typing), asynchronous client-server communication is successful.
  9. Perform a graceful shutdown by entering the following command in the client window type:
    Bye!
    
    The client and server sessions end, and both command shells are closed.

Community Edition

  1. Run the following command:
    export LD_LIBRARY_PATH=lib/:crypto_lib/linux-x86_64/:$LD_LIBRARY_PATH./samples/bin/ssh_server -port 8818
    
    Leave the terminal running.
  2. In a new terminal window, set the library path, and start the client:
    export LD_LIBRARY_PATH=lib/:crypto_lib/linux-x86_64/:$LD_LIBRARY_PATH./samples/bin/ssh_client -ip 127.0.0.1 -port 8818 -username admin -password secure
    
    If the connection succeeds, you receive the server’s shell prompt. All input you type is executed on the remote host.

Verify NanoSSH client shell communication with any SSH server

It is recommended to verify basic NanoSSH client communications with an SSH server before beginning custom code implementations. This process is easily done using the NanoSSH client shell or SFTP example code, as follows.

The following procedure assumes that Cygwin is used to interface to a UNIX/Linux-like development system. For other environments, modify the commands accordingly.

To verify NanoSSH client shell communication with any SSH server:

Standard Edition

  1. Configure the NanoSSH client example code:
    1. If the NanoSSH client executable does not include the NanoSSH client example code from the sshc_shell_example.c file, modify the makefiles to include this file.
    2. Define the necessary compiler flags in the moptions.h file.
    3. Open the sshc_shell_example.c file for editing and locate the following lines:
      static const char sshc_exampleUserName[] = "admin";
      static const char sshc_examplePassword[] = "secure";
      static const char *sshc_exampleIPAddress = "127.0.0.1";
      static const unsigned short sshc_exampleServerPort = 22;
      
    4. Edit the values so that they match the user’s credentials and system’s IP address, and then save and close the file.
    5. Rebuild the executable, making sure to do a “clean” build.
  2. Start the SSH server.
  3. Open a command shell and start the NanoSSH client. The NanoSSH client example code securely connects (via HTTPS) to the SSH server, dumps debug information to a temporary command prompt window, and then automatically terminates.
  4. Stop the SSH server.

Community Edition

To connect to the sample NanoSSH server built from the same repository:

  1. Edit samples/ssh_client/src/sshc_example.c (path is relative to the repository root) and update the following variables to match your target SSH server:
    static const char sshc_exampleUserName[] = "admin";
    static const char sshc_examplePassword[] = "secure";
    static const char *sshc_exampleIPAddress = "127.0.0.1";
    static const unsigned short sshc_exampleServerPort = 22;
    
  2. Run the following command:
    export LD_LIBRARY_PATH=lib/:crypto_lib/linux-x86_64/:$LD_LIBRARY_PATH./samples/bin/ssh_server -port 8818
    
    Leave the terminal running.
  3. In a new terminal window, set the library path, and start the client:
    export LD_LIBRARY_PATH=lib/:crypto_lib/linux-x86_64/:$LD_LIBRARY_PATH./samples/bin/ssh_client -ip 127.0.0.1 -port 8818 -username admin -password secure
    
    If the connection succeeds, you receive the server’s shell prompt. All input you type is executed on the remote host.

Client shell integration flowchart

The following flowchart shows the NanoSSH client shell integration. For detailed steps to customizing the NanoSSH client shell implementation, see Customizing a client implementation.

image

Use NanoSSH client for secure file transfer

The NanoSSH SFTP client enables secure writing (PUT) and retrieval (GET) of files to/from a remote machine; for example, to retrieve an updated image file from a server and to write a log file to the server, as shown below.

image

Build SFTP example code

Standard Edition

  1. Add the NanoSSH SFTP example code and supporting software (such as TrustCore SDK code) to the application development environment.
    • Be sure to include the sshc_example.c file.
  2. If there is no pre-configured TrustCore SDK port for the operating system, edit the appropriate abstraction files to port the code to the operating system.
  3. In the sshc_example.c example code file, change the following login credential variable values to match the SSH server, which may be NanoSSH server or any SSH server:
    • sshc_exampleUserName[]
    • sshc_examplePassword[]
    • sshc_exampleIPAddress
  4. Create the object files and executable. The commands are:
    • make -f make/Makefile.<os> clean
    • make -f make/Makefile.<os> sshc
  5. Verify that the TrustCore SDK NanoSSH SFTP client example code executes in the environment.
  6. Repeat step 5 and step 6 as needed to add features one at a time.

Community Edition

  1. From the root of the Community Edition repository, run the following commands to compile all samples (including SFTP):
    cmake -DBUILD_SAMPLES=ON -B build -S .
    cd build
    make
    
  2. Confirm that the expected binaries exist:
    ls samples/bin/ssh_client samples/bin/ssh_server
    
  3. Open Terminal A and set the runtime library path, then launch the sample server on port 8818:
    export LD_LIBRARY_PATH=lib/:crypto_lib/linux-x86_64/:$LD_LIBRARY_PATH
    ./samples/bin/ssh_server -port 8818
    
    Leave this terminal running.
  4. Open Terminal B, set the same library path, and start the SFTP client:
    export LD_LIBRARY_PATH=lib/:crypto_lib/linux-x86_64/:$LD_LIBRARY_PATH
    ./samples/bin/ssh_client -ip 127.0.0.1 -port 8818 -username admin -password secure
    
    If the connection succeeds, the client enters SFTP mode and is ready for file-transfer commands such as ls, put, and get.

Verifying NanoSSH client SFTP communication with any SSH server

Be sure to verify basic NanoSSH SFTP client communications with the SSH server before beginning custom code implementations. This process is easily done using the NanoSSH client shell or SFTP example code, as follows:

  1. Open Cygwin and change to the directory where the TrustCore SDK distribution package ZIP file was extracted.
  2. If any source code or makefiles have been modified since the sshc target was last built, rebuild the executable:
    • ./script/nanossh/ssh_client/build_ssh_client_ncrypto.sh
  3. Run the example code executable:
    • ./bin/ssh_client

NanoSSH SFTP client integration flowchart

The following flowchart shows the NanoSSH SFTP client integration. For detailed steps to customizing the NanoSSH SFTP client implementation, see Customize a client Implementation.

image

Use NanoSSH client for port forwarding

NanoSSH client port forwarding encrypts and decrypts TCP/IP traffic. A typical application, as shown in Figure 6 below, is for proprietary applications that are operating on distributed machines to securely communicate over any network or the Internet using TCP/IP.

image

Building the port forwarding example code

  1. Add the NanoSSH port forwarding example code and supporting software (such as TrustCore SDK code) to the application development environment.
    • Be sure to include the sshc_pf_example.c file.
  2. If there is no pre-configured TrustCore SDK port for the operating system, edit the appropriate abstraction files to port the code to the operating system.
  3. In the sshc_pf_example.c example code file, change the following values to match the environment’s:
    • CONNECT_HOST
    • sshc_exampleUserName[]
    • sshc_examplePassword[]
    • sshc_exampleIPAddress
  4. Create the object files and executable. The commands are:
    • make -f make/Makefile.<os> clean
    • make -f make/Makefile.<os> sshc
  5. Verify that the NanoSSH client example code executes in the environment.
  6. Repeat step 5 and step 6 as needed to add features one at a time.

Client port forwarding integration flowchart

The following flowchart displays the NanoSSH client port forwarding integration.

image

Use NanoSSH client for reverse port forwarding

SSH reverse port forwarding lets you reach a device that can only make outbound connections (because it sits behind a firewall or NAT) by routing traffic through a public “relay” host.

RoleRuns onResponsibility
Isolated devicePrivate networkOpens an outbound SSH session that requests reverse port forwarding.
Relay hostPublicly reachable VM/serverSSH server that accepts reverse-forward requests and relays traffic.
Remote user/deviceAny locationOpens a normal SSH session to the relay to reach the isolated device.

Why and when to use it

  • Inbound blocked, outbound allowed. Your target device lives on a locked-down network but can open outbound TCP connections.
  • No firewall changes. You avoid reconfiguring NAT rules or requesting new ports from network admins.
  • Ad-hoc or permanent access. Keep the tunnel up permanently (service/watchdog) or start it only when remote access is required.

How the workflow unfolds

  1. Isolated device dials out. It initiates an SSH session to the relay and asks the relay to listen on a specific port.
  2. Relay binds the port. It exposes that port externally and links it to the tunnel.
  3. Remote user connects. They SSH (or otherwise TCP-connect) to the relay’s exposed port. The relay pipes that traffic through the tunnel to the isolated device.
  4. Bi-directional exchange. From here, traffic flows both ways—remote ↔ relay ↔ isolated—as if there were a direct connection.

Implementation reminders

  • Isolated-side client still hooks standard SSH port-forward callbacks plus the events for registering/canceling reverse forwards.
  • Relay server needs AllowTcpForwarding yes (and often GatewayPorts yes) and handlers for reverse-forward requests.
  • Remote-side client behaves like a regular port-forwarding SSH client; no extras required.

Building the reverse port forwarding example code

  1. Add the NanoSSH reverse port forwarding example code and supporting software (such as TrustCore SDK code) to the application development environment.
    • Be sure to include the src/examples/sshc_rpf_example.c file.
  2. If there is no pre-configured TrustCore SDK port for the operating system, edit the appropriate abstraction files to port the code to the operating system.
  3. In the sshc_rpf_example.c example code file, change the following values to match the environment’s:
    • CONNECT_HOST
    • sshc_exampleUserName[]
    • sshc_examplePassword[]
    • sshc_exampleIPAddress
  4. Use the sshc_rpf_example.c sample code’s implementation “as-is” or modify it as desired.
  5. Create the object files and executable. The commands are:
    • make -f make/Makefile.<os> clean
    • make -f make/Makefile.<os> sshc
  6. Verify that the NanoSSH client example code executes in the environment.
  7. Repeat step 4 to step 6 as needed to add features one at a time.

Implementing Reverse Port Forwarding for a NanoSSH client

  1. (Optional) Set up environment-specific thread support.
    • The example client creates a thread for each channel opened in the port-forwarding tunnel, and the code sets up lpfTable to track information about the open channels. To avoid thread conflicts, a mutex is used for access control.
  2. Initialize the NanoSSH client’s session manager, internal structures, and NanoSSH client-specific settings.
  3. Customize and register upcalls (callbacks) for all desired products and features:
    • Replace stub functions with the corresponding custom routines, modeling them after the NanoSSH client example code.
    • Register the callbacks as required.
  4. Set up management for authentication keys.
  5. Set up a TCP/IP socket connection with the remote SSH server (NanoSSH or any SSH server).
  6. Initialize the SSH session context.
  7. (Optional) Customize the session establishment, such as to override the default choice of the strongest available cipher and specify a particular cipher suite instead.
  8. Set up a secure and authenticated SSH session with the remote server.
  9. If using the NanoSSH SFTP client, open an SFTP session and negotiate SFTP version support.
  10. Send a remote port forwarding request to the SSH server to establish the client-server link.
  • The tunnel with a remote device is not established yet and not created until after the server uses the established client-server link to forward a connection request from a remote device.
  1. Verify that the client-server link was successfully established.
  2. Allocate the resources that the application needs for receiving data on the connection.
  3. Loop continuously to process messages from the SSH server and from local ports.
  4. Close the connection.
  5. Shut down the NanoSSH client and reclaim device and NanoSSH client resources.

To test whether an SSH client-server link is successfully established, use code similar to that in the sshc_rpf_example.c sample code, as follows:

  • If the function returns an OK status within the configured timeout, a link has been established.