From d1a3219cccf8c734e6e1391cfbcbf95b3633fae6 Mon Sep 17 00:00:00 2001 From: notohh Date: Mon, 8 Apr 2024 19:36:52 -0400 Subject: [PATCH] init basic system --- .envrc | 1 + .sops.yaml | 17 +++++ README.md | 1 + flake.lock | 158 ++++++++++++++++++++++++++++++++++++++++++ flake.nix | 41 +++++++++++ modules/default.nix | 10 +++ modules/nix.nix | 31 +++++++++ modules/security.nix | 67 ++++++++++++++++++ modules/sops.nix | 6 ++ modules/ssh.nix | 11 +++ modules/tailscale.nix | 41 +++++++++++ modules/time.nix | 26 +++++++ secrets/secrets.yaml | 0 system/default.nix | 64 +++++++++++++++++ system/hardware.nix | 27 ++++++++ 15 files changed, 501 insertions(+) create mode 100644 .envrc create mode 100644 .sops.yaml create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 modules/default.nix create mode 100644 modules/nix.nix create mode 100644 modules/security.nix create mode 100644 modules/sops.nix create mode 100644 modules/ssh.nix create mode 100644 modules/tailscale.nix create mode 100644 modules/time.nix create mode 100644 secrets/secrets.yaml create mode 100644 system/default.nix create mode 100644 system/hardware.nix diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..8392d15 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake \ No newline at end of file diff --git a/.sops.yaml b/.sops.yaml new file mode 100644 index 0000000..28a4398 --- /dev/null +++ b/.sops.yaml @@ -0,0 +1,17 @@ +keys: + - &users + - ¬oh age1ckvmyqkwk69j64ev3fmckytz6k2dv79z4gn5qf6gxqyevp5yjfesdfkxmn + - &tori key + - &force key + - &haru key + - &saru key + +creation_rules: + - path_regex: secrets/[^/]+\.yaml$ + key_groups: + - age: + - *notoh + - *tori + - *force + - *haru + - *saru diff --git a/README.md b/README.md index f2b8e33..edc44a4 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,3 @@ # nixos-system +nixos prod instance for basegbot diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..6232a0a --- /dev/null +++ b/flake.lock @@ -0,0 +1,158 @@ +{ + "nodes": { + "deploy-rs": { + "inputs": { + "flake-compat": "flake-compat", + "nixpkgs": [ + "nixpkgs" + ], + "utils": "utils" + }, + "locked": { + "lastModified": 1711973905, + "narHash": "sha256-UFKME/N1pbUtn+2Aqnk+agUt8CekbpuqwzljivfIme8=", + "owner": "serokell", + "repo": "deploy-rs", + "rev": "88b3059b020da69cbe16526b8d639bd5e0b51c8b", + "type": "github" + }, + "original": { + "owner": "serokell", + "repo": "deploy-rs", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "nh": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1712310030, + "narHash": "sha256-YsTIJWqANadeXKKAtw41IKGOD55/bML7H9No8lu3h4Q=", + "owner": "viperML", + "repo": "nh", + "rev": "fd98e31fbf741045b9a649b004b99dfa61f5a63b", + "type": "github" + }, + "original": { + "owner": "viperML", + "repo": "nh", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1712439257, + "narHash": "sha256-aSpiNepFOMk9932HOax0XwNxbA38GOUVOiXfUVPOrck=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "ff0dbd94265ac470dda06a657d5fe49de93b4599", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-stable": { + "locked": { + "lastModified": 1712437997, + "narHash": "sha256-g0whLLwRvgO2FsyhY8fNk+TWenS3jg5UdlWL4uqgFeo=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "e38d7cb66ea4f7a0eb6681920615dfcc30fc2920", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "release-23.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "deploy-rs": "deploy-rs", + "nh": "nh", + "nixpkgs": "nixpkgs", + "sops-nix": "sops-nix" + } + }, + "sops-nix": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ], + "nixpkgs-stable": "nixpkgs-stable" + }, + "locked": { + "lastModified": 1712458908, + "narHash": "sha256-DMgBS+jNHDg8z3g9GkwqL8xTKXCRQ/0FGsAyrniVonc=", + "owner": "Mic92", + "repo": "sops-nix", + "rev": "39191e8e6265b106c9a2ba0cfd3a4dafe98a31c6", + "type": "github" + }, + "original": { + "owner": "Mic92", + "repo": "sops-nix", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1701680307, + "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..190ec37 --- /dev/null +++ b/flake.nix @@ -0,0 +1,41 @@ +{ + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + nh = { + url = "github:viperML/nh"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + deploy-rs = { + url = "github:serokell/deploy-rs"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + sops-nix = { + url = "github:Mic92/sops-nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + outputs = {nixpkgs, ...} @ inputs: let + system = "x86_64-linux"; + pkgs = import nixpkgs { + inherit system; + }; + lib = nixpkgs.lib; + in { + devShells.${system}.default = pkgs.mkShell { + name = "basegbot-devenv"; + packages = with pkgs; [ + nil + alejandra + ]; + }; + nixosConfigurations = { + basegbot = lib.nixosSystem { + inherit system; + modules = [ + ./system + inputs.nh.nixosModules.default + ]; + }; + }; + }; +} diff --git a/modules/default.nix b/modules/default.nix new file mode 100644 index 0000000..532b535 --- /dev/null +++ b/modules/default.nix @@ -0,0 +1,10 @@ +_: { + imports = [ + ./nix.nix + ./security.nix + # ./sops.nix + ./ssh.nix + # ./tailscale.nix + ./time.nix + ]; +} diff --git a/modules/nix.nix b/modules/nix.nix new file mode 100644 index 0000000..67b8781 --- /dev/null +++ b/modules/nix.nix @@ -0,0 +1,31 @@ +_: { + nh = { + enable = true; + clean = { + enable = true; + dates = "weekly"; + extraArgs = "--keep-since 3d --keep 5"; + }; + }; + + nix = { + settings = { + extra-experimental-features = ["flakes" "nix-command"]; + auto-optimise-store = true; + builders-use-substitutes = true; + keep-outputs = true; + allowed-users = ["@wheel"]; + trusted-users = ["root" "@wheel"]; + substituters = [ + "https://cache.flake.sh/kyasshu" + "https://cache.nixos.org" + ]; + trusted-public-keys = [ + "kyasshu:g1heIgCgG7M4San6nRsz/omcVQ1GTc7+zKKm3L9Co7o=" + "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" + ]; + }; + }; + + nixpkgs.config.allowUnfree = true; +} diff --git a/modules/security.nix b/modules/security.nix new file mode 100644 index 0000000..50d6913 --- /dev/null +++ b/modules/security.nix @@ -0,0 +1,67 @@ +# security tweaks borrowed from @hlissner +{ + boot.kernel.sysctl = { + # The Magic SysRq key is a key combo that allows users connected to the + # system console of a Linux kernel to perform some low-level commands. + # Disable it, since we don't need it, and is a potential security concern. + "kernel.sysrq" = 0; + + ## TCP hardening + # Prevent bogus ICMP errors from filling up logs. + "net.ipv4.icmp_ignore_bogus_error_responses" = 1; + # Reverse path filtering causes the kernel to do source validation of + # packets received from all interfaces. This can mitigate IP spoofing. + "net.ipv4.conf.default.rp_filter" = 1; + "net.ipv4.conf.all.rp_filter" = 1; + # Do not accept IP source route packets (we're not a router) + "net.ipv4.conf.all.accept_source_route" = 0; + "net.ipv6.conf.all.accept_source_route" = 0; + # Don't send ICMP redirects (again, we're on a router) + "net.ipv4.conf.all.send_redirects" = 0; + "net.ipv4.conf.default.send_redirects" = 0; + # Refuse ICMP redirects (MITM mitigations) + "net.ipv4.conf.all.accept_redirects" = 0; + "net.ipv4.conf.default.accept_redirects" = 0; + "net.ipv4.conf.all.secure_redirects" = 0; + "net.ipv4.conf.default.secure_redirects" = 0; + "net.ipv6.conf.all.accept_redirects" = 0; + "net.ipv6.conf.default.accept_redirects" = 0; + # Protects against SYN flood attacks + "net.ipv4.tcp_syncookies" = 1; + # Incomplete protection again TIME-WAIT assassination + "net.ipv4.tcp_rfc1337" = 1; + + ## TCP optimization + # TCP Fast Open is a TCP extension that reduces network latency by packing + # data in the sender’s initial TCP SYN. Setting 3 = enable TCP Fast Open for + # both incoming and outgoing connections: + "net.ipv4.tcp_fastopen" = 3; + # Bufferbloat mitigations + slight improvement in throughput & latency + "net.ipv4.tcp_congestion_control" = "bbr"; + "net.core.default_qdisc" = "cake"; + }; + + boot.kernelModules = ["tcp_bbr"]; + + services = { + openssh.settings.LogLevel = "VERBOSE"; + fail2ban = { + enable = true; + bantime = "1h"; + maxretry = 1; + ignoreIP = [ + "192.168.0.0/16" + "172.16.0.0/12" + "10.0.0.0/8" + ]; + jails = { + DEFAULT = { + settings = { + findtime = 100000; + mode = "aggressive"; + }; + }; + }; + }; + }; +} diff --git a/modules/sops.nix b/modules/sops.nix new file mode 100644 index 0000000..4d6f9fa --- /dev/null +++ b/modules/sops.nix @@ -0,0 +1,6 @@ +_: { + sops = { + defaultSopsFile = ../secrets/secrets.yaml; + age.keyFile = ""; + }; +} diff --git a/modules/ssh.nix b/modules/ssh.nix new file mode 100644 index 0000000..6484428 --- /dev/null +++ b/modules/ssh.nix @@ -0,0 +1,11 @@ +{lib, ...}: { + services.openssh = { + enable = true; + settings = { + PermitRootLogin = "yes"; + KbdInteractiveAuthentication = false; + PasswordAuthentication = lib.mkForce false; + PubkeyAuthentication = lib.mkForce true; + }; + }; +} diff --git a/modules/tailscale.nix b/modules/tailscale.nix new file mode 100644 index 0000000..2d0e755 --- /dev/null +++ b/modules/tailscale.nix @@ -0,0 +1,41 @@ +{ + config, + lib, + pkgs, + ... +}: { + # sops.secrets.tsauth = {sopsFile = ../secrets/secrets.yaml;}; + environment.systemPackages = [pkgs.jq pkgs.tailscale]; + services.tailscale = { + useRoutingFeatures = lib.mkDefault "client"; + }; + networking.firewall.allowedUDPPorts = [config.services.tailscale.port]; + networking.firewall.trustedInterfaces = [config.services.tailscale.interfaceName]; + + systemd.services.tailscale-autoconnect = { + description = "Automatic connection to Tailscale"; + + # make sure tailscale is running before trying to connect to tailscale + after = ["network-pre.target" "tailscale.service"]; + wants = ["network-pre.target" "tailscale.service"]; + wantedBy = ["multi-user.target"]; + + # set this service as a oneshot job + serviceConfig.Type = "oneshot"; + + # have the job run this shell script + script = with pkgs; '' + # wait for tailscaled to settle + sleep 2 + + # check if we are already authenticated to tailscale + status="$(${tailscale}/bin/tailscale status -json | ${jq}/bin/jq -r .BackendState)" + if [ $status = "Running" ]; then # if so, then do nothing + exit 0 + fi + + # otherwise authenticate with tailscale + ${tailscale}/bin/tailscale up -authkey file:${config.sops.secrets.eventual-secret} --exit-node=100.104.42.96 --exit-node-allow-lan-access=true --accept-dns=false + ''; + }; +} diff --git a/modules/time.nix b/modules/time.nix new file mode 100644 index 0000000..b5538d9 --- /dev/null +++ b/modules/time.nix @@ -0,0 +1,26 @@ +_: { + time.timeZone = "America/New_York"; + + services = { + chrony = { + enable = true; + servers = [ + # 0.us.pool.ntp.org + "134.215.114.62" + "192.189.65.187" + "96.245.170.99" + "192.92.6.30" + ]; + }; + timesyncd = { + enable = true; + servers = [ + # 0.us.pool.ntp.org + "134.215.114.62" + "192.189.65.187" + "96.245.170.99" + "192.92.6.30" + ]; + }; + }; +} diff --git a/secrets/secrets.yaml b/secrets/secrets.yaml new file mode 100644 index 0000000..e69de29 diff --git a/system/default.nix b/system/default.nix new file mode 100644 index 0000000..7c4c194 --- /dev/null +++ b/system/default.nix @@ -0,0 +1,64 @@ +{pkgs, ...}: { + imports = [ + ./hardware.nix + ../modules + ]; + + documentation = { + enable = true; + doc.enable = false; + man.enable = true; + dev.enable = false; + }; + + boot.loader = { + grub = { + enable = true; + device = "/dev/sda"; + configurationLimit = 10; + }; + }; + + boot.kernelPackages = pkgs.linuxPackages_latest; + + networking.hostName = "basegbot"; + + networking.networkmanager.enable = true; + + i18n.defaultLocale = "en_US.UTF-8"; + + services.tailscale.enable = true; + services.fstrim.enable = true; + + programs.direnv = { + enable = true; + loadInNixShell = true; + nix-direnv.enable = true; + }; + + services.xserver = { + layout = "us"; + xkbVariant = ""; + }; + + users = { + defaultUserShell = pkgs.nushell; + users.basegbot = { + openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEFgkIK+VR+xpAL85buL9ocql82kcVCcHbZyaytVDYB6 basegbot" + ]; + isNormalUser = true; + description = "basegbot"; + extraGroups = ["networkmanager" "wheel"]; + packages = with pkgs; [ + git + helix + lazygit + croc + ]; + }; + }; + + system.autoUpgrade.enable = false; + system.stateVersion = "23.05"; +} diff --git a/system/hardware.nix b/system/hardware.nix new file mode 100644 index 0000000..f937f4a --- /dev/null +++ b/system/hardware.nix @@ -0,0 +1,27 @@ +{ + lib, + modulesPath, + ... +}: { + imports = [ + (modulesPath + "/profiles/qemu-guest.nix") + ]; + + boot.initrd.availableKernelModules = ["ata_piix" "uhci_hcd" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod"]; + boot.initrd.kernelModules = []; + boot.kernelModules = ["kvm-intel"]; + boot.extraModulePackages = []; + + fileSystems."/" = { + device = "/dev/disk/by-uuid/477575a1-4100-4a02-b3ee-f68865792026"; + fsType = "ext4"; + }; + + swapDevices = [ + {device = "/dev/disk/by-uuid/a4556ca7-ea7b-4c5b-81fe-370d4157366b";} + ]; + + networking.useDHCP = lib.mkDefault true; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; +}