# 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"; }; }; }; }