# SPDX-FileCopyrightText: 2022 Richard Brežák # # SPDX-License-Identifier: LGPL-3.0-or-later { notnft, inputs', lib, config, ... }: let inherit (lib) mkBefore flip genAttrs; in { networking.notnft = { enable = true; flush = false; }; networking.notnft.preRules = [ { add.table = { family = "bridge"; name = "bridge-t"; }; } { flush.table = { family = "bridge"; name = "bridge-t"; }; } ]; networking.notnft.rules = let interfaces = [ "mvm-test" "mvm0" ]; logRule = with notnft.dsl; with payload; prefix: [ (log { prefix = "${prefix} dropped: "; flags = (f: [ f.all ]); } ) ]; dropRule = with notnft.dsl; with payload; [ drop ]; in with notnft.dsl; with payload; ruleset { bridge-t = add table { family = f: f.bridge; } { input-body = add chain; input-mvm = add chain [ (vmap ct.state { established = accept; related = accept; invalid = drop; }) ] [ (is.eq meta.protocol (f: f.arp)) accept ] [ (mangle meta.nftrace 1) ] [ (jump "input-body") ] (logRule "Bridge input") (dropRule); input = add chain { type = f: f.filter; hook = f: f.input; prio = 0; policy = f: f.accept; } [ (vmap meta.iifname (genAttrs interfaces (_: (goto "input-mvm")))) ] [ (vmap meta.oifname (genAttrs interfaces (_: (goto "input-mvm")))) ]; output-body = add chain; output-mvm = add chain [ (is.eq ether.type (f: f.arp)) accept ] [ (mangle meta.nftrace 1) ] [ (jump "output-body") ] (logRule "Bridge output") (dropRule); output = add chain { type = f: f.filter; hook = f: f.output; prio = 0; policy = f: f.accept; } [ (vmap meta.iifname (genAttrs interfaces (_: (goto "output-mvm")))) ] [ (vmap meta.oifname (genAttrs interfaces (_: (goto "output-mvm")))) ]; forward-body = add chain; forward-mvm = add chain [ (mangle meta.nftrace 1) ] [ (jump "forward-body") ] (logRule "Bridge forward") (dropRule); forward = add chain { type = f: f.filter; hook = f: f.forward; prio = 0; policy = f: f.accept; } [ (vmap meta.iifname (genAttrs interfaces (_: (goto "input-mvm")))) ] [ (vmap meta.oifname (genAttrs interfaces (_: (goto "input-mvm")))) ]; # prerouting = add chain # { type = f: f.filter; hook = f: f.prerouting; prio = -300; policy = f: f.accept; } # ; # postrouting = add chain # { type = f: f.filter; hook = f: f.postrouting; prio = -300; policy = f: f.accept; } # ; }; }; systemd.services.notnftables = { requires = [ "nftables.service" ]; after = [ "nftables.service" ]; }; networking.bridges.mvm0 = { interfaces = []; }; networking.interfaces.mvm0 = { useDHCP = false; ipv4.addresses = [ { address = "10.80.1.1"; prefixLength = 24; } ]; }; microvm.services.tcpUdp.test-ssh = { hostName = "test"; port = 22; protocol = [ "tcp" ]; }; microvm.services.tcpUdp.test-http = { hostName = "test"; port = 80; protocol = [ "tcp" ]; }; microvm.services.icmp.test = { hostName = "test"; }; microvm.connections.tcpUdp = [ { target = "test-ssh"; } { target = "test-http"; } ]; microvm.connections.icmp = [ { target = "test"; } ]; microvm.vms = { test.config = { imports = [ inputs'.self.nixosModules.microvm-extras ]; microvm = { hostName = "test"; hostsHostName = "omen"; groupId = 1; taskId = 2; }; microvm.hypervisor = "cloud-hypervisor"; microvm.shares = [{ source = "/nix/store"; mountPoint = "/nix/.ro-store"; tag = "ro-store"; proto = "virtiofs"; }]; microvm.storeOnDisk = false; networking.firewall.allowedTCPPorts = [ 80 22 ]; services.nginx = { enable = true; virtualHosts."example.com" = { root = "/var/www/blog"; }; }; users.users.root.password = ""; services.getty.helpLine = '' Log in as "root" with an empty password. ''; services.openssh = { enable = true; settings.PermitRootLogin = "yes"; }; }; }; }