# Securing Traffic Between two Socat Instances Using SSL

## Introduction

When you want to connect two socat processes running on different machines and feel that you need to protect the connection against unauthorized access, sniffing, data manipulation etc., you might want to encrypt the communications.

For this purpose socat integrates the OpenSSL library and provides SSL client and server features.

SSL is a complex protocol that provides much more features than required for protecting a single connection; in this document we present only a simple scenario that provides just the basic security requirements.

## Configuring OpenSSL in socat

This section shows how the SSL addresses can be configured in socat. In this docu we only use self signed certificates for the sake of simplicity.

We assume that the server host is called `server.domain.org` and the server process uses port 4433. To keep it simple, we use a very simple server functionality that just echos data (`echo`), and `stdio` on the client.

### Generate a server certificate

Perform the following steps on a trusted host where OpenSSL is installed. It might as well be the client or server host themselves.

Prepare a basename for the files related to the server certificate:

FILENAME=server

Generate a public/private key pair:

openssl genrsa -out $FILENAME.key 2048

Generate a self signed certificate:

openssl req -new -key $FILENAME.key -x509 -days 3653 -out $FILENAME.crt

You will be prompted for your country code, name etc.; you may quit all prompts with the ENTER key, except for the Common Name which must be exactly the name or IP address of the server that the client will use.

Generate the PEM file by just appending the key and certificate files:

cat $FILENAME.key $FILENAME.crt >$FILENAME.pem

The files that contain the private key should be kept secret, thus adapt their permissions:

chmod 600 $FILENAME.key $FILENAME.pem

Now bring the file `server.pem` to the SSL server, e.g. to directory `$HOME/etc/`, using a secure channel like USB memory stick or SSH. Keep tight permissions on the file even on the target host, and remove all other instances of `server.key` and `server.pem`.

Copy the trust certificate server.crt to the SSL client host, e.g. to directory `$HOME/etc/`; a secure channel is not required here, and the permissions are not critical.

### Generate a client certificate

First prepare a different basename for the files related to the client certificate:

FILENAME=client

Repeat the procedure for certificate generation described above. A special common name is not required. Copy `client.pem` to the SSL client, and `client.crt` to the server.

### OpenSSL Server

Instead of using a tcp-listen (tcp-l) address, we use openssl-listen (ssl-l) for the server, `cert=...` tells the program to the file containing its certificate and private key, and `cafile=...` points to the file containing the certificate of the peer; we trust clients only if they can proof that they have the related private key (OpenSSL handles this for us):

socat \ OPENSSL-LISTEN:4433,reuseaddr,cert=$HOME/etc/server.pem,cafile=$HOME/etc/client.crt \ PIPE

After starting this command, socat should be listening on port 4433, but will require client authentication.

### OpenSSL Client

Substitute your `tcp-connect` or `tcp` address keyword with `openssl-connect` or just `ssl` and here too add the `cert` and `cafile` options:

socat STDIO \ OPENSSL-CONNECT:server.domain.org:4433,cert=$HOME/etc/client.pem,cafile=$HOME/etc/server.crt

This command should establish a secured connection to the server process.

### TCP/IP version 6

If the communication is to go over IPv6, the above described commands have to be adapted; `ip6name.domain.org` is assumed to resolve to the IPv6 address of the server:

Server:

socat \ OPENSSL-LISTEN:4433,pf=ip6,reuseaddr,cert=$HOME/etc/server.pem,cafile=$HOME/etc/client.crt \ PIPE

Client:

socat STDIO \ OPENSSL-CONNECT:ip6name.domain.org:4433,cert=$HOME/etc/client.pem,cafile=$HOME/etc/server.crt

## Troubleshooting

### Test OpenSSL Integration

If you get error messages like this:

... E unknown device/address "OPENSSL-LISTEN"

your socat executable probably does not have the OpenSSL library linked in. Check socat's compile time configuration with the following command:

socat -V |grep SSL

Positive output: `#define WITH_OPENSSL 1`
Negative output: `#undef WITH_OPENSSL`

In the latter case, make sure you have OpenSSL and its development package (include files) installed, and check the run of the configure script.

## History

A first OpenSSL client was implemented in socat 1.2.0; it did not support client certificates and could not verify server certificates. It was rather considered as a tool for probing typical SSL secured Internet services.

From version 1.4.0 on, socat provided experimental support for SSL client and SSL server, implemented using the OpenSSL libraries. Only TCP/IPv4 transport was supported. With both SSL client and server, trust certificates for checking the peers authentication, and certificates for authentication could be specified. This allowed for non interactive secure connection establishing. The features were considered experimental; like most Internet sites, socat server did not require the client to present a certificate per default, but the client required a server certificate.

DSA certificate support is implemented since version 1.4.2.

Socat version 1.5.0 extended SSL to TCP/IPv6 transports.

With socat version 1.6.0, the SSL server per default requires the client to present a trusted certificate. socat's OpenSSL implementation still does not check the contents of a certificate like host name or host address.

Socat 1.7.3.0 introduces check of servers commonname by the client, and optionally check of clients commonname by the server.

This document was last modified in Oct. 2023.

## More info about socat OpenSSL

### Links regarding this tutorial

address openssl-connect
address openssl-listen
option cert
option cafile

### More socat options for OpenSSL addresses

OpenSSL options
TCP options
IP options
socket options
file descriptor options
retry options

For openssl-listen only:

listen options
child options
range options

## References

socat home page
socat man page
OpenSSL home page
stunnel home page
secure sockets layer on Wikipedia

Copyright: Gerhard Rieger 2007
License: GNU Free Documentation License (FDL)