本文目录导读:

stunnel 是一个开源的代理程序,它通过为现有的 TCP 连接添加 SSL/TLS 加密,来提供安全的通信通道,而无需修改应用程序本身的代码,它的核心功能就是将未加密的 TCP 流量包裹在 SSL/TLS 隧道中。
stunnel 的工作原理是:
- 客户端(Client):stunnel 客户端程序监听一个本地端口(7777),原本应该直接连接目标服务器的应用程序(MySQL 客户端),改为连接这个本地端口。
- 服务器端(Server):stunnel 服务器程序运行在目标服务器上,监听一个 SSL/TLS 端口(3306 的 SSL 版本 33060),它接收来自 stunnel 客户端的加密连接。
- 加密隧道:stunnel 客户端和服务器端之间建立起 SSL/TLS 隧道,所有在隧道中传输的数据都是加密的。
- 解密转发:stunnel 服务器端将解密后的明文 TCP 数据,发送给目标应用服务器(MySQL 守护进程)。
换句话说,stunnel 在中间起了一个“翻译”作用:一边是未加密的 TCP 应用,另一边是加密的 SSL 网络。
典型架构
[应用客户端] --未加密TCP--> [stunnel客户端] --SSL/TLS加密--> [stunnel服务器] --未加密TCP--> [应用服务器]
(MySQL) (监听本地:7777) (监听公共:33060) (监听本地:3306)
stunnel 如何为 TCP 提供 SSL 加密:分步配置指南
第一步:在服务器端配置 stunnel
目标:stunnel 服务器监听一个 SSL 端口,将解密后的数据转发给本地未加密的 TCP 服务。
-
安装 stunnel:
# Debian/Ubuntu sudo apt-get install stunnel4 # CentOS/RHEL sudo yum install stunnel
-
准备 SSL 证书和私钥: 你可以使用自签名证书(测试环境)或从 CA 机构获取。
# 生成自签名证书和私钥(有效期365天) sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -keyout /etc/stunnel/stunnel.pem \ -out /etc/stunnel/stunnel.pem \ -subj "/CN=your-server-domain-or-ip" # 确保文件权限正确 sudo chmod 600 /etc/stunnel/stunnel.pem -
创建/编辑 stunnel 配置文件 (
/etc/stunnel/stunnel.conf):; 全局设置 pid = /var/run/stunnel.pid ; 设置日志级别(可选) ; debug = 7 ; output = /var/log/stunnel/stunnel.log ; 启用 SSL 版本选择(建议使用 TLS) sslVersion = TLSv1.2 ; 定义服务(可定义多个服务) [mysql_server] ; 服务名称,可自定义 accept = 0.0.0.0:33060 ; stunnel 服务器监听的 SSL 端口(公网访问) connect = 127.0.0.1:3306 ; 解密的 TCP 请求转发到的本地应用端口 cert = /etc/stunnel/stunnel.pem ; 服务器端 SSL 证书和私钥路径 ; 客户端连接时不需要证书验证(常用) verifyChain = no
-
启动 stunnel 服务:
# 启用 stunnel 开机自启 sudo systemctl enable stunnel4 # 启动 stunnel sudo systemctl start stunnel4 # 检查状态 sudo systemctl status stunnel4
第二步:在客户端配置 stunnel
目标:stunnel 客户端监听一个本地端口,将收到的数据通过 SSL 加密发送到 stunnel 服务器。
-
安装 stunnel(客户端也需要安装,但只需一个配置文件):
sudo apt-get install stunnel4 # 或 yum install stunnel
-
创建/编辑客户端 stunnel 配置文件 (
/etc/stunnel/stunnel.conf):; 全局设置 pid = /var/run/stunnel.pid client = yes ; ★ 关键设置:标记此实例为客户端模式 ; 定义客户端服务 [mysql_client] ; 服务名称,可自定义 accept = 127.0.0.1:7777 ; 客户端 stunnel 监听的本地端口 connect = your-server-ip:33060 ; 远程 stunnel 服务器的 IP 和 SSL 端口 ; 如果服务器使用自签名证书,需要才去不验证(生产环境不建议) ; verifyChain = no ; 如果服务器有合法证书,最好验证 verifyChain = yes CAfile = /etc/stunnel/stunnel.pem ; 如果使用自签名,放服务端的公钥
-
启动客户端 stunnel:
sudo systemctl start stunnel4 # 或直接运行 sudo stunnel /etc/stunnel/stunnel.conf
第三步:配置你的应用
你的应用(MySQL 客户端)需要连接的不是远程服务器的 3306 端口,而是本地的 7777 端口。
# 原来连接(不安全) # mysql -h your-server-ip -P 3306 -u root -p # 现在连接(经过 SSL 加密) mysql -h 127.0.0.1 -P 7777 -u root -p
工作流程:
- 你的 MySQL 客户端明文连接
0.0.1:7777。 - 客户端的 stunnel 捕获这个连接,并将数据通过 SSL/TLS 加密,发送到
your-server-ip:33060。 - 服务器端的 stunnel 接收加密数据,解密后转发给
0.0.1:3306(MySQL 服务)。 - MySQL 服务返回的响应,也经过相反的路径加密回传。
stunnel 的核心优势
- 零代码修改:你不需要修改任何应用程序(如 MySQL、PostgreSQL、Redis、自定义 TCP 服务)的代码,只需改变它们连接的目标地址。
- 简单可靠:配置极其简单,通常只需要几行。
- 跨平台:支持 Linux、Windows、macOS 等主流操作系统。
- 灵活:可以为任意 TCP 服务提供加密,从数据库到消息队列、Web 服务(非 HTTP 时特别有用)。
- 安全增强:支持现代 TLS 协议、证书验证、身份伪造防护等。
与其它 SSL 加密方式的对比
| 特性 | stunnel | 应用自身 SSL (如 MySQL SSL) | VPN (如 OpenVPN) |
|---|---|---|---|
| 对应用的侵入性 | 最低(无需修改应用) | 较高(应用需编译支持 SSL) | 最低(应用无感知) |
| 加密粒度 | 单端口/单服务 | 特定协议 / 特定连接 | 整个网络 / 子网 |
| 配置复杂度 | 非常简单(几行配置) | 中等(需生成证书、配置应用) | 较高(需要网络、路由配置) |
| 资源占用 | 低 | 低 | 中(额外封装) |
| 适用场景 | 快速为遗留系统、无原生 SSL 的服务增加加密 | 新系统 / 云原生架构(如 Kubernetes 中) | 需要隔离整个网络(如全公司加密) |
stunnel 本质上是一个轻量级的 TLS 代理,它通过在未加密的 TCP 前端和后端之间插入一个 SSL 层,让任何 TCP 应用(无论设计时是否考虑过安全)都能获得加密传输能力。
典型使用场景:
- 你的公司有一个内部使用的老版 Redis(无密码,无 SSL)。
- 你希望在公网上安全地访问 MySQL 数据库,但你的数据库客户端不支持原生 SSL,或者你不想花时间配置复杂的 SSL 选项。
- 你需要加密一个自定义的、基于 TCP 的即时通讯协议。
配置核心思路:
- 服务端:
accept = SSL端口,connect = 本地应用端口,client = no(默认)。 - 客户端:
client = yes,accept = 本地监听端口,connect = 服务端IP:SSL端口。
stunnel 本身不处理业务逻辑,它只负责加解密和纯转发。 它是 TCP 世界里的“加密胶水”。
如果还需要更具体的案例(比如为 HTTP/2 代理或特定数据库做配置),随时告诉我。
标签: SSL加密