Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ ARG LINUX_VERSION="2.4.26"
ARG LIBNVRAM_VERSION="0.0.16"
ARG CONSOLE_VERSION="1.0.5"
ARG PENGUIN_PLUGINS_VERSION="1.5.15"
ARG VPN_VERSION="1.0.20"
ARG VPN_VERSION="1.0.23"
ARG HYPERFS_VERSION="0.0.38"
ARG GUESTHOPPER_VERSION="1.0.15"
ARG GLOW_VERSION="1.5.1"
Expand Down
26 changes: 26 additions & 0 deletions docs/schema_doc.md
Original file line number Diff line number Diff line change
Expand Up @@ -1154,4 +1154,30 @@ Whether to enable this plugin (default depends on plugin)
|__Default__|`null`|


## `network` Network Configuration

Configuration for networks to attach to guest

### `network.external` Set up NAT for outgoing connections

Configuration for NAT for external connections

#### `network.external.mac` MAC Address for external interface

|||
|-|-|
|__Type__|string or null|
|__Default__|`'52:54:00:12:34:56'`|

MAC Address for external network interface

#### `network.external.pcap` pcap file name

|||
|-|-|
|__Type__|boolean or null|
|__Default__|`null`|

Whether to capture traffic over the external net in a pcap file. The file will be called 'ext.pcap' in the output directory. Capture disabled if unset.


10 changes: 7 additions & 3 deletions pyplugins/actuation/vpn.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ def __init__(self, panda):
self.launch_host_vpn(self.get_arg("CID"),
self.get_arg("socket_path"),
self.get_arg("uds_path"),
self.get_arg_bool("log"))
self.get_arg_bool("log"),
self.get_arg_bool("pcap"))

port_maps = self.get_arg("IGLOO_VPN_PORT_MAPS")
self.seen_ips = set() # IPs we've seen
Expand Down Expand Up @@ -124,7 +125,7 @@ def __init__(self, panda):
# Whenever NetLog detects a bind, we'll set up bridges
plugins.subscribe(plugins.NetBinds, "on_bind", self.on_bind)

def launch_host_vpn(self, CID, socket_path, uds_path, log=False):
def launch_host_vpn(self, CID, socket_path, uds_path, log=False, pcap=False):
'''
Launch vhost-device-vsock and VPN on host
'''
Expand Down Expand Up @@ -157,7 +158,9 @@ def launch_host_vpn(self, CID, socket_path, uds_path, log=False):
]
if log:
host_vpn_cmd.extend(["-o", self.outdir])
self.host_vpn = subprocess.Popen(host_vpn_cmd, stdout=subprocess.DEVNULL)
if pcap:
host_vpn_cmd.extend(["-l", join(self.outdir, "vpn.pcap")])
self.host_vpn = subprocess.Popen(host_vpn_cmd, stdout=subprocess.DEVNULL, stderr=None)
running_vpns.append(self.host_vpn)

def on_bind(self, sock_type, ipvn, ip, port, procname):
Expand Down Expand Up @@ -316,6 +319,7 @@ def uninit(self):

if hasattr(self, "host_vpn"):
self.host_vpn.terminate()
self.host_vpn.wait(timeout=2) # Wait for logged packets to flush
self.host_vpn.kill()
running_vpns[:] = [x for x in running_vpns if x != self.host_vpn]
self.logger.debug("Killed VPN")
33 changes: 33 additions & 0 deletions src/penguin/penguin_config/structure.py
Original file line number Diff line number Diff line change
Expand Up @@ -763,6 +763,38 @@ class Plugin(BaseModel):
version: Annotated[Optional[str], Field(None, title="Plugin version")]


class ExternalNetwork(BaseModel):
"""Configuration for NAT for external connections"""

model_config = ConfigDict(title="Set up NAT for outgoing connections", extra="forbid")

mac: Optional[str] = Field(
title="MAC Address for external interface",
default="52:54:00:12:34:56",
description="MAC Address for external network interface"
)

# Not supported until QEMU 4.0+
# net: Optional[str] = Field(
# default="10.0.2.0/24",
# description="Net for external interface (e.g., 10.0.2.0/24). Host will accessible via .2"
# )

pcap: Optional[bool] = Field(
title="pcap file name",
default=None,
description="Whether to capture traffic over the external net in a pcap file. The file will be called 'ext.pcap' in the output directory. Capture disabled if unset."
)


class Network(BaseModel):
"""Configuration for networks to attach to guest"""

model_config = ConfigDict(title="Network Configuration", extra="forbid")

external: ExternalNetwork = Field(default_factory=ExternalNetwork)


class Main(BaseModel):
"""Configuration file for config-file-based rehosting with IGLOO"""

Expand All @@ -779,3 +811,4 @@ class Main(BaseModel):
lib_inject: LibInject
static_files: StaticFiles
plugins: Annotated[dict[str, Plugin], Field(title="Plugins")]
network: Optional[Network] = None
15 changes: 15 additions & 0 deletions src/penguin/penguin_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,21 @@ def run_config(
# Add args from config
args += shlex.split(conf["core"].get("extra_qemu_args", ""))

# If we have network args
if network := conf.get("network", None):
if "external" in network:
mac = network["external"]["mac"]
arg_str = f"-netdev user,id=ext -device virtio-net-pci,netdev=ext,mac={mac}"
# Supported in future versions of QEMU
# if net := network["external"].get("net", None):
# arg_str += ",net={net}"
if network["external"].get("pcap"):
pcap_path = os.path.join(out_dir, "ext.pcap")
arg_str += f" -object filter-dump,id=fext,netdev=ext,file={pcap_path}"
args += shlex.split(arg_str)
conf["env"]["IGLOO_EXT_MAC"] = mac
logger.info(f"Starting external network on interface {mac}. Host is available on 10.0.2.2")

# Disable audio (allegedly speeds up emulation by avoiding running another thread)
os.environ["QEMU_AUDIO_DRV"] = "none"

Expand Down
13 changes: 13 additions & 0 deletions src/resources/source.d/85_external_net.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

#!/igloo/utils/busybox sh

if [ ! -z "${IGLOO_EXT_MAC}" ]; then
for iface in $(/igloo/utils/busybox ls /sys/class/net); do
if [ "$(/igloo/utils/busybox cat /sys/class/net/$iface/address)" = "${IGLOO_EXT_MAC}" ]; then
break
fi
done
/igloo/utils/busybox ip addr add 10.0.2.15/24 dev $iface
/igloo/utils/busybox ip route add default via 10.0.2.2
echo "[IGLOO INIT] Found interface $iface with MAC $IGLOO_EXT_MAC and configured with IP 10.0.2.15/24"
fi