As I think it’d distract too much from the CoAP security thread I’d like to pull the CoAP remote shell topic out; @Kaspar and @miri64 made very good points there, and it’s not the first time this comes up.
My (also historical, but largely maintained) position on the shell over network is shaped by two observations:
- I’m personally not a heavy shell user on RIOT (I am on Linux, but that’s a different story).
- Shell commands are diverse beasts. Many of them behave as “single input, single ouput” (with the output being practically immediate / one could block everything but interrupts until it’s here), but there are progressiv-output commands (ping), commands with delayed output (CoAP client) and possibly interactive commands.
Their diversity makes it hard to abstract over them, and makes any sufficiently powerful CoAP interface either complex (different interaction patterns for different beasts of commands) or ugly (emulating a stream of input and output).
The road I’d like to take on the shell is to provide idiomatic remote replacements for shell commands. Some work on that I’ve already started in the Rust riot-coap-handler-demos. These already provide a simple ps
, an even more minimal netif
(like ifconfig; ugly addresses shown here because CBOR tag support is broken in my implementation):
Transcript (because I can't copy-paste the colorful HTML my shell creates in here)
$ ./aiocoap-client 'coap://[2a02:b18:c13b:8014:a8a8:6858:5197:8001]/ps/' CBOR message shown in naïve Python decoding [[1, 'Sleeping', 'main'], [2, 'ReceiveBlocked', '6lo'], [3, 'ReceiveBlocked', 'ipv6'], [4, 'ReceiveBlocked', 'udp'], [5, 'Running', 'coap'], [6, 'ReceiveBlocked', 'nrf802154']] $ ./aiocoap-client 'coap://[2a02:b18:c13b:8014:a8a8:6858:5197:8001]/netif/' CBOR message shown in naïve Python decoding [[6, b'\xaa\xa8hXQ\x97\x80\x01', [b'\xfe\x80\x00\x00\x00\x00\x00\x00\xa8\xa8hXQ\x97\x80\x01', b'*\x02\x0b\x18\xc1;\x80\x14\xa8\xa8hXQ\x97\x80\x01']]] $
It also provides minimal support for GPIOs (no setup yet, just reading and writing), graphics (setting images on supported displays like the microbit one) and some i2p. Also for a ping I have plans, and (still in C) also for file system access. All these can be compact on the air, and support block-wise without any additional buffers.
This is how I think things should be on the long run. Enhancements to the tooling on the CoAP side could help make the experience more shell-like. Access control can be done on a by-command or even ore detailed. (Plus some of these might be easy to turn into shell commands with a more readable serialization, just not the other way 'round).
Now that leaves the issue of transition, and of cases where we do want interactive commands.
That case I’ve so far left out of consideration because of observation 1.
One thing that’s already included in the above demos (but not executed well yet) is the “other” side of shell: Interacting with stdio in the role of a program (ie. making RIOT put characters out on the stdio UART, and reading from them). But that could just as well be short-circuited into a buffered stdio, so that any existing application with printf etc could be run. The USB and semihosting stdio implementations are probably good templates.
The downside of this generality is that it’s not a pretty interface, CoAP-wise: There’d need be POSTs to send input with checks for lost messages (or full lock-stepping) and manual deduplication (no RIOT CoAP library deduplicates), and an GET+Observe for output (with some trickery to ensure a continuous flow and recovery). Using this would need tooling we don’t currently have on the client side – I can probably come up with something in aiocoap, if that’s sufficiently universal.
On the side, most of this can probably double as remote UART – either way, it’s Telnet over CoAP.
To tie everything back to the original topic, most of this (and definitely the second half) is only viable if we have a good security story for overall CoAP use with RIOT; unless that’s set up, a remote shell should nowhere be default, and only activated after having clicked through a very explicit warning about how wide open the system is.
</ted-talk>