mirror of
https://github.com/cirruslabs/softnet.git
synced 2026-10-01 12:32:05 +02:00
Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a540299219 | ||
|
|
16864f38f0 | ||
|
|
0a92c290be | ||
|
|
f5a1b1cdbd | ||
|
|
817dbb6e32 |
@@ -1 +1,3 @@
|
||||
/.idea
|
||||
/dist
|
||||
/target
|
||||
|
||||
+4
-15
@@ -1,27 +1,18 @@
|
||||
project_name: softnet
|
||||
|
||||
builds:
|
||||
- id: softnet-arm64
|
||||
- id: softnet
|
||||
builder: prebuilt
|
||||
goamd64: [v1]
|
||||
goos:
|
||||
- darwin
|
||||
goarch:
|
||||
- arm64
|
||||
prebuilt:
|
||||
path: "target/aarch64-apple-darwin/release-with-debug/softnet"
|
||||
- id: softnet-x86
|
||||
builder: prebuilt
|
||||
goos:
|
||||
- darwin
|
||||
goarch:
|
||||
- amd64
|
||||
prebuilt:
|
||||
path: "target/x86_64-apple-darwin/release-with-debug/softnet"
|
||||
path: 'target/{{- if eq .Arch "arm64" }}aarch64{{- else }}x86_64{{ end }}-apple-darwin/release-with-debug/softnet'
|
||||
|
||||
archives:
|
||||
- id: binary
|
||||
format: binary
|
||||
name_template: "{{ .ProjectName }}-{{ .Arch }}"
|
||||
- id: regular
|
||||
name_template: "{{ .ProjectName }}-{{ .Arch }}"
|
||||
|
||||
@@ -30,9 +21,7 @@ release:
|
||||
|
||||
brews:
|
||||
- name: softnet
|
||||
ids:
|
||||
- regular
|
||||
tap:
|
||||
repository:
|
||||
owner: cirruslabs
|
||||
name: homebrew-cli
|
||||
caveats: See the Github repository for more information
|
||||
|
||||
+19
-3
@@ -1,3 +1,4 @@
|
||||
use clap::ArgEnum;
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use std::net::Ipv4Addr;
|
||||
use std::os::unix::io::{AsRawFd, RawFd};
|
||||
@@ -8,6 +9,18 @@ use vmnet::mode::Mode;
|
||||
use vmnet::parameters::{Parameter, ParameterKind};
|
||||
use vmnet::{Events, Options};
|
||||
|
||||
#[derive(ArgEnum, Clone, Debug)]
|
||||
pub enum NetType {
|
||||
/// Shared network
|
||||
///
|
||||
/// Uses NAT-translation to give guests access to the global network
|
||||
Nat,
|
||||
/// Host network
|
||||
///
|
||||
/// Guests will be able to talk only to the host without access to global network
|
||||
Host,
|
||||
}
|
||||
|
||||
pub struct Host {
|
||||
interface: vmnet::Interface,
|
||||
new_packets_rx: UnixDatagram,
|
||||
@@ -18,10 +31,13 @@ pub struct Host {
|
||||
}
|
||||
|
||||
impl Host {
|
||||
pub fn new() -> Result<Host> {
|
||||
// Initialize a vmnet.framework NAT interface with isolation enabled
|
||||
pub fn new(vm_net_type: NetType) -> Result<Host> {
|
||||
// Initialize a vmnet.framework NAT or Host interface with isolation enabled
|
||||
let mut interface = vmnet::Interface::new(
|
||||
Mode::Shared(Default::default()),
|
||||
match vm_net_type {
|
||||
NetType::Nat => Mode::Shared(Default::default()),
|
||||
NetType::Host => Mode::Host(Default::default()),
|
||||
},
|
||||
Options {
|
||||
enable_isolation: Some(true),
|
||||
..Default::default()
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
mod dhcp_snooper;
|
||||
mod host;
|
||||
pub use host::NetType;
|
||||
mod poller;
|
||||
pub mod proxy;
|
||||
mod vm;
|
||||
|
||||
+3
-2
@@ -4,6 +4,7 @@ mod vm;
|
||||
|
||||
use crate::dhcp_snooper::DhcpSnooper;
|
||||
use crate::host::Host;
|
||||
use crate::host::NetType;
|
||||
use crate::poller::Poller;
|
||||
use crate::vm::VM;
|
||||
use anyhow::Result;
|
||||
@@ -22,9 +23,9 @@ pub struct Proxy {
|
||||
}
|
||||
|
||||
impl Proxy {
|
||||
pub fn new(vm_fd: RawFd, vm_mac_address: MacAddress) -> Result<Proxy> {
|
||||
pub fn new(vm_fd: RawFd, vm_mac_address: MacAddress, vm_net_type: NetType) -> Result<Proxy> {
|
||||
let vm = VM::new(vm_fd)?;
|
||||
let host = Host::new()?;
|
||||
let host = Host::new(vm_net_type)?;
|
||||
let poller = Poller::new(vm.as_raw_fd(), host.as_raw_fd())?;
|
||||
|
||||
Ok(Proxy {
|
||||
|
||||
+7
-3
@@ -61,10 +61,14 @@ impl Proxy {
|
||||
// Once we've learned the VM's IP from the DHCP snooping,
|
||||
// allow all global traffic for that VM's IP
|
||||
if let Some(lease) = &self.dhcp_snooper.lease() {
|
||||
let dst_is_global =
|
||||
ip_network::IpNetwork::from(Ipv4Addr::from(ipv4_pkt.dst_addr().0)).is_global();
|
||||
let ip_net = &ip_network::IpNetwork::from(Ipv4Addr::from(ipv4_pkt.dst_addr().0));
|
||||
let dst_is_global_or_private =
|
||||
match &ip_net {
|
||||
ip_network::IpNetwork::V4(ip_net) => ip_net.is_global() || ip_net.is_private(),
|
||||
ip_network::IpNetwork::V6(ip_net) => ip_net.is_global(),
|
||||
};
|
||||
|
||||
if lease.valid_ip_source(ipv4_pkt.src_addr()) && dst_is_global {
|
||||
if lease.valid_ip_source(ipv4_pkt.src_addr()) && dst_is_global_or_private {
|
||||
return Some(());
|
||||
}
|
||||
}
|
||||
|
||||
+5
-1
@@ -2,6 +2,7 @@ use anyhow::{anyhow, Context};
|
||||
use clap::Parser;
|
||||
use nix::sys::signal::{signal, SigHandler, Signal};
|
||||
use privdrop::PrivDrop;
|
||||
use softnet::NetType;
|
||||
use softnet::proxy::Proxy;
|
||||
use std::borrow::Cow;
|
||||
use std::env;
|
||||
@@ -28,6 +29,9 @@ struct Args {
|
||||
#[clap(long, help = "MAC address to enforce for the VM")]
|
||||
vm_mac_address: mac_address::MacAddress,
|
||||
|
||||
#[clap(long, arg_enum, help = "type of network to use for the VM", default_value_t=NetType::Nat)]
|
||||
vm_net_type: NetType,
|
||||
|
||||
#[clap(
|
||||
long,
|
||||
help = "set bootpd(8) lease time to this value (in seconds) before starting the VM",
|
||||
@@ -140,7 +144,7 @@ fn try_main() -> anyhow::Result<()> {
|
||||
set_bootpd_lease_time(args.bootpd_lease_time);
|
||||
|
||||
// Initialize the proxy while still having the root privileges
|
||||
let mut proxy = Proxy::new(args.vm_fd as RawFd, args.vm_mac_address)
|
||||
let mut proxy = Proxy::new(args.vm_fd as RawFd, args.vm_mac_address, args.vm_net_type)
|
||||
.context("failed to initialize proxy")?;
|
||||
|
||||
// Drop effective privileges to the user
|
||||
|
||||
Reference in New Issue
Block a user