feat: scaffold netcup vps host (disko/vda, static net, tailscale, caddy)
- new nixosConfigurations.vps: UEFI systemd-boot, disko on /dev/vda - static IPv4 159.195.64.117/22 gw .1 (+ IPv6), eth0 pinned, public DNS - tailscale via headscale + sops authkey (secrets/vps.yaml, own host key) - caddy public reverse proxy: audiobookshelf.mgaction.town -> jupiter tailnet:8000 - shared common.nix (user/ssh/nix) ; .sops.yaml per-host rules
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
# netcup VPS (UEFI, /dev/vda). Public reverse proxy + tailnet node.
|
||||
{
|
||||
imports = [
|
||||
./hardware-configuration.nix
|
||||
./disk-config.nix # disko: vda partitions + filesystems
|
||||
./secrets.nix # sops-nix: tailscale authkey
|
||||
../common.nix # shared user / ssh / nix settings
|
||||
];
|
||||
|
||||
# ---- Boot (UEFI) ----
|
||||
boot.loader.systemd-boot.enable = true;
|
||||
boot.loader.efi.canTouchEfiVariables = true;
|
||||
# Root is on the virtio disk — pin these so stage-1 mounts it regardless of
|
||||
# what nixos-generate-config detects in the installer.
|
||||
boot.initrd.availableKernelModules = [ "virtio_pci" "virtio_blk" "virtio_scsi" ];
|
||||
|
||||
networking.hostName = "vps";
|
||||
|
||||
# ---- Static networking (netcup) ----
|
||||
# No LAN fallback: get this right or the box is unreachable (use netcup's
|
||||
# VNC console / rescue system to fix). Values captured from the running VPS.
|
||||
networking.useDHCP = false;
|
||||
networking.usePredictableInterfaceNames = false; # keep the NIC named eth0
|
||||
networking.interfaces.eth0 = {
|
||||
ipv4.addresses = [ { address = "159.195.64.117"; prefixLength = 22; } ];
|
||||
ipv6.addresses = [ { address = "2a0a:4cc0:c2:19e1:44b4:8dff:fe4d:c7d7"; prefixLength = 64; } ];
|
||||
};
|
||||
networking.defaultGateway = { address = "159.195.64.1"; interface = "eth0"; };
|
||||
# netcup IPv6 gateway is conventionally fe80::1 — VERIFY with `ip -6 route`
|
||||
# on the running VPS; wrong v6 gw won't break v4 reachability.
|
||||
networking.defaultGateway6 = { address = "fe80::1"; interface = "eth0"; };
|
||||
# Public resolvers for early boot; tailscale MagicDNS overrides once up.
|
||||
networking.nameservers = [ "9.9.9.9" "1.1.1.1" "2620:fe::fe" ];
|
||||
|
||||
networking.firewall = {
|
||||
enable = true;
|
||||
allowedTCPPorts = [ 22 80 443 ];
|
||||
trustedInterfaces = [ "tailscale0" ]; # reach admin services over the tailnet
|
||||
};
|
||||
|
||||
# ---- Tailscale (via headscale) ----
|
||||
services.tailscale = {
|
||||
enable = true;
|
||||
authKeyFile = config.sops.secrets.tailscale_authkey.path;
|
||||
extraUpFlags = [ "--login-server=https://vpn.mgaction.town" ];
|
||||
};
|
||||
|
||||
# ---- Public reverse proxy ----
|
||||
# Caddy gets automatic public HTTPS (Let's Encrypt) for real domains.
|
||||
# Proxies to jupiter's audiobookshelf over the tailnet (MagicDNS name).
|
||||
# Add one block per public service. Needs a public A record -> this VPS IP
|
||||
# and ports 80/443 open (they are, above).
|
||||
services.caddy = {
|
||||
enable = true;
|
||||
virtualHosts."audiobookshelf.mgaction.town".extraConfig = ''
|
||||
reverse_proxy http://jupiter.hosts.mgaction.town:8000
|
||||
'';
|
||||
# TODO: port your other VPS services' vhosts here before deploying.
|
||||
};
|
||||
|
||||
system.stateVersion = "26.05"; # set at install time; do NOT bump on upgrades
|
||||
}
|
||||
Reference in New Issue
Block a user