liminix/bordervm-configuration.nix
Daniel Barlow 5a3646cb29 add authorized keys to bordervm
You don't often need this because it has autologin, but sometimes
you want to do antics involving sshing through it to the wan port
of a test device.

Note that you probably wanted to start bordervm with funny qemu
options to even make that possible

 nix-shell --run "QEMU_NET_OPTS=hostfwd=tcp::10022-:22 run-border-vm"
2024-05-01 23:07:11 +01:00

133 lines
3.7 KiB
Nix

{ config, pkgs, lib, ... }:
let
cfg = config.bordervm;
inherit (lib) mkOption mkEnableOption mdDoc types optional optionals;
in {
options.bordervm = {
keys = mkOption {
type = types.listOf types.str;
default = [];
};
l2tp = {
host = mkOption {
description = mdDoc ''
Hostname or IP address of an L2TP LNS that this VM
will connect to when it receives a PPPoE connection request
'';
type = types.str;
example = "l2tp.example.org";
};
port = mkOption {
description = mdDoc ''
Port number, if non-standard, of the LNS.
'';
type = types.int;
default = 1701;
};
};
ethernet = {
pci = {
enable = mkEnableOption "passthru PCI ethernet";
id = mkOption {
description = ''
Host PCI ID (as shown by `lspci`) of the ethernet adaptor
to be used by the VM. This uses VFIO and requires setup
on the emulation host before it will work!
'';
type = types.str;
example = "04:00.0";
};
};
usb = {
enable = mkEnableOption "passthru USB ethernet";
vendor = mkOption {
type = types.str;
example = "0x0bda";
};
product = mkOption {
type = types.str;
example = "0x8153";
};
};
};
};
imports = [
<nixpkgs/nixos/modules/virtualisation/qemu-vm.nix>
];
config = {
boot.kernelParams = [
"loglevel=9"
];
systemd.services.pppoe =
let conf = pkgs.writeText "kpppoed.toml"
''
interface_name = "eth1"
services = [ "myservice" ]
lns_ipaddr = "${cfg.l2tp.host}:${builtins.toString cfg.l2tp.port}"
ac_name = "kpppoed-1.0"
'';
in {
wantedBy = [ "multi-user.target" ];
after = [ "network-online.target" ];
serviceConfig = {
ExecStart = "${pkgs.go-l2tp}/bin/kpppoed -config ${conf}";
};
};
systemd.services.tufted = {
wantedBy = [ "multi-user.target" ];
serviceConfig = {
ExecStart = "${pkgs.tufted}/bin/tufted /home/liminix/liminix";
};
};
services.openssh.enable = true;
systemd.services.sshd.wantedBy = pkgs.lib.mkForce [ "multi-user.target" ];
virtualisation = {
qemu = {
networkingOptions = [];
options = [] ++
optional cfg.ethernet.pci.enable
"-device vfio-pci,host=${cfg.ethernet.pci.id}" ++
optionals cfg.ethernet.usb.enable [
"-device usb-ehci,id=ehci"
"-device usb-host,bus=ehci.0,vendorid=${cfg.ethernet.usb.vendor},productid=${cfg.ethernet.usb.product}"
] ++ [
"-nographic"
"-serial mon:stdio"
];
};
sharedDirectories = {
liminix = {
source = builtins.toString ./.;
target = "/home/liminix/liminix";
};
};
};
environment.systemPackages =
let wireshark-nogui = pkgs.wireshark.override { withQt = false ; };
in with pkgs; [
tcpdump
wireshark-nogui
socat
tufted
iptables
usbutils
];
security.sudo.wheelNeedsPassword = false;
networking = {
hostName = "border";
firewall = { enable = false; };
interfaces.eth1 = {
useDHCP = false;
ipv4.addresses = [ { address = "10.0.0.1"; prefixLength = 24;}];
};
};
users.users.liminix = {
isNormalUser = true;
uid = 1000;
extraGroups = [ "wheel"];
openssh.authorizedKeys.keys = cfg.keys;
};
services.getty.autologinUser = "liminix";
};
}