NAME
krsh - Kernera restricted shell, for sharing access to embedded hardware
SYNOPSIS
krsh [options] [command_file]
krsh [options] -c command_string
krsh [options] -s
DESCRIPTION
The krsh(1) shell is a command language interpreter that shall execute command read from a command line string, the standard input, or a specified file.
It is usually used interactively as a login shell on a remote server for sharing access between multiple users to hardware such as serial ports, power supplies or development boards, while abstracting system specific details.
Design
This section describes a few paradigms used to develop krsh.
-
This project has no notion of authentication whatsoever. If authentication is needed (which is often the case), the shell must be used as a login shell and accessed via SSH, which deals with the preferred method. Therefore there is no convention to describe or split the access to a embedded work bench, it is up to the user to abstract all hardware behind a single krsh user, having one krsh user per target machines, or even one krsh user per human accessing the hardware.
-
If possible, hardware and physical details such as IP addresses or TTY devices shouldn’t be exposed to the user, they are only described in the configuration file and used internally by the shell.
-
The shell is not distributed and thus only describes hardware physically accessible via the machine itself where krsh is executed.
Installation
This section describes how to install krsh from source as a login shell for a new user bench.
Note
|
krsh is not packaged yet and does not use a compilation utility yet, therefore its installation is manual. |
Download and compile krsh from source with:
# git clone https://github.com/kernera/krsh /opt/krsh # make -C /opt/krsh krsh
Create a new user bench and define its login shell with:
# useradd -s /opt/krsh/krsh -m -k /opt/krsh/skel bench
Test krsh with:
# su -l bench -c help
Assuming that key authentication is already configured on the server, it is convenient to configure SSH on a remote client with the following host:
Host bench HostName remote.server.com RequestTTY yes User bench
Accessing the restricted shell from a remote client becomes as intuitive as:
$ ssh bench Last login: Mon Oct 5 16:39:45 2020 from 192.168.1.1 Welcome to Kernera restricted shell! Try 'help' or ^D to quit. [0] krsh>
Syntax
Lines starting with a # are considered a comment and ignored. Commands are separated by ; or a newline. The first word is the command itself, following words are arguments.
The following snippet calls two commands "foo" and "bar" with respective arguments a, b, c and d, e, f:
krsh> foo a b c ; bar d e f
Builtins
The shell includes the following builtin commands:
- help
-
List or describe command(s).
- power
-
List power compatible units.
- poweron
-
Power on some or all power units.
- poweroff
-
Power off some or all power units.
- reboot
-
Reboot some or all power units.
- remote
-
List remote units or connect to a remote host unit.
- ssh
-
Alias for remote.
- scp
-
Adapter for file transfer over SSH.
- tty
-
List TTY compatible units or access a serial port.
For more information about a command and its arguments, type help command.
Debugging
All non-user messages are sent to the system logger. On a system using systemd, debug messages and system errors can be tracked with:
# journalctl -f -t krsh
OPTIONS
- -c
-
Read commands from the command_string operand.
- -i
-
Specify that the shell is interactive.
- -s
-
Read commands from the standard input.
If there are no operands and the -c option is not specified, the -s option is assumed.
If the -i option is present, or if there are no operands and the shell’s standard input and standard output are attached to a terminal, the shell is considered to be interactive.
CONFIGURATION
By default, krsh looks for the configuration file ~/.krsh/config in the current working directory.
The configuration file is a plain text ini-style file describing units, inspired from the syntax used in systemd unit files.
Each section describes a single unit. The section title describes the unit type and its properties describe common unit properties or type-specific properties. A property may refer to the name of a previously described unit or simply a text value. Both section titles and properties use the upper camel case syntax.
The following configuration options are common to all unit types.
- Name=
-
A unique identifier for the unit. Units refer to each other using this string.
- Description=
-
A human readable label describing the unit.
[Command] UNITS
This section describes units of the command subsystem. A command is a generic user-specified program added to the existing set of commands. The unit Name= identifies the command interpreted by the shell. Additional arguments are passed to the program as is.
- Synopsis=
-
Optional string describing the command usage.
The following example adds a "list" command which lists the binary images found in the TFTP directory.
[Command]
Name=list
Description=List binary images bootable via TFTP.
Path=/opt/tftplist.sh
Synopsis=list [type]
#!/bin/bash
cd /srv/tftp
set -- ${*:-linux oftree initramfs}
for type in $*
do
case $type in
linux) file * | grep 'ARM OpenFirmware' | cut -d: -f1 ;;
oftree) file * | grep 'Device Tree Blob' | cut -d: -f1 ;;
initramfs) file * | grep 'ASCII cpio archive' | cut -d: -f1 ;;
*) echo "Invalid type $type." >&2 ; exit 1 ;;
esac
done
krsh> list zImage vf610-zii-dev-rev-b.dtb vf610-zii-dev-rev-c.dtb rootfs.cpio
[Directory] UNITS
This section describes units of the directory subsystem. A directory unit is used to filter file transfer via SSH. The unit Name= identifies the directory used during the invocation of scp(1). Only uploading is allowed at the moment.
- Path=
-
Real path to the directory passed to scp(1).
The following example exposes a "tftpboot" directory pointing to /srv/tftp/myboard/ used to upload bootable images.
[Command]
Name=tftpboot
Description=Directory containing bootable images
Path=/srv/tftp/myboard
Assuming that this shell is installed as the login shell for the user "bench" on the host "server", the following command uploads the "zImage" file to the TFTP directory:
scp ./build/zImage bench@server:tftpboot/
[Link] UNITS
This section describes units of the link subsystem. A link unit is used to describe a network cable connecting a local interface to a remote interface. Such unit has no usage at the moment except for documentation purpose.
- LocalInterface=
-
Name of the local network interface.
- RemoteInterface=
-
Name of the network interface on the remote machine.
- Remote=
-
Name of the remote unit.
The following example describes a network cable connected to the machine "foobar".
[Remote]
Name=foobar
[Link]
LocalInterface=enp0s2
RemoteInterface=eth1
Remote=foobar
[Power] UNITS
This section describes units of the power subsystem. A power unit describes a single port of a power distribution unit.
- Driver=
-
Name of the builtin driver used to control the power distribution unit. The list of supported power drivers include synaccess (for the NetBooter family) and webrelay (for the WebRelay device). A driver is a command named power-Driver= executed with the environment variables KRSH_POWER_HOSTNAME and KRSH_POWER_PORT, and poweron, poweroff or reboot as the first argument.
- Hostname=
-
Network name or address of the power distribution unit.
- Port=
-
Number of the port on the power distribution unit.
The following example power cycle the "foobar" board connected on the port 3 of a Synaccess device.
[Power]
Name=pdu3
Driver=synaccess
Hostname=192.168.42.100
Port=3
[Remote]
Name=foobar
Power=pdu3
krsh> reboot foobar
[Remote] UNITS
This section describes units of the remote subsystem. A remote unit groups a directory, power and TTY, and describes the logging into a remote machine.
- Hostname=
-
Network address or name of the remote machine.
- User=
-
Name of the user to log in as on the remote machine.
- Password=
-
User password to log in on the remote machine.
- Directory=
-
Name of the directory unit associated with this remote.
- Power=
-
Name of the power unit associated with this remote.
- TTY=
-
Name of the TTY unit associated with this remote.
The following example executes a command on a remote machine "foobar".
[remote]
Name=foobar
Hostname=192.168.42.203
User=root
Password=w00t
krsh> remote foobar uname -a Linux foobar 5.8.0-rc1 #89 Thu Jun 25 21:32:33 EDT 2020 armv7l GNU/Linux
Note
|
Accessing a remote makes use of ssh(1) and sshpass(1) if Password= is defined, thus these packages must be installed. |
[TTY] UNITS
This section describes units of the TTY subsystem. A TTY unit provides shared connection to a serial interface. If two users access a TTY unit at the same time, both will have read and write access to it.
Note
|
Non-root system users of the shell must be part of a specific group to access serial ports, such as "dialout" or "uucp" (see ls -l /dev/ ).
|
- Device=
-
Pathname of the local serial port.
- Baudrate=
-
Optional baudrate for the serial port.
The following example exposes /dev/ttyUSB0 as "tty0".
[TTY]
Name=tty0
Device=/dev/ttyUSB0
Baudrate=115200
Note
|
The current TTY driver use dtach(1) and picocom(1) to share a serial port, thus these packages must be installed. |
SEE ALSO
chsh(1), ssh(1), scp(1)
AUTHORS
krsh is written by Vivien Didelot and other contributors.
RESOURCES
Project web site: https://kernera.github.io/krsh
Git source repository and issue tracker: https://github.com/kernera/krsh
Manual page: krsh(1)
COPYING
Copyright © Vivien Didelot.
Free use of this software is granted under the terms of the GPLv3+ License.