diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index 09712b350..728a9f704 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -14,6 +14,7 @@ - [Architecture Decision Records](architecture/adr.md) - [Minimal Host](architecture/adr/minimal-host.md) - [Networking VM](architecture/adr/netvm.md) + - [Intrusion Detection System VM](architecture/adr/idsvm.md) - [Platform Bus for Rust VMM](architecture/adr/platform-bus-passthrough-support.md) - [Hardening](architecture/hardening.md) - [Secure Boot](architecture/secureboot.md) @@ -29,7 +30,8 @@ - [Installer](ref_impl/installer.md) - [Cross-Compilation](ref_impl/cross_compilation.md) - [Creating Application VM](ref_impl/creating_appvm.md) - - [labWC Desktop Environment](ref_impl/labwc.md) + - [LabWC Desktop Environment](ref_impl/labwc.md) + - [Further Development of the idsvm](ref_impl/idsvm-development.md) - [Ghaf as Library: Templates](ref_impl/ghaf-based-project.md) - [Example Project](ref_impl/example_project.md) - [Modules Options](ref_impl/modules_options.md) diff --git a/docs/src/architecture/adr.md b/docs/src/architecture/adr.md index cfd762442..c3b000d20 100644 --- a/docs/src/architecture/adr.md +++ b/docs/src/architecture/adr.md @@ -13,6 +13,7 @@ The Ghaf platform decision log: | -------- | ----------- | | [Minimal Host](../architecture/adr/minimal-host.md) | Proposed. | | [netvm—Networking Virtual Machine](../architecture/adr/netvm.md) | Proposed, partially implemented for development and testing. | +| [idsvm—Intrusion Detection System Virtual Machine](../architecture/adr/idsvm.md) | Proposed, partially implemented for development and testing. | | [Platform Bus for RustVMM](../architecture/adr/platform-bus-passthrough-support.md) | Proposed, WIP. | diff --git a/docs/src/architecture/adr/idsvm.md b/docs/src/architecture/adr/idsvm.md new file mode 100644 index 000000000..39b761cb7 --- /dev/null +++ b/docs/src/architecture/adr/idsvm.md @@ -0,0 +1,40 @@ + + +# idsvm-Itrusion Detection System Virtual Machine + +## Status + +Proposed, partially implemented for development and testing. + +*idsvm* reference declaration will be available at [microvm/idsvm.nix] +(https://github.com/tiiuae/ghaf/blob/main/modules/virtualization/microvm/idsvm.nix) + +## Context + +Ghaf high-level design target is to secure a monolithic OS by modularizing +the OS to networked VMs. The key security target is to detect intrusions by +analyzing the network traffic in the internal network of the OS. + +## Decision + +The main goal is to have networking entity in Ghaf internal network so that +all network traffic goes via that entity. Traffic then can be analysed to +detect possible intrusions in inter VM communication and outgoing network +traffic (from VM to internet). This goal is achieved itroducing a dedicated +virtual machine and route all networking from other virtual machines to go +through it. Then it is possible to use various IDS software solutions in +idsvm to detect possible suspicious network activities. + +![Scope!](../../img/idsvm.drawio.png "idsvm Solution") + +## Consequences + +A dedicated idsvm provides a single checkpoint to detect intrusions +and anomalies in the internal network of the OS and to initiate required +countermeasures. + +Routing and analysing the network traffic in separate VM will reduce network +performance. diff --git a/docs/src/architecture/architecture.md b/docs/src/architecture/architecture.md index 727ad34f6..004cfdc98 100644 --- a/docs/src/architecture/architecture.md +++ b/docs/src/architecture/architecture.md @@ -22,5 +22,6 @@ The Ghaf Platform components are used in reference configurations to build image - [Architecture Decision Records](./adr.md) - [Minimal Host](./adr/minimal-host.md) - [Networking VM](./adr/netvm.md) + - [Intrusion Detection System VM](./adr/idsvm.md) - [Platform Bus for Rust VMM](./adr/platform-bus-passthrough-support.md) - [Stack](./stack.md) \ No newline at end of file diff --git a/docs/src/img/idsvm.drawio.png b/docs/src/img/idsvm.drawio.png new file mode 100644 index 000000000..0f890d297 Binary files /dev/null and b/docs/src/img/idsvm.drawio.png differ diff --git a/docs/src/ref_impl/idsvm-development.md b/docs/src/ref_impl/idsvm-development.md new file mode 100644 index 000000000..bca40baf8 --- /dev/null +++ b/docs/src/ref_impl/idsvm-development.md @@ -0,0 +1,34 @@ + + +# Futher Development of the idsvm + +## About Implementation + +The idsvm is implemented as a regular microVM with static IP. +The mitmproxy is included to demonstrative interactive proxy to enable analysis of TLS protected data on the fly. Also Snort network intrusion detection and prevention system package is included, but no dedicated UI nor proper utilization is provided. + +Enforcing network traffic to go through idsvm is crucial part of the idsvm functionality. +It is achieved by setting the idsvm to be the gateway of other VMs in dnsmasq configuration +of netvm. There is a risk is that one could change gateway settings of the VM to bypass the idsvm. This however requires root (sudo) rights and it is assumed here that these rights are enabled only in debug build. + +## About mitmproxy + +"The mitmproxy is a free and open source interactive HTTPS proxy. It is your swiss-army knife for debugging, testing, privacy measurements, and penetration testing. It can be used to intercept, inspect, modify and replay web traffic such as HTTP/1, HTTP/2, WebSockets, or any other SSL/TLS-protected protocols." +https://mitmproxy.org/ + +In idsvm we use mitmweb tool to demonstrate mitmproxy's capabilities. It provides web-based user interface that allows interactive examination and modification of HTTP(s) traffic. +Mitmproxy package also includes console tool that provides basically same functionalities in text-based interface and it also includes a command-line tool mitmdump to view, record, and programmatically transform HTTP(s) traffic. + +Mitmweb tool is run in idsvm as a systemd service. It starts automatically when idsvm boots up. +The UI it provides is accessible in the web address http://localhost:8081 so basically it is available from idsvm only. However using SSH portforwarfing it is possible to access the UI from other VMs. To that purpose the guivm has a script called mitmweb-ui. It creates a SSH tunnel between idsvm and chromium-vm, launches the Chromium and connects to the UI-address. + +## About Certificates + +Mitmproxy can decrypt encrypted traffic on the fly, as long as the client trusts mitmproxy's built-in certificate authority (CA). CA certificates are in hardcoded to the idsvm implementation which means they are same for all idsvm instances. In release version these should be randomly generated and stored securely. + +By default any of the clients should not trust mitmproxy's CA. That is why these CA certicates should be installed to OS's CA storage. However many client applications (web browsers) use their own CA bundles and importing custom certificates to there can be very complicated or requires manual user interaction. In our case this difficulty is circumvented in chromium-vm by disabling certicate verification errors, if the certicate chain contains a certificate which SPKI fingerprint matches that of mitmproxy's CA certificate fingerprint. This does not degrade security of server verification since mitmproxy itself validates upstream certificates using certifi Python package, which provides Mozilla's CA Bundle. + +Some applications use certificate pinning to prevent man-in-the-middle attacks. As a consequence mitmproxy's certificates will not be accepted by these applications without patching applications manually. Other option is to set mitmproxy to use ignore_hosts option to prevent mitmproxy from intercepting traffic to these specific domains. diff --git a/modules/microvm/default.nix b/modules/microvm/default.nix index c6ed61070..620ff391f 100644 --- a/modules/microvm/default.nix +++ b/modules/microvm/default.nix @@ -7,6 +7,8 @@ imports = [ ./virtualization/microvm/microvm-host.nix ./virtualization/microvm/netvm.nix + ./virtualization/microvm/idsvm/idsvm.nix + ./virtualization/microvm/idsvm/mitmproxy ./virtualization/microvm/appvm.nix ./virtualization/microvm/guivm.nix ./networking.nix diff --git a/modules/microvm/virtualization/microvm/guivm.nix b/modules/microvm/virtualization/microvm/guivm.nix index 169a36255..ddc29521e 100644 --- a/modules/microvm/virtualization/microvm/guivm.nix +++ b/modules/microvm/virtualization/microvm/guivm.nix @@ -63,11 +63,13 @@ }; environment = { - systemPackages = [ - pkgs.waypipe - pkgs.networkmanagerapplet - pkgs.nm-launcher - ]; + systemPackages = + [ + pkgs.waypipe + pkgs.networkmanagerapplet + pkgs.nm-launcher + ] + ++ (lib.optional (configHost.ghaf.profiles.debug.enable && configHost.ghaf.virtualization.microvm.idsvm.mitmproxy.enable) pkgs.mitmweb-ui); }; system.stateVersion = lib.trivial.release; diff --git a/modules/microvm/virtualization/microvm/idsvm/idsvm.nix b/modules/microvm/virtualization/microvm/idsvm/idsvm.nix new file mode 100644 index 000000000..15cf244bb --- /dev/null +++ b/modules/microvm/virtualization/microvm/idsvm/idsvm.nix @@ -0,0 +1,99 @@ +# Copyright 2022-2023 TII (SSRC) and the Ghaf contributors +# SPDX-License-Identifier: Apache-2.0 +{ + config, + lib, + pkgs, + ... +}: let + configHost = config; + vmName = "ids-vm"; + macAddress = "02:00:00:01:01:02"; + networkName = "ethint0"; + idsvmBaseConfiguration = { + imports = [ + (import ../common/vm-networking.nix {inherit vmName macAddress;}) + ({lib, ...}: { + ghaf = { + users.accounts.enable = lib.mkDefault configHost.ghaf.users.accounts.enable; + + virtualization.microvm.idsvm.mitmproxy.enable = configHost.ghaf.virtualization.microvm.idsvm.mitmproxy.enable; + + development = { + # NOTE: SSH port also becomes accessible on the network interface + # that has been passed through to NetVM + ssh.daemon.enable = lib.mkDefault configHost.ghaf.development.ssh.daemon.enable; + debug.tools.enable = lib.mkDefault configHost.ghaf.development.debug.tools.enable; + nix-setup.enable = lib.mkDefault configHost.ghaf.development.nix-setup.enable; + }; + }; + + system.stateVersion = lib.trivial.release; + + nixpkgs.buildPlatform.system = configHost.nixpkgs.buildPlatform.system; + nixpkgs.hostPlatform.system = configHost.nixpkgs.hostPlatform.system; + + microvm.hypervisor = "cloud-hypervisor"; + + environment.systemPackages = + [ + pkgs.snort # TODO: put into separate module + ] + ++ (lib.optional configHost.ghaf.profiles.debug.enable pkgs.tcpdump); + + systemd.network = { + networks."10-${networkName}" = { + gateway = ["192.168.100.1"]; + addresses = [ + { + # IP-address for debugging subnet + addressConfig.Address = "192.168.101.4/24"; + } + ]; + }; + }; + + microvm = { + optimize.enable = true; + shares = [ + { + tag = "ro-store"; + source = "/nix/store"; + mountPoint = "/nix/.ro-store"; + proto = "virtiofs"; + } + ]; + writableStoreOverlay = lib.mkIf config.ghaf.development.debug.tools.enable "/nix/.rw-store"; + }; + + imports = [../../../../common ./mitmproxy]; + }) + ]; + }; + cfg = config.ghaf.virtualization.microvm.idsvm; +in { + options.ghaf.virtualization.microvm.idsvm = { + enable = lib.mkEnableOption "Whether to enable IDS-VM on the system"; + + extraModules = lib.mkOption { + description = '' + List of additional modules to be imported and evaluated as part of + IDSVM's NixOS configuration. + ''; + default = []; + }; + }; + + config = lib.mkIf cfg.enable { + microvm.vms."${vmName}" = { + autostart = true; + config = + idsvmBaseConfiguration + // { + imports = + idsvmBaseConfiguration.imports + ++ cfg.extraModules; + }; + }; + }; +} diff --git a/modules/microvm/virtualization/microvm/idsvm/mitmproxy/default.nix b/modules/microvm/virtualization/microvm/idsvm/mitmproxy/default.nix new file mode 100644 index 000000000..17f15e80e --- /dev/null +++ b/modules/microvm/virtualization/microvm/idsvm/mitmproxy/default.nix @@ -0,0 +1,61 @@ +# Copyright 2022-2024 TII (SSRC) and the Ghaf contributors +# SPDX-License-Identifier: Apache-2.0 +{ + lib, + pkgs, + config, + ... +}: let + cfg = config.ghaf.virtualization.microvm.idsvm.mitmproxy; + mitmproxyport = 8080; + mitmwebUIport = 8081; +in { + options.ghaf.virtualization.microvm.idsvm.mitmproxy = { + enable = lib.mkEnableOption "Whether to enable mitmproxy on ids-vm"; + }; + + config = lib.mkIf cfg.enable { + # Here we add default CA keypair and corresponding self-signed certificate + # for mitmproxy in different formats. These should be, of course, randomly and + # securely generated and stored for each instance, but for development purposes + # we use these fixed ones. + environment.etc = { + "mitmproxy/mitmproxy-ca-cert.cer".source = ./mitmproxy-ca/mitmproxy-ca-cert.cer; + "mitmproxy/mitmproxy-ca-cert.p12".source = ./mitmproxy-ca/mitmproxy-ca-cert.p12; + "mitmproxy/mitmproxy-ca-cert.pem".source = ./mitmproxy-ca/mitmproxy-ca-cert.pem; + "mitmproxy/mitmproxy-ca.pem".source = ./mitmproxy-ca/mitmproxy-ca.pem; + "mitmproxy/mitmproxy-ca.p12".source = ./mitmproxy-ca/mitmproxy-ca.p12; + "mitmproxy/mitmproxy-dhparam.pem".source = ./mitmproxy-ca/mitmproxy-dhparam.pem; + }; + + systemd.services."mitmweb-server" = let + mitmwebScript = pkgs.writeShellScriptBin "mitmweb-server" '' + ${pkgs.mitmproxy}/bin/mitmweb --web-host localhost --web-port ${toString mitmwebUIport} --set confdir=/etc/mitmproxy + ''; + in { + enable = true; + description = "Run mitmweb to establish web interface for mitmproxy"; + path = [mitmwebScript]; + wantedBy = ["multi-user.target"]; + serviceConfig = { + Type = "simple"; + StandardOutput = "journal"; + StandardError = "journal"; + ExecStart = "${mitmwebScript}/bin/mitmweb-server"; + Restart = "on-failure"; + RestartSec = "1"; + }; + }; + + networking = { + firewall.allowedTCPPorts = [mitmproxyport mitmwebUIport]; + nat.extraCommands = + # Redirect http(s) traffic to mitmproxy. + '' + iptables -t nat -A PREROUTING -i ethint0 -p tcp --dport 80 -j REDIRECT --to-port ${toString mitmproxyport} + iptables -t nat -A PREROUTING -i ethint0 -p tcp --dport 443 -j REDIRECT --to-port ${toString mitmproxyport} + ''; + }; + environment.systemPackages = [pkgs.mitmproxy]; + }; +} diff --git a/modules/microvm/virtualization/microvm/idsvm/mitmproxy/mitmproxy-ca/mitmproxy-ca-cert.cer b/modules/microvm/virtualization/microvm/idsvm/mitmproxy/mitmproxy-ca/mitmproxy-ca-cert.cer new file mode 100644 index 000000000..9beb77739 --- /dev/null +++ b/modules/microvm/virtualization/microvm/idsvm/mitmproxy/mitmproxy-ca/mitmproxy-ca-cert.cer @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDNTCCAh2gAwIBAgIUItvWgfGeI8GlhgumoYarXZhO1OMwDQYJKoZIhvcNAQEL +BQAwKDESMBAGA1UEAwwJbWl0bXByb3h5MRIwEAYDVQQKDAltaXRtcHJveHkwHhcN +MjMwNjI2MjA0MjUxWhcNMzMwNjI1MjA0MjUxWjAoMRIwEAYDVQQDDAltaXRtcHJv +eHkxEjAQBgNVBAoMCW1pdG1wcm94eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAOPknE6S+anfr52iO58VsPBcKrTbpWCV1NPmpWh6YmZxuzA3IjNu8X9i +0ByVgutysmrIXWqt7EOds8vCqLCX3+pGB6XsNMC4ksn42SH6QmWUTZizUjCI+7c2 +B1fYxzU5aaG2Z9TDtfExdWqnHR0c0dTR7c2IUeH7qgy/8oSukQeFdhp/j/d+cosU +KtXxMl9vk4wiseLRS2JBb+QKdM+TdNKLpAZmYT68WIIPB/0Vsxo1ZeSf8A4KLElr +9z9oksT5RPZAkuqV4TtWZoSPf01lB5jBCRblSGqw3m9ARAjH3MN1cDvwKkOtPrEC +iBKv9S51CyGPLkrEQoQrscvGKkEp5mECAwEAAaNXMFUwDwYDVR0TAQH/BAUwAwEB +/zATBgNVHSUEDDAKBggrBgEFBQcDATAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FLfWC+xt92Gs5X8I0H9E0ZPZ1nUZMA0GCSqGSIb3DQEBCwUAA4IBAQCEuExtxt6S +Pr7hXul8xNl8gjb94xB2vB6DJwtn97vXDtMqQ7P6o9e+7d2Yzp/y/hAlVpkZbwJo +WnE5aKI+SiuoyPJhM3qtSqFEnjogm+2GS+Htd9SGYPX6qrsbG5/FUE2NKF4sr9zB +vNYOzcaJO6X1+A3a7fS65ytjRYwO0T+6NtPkqwJ/ACT3vov94u9oGJ8O9rkFoG93 +7Guyh26JA71/N8SKWSIB/35pYKvX2usmsPCs8UYNC3UH4fH4d0yHBA9vV9XLE5H5 +cgESHG6F13V3WpeEgc83DWG6Tvml64ldORCVSi5doLTfaN/UIEZXFPMZ2ZCfsQvA ++PqFqfsCDYU1 +-----END CERTIFICATE----- diff --git a/modules/microvm/virtualization/microvm/idsvm/mitmproxy/mitmproxy-ca/mitmproxy-ca-cert.p12 b/modules/microvm/virtualization/microvm/idsvm/mitmproxy/mitmproxy-ca/mitmproxy-ca-cert.p12 new file mode 100644 index 000000000..b7103f08e Binary files /dev/null and b/modules/microvm/virtualization/microvm/idsvm/mitmproxy/mitmproxy-ca/mitmproxy-ca-cert.p12 differ diff --git a/modules/microvm/virtualization/microvm/idsvm/mitmproxy/mitmproxy-ca/mitmproxy-ca-cert.pem b/modules/microvm/virtualization/microvm/idsvm/mitmproxy/mitmproxy-ca/mitmproxy-ca-cert.pem new file mode 100644 index 000000000..9beb77739 --- /dev/null +++ b/modules/microvm/virtualization/microvm/idsvm/mitmproxy/mitmproxy-ca/mitmproxy-ca-cert.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDNTCCAh2gAwIBAgIUItvWgfGeI8GlhgumoYarXZhO1OMwDQYJKoZIhvcNAQEL +BQAwKDESMBAGA1UEAwwJbWl0bXByb3h5MRIwEAYDVQQKDAltaXRtcHJveHkwHhcN +MjMwNjI2MjA0MjUxWhcNMzMwNjI1MjA0MjUxWjAoMRIwEAYDVQQDDAltaXRtcHJv +eHkxEjAQBgNVBAoMCW1pdG1wcm94eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAOPknE6S+anfr52iO58VsPBcKrTbpWCV1NPmpWh6YmZxuzA3IjNu8X9i +0ByVgutysmrIXWqt7EOds8vCqLCX3+pGB6XsNMC4ksn42SH6QmWUTZizUjCI+7c2 +B1fYxzU5aaG2Z9TDtfExdWqnHR0c0dTR7c2IUeH7qgy/8oSukQeFdhp/j/d+cosU +KtXxMl9vk4wiseLRS2JBb+QKdM+TdNKLpAZmYT68WIIPB/0Vsxo1ZeSf8A4KLElr +9z9oksT5RPZAkuqV4TtWZoSPf01lB5jBCRblSGqw3m9ARAjH3MN1cDvwKkOtPrEC +iBKv9S51CyGPLkrEQoQrscvGKkEp5mECAwEAAaNXMFUwDwYDVR0TAQH/BAUwAwEB +/zATBgNVHSUEDDAKBggrBgEFBQcDATAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FLfWC+xt92Gs5X8I0H9E0ZPZ1nUZMA0GCSqGSIb3DQEBCwUAA4IBAQCEuExtxt6S +Pr7hXul8xNl8gjb94xB2vB6DJwtn97vXDtMqQ7P6o9e+7d2Yzp/y/hAlVpkZbwJo +WnE5aKI+SiuoyPJhM3qtSqFEnjogm+2GS+Htd9SGYPX6qrsbG5/FUE2NKF4sr9zB +vNYOzcaJO6X1+A3a7fS65ytjRYwO0T+6NtPkqwJ/ACT3vov94u9oGJ8O9rkFoG93 +7Guyh26JA71/N8SKWSIB/35pYKvX2usmsPCs8UYNC3UH4fH4d0yHBA9vV9XLE5H5 +cgESHG6F13V3WpeEgc83DWG6Tvml64ldORCVSi5doLTfaN/UIEZXFPMZ2ZCfsQvA ++PqFqfsCDYU1 +-----END CERTIFICATE----- diff --git a/modules/microvm/virtualization/microvm/idsvm/mitmproxy/mitmproxy-ca/mitmproxy-ca.p12 b/modules/microvm/virtualization/microvm/idsvm/mitmproxy/mitmproxy-ca/mitmproxy-ca.p12 new file mode 100644 index 000000000..c7060fa0e Binary files /dev/null and b/modules/microvm/virtualization/microvm/idsvm/mitmproxy/mitmproxy-ca/mitmproxy-ca.p12 differ diff --git a/modules/microvm/virtualization/microvm/idsvm/mitmproxy/mitmproxy-ca/mitmproxy-ca.pem b/modules/microvm/virtualization/microvm/idsvm/mitmproxy/mitmproxy-ca/mitmproxy-ca.pem new file mode 100644 index 000000000..b2c545328 --- /dev/null +++ b/modules/microvm/virtualization/microvm/idsvm/mitmproxy/mitmproxy-ca/mitmproxy-ca.pem @@ -0,0 +1,47 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA4+ScTpL5qd+vnaI7nxWw8FwqtNulYJXU0+alaHpiZnG7MDci +M27xf2LQHJWC63Kyashdaq3sQ52zy8KosJff6kYHpew0wLiSyfjZIfpCZZRNmLNS +MIj7tzYHV9jHNTlpobZn1MO18TF1aqcdHRzR1NHtzYhR4fuqDL/yhK6RB4V2Gn+P +935yixQq1fEyX2+TjCKx4tFLYkFv5Ap0z5N00oukBmZhPrxYgg8H/RWzGjVl5J/w +DgosSWv3P2iSxPlE9kCS6pXhO1ZmhI9/TWUHmMEJFuVIarDeb0BECMfcw3VwO/Aq +Q60+sQKIEq/1LnULIY8uSsRChCuxy8YqQSnmYQIDAQABAoIBAQC/S1L5kd4Ifj+H +7nplm2ufF36xuf4kCSFRjjYicTjQDX+3hVAsJGCLMYLHu6jdwrWJdQ8VUVEVoPcf +fxLiyVmn6YjZ+mB9tXFiIIUDRHMfmVFZcIz5OMMykyOu1cTCJKNKnzahHndHMuEA +2a5SlbJ9FoqrEFbLftjLQwRr46zRxduoF2Znz/XhPMcoOsMoFuUIEtS3kmblW8Zr +UzKkvT2GUb5b19WNIbK/1ZWnkYTh6nTQPNz8FYpNb7ZuS/UfNGP05r+ZbgzmSS8B +Mwl2u2AqXEo15ULjEP8XQpmQXDbaOAjZHzF0nqx2Sw7iY9MfAarIekGLVRJ+LRwA +mkT8TPuRAoGBAP+20Ah6SCJN4DpDLC/Zu/2rRanpxxyk1awseFlfNOPegAuM+Gic +fHeUDYooHxZwbowAjyo4o36rnHJJi8ZniTHZG9ddy9U75TgVZK4Xr7MkmmOCpv1Q +50BTxsnWir3pTspgWCZ8oXmyvNJV/hl0fGqFW3WxI41upMM6w3uSMdvnAoGBAOQl +1dgXh+Qo8DhAaWmhmDLpcfWD2XB3rhZxQfbYCC+oyrQgpgyQpOEgmPKcjDrsToRK +Ze08O3t5inrvyH41THhByDfV6pxZSGRPoBxr1ZMej6V50FFHctQbDqDhmBdlKpkx +3ryGBrhUxjwklg915UwvZc1iewYdZxd0JeST+CJ3AoGBALbU9QU6uRyd5baClLNZ +0InczaBhIBYg3Q2PdjUgV2adjZu0nV/ekzfESbIAYcnfdYrwU2xytqM4/FDSuPeQ +y40ymC9yRu0dOBTTZvr6wIsrnp+LqO3xzIY34CgsF2MVz1nvbNeHwMSMwWj6RwXY +PaTD2NLbZnoXJALany5ZJwD9AoGAVKqZ1my9GHX819NHi1TVx6cMjIFWsz8m0ttL +EJERUKaCOyCWnrkbBxTyza48+Czz4nI9qzGcHXF4a7EKpZOgAkzfQaFYRJd5nwhR +sdpu0v8XbeBr543tVjuITToLGDuJ+HoiX7IZUlTbkDw/mBM3efNpAzRV1WoZ9QE8 +grxK7HcCgYAT0dGsFd1RY+m/Ik/jTxRDSi7zLLtyZO8AsGsfqsm0b8GhTTlXzEmH +kgp75/W058vjc7H1PY7FNr5neUn/Dtom2YtJRhANK/dhzh+RDSfFgbCX+VHTwh1a +nb7F25+bEhlvfe5yLb+O6ZzbsL/EdJYg0BoHCgTI2bZJkzRtAzdHuA== +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIDNTCCAh2gAwIBAgIUItvWgfGeI8GlhgumoYarXZhO1OMwDQYJKoZIhvcNAQEL +BQAwKDESMBAGA1UEAwwJbWl0bXByb3h5MRIwEAYDVQQKDAltaXRtcHJveHkwHhcN +MjMwNjI2MjA0MjUxWhcNMzMwNjI1MjA0MjUxWjAoMRIwEAYDVQQDDAltaXRtcHJv +eHkxEjAQBgNVBAoMCW1pdG1wcm94eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAOPknE6S+anfr52iO58VsPBcKrTbpWCV1NPmpWh6YmZxuzA3IjNu8X9i +0ByVgutysmrIXWqt7EOds8vCqLCX3+pGB6XsNMC4ksn42SH6QmWUTZizUjCI+7c2 +B1fYxzU5aaG2Z9TDtfExdWqnHR0c0dTR7c2IUeH7qgy/8oSukQeFdhp/j/d+cosU +KtXxMl9vk4wiseLRS2JBb+QKdM+TdNKLpAZmYT68WIIPB/0Vsxo1ZeSf8A4KLElr +9z9oksT5RPZAkuqV4TtWZoSPf01lB5jBCRblSGqw3m9ARAjH3MN1cDvwKkOtPrEC +iBKv9S51CyGPLkrEQoQrscvGKkEp5mECAwEAAaNXMFUwDwYDVR0TAQH/BAUwAwEB +/zATBgNVHSUEDDAKBggrBgEFBQcDATAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FLfWC+xt92Gs5X8I0H9E0ZPZ1nUZMA0GCSqGSIb3DQEBCwUAA4IBAQCEuExtxt6S +Pr7hXul8xNl8gjb94xB2vB6DJwtn97vXDtMqQ7P6o9e+7d2Yzp/y/hAlVpkZbwJo +WnE5aKI+SiuoyPJhM3qtSqFEnjogm+2GS+Htd9SGYPX6qrsbG5/FUE2NKF4sr9zB +vNYOzcaJO6X1+A3a7fS65ytjRYwO0T+6NtPkqwJ/ACT3vov94u9oGJ8O9rkFoG93 +7Guyh26JA71/N8SKWSIB/35pYKvX2usmsPCs8UYNC3UH4fH4d0yHBA9vV9XLE5H5 +cgESHG6F13V3WpeEgc83DWG6Tvml64ldORCVSi5doLTfaN/UIEZXFPMZ2ZCfsQvA ++PqFqfsCDYU1 +-----END CERTIFICATE----- diff --git a/modules/microvm/virtualization/microvm/idsvm/mitmproxy/mitmproxy-ca/mitmproxy-dhparam.pem b/modules/microvm/virtualization/microvm/idsvm/mitmproxy/mitmproxy-ca/mitmproxy-dhparam.pem new file mode 100644 index 000000000..c10121fbf --- /dev/null +++ b/modules/microvm/virtualization/microvm/idsvm/mitmproxy/mitmproxy-ca/mitmproxy-dhparam.pem @@ -0,0 +1,14 @@ + +-----BEGIN DH PARAMETERS----- +MIICCAKCAgEAyT6LzpwVFS3gryIo29J5icvgxCnCebcdSe/NHMkD8dKJf8suFCg3 +O2+dguLakSVif/t6dhImxInJk230HmfC8q93hdcg/j8rLGJYDKu3ik6H//BAHKIv +j5O9yjU3rXCfmVJQic2Nne39sg3CreAepEts2TvYHhVv3TEAzEqCtOuTjgDv0ntJ +Gwpj+BJBRQGG9NvprX1YGJ7WOFBP/hWU7d6tgvE6Xa7T/u9QIKpYHMIkcN/l3ZFB +chZEqVlyrcngtSXCROTPcDOQ6Q8QzhaBJS+Z6rcsd7X+haiQqvoFcmaJ08Ks6LQC +ZIL2EtYJw8V8z7C0igVEBIADZBI6OTbuuhDwRw//zU1uq52Oc48CIZlGxTYG/Evq +o9EWAXUYVzWkDSTeBH1r4z/qLPE2cnhtMxbFxuvK53jGB0emy2y1Ei6IhKshJ5qX +IB/aE7SSHyQ3MDHHkCmQJCsOd4Mo26YX61NZ+n501XjqpCBQ2+DfZCBh8Va2wDyv +A2Ryg9SUz8j0AXViRNMJgJrr446yro/FuJZwnQcO3WQnXeqSBnURqKjmqkeFP+d8 +6mk2tqJaY507lRNqtGlLnj7f5RNoBFJDCLBNurVgfvq9TCVWKDIFD4vZRjCrnl6I +rD693XKIHUCWOjMh1if6omGXKHH40QuME2gNa50+YPn1iYDl88uDbbMCAQI= +-----END DH PARAMETERS----- diff --git a/modules/microvm/virtualization/microvm/netvm.nix b/modules/microvm/virtualization/microvm/netvm.nix index bfdc6d458..09221a4bc 100644 --- a/modules/microvm/virtualization/microvm/netvm.nix +++ b/modules/microvm/virtualization/microvm/netvm.nix @@ -62,10 +62,6 @@ dhcp-authoritative = true; domain = "ghaf"; listen-address = ["127.0.0.1,192.168.100.1"]; - dhcp-option = [ - "option:router,192.168.100.1" - "6,192.168.100.1" - ]; expand-hosts = true; domain-needed = true; bogus-priv = true; diff --git a/overlays/custom-packages/default.nix b/overlays/custom-packages/default.nix index e1add9499..5a61b59d6 100644 --- a/overlays/custom-packages/default.nix +++ b/overlays/custom-packages/default.nix @@ -22,4 +22,5 @@ # launcher overlays networkmanagerapplet = import ./networkmanagerapplet {inherit prev;}; htop = import ./htop {inherit prev;}; + mitmweb-ui = final.callPackage ../../packages/mitmweb-ui {}; }) diff --git a/overlays/custom-packages/mitmweb-ui/default.nix b/overlays/custom-packages/mitmweb-ui/default.nix new file mode 100644 index 000000000..79e7b34c7 --- /dev/null +++ b/overlays/custom-packages/mitmweb-ui/default.nix @@ -0,0 +1,5 @@ +# Copyright 2022-2023 TII (SSRC) and the Ghaf contributors +# SPDX-License-Identifier: Apache-2.0 +(final: _prev: { + mitmweb-ui = final.callPackage ../../../packages/mitmweb-ui {}; +}) diff --git a/packages/mitmweb-ui/default.nix b/packages/mitmweb-ui/default.nix new file mode 100644 index 000000000..e3d444755 --- /dev/null +++ b/packages/mitmweb-ui/default.nix @@ -0,0 +1,53 @@ +# Copyright 2022-2024 TII (SSRC) and the Ghaf contributors +# SPDX-License-Identifier: Apache-2.0 +{ + stdenvNoCC, + pkgs, + lib, + ... +}: let + waypipePort = 1100; # TODO: remove hardcoded port number + idsvmIP = "192.168.100.4"; + mitmwebUI = + pkgs.writeShellScript + "mitmweb-ui" + '' + # Create ssh-tunnel between chromium-vm and ids-vm + ${pkgs.openssh}/bin/ssh -i /run/waypipe-ssh/id_ed25519 \ + -o StrictHostKeyChecking=no \ + -t ghaf@chromium-vm.ghaf \ + ${pkgs.openssh}/bin/ssh -M -S /tmp/control_socket \ + -f -N -L 8081:localhost:8081 ghaf@${idsvmIP} + # TODO: check pipe creation failures + + # Launch chromium application and open mitmweb page + ${pkgs.openssh}/bin/ssh -i /run/waypipe-ssh/id_ed25519 -o StrictHostKeyChecking=no chromium-vm.ghaf \ + ${pkgs.waypipe}/bin/waypipe --border=#ff5733,5 --vsock -s ${toString waypipePort} server \ + chromium --enable-features=UseOzonePlatform --ozone-platform=wayland \ + http://localhost:8081 + + # Use the control socket to close the ssh tunnel between chromium-vm and ids-vm + ${pkgs.openssh}/bin/ssh -i /run/waypipe-ssh/id_ed25519 \ + -o StrictHostKeyChecking=no \ + -t ghaf@chromium-vm.ghaf \ + ${pkgs.openssh}/bin/ssh -q -S /tmp/control_socket -O exit ghaf@${idsvmIP} + ''; +in + stdenvNoCC.mkDerivation { + name = "mitmweb-ui"; + + phases = ["installPhase"]; + + installPhase = '' + mkdir -p $out/bin + cp ${mitmwebUI} $out/bin/mitmweb-ui + ''; + + meta = with lib; { + description = "Script to launch Chromium to open mitmweb interface using ssh-tunneling and authentication."; + platforms = [ + "x86_64-linux" + "aarch64-linux" + ]; + }; + } diff --git a/targets/generic-x86_64/flake-module.nix b/targets/generic-x86_64/flake-module.nix index 71cc549ff..49c841ff1 100644 --- a/targets/generic-x86_64/flake-module.nix +++ b/targets/generic-x86_64/flake-module.nix @@ -29,6 +29,10 @@ # networks."SSID_OF_NETWORK".psk = "WPA_PASSWORD"; }; + services.dnsmasq.settings.dhcp-option = [ + "option:router,192.168.100.1" # set net-vm as a default gw + "option:dns-server,192.168.100.1" + ]; } ]; hostConfiguration = lib.nixosSystem { diff --git a/targets/lenovo-x1/appvms/default.nix b/targets/lenovo-x1/appvms/default.nix index e93302a20..6033c33f5 100644 --- a/targets/lenovo-x1/appvms/default.nix +++ b/targets/lenovo-x1/appvms/default.nix @@ -3,11 +3,12 @@ # { pkgs, + lib, config, ... }: let chromium = import ./chromium.nix {inherit pkgs;}; - gala = import ./gala.nix {inherit pkgs;}; + gala = import ./gala.nix {inherit pkgs lib config;}; zathura = import ./zathura.nix {inherit pkgs;}; element = import ./element.nix {inherit pkgs;}; includeAppflowy = pkgs.stdenv.isx86_64; diff --git a/targets/lenovo-x1/appvms/gala.nix b/targets/lenovo-x1/appvms/gala.nix index 4371d790b..a4ff7c80e 100644 --- a/targets/lenovo-x1/appvms/gala.nix +++ b/targets/lenovo-x1/appvms/gala.nix @@ -1,7 +1,12 @@ # Copyright 2024 TII (SSRC) and the Ghaf contributors # SPDX-License-Identifier: Apache-2.0 # -{pkgs, ...}: { +{ + pkgs, + lib, + config, + ... +}: { name = "gala"; packages = [pkgs.gala-app]; macAddress = "02:00:00:03:06:01"; @@ -9,7 +14,10 @@ cores = 2; extraModules = [ { - time.timeZone = "Asia/Dubai"; + time.timeZone = config.time.timeZone; + security.pki.certificateFiles = + lib.mkIf config.ghaf.virtualization.microvm.idsvm.mitmproxy.enable + [../../../modules/microvm/virtualization/microvm/idsvm/mitmproxy/mitmproxy-ca/mitmproxy-ca-cert.pem]; } ]; borderColor = "#027d7b"; diff --git a/targets/lenovo-x1/everything.nix b/targets/lenovo-x1/everything.nix index 79f7523b8..0cbcd8b36 100644 --- a/targets/lenovo-x1/everything.nix +++ b/targets/lenovo-x1/everything.nix @@ -91,6 +91,12 @@ configH = config; }; }; + + virtualization.microvm.idsvm = { + enable = false; + mitmproxy.enable = false; + }; + virtualization.microvm.guivm = { enable = true; extraModules = @@ -102,7 +108,7 @@ }; virtualization.microvm.appvm = { enable = true; - vms = import ./appvms/default.nix {inherit pkgs config;}; + vms = import ./appvms/default.nix {inherit pkgs lib config;}; }; # Enable all the default UI applications diff --git a/targets/lenovo-x1/guivmExtraModules.nix b/targets/lenovo-x1/guivmExtraModules.nix index 3a486f6dc..c64eb1b30 100644 --- a/targets/lenovo-x1/guivmExtraModules.nix +++ b/targets/lenovo-x1/guivmExtraModules.nix @@ -46,8 +46,14 @@ privateSshKeyPath = configH.ghaf.security.sshKeys.sshKeyPath; in [ { + # The SPKI fingerprint is calculated like this: + # $ openssl x509 -noout -in mitmproxy-ca-cert.pem -pubkey | openssl asn1parse -noout -inform pem -out public.key + # $ openssl dgst -sha256 -binary public.key | openssl enc -base64 name = "chromium"; - path = "${pkgs.openssh}/bin/ssh -i ${privateSshKeyPath} -o StrictHostKeyChecking=no chromium-vm.ghaf run-waypipe chromium --enable-features=UseOzonePlatform --ozone-platform=wayland"; + path = + if configH.ghaf.virtualization.microvm.idsvm.mitmproxy.enable + then "${pkgs.openssh}/bin/ssh -i ${privateSshKeyPath} -o StrictHostKeyChecking=no chromium-vm.ghaf run-waypipe chromium --enable-features=UseOzonePlatform --ozone-platform=wayland --user-data-dir=/home/${configH.ghaf.users.accounts.user}/.config/chromium/Default --ignore-certificate-errors-spki-list=Bq49YmAq1CG6FuBzp8nsyRXumW7Dmkp7QQ/F82azxGU=" + else "${pkgs.openssh}/bin/ssh -i ${privateSshKeyPath} -o StrictHostKeyChecking=no chromium-vm.ghaf run-waypipe chromium --enable-features=UseOzonePlatform --ozone-platform=wayland"; icon = "${../../assets/icons/png/browser.png}"; } diff --git a/targets/lenovo-x1/netvmExtraModules.nix b/targets/lenovo-x1/netvmExtraModules.nix index 0f51d92d7..fec549189 100644 --- a/targets/lenovo-x1/netvmExtraModules.nix +++ b/targets/lenovo-x1/netvmExtraModules.nix @@ -30,6 +30,22 @@ unmanaged = ["ethint0"]; }; }; + services.dnsmasq.settings = { + # set static IP for IDS-VM + dhcp-host = lib.mkIf configH.ghaf.virtualization.microvm.idsvm.enable [ + "02:00:00:01:01:02,192.168.100.4,ids-vm,infinite" + ]; + dhcp-option = + if configH.ghaf.virtualization.microvm.idsvm.enable + then [ + "option:router,192.168.100.4" # set IDS-VM as a default gw + "option:dns-server,192.168.100.1" + ] + else [ + "option:router,192.168.100.1" # set NetVM as a default gw + "option:dns-server,192.168.100.1" + ]; + }; # noXlibs=false; needed for NetworkManager stuff environment.noXlibs = false; environment.etc."NetworkManager/system-connections/Wifi-1.nmconnection" = { diff --git a/targets/nvidia-jetson-orin/flake-module.nix b/targets/nvidia-jetson-orin/flake-module.nix index 0afea9854..3a089f20c 100644 --- a/targets/nvidia-jetson-orin/flake-module.nix +++ b/targets/nvidia-jetson-orin/flake-module.nix @@ -30,6 +30,11 @@ enableRedistributableFirmware = som == "agx"; wirelessRegulatoryDatabase = true; }; + + services.dnsmasq.settings.dhcp-option = [ + "option:router,192.168.100.1" # set net-vm as a default gw + "option:dns-server,192.168.100.1" + ]; } ]; hostConfiguration = lib.nixosSystem {