Linux: Serial interface/terminal redirecting/forwarding over a TLS encrypted TCP/IP connection


the scenario: A device with a serial console for example a raspberry pi, orange pi, esp8266 with tasmota, digital multimeter etc. runs headless, but you want to able to connect to the serial console with linux system here called serialServer over the network.

Requirements are: The traffic must be encrypted and only IP Address is allowed to connect.

Connect the physical wires by crossing RX-TX of the Raspberry Clients ( serial console to UART of the Raspberry SerialServer ( To use the UART on the SerialServer you have to disable serial console on that system during raspi-config or by removing of console=serial0,115200 in /boot/cmdline.txt.

Raspberry Client       Raspberry SerialServer
      Pin 8   ------------     Pin 10
      Pin 10  ------------     Pin 8
    GND Pin 6 ------------   GND Pin 6

If you do not have a valid x509 certificate simply create one. Importend is the common name if you later want to verify the certifcate on the client side.

michael@serialserver ~ # openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /tmp/server.key -out /tmp/server.pem
Common Name (e.g. server FQDN or YOUR name) []:serialServer

Concat key and certificate into one file

michael@serialserver ~ # cat /tmp/server.key /tmp/server.pem  > /tmp/server.cer

The tool to tunnel the serial connection over the network is socat. Install it on the serial server and on the machine where the serial console should forwarded to.

michael@serialserver ~ # apt install socat

At the serial server setup the serial device (here /dev/ttyACM0, set BAUDRATE, Flowcontrol..) and start the server. First example by piping stdin and stdout. Be aware, by default, everyone can connect over the network! Ensure you use the same BAUDRATE with all commands! In my example 115200.

michael@serialserver ~ # stty -F /dev/ttyACM0 115200 raw
michael@serialserver ~ # socat openssl-listen:11111,reuseaddr,cert=/tmp/server.cer,verify=0,fork stdio < /dev/ttyACM0 > /dev/ttyACM0

or let socat open the serial interface (prefered). Here the range parameter is added. This limits the connections to, otherwise everyone can connect!

michael@serialserver ~ # socat -d -d open:/dev/ttyACM0,nonblock,echo=0,raw,b115200 openssl-listen:11111,reuseaddr,cert=/tmp/server.cer,verify=0,fork,range= 

Setup the client which should connects to the serial server.
Open a terminal.

This opens a “remote” terminal without checking the certificate (verify=0). This is less secure because someone could setup a honey pot and if you connect, your login data can captured!

michael@serialclient ~ # socat stdio openssl-connect:,verify=0

Here the more secure version. Copy the server.pem from the serialserver and append the cafile and the openssl-commonname perameter. The common name parameter must match the common name in the certificate. It is set during the certificate creation by openssl. See above. Both options ensures the TLS certificate must match to the server certificate

michael@serialclient ~ # socat stdio openssl-connect:,openssl-commonname=serialServer,cafile=/tmp/server.pem

For some someone who need a “real” serial interface forwarding a virtual serial interface could created to which other processes could connect. The virtual serial interface at the client then represents the physical interface on the serial server. socat must be start with root permissions to create a virtual interface.

michael@serialclient ~ # sudo socat pty,link=/dev/ttyVIRT,b115200,raw openssl-connect:,verify=0

or more secure 🙂

michael@serialclient ~ # sudo socat pty,link=/dev/ttyVIRT,b115200,raw openssl-connect:,openssl-commonname=serialServer,cafile=/tmp/server.pem

Set permissions who is allowed to use the virtual device

michael@serialclient ~ # sudo chown :dialout /dev/ttyVIRT

Using the virtual interface

michael@serialclient ~ # screen /dev/ttyVIRT 


Advertisment to support

Leave a Reply

Your email address will not be published.

Time limit is exhausted. Please reload CAPTCHA.