How to attach ttyS to screen and capture it simultaneously - linux

For capturing ssh sessions I use "script" command: "script -c 'ssh user#host' outfile". But I have no idea how to capture sessions to remote hosts, that connected over com(serial) port.
screen script -c 'screen /dev/ttyS0 57600' file
ends immediately with empty log. Both 2 functions that implemented in screen is necessary: ability to switch between opened sessions and ability to perform i/o to /dev/ttyS. I started develop some tiny utility to redirect stdin/stdout to /dev/ttyS but now it's so buggy and doesn't work yet.

First off, a terminal program, like minicom (or good-ol cu), as suggested by Laszlo, is needed to communicate with the remote system. Once you can get such a program to work, then screen can be brought into the picture. Note that this also requires a getty running on the remote computer's serial port. If it's an old-fashioned serial port, you may also need a special null-modem cable.
Screen can be used with such a connection to be able to move access of the session across terminals. However, it cannot be used to spawn more than one session with the remote server. That's because the program running on the serial port (getty) only supports a single session. In this case, the screen runs on the local machine, and the terminal-program session running within screen connects to the remote server. So, it is possible to have multiple screens, but just not more than one connected to the remote server over a single serial port.
With all of that said, serial ports can be used to network two machines, assuming both support the same serial-line networking protocol. Networking eliminates these restrictions.

To open an interactive terminal session to a COM port (/dev/ttyS*), you probably want to use a terminal emulator software, like 'minicom'.

Related

How to start and stop an external program in another device using Qt?

I'm developing a firmware updater that should download data from a web server and upload it to an Embedded Linux device.
I want a program (client) to start another program (server) before establishing a connection between them and start sending the data. To do that in the same environment is easy: just call QProcess and startDetached(), but I want to do that remotely: I want to start the client in the Desktop machine and, with the device connected via ETH/TCP in a known IP address, click a button which will ask the device to start the server. When the server finishes starting and start waiting for connections, the Desktop app will then open the socket connection and start sending the data. After all data have being send, another command should be send to ask the server to shut down, closing the connection and finishing the file transfer operation.
My question is: how can I do this operation of asking for an application to either start or stop when it is located in a different machine (in an Embedded Linux device while the caller is in a PC)? Notice that the solution must be such that doesn't depend on some extra software (such as a Tcp server) to constantly run on the device - that's precisely what I'm trying to avoid.
This is not related to Qt in any way, because it doesn't provides anything for that purpose.
There are at least two paths from this point:
use SSH from your application to start any process in the remote machine: ssh user#remote-machine "any command here". This can be called using QProcess;
or
write another software to listen to socket commands and start/stop any process you want, then get it running all the time in the remote machine. Then, it's just a matter of changing your client software to send the relevant commands
Beware of any security issue that may arise by allowing the machine to execute arbitrary commands from external sources.

Handle terminal window closing

I'm currently working on an automation script that connects users via telnet to different ports (for different command interpreters) on an embedded system. Since the amount of available memory is pretty low on the system, the number of telnet sessions is limited. If a user doesn't close the telnet session normally, the server-side session will just hang and use up an available telnet session. Is there a way in tcl/expect to send commands/execute a procedure before an xterm window closes?
I did some googling, at it turns out expect supports the trap command which allows to run a script when a certain Unix signal is sent to the process hosting the interpreter.
It appears you have to trap SIGHUP but may be you'll also need to trap SIGTERM and/or SIGQUIT. man 7 signal — if on a Linux-based OS — for more info (on a different OS flavor the manual page section may be different).

How to provide "reverse ssh" to a shell?

