Securing Traffic Between two Socat Instances Using SSL

Securing Traffic Between two Socat Instances Using SSL
使用 SSL 加密两个 Socat 实例之间的流量

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.
当您想要连接运行在不同计算机上的两个 socat 进程,并且感觉需要保护连接免受未经授权访问、窃听、数据篡改等时,您可能希望加密通信。

For this purpose socat integrates the OpenSSL library and provides SSL client and server features.
为此,socat 集成了 OpenSSL 库,并提供 SSL 客户端和服务器功能。

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.
SSL 是一个复杂的协议,提供了比保护单个连接所需更多的功能;在本文档中,我们仅介绍一个仅提供基本安全要求的简单场景。

Configuring OpenSSL in socat
在 socat 中配置 OpenSSL

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.
本节展示了如何在 socat 中配置 SSL 地址。在本文档中,我们仅使用自签名证书以简化操作。

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 funtionality that just echos data (echo), and stdio on the client.
我们假设服务器主机名为 server.domain.org ,服务器进程使用端口 4433。为了简单起见,我们使用一个非常简单的服务器功能,只是回显数据( echo ),并在客户端上 stdio

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.
在已安装 OpenSSL 的受信任主机上执行以下步骤。它可以是客户端或服务器主机本身。

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.
会提示您输入国家代码、名称等信息;您可以使用回车键退出所有提示,除了“通用名称”必须确切地是客户端将使用的服务器的名称或 IP 地址。

Generate the PEM file by just appending the key and certificate files:
通过简单地附加密钥和证书文件来生成 PEM 文件:

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
更改 $FILENAME.key $FILENAME.pem 的权限为 600

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.
现在将文件 server.pem 带到 SSL 服务器,例如到目录 $HOME/etc/ ,使用 USB 存储设备或 SSH 等安全通道。即使在目标主机上,也要保持文件的严格权限,并删除所有其他实例 server.keyserver.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.
将信任证书 server.crt 复制到 SSL 客户端主机,例如到目录 $HOME/etc/ ;这里不需要安全通道,权限也不是关键的。

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.
重复上述描述的证书生成过程。不需要特殊的通用名称。将 client.pem 复制到 SSL 客户端,将 client.crt 复制到服务器。

OpenSSL Server OpenSSL 服务器

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 ceritificate 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):
服务器不使用 tcp-listen (tcp-l) 地址,而是使用 openssl-listen (ssl-l), cert=... 告诉程序文件包含其证书和私钥, cafile=... 指向包含对等方证书的文件;我们只信任客户端,如果他们能证明拥有相关的私钥(OpenSSL 会为我们处理这个):

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.
启动此命令后,socat 应该在端口 4433 上进行侦听,但将需要客户端身份验证。

OpenSSL Client OpenSSL 客户端

Substitute your tcp-connect or tcp address keyword with openssl-connect or just ssl and here too add the cert and cafile options:
使用 openssl-connect 或者仅仅 ssl 替换您的 tcp-connecttcp 地址关键字,并在这里添加 certcafile 选项:

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 TCP/IP 版本 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:
如果通信要通过 IPv6 进行,上述描述的命令必须进行调整; ip6name.domain.org 假定解析为服务器的 IPv6 地址:

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
测试 OpenSSL 集成

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 可执行文件可能没有链接 OpenSSL 库。请使用以下命令检查 socat 的编译时配置:

socat -V |grep SSL

Positive output: #define WITH_OPENSSL 1 正确输出: #define WITH_OPENSSL 1
Negative output: #undef WITH_OPENSSL 错误输出: #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.
在后一种情况下,请确保您已安装了 OpenSSL 及其开发包(包括文件),并检查配置脚本的运行。

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.
socat 1.2.0 中实现了第一个 OpenSSL 客户端;它不支持客户端证书,也无法验证服务器证书。它更被视为用于探测典型 SSL 安全的互联网服务的工具。

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.
从版本 1.4.0 开始,socat 提供了对 SSL 客户端和 SSL 服务器的实验性支持,使用了 OpenSSL 库进行实现。仅支持 TCP/IPv4 传输。使用 SSL 客户端和服务器时,可以指定用于检查对等体认证的信任证书以及用于认证的证书。这允许建立非交互式的安全连接。这些功能被视为实验性;与大多数互联网站一样,socat 服务器默认情况下不需要客户端提供证书,但客户端需要服务器证书。

DSA certificate support is implemented since version 1.4.2.
自版本 1.4.2 开始实现了 DSA 证书支持。

Socat version 1.5.0 extended SSL to TCP/IPv6 transports.
Socat 版本 1.5.0 扩展了 SSL 到 TCP/IPv6 传输。

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.6.0,默认情况下 SSL 服务器要求客户端提供受信任的证书。socat 的 OpenSSL 实现仍然不检查证书的内容,如主机名或主机地址。

Socat 1.7.3.0 introduces check of servers commonname by the client, and optionally check of clients commonname by the server.
Socat 1.7.3.0 引入了客户端对服务器通用名称的检查,并可选择由服务器对客户端通用名称进行检查。

This document was last modified in Oct. 2023.
本文档最后修改于 2023 年 10 月。

More info about socat OpenSSL
有关 socat OpenSSL 的更多信息

Links regarding this tutorial
有关本教程的链接

address openssl-connect 地址 openssl 连接
address openssl-listen 地址 openssl 监听
option cert 选项证书
option cafile 选项 cafile

More socat options for OpenSSL addresses
OpenSSL 地址的更多 socat 选项

OpenSSL options OpenSSL 选项
TCP options TCP 选项
IP options IP 选项
socket options 套接字选项
file descriptor options 文件描述符选项
retry options 重试选项

For openssl-listen only:
仅适用于 openssl-listen:

listen options 监听选项
child options 子选项
range options 范围选项

References 参考资料

socat home page socat 主页
socat man page socat 手册页面
OpenSSL home page OpenSSL 主页
stunnel home page stunnel 主页
secure sockets layer on Wikipedia
维基百科上的安全套接字层

Copyright: Gerhard Rieger 2007
版权所有:Gerhard Rieger 2007

License: GNU Free Documentation License (FDL)
许可证:GNU 自由文档许可证(FDL)