bordervm-configuration.nix (5966B)
1 nixpkgs: 2 { 3 config, 4 pkgs, 5 lib, 6 ... 7 }: 8 let 9 cfg = config.bordervm; 10 inherit (lib) 11 mkOption 12 mkEnableOption 13 mdDoc 14 types 15 optional 16 optionals 17 ; 18 in 19 { 20 options.bordervm = { 21 keys = mkOption { 22 type = types.listOf types.str; 23 default = [ ]; 24 }; 25 l2tp = { 26 host = mkOption { 27 description = mdDoc '' 28 Hostname or IP address of an L2TP LNS that this VM 29 will connect to when it receives a PPPoE connection request 30 ''; 31 type = types.str; 32 example = "l2tp.example.org"; 33 }; 34 port = mkOption { 35 description = mdDoc '' 36 Port number, if non-standard, of the LNS. 37 ''; 38 type = types.int; 39 default = 1701; 40 }; 41 }; 42 ethernet = { 43 pci = { 44 enable = mkEnableOption "passthru PCI ethernet"; 45 id = mkOption { 46 description = '' 47 Host PCI ID (as shown by `lspci`) of the ethernet adaptor 48 to be used by the VM. This uses VFIO and requires setup 49 on the emulation host before it will work! 50 ''; 51 type = types.str; 52 example = "04:00.0"; 53 }; 54 }; 55 usb = { 56 enable = mkEnableOption "passthru USB ethernet"; 57 vendor = mkOption { 58 type = types.str; 59 example = "0x0bda"; 60 }; 61 product = mkOption { 62 type = types.str; 63 example = "0x8153"; 64 }; 65 }; 66 }; 67 }; 68 imports = [ 69 "${nixpkgs}/nixos/modules/virtualisation/qemu-vm.nix" 70 ]; 71 config = { 72 boot.kernelParams = [ "loglevel=9" ]; 73 systemd.services.pppoe = 74 let 75 conf = pkgs.writeText "kpppoed.toml" '' 76 interface_name = "eth1" 77 services = [ "myservice" ] 78 lns_ipaddr = "${cfg.l2tp.host}:${builtins.toString cfg.l2tp.port}" 79 ac_name = "kpppoed-1.0" 80 ''; 81 in 82 { 83 wantedBy = [ "multi-user.target" ]; 84 after = [ "network-online.target" ]; 85 serviceConfig = { 86 ExecStart = "${pkgs.go-l2tp}/bin/kpppoed -config ${conf}"; 87 }; 88 }; 89 systemd.services.tufted = { 90 wantedBy = [ "multi-user.target" ]; 91 serviceConfig = { 92 ExecStart = "${pkgs.tufted}/bin/tufted /home/liminix/liminix"; 93 }; 94 }; 95 services.openssh.enable = true; 96 services.dnsmasq = { 97 enable = true; 98 resolveLocalQueries = false; 99 settings = { 100 # domain-needed = true; 101 dhcp-range = [ "10.0.0.12,10.0.0.240" ]; 102 interface = "eth1"; 103 }; 104 }; 105 106 services.nginx = { 107 enable = true; 108 user = "liminix"; 109 virtualHosts.${config.networking.hostName} = { 110 root = "/home/liminix"; 111 default = true; 112 }; 113 }; 114 systemd.services.nginx.serviceConfig.ProtectHome = "read-only"; 115 116 systemd.services.sshd.wantedBy = pkgs.lib.mkForce [ "multi-user.target" ]; 117 118 virtualisation = { 119 forwardPorts = [ 120 # { 121 # # guest tang service exposed on host for easy querying 122 # from = "host"; 123 # host.port = 7654; 124 # guest.port = 7654; 125 # } 126 { 127 host.port = 2222; 128 guest.address = "10.0.2.15"; 129 guest.port = 22; 130 } 131 { 132 # expose victorialogs on host so (clients attached to) guest 133 # can log 134 from = "guest"; # packets are forwarded from guest 135 guest.address = "10.0.2.10"; 136 guest.port = 443; 137 host.address = "127.0.0.1"; 138 host.port = 443; 139 } 140 { 141 from = "guest"; # packets are forwarded from guest 142 guest.address = "10.0.2.10"; 143 guest.port = 19613; 144 host.address = "127.0.0.1"; 145 host.port = 19613; 146 } 147 ]; 148 qemu = { 149 networkingOptions = [ ]; 150 options = 151 [ ] 152 ++ optional cfg.ethernet.pci.enable "-device vfio-pci,host=${cfg.ethernet.pci.id}" 153 ++ optionals cfg.ethernet.usb.enable [ 154 "-device qemu-xhci" 155 # "-device usb-ehci,id=ehci" 156 # "-device usb-host,bus=ehci.0,vendorid=${cfg.ethernet.usb.vendor},productid=${cfg.ethernet.usb.product}" 157 "-device usb-host,vendorid=${cfg.ethernet.usb.vendor},productid=${cfg.ethernet.usb.product}" 158 ] 159 ++ [ 160 "-nographic" 161 "-serial mon:stdio" 162 ]; 163 }; 164 sharedDirectories = { 165 liminix = { 166 source = builtins.toString ./.; 167 target = "/home/liminix/liminix"; 168 }; 169 }; 170 }; 171 172 services.tang = { 173 enable = true; 174 ipAddressAllow = [ 175 "10.0.0.0/24" 176 "0.0.0.0/0" 177 ]; 178 }; 179 180 environment.systemPackages = 181 let 182 wireshark-nogui = pkgs.wireshark.override { withQt = false; }; 183 in 184 with pkgs; 185 [ 186 tcpdump 187 wireshark-nogui 188 socat 189 tufted 190 iptables 191 usbutils 192 busybox 193 clevis 194 ]; 195 security.sudo.wheelNeedsPassword = false; 196 networking = { 197 hostName = "border"; 198 firewall = { 199 enable = false; 200 }; 201 interfaces.eth1 = { 202 useDHCP = false; 203 ipv4.addresses = [ 204 { 205 address = "10.0.0.1"; 206 prefixLength = 24; 207 } 208 ]; 209 }; 210 nat = { 211 enable = true; 212 internalInterfaces = [ "eth1" ]; 213 externalInterface = "eth0"; 214 extraCommands = '' 215 portfwd() { 216 iptables -t nat -A PREROUTING -p tcp --dport $2 -j DNAT --to-destination $1:$2 217 iptables -t nat -A POSTROUTING -p tcp -d $1 --dport $2 -j SNAT --to-source 10.0.0.1 218 } 219 portfwd 10.0.2.10 443 220 portfwd 10.0.2.10 19613 221 ''; 222 }; 223 }; 224 users.users.liminix = { 225 isNormalUser = true; 226 uid = 1000; 227 extraGroups = [ "wheel" ]; 228 openssh.authorizedKeys.keys = cfg.keys; 229 }; 230 services.getty.autologinUser = "liminix"; 231 }; 232 }