25 Jul 2021 - tsp
Last update 25 Jul 2021
7 mins
A common problem: Sharing a single physical serial port on multiple machines - or having to access a remote serial port for example for a machine interface, laboratory equipment, etc. from a remote machine. Or having some annoying Windows (or some Linux version) only Software required for some FPGAs or microcontrollers that should be used to flash from a host running some sane open operating system while running the tools on some isolated virtual machine on one of the XEN VM hosts. It’s also a nice utility for small datacenter management in case one has old machines that don’t offer more sophisticated remote management solutions and wants to access the serial terminals of the machines via the network for manual setup (like for example when renting root servers, etc.)
The solution: Running a console server that’s reachable via the network. In this blog post a solution is described that builds on a set of software:
ser2net
to offer a serial (RS232, RS485, etc.) port via the
network, even allowing configuration using RFC2217.socat
to create a local virtual com port and establish the connection.com0com
to create a local Null-Modem connection that offers two
interconnected virtual serial ports.hub4com
that also includes com2tcp-rfc2217
which can connect
one side of the local virtual nullmodem ports to a remote RFC2217 service.The server in this case is the host offering the physical serial ports. These might be RS232 ports, RS485 interfaces or simple USB to TTL/CMOS serial converters.
The latest host I personally built consisted of (note: Links are Amazon affiliate links, this pages author profits from qualified purchases):
First one has to install the ser2net
service. On FreeBSD this is pretty
easy:
pkg install comms/ser2net
On Linux ser2net
is included in many package repositories. It’s configured
via the /usr/local/etc/ser2net.conf
file (/etc/ser2net.conf
on Linux).
Usually there is a sample configuration file that’s also deployed. The configuration
basically includes a list of ports that are exposed on dedicated ports. A typical
configuration line looks like:
7000:telnet:3600:/dev/ttyU0:57600 8DATABITS NONE 1STOPBIT remctl
This line would expose the device /dev/ttyU0
with a default BAUD rate
of 57600
bits per second on port 7000 with 8 bits per byte, no parity
and one stop bit. It would also allow remote control using RFC2217 which allows
the remote to set BAUD rate, byte size, parity and stop bits itself. ser2net
would also allow a raw
mode instead of telnet which is even more easy
when one develops own software - but telnet
mode is supported by the Windows
software mentioned later on.
The third value in the configuration file specifies a timeout value - if no traffic is routed over the given port for the specified amount of seconds it gets disconnected automatically.
One might also specify a custom banner that’s displayed on connection:
BANNER:banner:Serial host server
This might be interesting in case there are multiple devices in use to allow easier manual identification.
After configuration one can auto-start ser2net
on every boot by adding
the setting to /etc/rc.conf
:
ser2net_enable="YES"
Since new rc.init
script system one might also simply use /usr/local/etc/rc.d/ser2net enable
.
After that one can manually start the service:
/usr/local/etc/rc.d/ser2net start
This is rather simple - there is a utility called socat
. On FreeBSD this
is available at net/socat
and can simply be installed using pkg install net/socat
.
It’s also available in most Linux package repositories and preinstalled on many
systems.
To establish a serial port connection one simply executes socat
with the
desired port name:
socat pty,link=/dev/ttyS0,raw,echo=0 tcp:128.66.0.1:7000
In this case it will create the device /dev/ttyS0
on a pseudo terminal and
connect to 128.66.0.1
on port 7000
As usual client configuration on Microsoft Windows is more cumbersome than on
more sane platforms. One first has to install the virtual null modem driver com0com
which requires one to disable driver signature checking at first:
After reboot you will be able to install com0com
that’s available on SourceForge.
The installer usually already creates a pair of COM ports for you. After that one
also required hub4com
that’s available at the same location.
This program just has to be unpacked into any desired location.
After the virtual COM port is available one can use the command line (cmd.exe
)
and establish a connection using the hub4com
utility:
com2tcp-rfc2217 \\.\COM4 128.66.0.1 7000
In this case the COM port name specifies one of the previously generated virtual ports, the IP address (or hostname) is the name or address of the server exposing the port and the last argument the port number.
C:\tools\hub4com>"hub4com" --create-filter=escparse,com,parse --create-filter=pinmap,com,pinmap:"--rts=cts --dtr=dsr" --create-filter=linectl,com,lc:"--br=local --lc=local" --add-filters=0:com --create-filter=telnet,tcp,telnet:" --comport=client" --create-filter=pinmap,tcp,pinmap:"--rts=cts --dtr=dsr --break=break" --create-filter=linectl,tcp,lc:"--br=remote --lc=remote" --add-filters=1:tcp --octs=off "\\.\COM4" --use-driver=tcp "*128.66.0.1:7000"
Open("\\.\COM4", baud=19200, data=8, parity=no, stop=1, octs=off, odsr=off, ox=off, ix=off, idsr=off, ito=0) - OK
Route data COM4(0) --> TCP(1)
Route data TCP(1) --> COM4(0)
Route flow control COM4(0) --> TCP(1)
Route flow control TCP(1) --> COM4(0)
Filters:
________
\->{parse.IN}----------------->
COM4(0) | /
________/<-----{pinmap.OUT}<-{lc.OUT}<-
_______
\->{telnet.IN}------------------------------>
TCP(1) | /
_______/<-----{telnet.OUT}<-{pinmap.OUT}<-{lc.OUT}<-
Socket(0.0.0.0:0) = 188
TCP(1): Connect(188, 128.66.0.1:7000) ...
Started COM4(0)
Started TCP(1)
TCP(1): Connected
TCP(1) START
TCP(1) SEND: WILL 44
TCP(1) SEND: SB 44
1 0 0 4 176 SE
TCP(1) SEND: SB 44
2 7 SE
TCP(1) SEND: SB 44
3 1 SE
TCP(1) SEND: SB 44
4 1 SE
TCP(1) SEND: SB 44
5 9 SE
TCP(1) SEND: SB 44
5 12 SE
TCP(1) SEND: SB 44
5 6 SE
TCP(1) RECV: WILL 3
TCP(1) SEND: DO 3
TCP(1) RECV: WILL 1
TCP(1) SEND: DO 1
TCP(1) RECV: DONT 1
TCP(1) RECV: DO 0
TCP(1) SEND: WILL 0
TCP(1) RECV: WILL 0
TCP(1) SEND: DO 0
TCP(1) RECV: SB 44
107 0 SE
TCP(1) RECV: DO 44
TCP(1) RECV: SB 44
101 0 0 4 176 SE
TCP(1) RECV: SB 44
102 7 SE
TCP(1) RECV: SB 44
103 1 SE
TCP(1) RECV: SB 44
104 1 SE
TCP(1) RECV: SB 44
105 9 SE
TCP(1) RECV: SB 44
105 12 SE
TCP(1) RECV: SB 44
105 6 SE
Note that there is no authentication and no encryption done. The traffic is open and the ports can be used by anyone who’s able to reach the service so:
ser2net
directly to the Internet (i.e. don’t publically expose
on machines not properly firewalled - even though such machines shouldn’t exist anyways)I’m personally using ser2net
on machines that are either running on a separate
virtual network using VLANs or as a service that’s isolated using proper dynamic
OpenFlow configuration when assigning a port to a machine inside the cluster.
This article is tagged:
Dipl.-Ing. Thomas Spielauer, Wien (webcomplains389t48957@tspi.at)
This webpage is also available via TOR at http://rh6v563nt2dnxd5h2vhhqkudmyvjaevgiv77c62xflas52d5omtkxuid.onion/