1 个不稳定版本

0.1.2 2021 年 12 月 14 日

#2204 in 加密学

AGPL-3.0-or-later

275KB
4.5K SLoC

C 3.5K SLoC // 0.4% comments Rust 1K SLoC // 0.1% comments

Rustunnel

沙箱化的 TLS 隧道库。

API 文档

许可证

版权所有 (C) 2019, 2020 Signal Messenger, LLC。
版权所有 (C) 2021 jessa0

本程序是自由软件:您可以按照自由软件基金会发布的 GNU Affero 通用公共许可证的条款重新分发和/或修改它,许可证版本为 3 或(根据您的选择)任何更新的版本。

本程序的分发是希望它是有用的,但没有任何保证;甚至不保证其适销性或适用于特定用途。有关详细信息,请参阅 GNU Affero 通用公共许可证。

您应该已经收到一份 GNU Affero 通用公共许可证副本。如果没有,请参阅 http://www.gnu.org/licenses/


lib.rs:

rustunnel 是一个沙箱化的 TLS 隧道库。

该库可以在进程沙箱内接受或发起 TLS 连接。使用此库的进程应该是最小化、范围有限和单线程的,以免打开未预见的漏洞或导致沙箱违规。

可移植性

目前仅支持 Linux,使用 libseccomp2 进行进程沙箱。

使用方法

在沙箱化进程中,应在开始沙箱化 TLS 连接之前清除所有秘密(例如加载的 TLS 私钥)。可以使用 clear_on_drop 包自动清除秘密。 Identity::from_pkcs12_file 提供了加载 TLS 私钥并在内存中清除所有秘密的实现。

沙箱化进程使用的 log 实现应确保在写入日志消息时不要执行任何可能被进程沙箱禁止的系统调用。例如,计算时间戳可能使用禁止的系统调用。 logger::Logger 提供了一个符合规范的实现(不包含时间戳),并将内容写入标准错误。

建议在运行沙箱化的TLS连接之前,尽快调用sandbox::close_all_fds,以确保在此期间没有意外打开额外的文件描述符。

use rustunnel::{tls, ServerChild};
use std::net::TcpListener;
use std::os::unix::io::AsRawFd as _;
use std::path::Path;

let (source_tcp_stream, _) = TcpListener::bind("127.0.0.1:8080")?.accept()?;
let identity = tls::Identity::from_pkcs12_file(Path::new("/path/to/identity.p12"), "pkcs12 password")?;
let target_pipe_stream = rustunnel::stream::ProxyPipeStream::stdio()?;

let source_fd = source_tcp_stream.as_raw_fd();
let allow_fds = [libc::STDIN_FILENO, libc::STDOUT_FILENO, libc::STDERR_FILENO, source_fd];
rustunnel::sandbox::close_all_fds(&allow_fds.iter().cloned().collect());

let child = ServerChild::new(tls::CaCertificate::System, identity, source_tcp_stream, target_pipe_stream)?;
child.run()?;

依赖项

约4.5MB
约94K SLoC