1 unstable release

0.1.2 Dec 14, 2021

#11 in #sandboxed

AGPL-3.0-or-later

275KB
4.5K SLoC

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

Rustunnel

A Sandboxed TLS tunnel library.

API Documentation

License

Copyright (C) 2019, 2020 Signal Messenger, LLC.
Copyright (C) 2021 jessa0

This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License along with this program. If not, see http://www.gnu.org/licenses/.


lib.rs:

rustunnel is a sandboxed TLS tunnel library.

This library can either accept or initiate a TLS connection inside a process sandbox. A process utilizing this library should be minimal, limited in scope, and single-threaded, so as to not open any unforeseen security holes or cause sandbox violations.

Portability

Currently only Linux is supported, using libseccomp2 for process sandboxing.

Usage

Care should be taken in the sandboxed process to clear all secrets in memory before starting the sandboxed TLS connection, e.g. loaded TLS private keys. The clear_on_drop crate can be used to clear secrets automatically. Identity::from_pkcs12_file provides an implementation of loading a TLS private key while clearing all secrets in memory.

The log implementation used in the sandboxed process should take care not to perform any system calls while writing log message which may be disallowed by the process sandbox. Calculating timestamps, for example, may use a prohibited system call. logger::Logger provides a conforming implementation (without timestamps) which writes to the standard error.

It is recommended that sandbox::close_all_fds be called, as immediately as possible, before running the sandboxed TLS connection, to ensure no additional file descriptors are unintentionally opened in the interim.

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()?;

Dependencies

~4.5MB
~96K SLoC