gems: add interactive SSH Terminal component
This component allows access to Terminal sessions via interactive SSH sessions. Please read _repos/gems/src/server/ssh_terminal/README_ for more detailed information. Fixes #3014.
This commit is contained in:
parent
82fb76c142
commit
9557e64822
|
@ -0,0 +1,12 @@
|
|||
SRC_DIR := src/server/ssh_terminal
|
||||
include $(GENODE_DIR)/repos/base/recipes/src/content.inc
|
||||
|
||||
MIRROR_FROM_LIBPORTS := lib/mk/libc_pipe.mk \
|
||||
src/lib/libc_pipe \
|
||||
include/libc-plugin
|
||||
|
||||
content: $(MIRROR_FROM_LIBPORTS)
|
||||
|
||||
$(MIRROR_FROM_LIBPORTS):
|
||||
mkdir -p $(dir $@)
|
||||
cp -r $(GENODE_DIR)/repos/libports/$@ $(dir $@)
|
|
@ -0,0 +1 @@
|
|||
2018-10-01 149f13d8d187bc35e8ce7875ac41b83a11682ba5
|
|
@ -0,0 +1,10 @@
|
|||
base
|
||||
gems
|
||||
libc
|
||||
libssh
|
||||
nic_session
|
||||
report_session
|
||||
os
|
||||
terminal_session
|
||||
timer_session
|
||||
vfs
|
|
@ -0,0 +1,197 @@
|
|||
#
|
||||
# \brief Test for the SSH terminal
|
||||
#
|
||||
|
||||
assert_spec x86
|
||||
|
||||
if {[have_spec linux]} {
|
||||
puts "Run script is not supported on this platform."
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Build
|
||||
#
|
||||
|
||||
set build_components {
|
||||
core init
|
||||
drivers/timer
|
||||
drivers/nic
|
||||
drivers/rtc
|
||||
server/ssh_terminal
|
||||
lib/libc_noux
|
||||
lib/vfs/jitterentropy
|
||||
lib/vfs/lxip
|
||||
test/libports/ncurses
|
||||
test/terminal_echo
|
||||
noux
|
||||
noux-pkg/bash
|
||||
}
|
||||
|
||||
source ${genode_dir}/repos/base/run/platform_drv.inc
|
||||
append_platform_drv_build_components
|
||||
|
||||
build $build_components
|
||||
|
||||
create_boot_directory
|
||||
|
||||
#
|
||||
# Generate config
|
||||
#
|
||||
|
||||
set config {
|
||||
<config verbose="no">
|
||||
<parent-provides>
|
||||
<service name="ROM"/>
|
||||
<service name="RAM"/>
|
||||
<service name="IRQ"/>
|
||||
<service name="IO_MEM"/>
|
||||
<service name="IO_PORT"/>
|
||||
<service name="PD"/>
|
||||
<service name="RM"/>
|
||||
<service name="CPU"/>
|
||||
<service name="LOG"/>
|
||||
</parent-provides>
|
||||
<default-route>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</default-route>
|
||||
<default caps="100"/>
|
||||
<start name="timer">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides> <service name="Timer"/> </provides>
|
||||
</start>
|
||||
<start name="report_rom">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides> <service name="Report"/> <service name="ROM"/> </provides>
|
||||
<config verbose="yes"/>
|
||||
</start>
|
||||
<start name="nic_drv">
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<provides> <service name="Nic"/> </provides>
|
||||
</start>
|
||||
<start name="rtc_drv">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides> <service name="Rtc"/> </provides>
|
||||
</start>
|
||||
<start name="ssh_terminal" caps="250">
|
||||
<resource name="RAM" quantum="32M"/>
|
||||
<provides> <service name="Terminal"/> </provides>
|
||||
<config port="22" allow_password="yes"
|
||||
show_password="yes" ed25519_key="/etc/ssh/ed25519_key">
|
||||
<policy label_prefix="noux" user="noux" password="xuon" multi_login="yes" request_terminal="yes"/>
|
||||
<policy label_prefix="test-terminal_echo" user="charlie" password="echo"/>
|
||||
|
||||
<vfs>
|
||||
<dir name="dev">
|
||||
<log/>
|
||||
<jitterentropy name="random"/>
|
||||
<jitterentropy name="urandom"/>
|
||||
<rtc/>
|
||||
</dir>
|
||||
<dir name="etc">
|
||||
<dir name="ssh">
|
||||
<rom name="ed25519_key"/>
|
||||
</dir>
|
||||
</dir>
|
||||
<dir name="socket"> <lxip dhcp="yes"/> </dir>
|
||||
</vfs>
|
||||
<libc stdout="/dev/log" stderr="/dev/log" socket="/socket" rtc="/dev/rtc">
|
||||
</libc>
|
||||
</config>
|
||||
<route>
|
||||
<service name="Report"> <child name="report_rom"/> </service>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</route>
|
||||
</start>
|
||||
<start name="test-terminal_echo">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
</start>
|
||||
<start name="noux" caps="500">
|
||||
<resource name="RAM" quantum="64M"/>
|
||||
<config verbose="yes">
|
||||
<fstab>
|
||||
<tar name="bash.tar" />
|
||||
</fstab>
|
||||
<start name="/bin/bash">
|
||||
<env name="TERM" value="screen"/>
|
||||
<env name="HOME" value="/"/>
|
||||
<env name="IGNOREEOF" value="3"/>
|
||||
</start>
|
||||
</config>
|
||||
</start>
|
||||
}
|
||||
|
||||
append_platform_drv_config
|
||||
|
||||
append config {
|
||||
</config>}
|
||||
|
||||
install_config $config
|
||||
|
||||
#
|
||||
# Generate a new host key
|
||||
#
|
||||
if {![file exists bin/ed25519_key]} {
|
||||
exec ssh-keygen -t ed25519 -f bin/ed25519_key -q -N ""
|
||||
}
|
||||
|
||||
#
|
||||
# Boot modules
|
||||
#
|
||||
|
||||
# generic modules
|
||||
set boot_modules {
|
||||
core ld.lib.so init timer nic_drv rtc_drv report_rom
|
||||
noux test-terminal_echo
|
||||
|
||||
libc.lib.so pthread.lib.so libm.lib.so vfs.lib.so
|
||||
vfs_lxip.lib.so lxip.lib.so libc_pipe.lib.so libc_noux.lib.so
|
||||
posix.lib.so libcrypto.lib.so libssh.lib.so zlib.lib.so ncurses.lib.so
|
||||
vfs_jitterentropy.lib.so ssh_terminal
|
||||
|
||||
bash.tar ed25519_key
|
||||
}
|
||||
|
||||
# platform-specific modules
|
||||
append_platform_drv_boot_modules
|
||||
|
||||
build_boot_image $boot_modules
|
||||
|
||||
#
|
||||
# Execute test
|
||||
#
|
||||
|
||||
append qemu_args " -m 512 -nographic "
|
||||
|
||||
append_if [have_spec x86] qemu_args " -net nic,model=e1000 "
|
||||
|
||||
append qemu_args " -net user -redir tcp:5555::22 "
|
||||
|
||||
set lxip_match_string "ipaddr=(\[0-9\]+\.\[0-9\]+\.\[0-9\]+\.\[0-9\]+).*\n"
|
||||
|
||||
if {[get_cmd_switch --autopilot]} {
|
||||
run_genode_until $lxip_match_string 60
|
||||
set serial_id [output_spawn_id]
|
||||
|
||||
if {[have_include "power_on/qemu"]} {
|
||||
set host "localhost"
|
||||
set port "5555"
|
||||
} else {
|
||||
regexp $lxip_match_string $output all host
|
||||
puts ""
|
||||
set port "22"
|
||||
}
|
||||
# wait for ssh_terminal to come up
|
||||
sleep 5
|
||||
spawn sshpass -p xuon ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -l noux $host -p $port
|
||||
set ssh_id $spawn_id
|
||||
set spawn_id_list [list $ssh_id $serial_id]
|
||||
run_genode_until "--- noux started ---" 15 $spawn_id_list
|
||||
puts ""
|
||||
puts ""
|
||||
} else {
|
||||
run_genode_until forever
|
||||
}
|
||||
|
||||
exec rm bin/ed25519_key bin/ed25519_key.pub
|
||||
|
||||
# vi: set ft=tcl :
|
|
@ -0,0 +1,114 @@
|
|||
This directory contains an minimal SSH Terminal server. It provides
|
||||
concurrent access to multiple Terminal sessions via interactive SSH sessions.
|
||||
Before using the component, please consult the _Notes_ section to learn
|
||||
about the current subtleties.
|
||||
|
||||
For an example on how to use the server please look at the run script
|
||||
provided by _repos/gem/run/ssh_terminal_.
|
||||
|
||||
|
||||
Configuration
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
Examplary configuration:
|
||||
|
||||
! <config port="2022" ed25519_key="/etc/ed25519_host_key
|
||||
! allow_password="yes" allow_publickey="yes"/>
|
||||
! <vfs>
|
||||
! <policy label="noux-system" user="root" password="toor"/>
|
||||
! <policy label="noux-user" user="user" pub_key="/etc/user.pub"/>
|
||||
!
|
||||
! <dir name="dev">
|
||||
! <log/> <rtc/>
|
||||
! <inline name="random">012345678</inline>
|
||||
! </dir>
|
||||
! <dir name="socket"> <lxip dhcp="yes"/> </dir>
|
||||
! <dir name="etc"> <fs/> </dir>
|
||||
! </vfs>
|
||||
! <libc stdout="/dev/log" stderr="/dev/log" rtc="/dev/rtc" socket="/socket"/>
|
||||
! </config>
|
||||
|
||||
The above config snippet shows a configuration where two Noux clients may
|
||||
connect to the Terminal server and SSH connections with either a password or a
|
||||
public are processed on port 2022. All SSH logins for the user 'root' are
|
||||
linked to the 'noux-system' session, while all 'user' logins are forwarded
|
||||
to the 'noux-user' session.
|
||||
|
||||
The '<config>' node has several mandatory attributes:
|
||||
|
||||
* 'port' specfies the TCP port the SSH server attempts to listen on.
|
||||
|
||||
* 'ecdsa_key', 'ed25519_key' and 'rsa_key' set the respective
|
||||
path to the host key. At least one of them must be specified.
|
||||
|
||||
* 'allow_password' enables password logins while 'allow_publickey'
|
||||
enables public-key logins. At least one of them must be specified.
|
||||
Those Authentication methods are set for all logins even if they
|
||||
are not useable by one or the other.
|
||||
|
||||
Aside from the mandatory attributes there are optional ones:
|
||||
|
||||
* 'log_logins' enables logging of login attempts. These attempts will
|
||||
be printed to the LOG session. The default is 'yes'.
|
||||
|
||||
The relation between a Terminal session and a SSH session is established
|
||||
by a '<policy>' node. It first specifes which Terminal client may access
|
||||
the server. Second and more importantly it specifies which SSH session has
|
||||
access to which Terminal session. The non policy-label specific attributes
|
||||
of the node form a login that is used to authenticate access via the SSH
|
||||
session:
|
||||
|
||||
* 'user' sets the name of a login and is used throughout the component
|
||||
to establish the relation between Terminal and SSH session and is therefor
|
||||
mandatory.
|
||||
|
||||
* 'password' sets the password of the login, which is used to authenticate
|
||||
a login attempt.
|
||||
|
||||
* 'pub_key' sets the path to the public-key file, which is used to authenticate
|
||||
a login attempt.
|
||||
|
||||
* 'multi_login' allows one Terminal session to be used by mutliple SSH
|
||||
sessions concurrently, the default is false.
|
||||
|
||||
Either one of the 'password' or 'pub_key' attributes must be set in order for
|
||||
the login to be valid.
|
||||
|
||||
Normally, all Terminal sessions are expected to be established before an SSH
|
||||
connection is made. To accommdate the use-case where the Terminal client is
|
||||
made available in a dynamic fashion, the 'request_terminal' attribute can by
|
||||
set to 'yes'. In this case the SSH Terminal server will generate a report,
|
||||
which then can be inspected and reacted upon by a management component,
|
||||
whenever a SSH connection for a detached Terminal session is made. Data coming
|
||||
from the SSH session will be ignored as long as the Terminal client is not
|
||||
attached to the server. This mechanism is useful in cases where the attached
|
||||
Terminal might terminate itself, e.g. a shell when receiving EOF, but a
|
||||
subsequent login attempt expects the Terminal client to be still attached.
|
||||
|
||||
The following snippet shows such a report:
|
||||
|
||||
! <request_terminal user="baron"/>
|
||||
|
||||
The component will generate the report only once when the first login
|
||||
via SSH is made and the corresponding Terminal session is not available.
|
||||
All subsequent logins have to wait until the session is provided. If
|
||||
there are active SSH session after the Terminal in question has been detached,
|
||||
a new report will be generated.
|
||||
|
||||
|
||||
Notes
|
||||
~~~~~
|
||||
|
||||
* The SSH connection MUST be forcefully cut at the client, e.g. when
|
||||
using OpenSSH by entering '~.'.
|
||||
|
||||
* Using tools that require an exec channel, e.g. scp(1) and rsync(1), is not
|
||||
supported.
|
||||
|
||||
* Host keys can be generated by using ssh-keygen(1) on your host system
|
||||
(e.g., 'ssh-keygen -t ed25519_key -f ed25519_key' without a passphrase and
|
||||
then use the 'ed25519_key' file).
|
||||
|
||||
* Although concurrent access to one Terminal session via multiple SSH sessions
|
||||
at the same time is possible, it should better be avoided as there are no
|
||||
safety measures in place.
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,5 @@
|
|||
TARGET = ssh_terminal
|
||||
SRC_CC = main.cc
|
||||
LIBS = base libc pthread libssh libc_pipe
|
||||
|
||||
CC_CXX_WARN_STRICT =
|
Loading…
Reference in New Issue