1 unstable release
0.1.2 | Dec 14, 2021 |
---|
#11 in #sandboxed
275KB
4.5K
SLoC
Rustunnel
A Sandboxed TLS tunnel library.
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
~98K SLoC