Scenario:
Many embedded devices (running Linux) out in the fields, behind routers so NAT'd and we can't make connections to them.
We need for a support person to be able to initiate a terminal/shell session on any of the devices.
Their local terminal will also be NAT'd behind a corporate firewall, so we need some central "meeting point" that both they and the device can connect to.
If necessary, we could require the support person to log into some sort of terminal server, but I'd prefer a solution that just popped up a terminal window on their desktop.
We can (through other means) tell the device to execute some arbitary script or application to start up the session.
Without the NAT, it's just SSH to the device and away we go. But what are my options in this NAT'd environment?
We're OK to develop code at either end or at the meeting point server if required, but obviously if there are apps out there so we don't have to write stuff, even better.
Pointers to other questions I may have missed (although I have looked) or to applications that I should consider for the central "meeting point" server welcomed
How about simply setting up an ssh server that is reachable by both the device and the support user, and have the device set up a reverse tunnel (using remote port forwarding)?
ssh -R 10022:localhost:22 device#server
Then the support personnel can simply connect to the server and log on using
ssh -p 10022 localhost
Of course there are several security aspects that need to be accounted for here, depending on what kind of information the devices hold/have access to and how the support organization is set up.
SSH is an adequate tool for this. You will, as you say, need a middle-man server. But it would be very easy to set up, assuming that your 'other means of executing a script' are remote and can be executed from your office.
So, fire up a new server on a global IP (an Amazon AWS micro node is free for a year and would do the job just fine), and install an ssh deamon. Say it has the hostname middleman.example.org.
The script to put onto your embedded devices would look like;
#!/bin/bash
ssh -i ./middle_id.pem -R 22:localhost:2222 middleuser#middle.example.org
(The private key authentication would be a way of making the login non-interactive)
The script to put onto your desktop machines would look like; (assuming the argument $1 is the IP of the embedded device, and that prod_remote_device.sh executes the above script on the chosen embedded device.)
#!/bin/bash
./prod_remote_device.sh $1
ssh -i ./device_id.pem deviceuser#middle.example.org:2222
And that should forward your connection to the embedded device.
In order to make it bind to all interfaces, use:
ssh -N -R 0.0.0.0:2222:localhost:22 root#example.com
Don't forget to edit /etc/ssh/sshd_config and go to GatewayPorts and enable it and set it to yes.
And Then connect to it from any Loopback or Ethernet interface.

Software serial port loopback on linux

Currently I need to develop some program that will communicate with cisco devices over serial line. I want to build testing environment on my development linux machine. So, I found dynamips cisco emulator. This emulator can provide interface via serial line with '-U /dev/ttyS0' option. Well, this causes dynamips to open hardware serial port and communicate via it. I'm able to connect to this hardware serial port from another linux machine with serial client like minicom.
However, since i'm using virtualbox for both linux machines, I link serial ports via virtualbox ability to forward serial port to named pipe. This scheme seems to be working, but very redunant. I'm looking for a method to run dynamips and minicom on a single linux machine.
I found that pseudo-terminals could be useful in my case. But I've tried to run dynamips with '-U /dev/ptmx' and then connect with minicom to created /dev/pts/... port and vice versa. In both cases I've got input/output error on both sides.
Unfortunately, modern pseudo-terminals aren't that easy. After opening the master with posix_openpt() or open("/dev/ptmx"), you must call grantpt() and unlockpt() on the master FD before it and its corresponding slave device are usable. (The openpty() etc. utility functions simplify this.)
As a workaround, the ever handy socat may be of use.
# terminal 1
socat pty:link=$PWD/pts unix-l:$PWD/ptm-pipe &
dynamips -U $PWD/pts
# terminal 2
socat unix:$PWD/ptm-pipe -

Get two Linux (virtual) boxes talking over a serial port

What is the best way to setup one Linux box to listen on its serial port for incoming connections? I've done a lot of googling but I can't find the right combination of commands to actually get them to talk!
My main objective is to provide a serial interface to running instances of kvm/qemu VMs. They currently only have a VNC interface (they are on headless servers, no X). I can get the VM to create a serial device by starting it with the -serial file: flag, but how to talk to it, is a whole other problem. Both boxes are running Ubuntu 8.04.
The Linux Serial HOWTO has a lot of detailed information about serial communication in general. The more-specific Linux Remote Serial Console HOWTO is what you're really looking for if you want to be able to log into your virtualized systems using the serial port as if you were at the console. As Hein indicated, you'll need a null modem cable and need to run minicom on the remote terminal.
The Linux console is used in two ways, each of which must be configured separately for serial use. You can configure the kernel to copy its messages over the serial port, which is occasionally interesting for watching the system boot and nearly indispensable if you're doing kernel debugging. (This requires kernel support and updating the boot parameters so the kernel knows you want serial output; see chapter 5 of the second howto.) You're probably more interested in logging in via the serial port, which requires running getty on the serial port after boot (just like your system already runs getty on the virtual terminals after boot), which is described in detail in chapter 6 of the howto.
I assume you connect the two serial ports using a "null modem" cable.
Use a program like minicom to talk to remote system -- you probably need to set up the communication parameters and possibly turn off hardware flow control (if your cable doesn't have the flow-control lines connected).
Say you're doing this on /dev/tty1.
in the shell
chown *youruser* /dev/tty1
then in a Perl script called example.pl
open PORT, "</dev/tty1" || die "Can't open port: $!";
while (defined ($_ = <PORT>))
{
do_something($_);
}
close PORT;
Obviously there is more to do if you want this to start automatically, and respawn on error, and so on. But the basic idea is to read from the serial port like a file.

Resources