# Static public IPv6 for hosts where SLAAC/RA doesn't bring up a global # address (e.g. Hetzner, which allocates a /64 but expects you to pick one # address yourself and route via the link-local gateway fe80::1). { lib, config, ... }: let cfg = config.cnx.staticIPv6; in { options.cnx.staticIPv6 = { enable = lib.mkEnableOption "static public IPv6 on the primary interface"; address = lib.mkOption { type = lib.types.str; example = "2a01:4f8:c014:b5c5::1"; description = "Public IPv6 address (no prefix length)."; }; prefixLength = lib.mkOption { type = lib.types.int; default = 64; description = "Prefix length of the allocated block."; }; interface = lib.mkOption { type = lib.types.str; default = "enp1s0"; description = "Interface to assign the address to."; }; gateway = lib.mkOption { type = lib.types.str; default = "fe80::1"; description = "IPv6 default gateway (Hetzner uses the link-local fe80::1)."; }; }; config = lib.mkIf cfg.enable { networking.interfaces.${cfg.interface}.ipv6.addresses = [ { inherit (cfg) address prefixLength; } ]; networking.defaultGateway6 = { address = cfg.gateway; interface = cfg.interface; }; }; }