Stunnel

来自 ArchWiki

stunnel (“安全隧道”) 是一个

跨平台应用程序,用于提供通用的 TLS/SSL 隧道服务。它是一种代理,旨在为现有的客户端和服务器添加 TLS 加密功能,而无需更改程序的代码。它专为安全性、可移植性和可扩展性(包括负载均衡)而设计,使其适用于大型部署。它使用 OpenSSL,并根据 GNU GPL version 2 或更高版本(带有 OpenSSL 例外)分发。

只能隧道传输 TCP 数据包。它的 FAQ 提供了一些针对 UDP 的解决方法。WireGuard 也具有 UDP 功能。

服务器也可以使用身份验证来仅允许经过批准的客户端访问。

安装

安装 stunnel 软件包。

根据您的使用情况,您可能还需要 编辑提供的 systemd 单元文件,以便更好地 处理依赖关系。为了使 stunnel 在系统启动时自动启动,您必须 启用 它。

配置

主配置文件从 /etc/stunnel/stunnel.conf 读取。它是一个 ini 风格的文件。它由一个全局节组成,后跟一个或多个服务节。

客户端是接受非 TLS 加密数据的端点。Stunnel 将对其数据进行 TLS 加密并连接到 stunnel 服务器。stunnel 服务器接受 TLS 加密的数据并提取它。然后它连接到数据应该发送到的位置。

默认的 debug 值为 5,这非常冗长。在验证操作正确后,值得在配置文件中显式设置较低的值。

/etc/stunnel/stunnel.conf
debug = 3

为了更好的安全性,建议为全局节和每个服务节显式设置适当的 uid 和 gid,而不是 root。配置令牌 setuidsetgid 可用于此目的。

字节顺序标记 (BOM)

配置文件应在文件开头具有 UTF-8 字节顺序标记 (BOM)。BOM 是 Unicode 字符 U+FEFF。它的 UTF-8 表示形式是(十六进制)字节序列 0xEF, 0xBB, 0xBF。可以通过以下方式在文件开头创建这些字节

# echo -e '\xef\xbb\xbf; BOM composed of non printable characters. It is here, before the semicolon!' > /etc/stunnel/stunnel.conf

要测试这些字节是否出现,可以使用

% od --address-radix=n --format=x1c --read-bytes=8 /etc/stunnel/stunnel.conf
  ef  bb  bf  3b  20  42  4f  4d
 357 273 277   ;       B   O   M

请注意,当将文件打印到屏幕上时,例如使用 cat,或者使用文本编辑器编辑文件时,BOM 字节通常不显示。但它们应该在那里。这就是为什么您可能需要在编辑完成后使用上面的 od 或类似的命令验证它们是否仍然存在。

认证

客户端和服务器至少其中一个,或者可选地两者都应该进行身份验证。预共享密钥或密钥和证书对都可以用于身份验证。预共享密钥必须事先通过其他方式(例如 SCP 和 SFTP)传输到所有相关机器。当这种传输可以接受时,预共享密钥是最快的方法。它的速度可能有助于缓解攻击。使用预共享密钥的单个服务器和单个客户端的简单配置是

client:/etc/stunnel/stunnel.conf
; BOM composed of non printable characters. It is here, before the semicolon!
setuid = stunnel
setgid = stunnel

[trivial client]
client     = yes
accept     = 127.0.0.1:<src_port>
connect    = <server_host>:<server_port>
debug      = 3
PSKsecrets = /etc/stunnel/psk.txt
setuid     = stunnel
setgid     = stunnel
server:/etc/stunnel/stunnel.conf
; BOM composed of non printable characters. It is here, before the semicolon!
setuid = stunnel
setgid = stunnel

[trivial server]
accept     = <server_port>
connect    = <dst_port>
ciphers    = PSK
debug      = 3
PSKsecrets = /etc/stunnel/psk.txt
setuid     = stunnel
setgid     = stunnel

其中 /etc/stunnel/psk.txt 可以在一台机器上通过以下方式创建

# openssl rand -base64 -out /etc/stunnel/psk.txt 180
# sed --in-place '1s/^/psk:/' /etc/stunnel/psk.txt

并在启动 stunnel 之前通过安全方式复制到另一台机器。每个 psk.txt 文件的 权限 应适当设置。来自 sed 命令的 psk 字符串只是为了示例而随机命名的。请阅读 stunnel(8)

技巧与诀窍

基于 TLS 的 DNS

本文或本节内容可能需要与 DNS over HTTPS servers#DNS over TLS configuration via stunnel 合并。

注意: 那里提供了一些配置示例。(在 Talk:Stunnel 中讨论)

BIND 不提供内置的查询和应答加密功能。Bind 知识库建议使用 stunnel。请参阅 https://kb.isc.org/docs/aa-01386。该链接在页面底部提到了 unbound。即使解析器和 NS 都不支持基于 TLS 的 DNS,仅在客户端和服务器上拥有 shell 帐户的用户仍然可以隧道传输 DNS 流量。

使用 Stunnel TLS 加密 NFSv4

请参阅 Encrypting NFSv4 with Stunnel TLS

参见