| <!-- $Revision: 1.1 $ $Date: 2007/03/06 20:54:43 $ --> |
| <html><head> |
| <title>Securing Traffic Between two Socat Instances Using SSL</title> |
| <link rel="stylesheet" type="text/css" href="dest-unreach.css"> |
| </head> |
| |
| <body> |
| |
| <h1>Securing Traffic Between two Socat Instances Using SSL</h1> |
| |
| <h2>Introduction</h2> |
| <p> |
| 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. |
| </p> |
| <p> |
| For this purpose socat integrates the OpenSSL library and provides SSL client |
| and server features. |
| </p> |
| <p> |
| 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. |
| </p> |
| |
| <!-- discussion --> |
| <h2>Configuring OpenSSL in socat</h2> |
| <p> |
| 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. |
| </p> |
| <p>We assume that the server host is called <tt>server.domain.org</tt> and the |
| server process uses port 4433. To keep it simple, we use a very simple server |
| funtionality that just echos data (<tt>echo</tt>), and <tt>stdio</tt> on the |
| client.</p> |
| <h3>Generate a server certificate</h3> |
| |
| <p>Perform the following steps on a trusted host where OpenSSL is |
| installed. It might as well be the client or server host themselves.</p> |
| <p>Prepare a basename for the files related to the server certificate:</p> |
| <span class="shell">FILENAME=server</span> |
| |
| <p>Generate a public/private key pair:</p> |
| <span class="shell">openssl genrsa -out $FILENAME.key 2048</span> |
| |
| <p>Generate a self signed certificate:</p> |
| <span class="shell">openssl req -new -key $FILENAME.key -x509 -days 3653 -out $FILENAME.crt</span> |
| <p>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.</p> |
| <p>Generate the PEM file by just appending the key and certificate files:<p> |
| <span class="shell">cat $FILENAME.key $FILENAME.crt >$FILENAME.pem</span> |
| |
| <p>The files that contain the private key should be kept secret, thus adapt |
| their permissions:<p> |
| <span class="shell">chmod 600 $FILENAME.key $FILENAME.pem</span> |
| |
| <p>Now bring the file <tt>server.pem</tt> to the SSL server, e.g. to directory |
| <tt>$HOME/etc/</tt>, 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 <tt>server.key</tt> and <tt>server.pem</tt>. |
| </p> |
| <p>Copy the trust certificate server.crt to the SSL client host, e.g. to directory |
| <tt>$HOME/etc/</tt>; a secure channel is not required here, and the permissions |
| are not critical. |
| </p> |
| |
| <h3>Generate a client certificate</h3> |
| <p>First prepare a different basename for the files related to the client certificate:</p> |
| <span class="shell">FILENAME=client</span> |
| |
| <p>Repeat the procedure for certificate generation described above. A special common name is not required. |
| Copy <tt>client.pem</tt> to the SSL client, and <tt>client.crt</tt> to the |
| server.</p> |
| |
| <h3>OpenSSL Server</h3> |
| |
| <p>Instead of using a tcp-listen (tcp-l) address, we use openssl-listen (ssl-l) |
| for the server, <tt>cert=...</tt> tells the program to the file containing its |
| ceritificate and private key, and <tt>cafile=...</tt> 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):<p> |
| <span class="shell">socat \ |
| OPENSSL-LISTEN:4433,reuseaddr,cert=$HOME/etc/server.pem,cafile=$HOME/etc/client.crt \ |
| PIPE</span> |
| <p>After starting this command, socat should be listening on port 4433, but |
| will require client authentication.</p> |
| |
| <h3>OpenSSL Client</h3> |
| <p>Substitute your <tt>tcp-connect</tt> or <tt>tcp</tt> address keyword with |
| <tt>openssl-connect</tt> or just <tt>ssl</tt> and here too add the |
| <tt>cert</tt> and <tt>cafile</tt> options:<p> |
| <span class="shell">socat STDIO \ |
| OPENSSL-CONNECT:server.domain.org:4433,cert=$HOME/etc/client.pem,cafile=$HOME/etc/server.crt</span> |
| <p>This command should establish a secured connection to the server |
| process.</p> |
| |
| <h3>TCP/IP version 6</h3> |
| |
| <p>If the communication is to go over IPv6, the above described commands have |
| to be adapted; <tt>ip6name.domain.org</tt> is assumed to resolve to the IPv6 |
| address of the server:</p> |
| <p>Server:</p> |
| <span class="shell">socat \ |
| OPENSSL-LISTEN:4433,<b style="color:yellow">pf=ip6</b>,reuseaddr,cert=$HOME/etc/server.pem,cafile=$HOME/etc/client.crt \ |
| PIPE</span> |
| |
| <p>Client:</p> |
| <span class="shell">socat STDIO \ |
| OPENSSL-CONNECT:<b style="color:yellow">ip6name</b>.domain.org:4433,cert=$HOME/etc/client.pem,cafile=$HOME/etc/server.crt</span> |
| |
| <h2>Troubleshooting</h2> |
| |
| <h3>Test OpenSSL Integration</h3> |
| <p> |
| If you get error messages like this:</p> |
| <span class="error">... E unknown device/address "OPENSSL-LISTEN"</span> |
| <p>your socat executable probably does not have the OpenSSL library linked in. |
| Check socat's compile time configuration with the following command:</p> |
| <span class="shell">socat -V |grep SSL</span> |
| <p>Positive output: |
| <tt>#define WITH_OPENSSL 1</tt><br> |
| Negative output: |
| <tt>#undef WITH_OPENSSL</tt><br> |
| </p> |
| <p> |
| In the latter case, make sure you have OpenSSL and its development package |
| (include files) installed, and check the run of the configure script. |
| </p> |
| |
| |
| <h2>History</h2> |
| <p> |
| 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. |
| </p> |
| <p> |
| 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. |
| |
| </p> |
| <p> |
| DSA certificate support is implemented since version 1.4.2. |
| </p> |
| <p> |
| Socat version 1.5.0 extended SSL to TCP/IPv6 transports. |
| </p> |
| <p> |
| 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. |
| </p> |
| <p> |
| Socat 1.7.3.0 introduces check of servers commonname by the client, and optionally check of clients commonname by the server. |
| </p> |
| |
| <p>This document was last modified in Oct. 2023.</p> |
| |
| <h2>More info about socat OpenSSL</h2> |
| |
| <h3>Links regarding this tutorial</h3> |
| <a href="socat.html#ADDRESS_OPENSSL_CONNECT">address openssl-connect</a><br> |
| <a href="socat.html#ADDRESS_OPENSSL_LISTEN">address openssl-listen</a><br> |
| <a href="socat.html#OPTION_OPENSSL_CERTIFICATE">option cert</a><br> |
| <a href="socat.html#OPTION_OPENSSL_CAFILE">option cafile</a><br> |
| |
| <h3>More socat options for OpenSSL addresses</h3> |
| <a href="socat.html#GROUP_OPENSSL">OpenSSL options</a><br> |
| <a href="socat.html#GROUP_TCP">TCP options</a><br> |
| <a href="socat.html#GROUP_IP">IP options</a><br> |
| <a href="socat.html#GROUP_SOCKET">socket options</a><br> |
| <a href="socat.html#GROUP_FD">file descriptor options</a><br> |
| <a href="socat.html#GROUP_RETRY">retry options</a><br> |
| <p>For openssl-listen only:</p> |
| <a href="socat.html#GROUP_LISTEN">listen options</a><br> |
| <a href="socat.html#GROUP_CHILD">child options</a><br> |
| <a href="socat.html#GROUP_RANGE">range options</a><br> |
| |
| <h2>References</h2> |
| <a href="http://www.dest-unreach.org/socat">socat home page</a><br> |
| <a href="socat.html">socat man page</a><br> |
| <a href="http://www.openssl.org/">OpenSSL home page</a><br> |
| <a href="http://www.stunnel.org/">stunnel home page</a><br> |
| <a href="http://en.wikipedia.org/wiki/Secure_Sockets_Layer">secure sockets layer on Wikipedia</a><br> |
| |
| <p> |
| <small>Copyright: Gerhard Rieger 2007</small><br> |
| <small>License: <a href="http://www.fsf.org/licensing/licenses/fdl.html">GNU Free Documentation License (FDL)</a></small> |
| </p> |
| |
| </body> |
| </html> |