24. Remote access


24.1. Overview

Agents offering the REMOTE service provide text messaging, file transfer, and remote command execution services across a network.

While the REMOTE service provides a field for credentials to be included in a request, it does not specify how authentication and security should be handled by an agent. It is important for developers and users of the REMOTE service to give due consideration to network security before enabling this service on their network.

24.1.1. Messages

Agents providing the REMOTE service support the following messages:

  • RemoteTextReq AGREE / REFUSE / FAILURE — send a text message to remote node

  • RemoteFileGetReq AGREE / REFUSE / FAILURE — download a file from remote node

  • RemoteFilePutReq AGREE / REFUSE / FAILURE — upload a file to remote node

  • RemoteExecReq AGREE / REFUSE / FAILURE — execute a shell command on the remote node

  • RemoteTextNtf — sent to the agent’s topic when a text message from another node arrives

  • RemoteFileNtf — sent to the agent’s topic when an incoming file transfer from another node is completed

  • RemoteSuccessNtf — sent to a requester when a remote operation is successfully completed, if an acknowledgement was requested

  • RemoteFailureNtf — sent to a requester when a remote operation fails, if an acknowledgement was requested

24.2. RemoteControl

Start the 2-node network and connect to node A:

> agentsForService org.arl.unet.Services.REMOTE
> remote
« Remote control »

Text messaging and remote command execution service.

  cwd = /Users/mandar/tmp/unet-3.2.0/scripts
  dsp = transport
  enable = false
  groovy = true
  reliability = true
  shell = websh

We see that the REMOTE service is provided by the remote agent of type RemoteControl . The agent’s behavior is controlled by several parameters:


Current working directory. This directory is the reference location for all file transfers and command execution.


Datagram service provider. This is the agent that is used to deliver datagrams.


SHELL service provider (see Chapter 27 ) used to execute commands. When a remote command is to be executed, a request is sent to this shell agent to execute the command.


Enable Groovy extensions for shell commands. This should only be enabled if the shell is a Groovy shell. The only Groovy extension defined at this point in time is the ? shortcut. Starting a command with a ? automatically sends the output of the command back to the requesting node (e.g. ?phy.MTU is equivalent to tell me, phy.MTU as String ). We have encountered the use of this extension before in Section 5.5 .


Setting this to true enables reliability for all datagrams used by the agent.


Setting this to true enables incoming remote file operations and remote commands. The parameter is false by default, for security reasons. Outgoing remote operations are always enabled, irrespective of this parameter. Incoming and outgoing text messaging is also always enabled when this agent is loaded.

The default RemoteControl agent in the basic stack does not implement any authentication. Once enabled, it will accept all file transfer and remote command execution requests. Care should be taken not to enable it in networks where malicious hackers may be able to send harmful requests to your node.
The phy[CONTROL].scrambler and phy[DATA].scrambler parameters available in many UnetStack-based modems provide a basic level of protection against malicious hackers by scrambling each transmission in the modem. Setting the scrambler to a "secret" value (64-bit key) in all your nodes enables this basic protection. Do bear in mind that scrambling is not a crypotgraphically strong technique, and will not protect you from a serious hacker. The technique is also vulnerable to playback attack, even if the malicious hacker is unable to unscramble your frame.

All remote commands ( tell , fget , fput , rsh , and ack ) encountered in Section 5.4 and Section 5.5 are implemented by the shell using the above messages. For example, the same effect as the tell command can be achieved by directly sending the RemoteTextReq message to the remote agent on node A:

> remote << new RemoteTextReq(to: host('B'), text: 'hello!', ack: true)
remote >> RemoteSuccessNtf:INFORM[RemoteTextReq:REQUEST[to:31 text:hello! ack:true]]

We should see the text message delivered on node B:

[232]: hello!

We encourage you to re-read Section 5.5 and explore the command’s help documentation ( help remote ) to fully appreciate the use of this service.

<<< [Transport service] [State persistence] >>>