feat: refactor the modules/servers directory.
This commit is contained in:
parent
4e783c052b
commit
8b754d3a7e
69 changed files with 61 additions and 62 deletions
8
modules/servers/common/additional-pkgs.nix
Normal file
8
modules/servers/common/additional-pkgs.nix
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
{pkgs, ...}: {
|
||||
environment.systemPackages = with pkgs; [
|
||||
aria2
|
||||
unzip
|
||||
lm_sensors
|
||||
neovim
|
||||
];
|
||||
}
|
||||
57
modules/servers/common/beszel-agent.nix
Normal file
57
modules/servers/common/beszel-agent.nix
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
lib.mkIf (config.networking.hostName != "tyr") {
|
||||
systemd.services.beszel-agent = {
|
||||
enable = true;
|
||||
description = "Beszel Agent";
|
||||
after = ["network.target"];
|
||||
wants = ["network.target"];
|
||||
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
Restart = "always";
|
||||
RestartSec = 3;
|
||||
User = "beszel";
|
||||
Group = "beszel";
|
||||
WorkingDirectory = "/var/lib/beszel";
|
||||
StateDirectory = "beszel-agent";
|
||||
|
||||
KeyringMode = "private";
|
||||
LockPersonality = "yes";
|
||||
NoNewPrivileges = "yes";
|
||||
ProtectClock = "yes";
|
||||
ProtectHome = "read-only";
|
||||
ProtectHostname = "yes";
|
||||
ProtectKernelLogs = "yes";
|
||||
ProtectSystem = "strict";
|
||||
RemoveIPC = "yes";
|
||||
RestrictSUIDSGID = true;
|
||||
SystemCallArchitectures = "native";
|
||||
};
|
||||
|
||||
script = "${pkgs.beszel}/bin/beszel-agent -listen '45876' --key 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC+T3fFx+Sv8jBGr2gNUHfuwUCbGhj8Mr/h4pmkI2Zjn'";
|
||||
|
||||
wantedBy = ["multi-user.target"];
|
||||
};
|
||||
|
||||
users = {
|
||||
users.beszel = {
|
||||
isSystemUser = true;
|
||||
home = "/var/lib/beszel";
|
||||
createHome = true;
|
||||
group = "beszel";
|
||||
};
|
||||
groups.beszel = {};
|
||||
};
|
||||
|
||||
networking.firewall.extraCommands = ''
|
||||
iptables -N beszel # create a new chain named beszel
|
||||
iptables -A beszel --src 65.21.241.194 -j ACCEPT # allow 65.21.241.194
|
||||
iptables -A beszel -j DROP # drop everyone else
|
||||
iptables -I INPUT -m tcp -p tcp --dport 45876 -j beszel # use chain beszel for packets coming to TCP port 45876
|
||||
'';
|
||||
}
|
||||
17
modules/servers/common/default.nix
Normal file
17
modules/servers/common/default.nix
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
{...}: {
|
||||
imports = [
|
||||
./openssh.nix
|
||||
./user.nix
|
||||
./traefik.nix
|
||||
./secrets.nix
|
||||
./podman.nix
|
||||
./additional-pkgs.nix
|
||||
./root.nix
|
||||
./optimise-storage.nix
|
||||
./restic.nix
|
||||
./nix-features.nix
|
||||
./shell.nix
|
||||
./fail2ban.nix
|
||||
./beszel-agent.nix
|
||||
];
|
||||
}
|
||||
16
modules/servers/common/fail2ban.nix
Normal file
16
modules/servers/common/fail2ban.nix
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{...}: {
|
||||
services.fail2ban = {
|
||||
enable = true;
|
||||
maxretry = 5;
|
||||
ignoreIP = [
|
||||
"65.21.241.194"
|
||||
];
|
||||
bantime = "24h"; # Ban IPs for one day on the first ban
|
||||
bantime-increment = {
|
||||
enable = true; # Enable increment of bantime after each violation
|
||||
multipliers = "1 2 4 8 16 32 64";
|
||||
maxtime = "168h"; # Do not ban for more than 1 week
|
||||
overalljails = true; # Calculate the bantime based on all the violations
|
||||
};
|
||||
};
|
||||
}
|
||||
4
modules/servers/common/nix-features.nix
Normal file
4
modules/servers/common/nix-features.nix
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
# Enable flakes
|
||||
nix.settings.experimental-features = ["nix-command" "flakes"];
|
||||
}
|
||||
32
modules/servers/common/openssh.nix
Normal file
32
modules/servers/common/openssh.nix
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
services.openssh = {
|
||||
enable = true;
|
||||
settings = {
|
||||
AllowUsers =
|
||||
lib.mkIf (config.networking.hostName != "tyr")
|
||||
[
|
||||
"root@65.21.241.194"
|
||||
"root@172.16.0.2"
|
||||
"crony@65.21.241.194"
|
||||
"crony@172.16.0.2"
|
||||
];
|
||||
X11Forwarding = false;
|
||||
PasswordAuthentication = false;
|
||||
};
|
||||
extraConfig = ''
|
||||
PubkeyAuthentication yes
|
||||
PermitEmptyPasswords no
|
||||
|
||||
AddressFamily inet
|
||||
MaxAuthTries 3
|
||||
'';
|
||||
};
|
||||
|
||||
users.users.root.openssh.authorizedKeys.keys = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBJLduAXHWJiglmfRfkBGKffzVWkJP6porxIzw6+Zz3W crony@cronyakatsuki.xyz"
|
||||
];
|
||||
}
|
||||
19
modules/servers/common/optimise-storage.nix
Normal file
19
modules/servers/common/optimise-storage.nix
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
{...}: {
|
||||
nix.optimise = {
|
||||
automatic = true;
|
||||
dates = "weekly";
|
||||
};
|
||||
|
||||
nix.gc = {
|
||||
automatic = true;
|
||||
dates = "weekly";
|
||||
options = "--delete-older-than 10d";
|
||||
};
|
||||
|
||||
nix.extraOptions = ''
|
||||
min-free = ${toString (100 * 1024 * 1024)}
|
||||
max-free = ${toString (1024 * 1024 * 1024)}
|
||||
'';
|
||||
|
||||
boot.loader.grub.configurationLimit = 3;
|
||||
}
|
||||
28
modules/servers/common/podman.nix
Normal file
28
modules/servers/common/podman.nix
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
{pkgs, ...}: {
|
||||
virtualisation = {
|
||||
podman = {
|
||||
enable = true;
|
||||
dockerCompat = true;
|
||||
autoPrune = {
|
||||
enable = true;
|
||||
dates = "weekly";
|
||||
flags = [
|
||||
"--filter=until=24h"
|
||||
"--filter=label!=important"
|
||||
];
|
||||
};
|
||||
defaultNetwork.settings.dns.enable = true;
|
||||
};
|
||||
};
|
||||
|
||||
# Enable system podman autoupdate timer
|
||||
systemd.timers.podman-auto-update = {
|
||||
enable = true;
|
||||
wantedBy = ["timers.target"];
|
||||
};
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
podman-compose
|
||||
podman-tui
|
||||
];
|
||||
}
|
||||
40
modules/servers/common/restic.nix
Normal file
40
modules/servers/common/restic.nix
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
{config, ...}: let
|
||||
opts = {
|
||||
paths = [
|
||||
"/var/lib/private"
|
||||
];
|
||||
pruneOpts = [
|
||||
"--keep-last 10"
|
||||
"--keep-daily 7"
|
||||
"--keep-weekly 5"
|
||||
"--keep-monthly 12"
|
||||
];
|
||||
pruneOptsLocal = [
|
||||
"--keep-last 2"
|
||||
];
|
||||
checkOpts = [
|
||||
"--read-data-subset=10%"
|
||||
"--with-cache"
|
||||
];
|
||||
};
|
||||
in {
|
||||
services.restic.backups = {
|
||||
local = {
|
||||
initialize = true;
|
||||
passwordFile = config.age.secrets.restic-server-local-pass.path;
|
||||
repository = "/var/lib/backup";
|
||||
paths = opts.paths;
|
||||
pruneOpts = opts.pruneOptsLocal;
|
||||
checkOpts = opts.checkOpts;
|
||||
};
|
||||
server = {
|
||||
initialize = true;
|
||||
passwordFile = config.age.secrets.restic-server-pass.path;
|
||||
repositoryFile = config.age.secrets.restic-server-repo.path;
|
||||
environmentFile = config.age.secrets.restic-server-env.path;
|
||||
paths = opts.paths;
|
||||
pruneOpts = opts.pruneOpts;
|
||||
checkOpts = opts.checkOpts;
|
||||
};
|
||||
};
|
||||
}
|
||||
6
modules/servers/common/root.nix
Normal file
6
modules/servers/common/root.nix
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{config, ...}: {
|
||||
users.users.root = {
|
||||
hashedPasswordFile = "${config.age.secrets.root-passwd.path}";
|
||||
};
|
||||
users.mutableUsers = false;
|
||||
}
|
||||
28
modules/servers/common/secrets.nix
Normal file
28
modules/servers/common/secrets.nix
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
age = {
|
||||
secrets = {
|
||||
traefik = {
|
||||
file = ../../../secrets/traefik.age;
|
||||
owner = "traefik";
|
||||
};
|
||||
crony-passwd = {
|
||||
file = ../../../secrets/crony-passwd-servers.age;
|
||||
};
|
||||
root-passwd = {
|
||||
file = ../../../secrets/root-passwd.age;
|
||||
};
|
||||
restic-server-local-pass = {
|
||||
file = ../../../secrets/restic-server-local-pass.age;
|
||||
};
|
||||
restic-server-pass = {
|
||||
file = ../../../secrets/restic-server-pass.age;
|
||||
};
|
||||
restic-server-repo = {
|
||||
file = ../../../secrets/restic-server-repo.age;
|
||||
};
|
||||
restic-server-env = {
|
||||
file = ../../../secrets/restic-server-env.age;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
11
modules/servers/common/shell.nix
Normal file
11
modules/servers/common/shell.nix
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{pkgs, ...}: {
|
||||
users.extraUsers.root = {
|
||||
shell = pkgs.zsh;
|
||||
};
|
||||
|
||||
users.extraUsers.crony = {
|
||||
shell = pkgs.zsh;
|
||||
};
|
||||
|
||||
programs.zsh.enable = true;
|
||||
}
|
||||
82
modules/servers/common/traefik.nix
Normal file
82
modules/servers/common/traefik.nix
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
{config, ...}: {
|
||||
services.traefik = {
|
||||
enable = true;
|
||||
staticConfigOptions = {
|
||||
serversTransport.insecureSkipVerify = true;
|
||||
log = {level = "DEBUG";};
|
||||
experimental = {
|
||||
plugins = {
|
||||
fail2ban = {
|
||||
moduleName = "github.com/tomMoulard/fail2ban";
|
||||
version = "v0.8.7";
|
||||
};
|
||||
};
|
||||
};
|
||||
certificatesResolvers = {
|
||||
porkbun = {
|
||||
acme = {
|
||||
email = "crony@cronyakatsuki.xyz";
|
||||
storage = "/var/lib/traefik/acme.json";
|
||||
caserver = "https://acme-v02.api.letsencrypt.org/directory";
|
||||
dnsChallenge = {
|
||||
provider = "porkbun";
|
||||
resolvers = ["1.1.1.1" "8.8.8.8"];
|
||||
propagation = {
|
||||
delayBeforeChecks = 60;
|
||||
disableChecks = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
api = {};
|
||||
entryPoints = {
|
||||
web = {
|
||||
address = ":80";
|
||||
http.redirections.entryPoint = {
|
||||
to = "websecure";
|
||||
scheme = "https";
|
||||
};
|
||||
};
|
||||
websecure = {
|
||||
address = ":443";
|
||||
http.middlewares = [
|
||||
"fail2ban"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
dynamicConfigOptions.http = {
|
||||
middlewares = {
|
||||
fail2ban = {
|
||||
plugin = {
|
||||
fail2ban = {
|
||||
rules = {
|
||||
bantime = "168h";
|
||||
enabled = true;
|
||||
findtime = "5m";
|
||||
maxretry = 50;
|
||||
statuscode = "400,401,403-499";
|
||||
urlregexps = [
|
||||
{
|
||||
regexp = "/*";
|
||||
mode = "allow";
|
||||
}
|
||||
];
|
||||
};
|
||||
allowlist = {
|
||||
ip = ["65.21.241.194"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.traefik.serviceConfig = {
|
||||
EnvironmentFile = ["${config.age.secrets.traefik.path}"];
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [80 443];
|
||||
}
|
||||
17
modules/servers/common/user.nix
Normal file
17
modules/servers/common/user.nix
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
{config, ...}: {
|
||||
# Not reall that safe but convenient af
|
||||
security.sudo.wheelNeedsPassword = false;
|
||||
|
||||
users.users.crony = {
|
||||
linger = true;
|
||||
isNormalUser = true;
|
||||
description = "crony";
|
||||
hashedPasswordFile = "${config.age.secrets.crony-passwd.path}";
|
||||
extraGroups = [
|
||||
"wheel"
|
||||
];
|
||||
openssh.authorizedKeys.keys = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBJLduAXHWJiglmfRfkBGKffzVWkJP6porxIzw6+Zz3W crony@cronyakatsuki.xyz"
|
||||
];
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue