503 lines
12 KiB
Nix
503 lines
12 KiB
Nix
{
|
|
config,
|
|
pkgs,
|
|
inputs,
|
|
...
|
|
}:
|
|
|
|
{
|
|
disabledModules = [
|
|
"services/security/crowdsec.nix"
|
|
"services/security/crowdsec-firewall-bouncer.nix"
|
|
];
|
|
|
|
imports = [
|
|
./hardware-configuration.nix
|
|
./disko-config.nix
|
|
"${inputs.crowdsec-rewrite}/nixos/modules/services/security/crowdsec.nix"
|
|
"${inputs.crowdsec-rewrite}/nixos/modules/services/security/crowdsec-firewall-bouncer.nix"
|
|
];
|
|
|
|
nix = {
|
|
package = pkgs.nixVersions.stable;
|
|
|
|
optimise = {
|
|
automatic = true;
|
|
dates = "Mon *-*-* 03:00:00";
|
|
randomizedDelaySec = "10m";
|
|
};
|
|
gc = {
|
|
automatic = true;
|
|
dates = "Mon *-*-* 03:00:00";
|
|
randomizedDelaySec = "10m";
|
|
options = "--delete-older-than 7d";
|
|
};
|
|
settings.experimental-features = [
|
|
"nix-command"
|
|
"flakes"
|
|
];
|
|
|
|
extraOptions = ''
|
|
min-free = 512000000
|
|
max-free = 2000000000
|
|
'';
|
|
};
|
|
|
|
boot.loader = {
|
|
systemd-boot = {
|
|
enable = true;
|
|
configurationLimit = 8;
|
|
};
|
|
efi.canTouchEfiVariables = true;
|
|
timeout = 0;
|
|
};
|
|
|
|
nixpkgs.hostPlatform = "x86_64-linux";
|
|
|
|
hardware.graphics = {
|
|
enable = true;
|
|
extraPackages = with pkgs; [
|
|
intel-media-driver # VAAPI
|
|
intel-compute-runtime # OpenCL
|
|
libvdpau-va-gl # VDPAU
|
|
];
|
|
};
|
|
|
|
security.wrappers.btop = {
|
|
enable = true;
|
|
owner = "root";
|
|
group = "root";
|
|
source = "${pkgs.btop}/bin/btop";
|
|
capabilities = "cap_perfmon=ep";
|
|
};
|
|
|
|
time.timeZone = "Europe/Tallinn";
|
|
|
|
networking = {
|
|
hostName = "plexy";
|
|
networkmanager.enable = true;
|
|
nftables.enable = true;
|
|
firewall.allowedTCPPorts = [
|
|
22
|
|
80
|
|
443
|
|
873 # rsyncd
|
|
5055 # Seerr
|
|
5201 # iperf3
|
|
8096 # Jellyfin
|
|
15835 # Glance
|
|
15836 # qBittorrent (Web UI)
|
|
15837 # Radarr
|
|
15838 # Sonarr
|
|
15839 # Prowlarr
|
|
17650 # qBittorrent (torrent)
|
|
];
|
|
};
|
|
|
|
sops = {
|
|
defaultSopsFile = ./secrets.yaml;
|
|
defaultSopsFormat = "yaml";
|
|
age.keyFile = "/var/lib/sops-nix/key.txt";
|
|
age.sshKeyPaths = [ ];
|
|
gnupg.sshKeyPaths = [ ];
|
|
|
|
secrets = {
|
|
"vaultwarden.env" = { };
|
|
"rsyncd.secrets" = { };
|
|
"caddy.env" = { };
|
|
"crowdsec-console-token" = { };
|
|
};
|
|
};
|
|
|
|
virtualisation.docker.enable = true;
|
|
|
|
environment.systemPackages = [
|
|
pkgs.jellyfin
|
|
pkgs.jellyfin-web
|
|
pkgs.jellyfin-ffmpeg
|
|
];
|
|
|
|
services = {
|
|
openssh = {
|
|
enable = true;
|
|
settings.PasswordAuthentication = false;
|
|
settings.PermitRootLogin = "no";
|
|
};
|
|
iperf3 = {
|
|
enable = true;
|
|
};
|
|
rsyncd = {
|
|
enable = true;
|
|
settings = {
|
|
globalSection = {
|
|
address = "0.0.0.0";
|
|
gid = "users";
|
|
"max connections" = 5;
|
|
uid = "wekuz";
|
|
};
|
|
sections = {
|
|
media = {
|
|
path = "/storage/media";
|
|
comment = "Media storage";
|
|
"read only" = false;
|
|
"auth users" = "wekuz";
|
|
"secrets file" = config.sops.secrets."rsyncd.secrets".path;
|
|
};
|
|
torrents = {
|
|
path = "/storage/torrents";
|
|
comment = "Torrents storage";
|
|
"read only" = false;
|
|
"auth users" = "wekuz";
|
|
"secrets file" = config.sops.secrets."rsyncd.secrets".path;
|
|
};
|
|
};
|
|
};
|
|
};
|
|
caddy = {
|
|
enable = true;
|
|
package = pkgs.caddy.withPlugins {
|
|
plugins = [
|
|
"github.com/caddy-dns/cloudflare@v0.2.4"
|
|
"github.com/WeidiDeng/caddy-cloudflare-ip@v0.0.0-20231130002422-f53b62aa13cb"
|
|
"github.com/mholt/caddy-l4@v0.1.2"
|
|
"github.com/caddyserver/transform-encoder@v0.0.0-20260423033309-ba4124974830"
|
|
"github.com/hslatman/caddy-crowdsec-bouncer/http@v0.14.1"
|
|
"github.com/hslatman/caddy-crowdsec-bouncer/appsec@v0.14.1"
|
|
"github.com/hslatman/caddy-crowdsec-bouncer/layer4@v0.14.1"
|
|
];
|
|
hash = "sha256-5kC1Rcrgxco/26B4Tb6h7bictQ3j8rycxH+3Rr28Fa0=";
|
|
doInstallCheck = false; # Because caddy-crowdsec-bouncer plugins are in subdirectories
|
|
};
|
|
environmentFile = config.sops.secrets."caddy.env".path;
|
|
logFormat = ''
|
|
level INFO
|
|
'';
|
|
globalConfig = ''
|
|
grace_period 10s
|
|
servers {
|
|
trusted_proxies cloudflare {
|
|
interval 1h
|
|
timeout 20s
|
|
}
|
|
trusted_proxies_strict
|
|
client_ip_headers Cf-Connecting-Ip X-Forwarded-For
|
|
}
|
|
crowdsec {
|
|
api_url http://127.0.0.1:8080
|
|
api_key {$CROWDSEC_APIKEY}
|
|
ticker_interval 10s
|
|
}
|
|
'';
|
|
extraConfig = ''
|
|
(proxy-route) {
|
|
route {
|
|
crowdsec
|
|
reverse_proxy {args[0]} {
|
|
# Strip intermediary proxies
|
|
header_up X-Forwarded-For {client_ip}
|
|
header_up X-Real-IP {client_ip}
|
|
}
|
|
}
|
|
}
|
|
'';
|
|
virtualHosts = {
|
|
"*.wekuz.localplayer.dev" = {
|
|
logFormat = ''
|
|
output stdout
|
|
format json
|
|
'';
|
|
extraConfig = ''
|
|
tls {
|
|
dns cloudflare {$CF_APIKEY}
|
|
}
|
|
'';
|
|
};
|
|
|
|
"glance.wekuz.localplayer.dev" = {
|
|
logFormat = null;
|
|
extraConfig = ''
|
|
import proxy-route http://localhost:15835
|
|
'';
|
|
};
|
|
|
|
"vw.wekuz.localplayer.dev" = {
|
|
logFormat = null;
|
|
extraConfig = ''
|
|
import proxy-route http://192.168.1.111:15830
|
|
'';
|
|
};
|
|
|
|
"lw.wekuz.localplayer.dev" = {
|
|
logFormat = null;
|
|
extraConfig = ''
|
|
import proxy-route http://192.168.1.111:15834
|
|
'';
|
|
};
|
|
|
|
"git.wekuz.localplayer.dev" = {
|
|
logFormat = null;
|
|
extraConfig = ''
|
|
import proxy-route http://192.168.1.111:15836
|
|
'';
|
|
};
|
|
|
|
"tv.wekuz.localplayer.dev" = {
|
|
logFormat = null;
|
|
extraConfig = ''
|
|
import proxy-route http://localhost:8096
|
|
'';
|
|
};
|
|
|
|
"seerr.wekuz.localplayer.dev" = {
|
|
logFormat = null;
|
|
extraConfig = ''
|
|
import proxy-route http://localhost:5055
|
|
'';
|
|
};
|
|
};
|
|
};
|
|
crowdsec = {
|
|
enable = true;
|
|
autoUpdateService = true;
|
|
|
|
settings = {
|
|
console.enrollKeyFile = config.sops.secrets."crowdsec-console-token".path;
|
|
config = {
|
|
|
|
api.server = {
|
|
enable = true;
|
|
online_client.credentials_path = "/var/lib/crowdsec/online_api_credentials.yaml";
|
|
};
|
|
};
|
|
|
|
acquisitions = [
|
|
{
|
|
source = "journalctl";
|
|
journalctl_filter = [ "_SYSTEMD_UNIT=sshd.service" ];
|
|
labels.type = "syslog";
|
|
}
|
|
{
|
|
source = "journalctl";
|
|
journalctl_filter = [ "-k" ];
|
|
labels.type = "syslog";
|
|
}
|
|
{
|
|
source = "journalctl";
|
|
journalctl_filter = [
|
|
"_SYSTEMD_UNIT=caddy.service"
|
|
"-o"
|
|
"cat"
|
|
];
|
|
labels.type = "caddy";
|
|
}
|
|
{
|
|
source = "journalctl";
|
|
journalctl_filter = [ "_SYSTEMD_UNIT=vaultwarden.service" ];
|
|
labels.type = "Vaultwarden";
|
|
}
|
|
{
|
|
source = "journalctl";
|
|
journalctl_filter = [ "_SYSTEMD_UNIT=jellyfin.service" ];
|
|
labels.type = "jellyfin";
|
|
}
|
|
{
|
|
source = "journalctl";
|
|
journalctl_filter = [ "_SYSTEMD_UNIT=seerr.service" ];
|
|
labels.type = "seerr";
|
|
}
|
|
];
|
|
};
|
|
|
|
hub.collections = [
|
|
"crowdsecurity/linux"
|
|
"crowdsecurity/sshd"
|
|
|
|
"crowdsecurity/base-http-scenarios"
|
|
"crowdsecurity/caddy"
|
|
|
|
"Dominic-Wagner/vaultwarden"
|
|
"LePresidente/jellyfin"
|
|
"LePresidente/jellyseerr"
|
|
|
|
"crowdsecurity/whitelist-good-actors"
|
|
];
|
|
};
|
|
crowdsec-firewall-bouncer = {
|
|
enable = true;
|
|
registerBouncer.enable = false;
|
|
secrets.apiKeyPath = "/var/lib/crowdsec/firewall-bouncer-key";
|
|
};
|
|
vaultwarden = {
|
|
enable = true;
|
|
environmentFile = config.sops.secrets."vaultwarden.env".path;
|
|
config = {
|
|
WEBSOCKET_ENABLED = true;
|
|
SIGNUPS_ALLOWED = false;
|
|
SIGNUPS_VERIFY = false;
|
|
INVITATIONS_ALLOWED = false;
|
|
SHOW_PASSWORD_HINT = false;
|
|
DATA_FOLDER = "/var/lib/vaultwarden/data";
|
|
LOG_LEVEL = "warn";
|
|
};
|
|
};
|
|
glance = {
|
|
enable = true;
|
|
settings = import ./glance.nix;
|
|
};
|
|
jellyfin = {
|
|
enable = true;
|
|
};
|
|
seerr = {
|
|
enable = true;
|
|
};
|
|
qbittorrent = {
|
|
enable = true;
|
|
torrentingPort = 17650;
|
|
webuiPort = 15836;
|
|
serverConfig = {
|
|
Application.FileLogger = {
|
|
Enabled = true;
|
|
Path = "/var/log/qBittorrent";
|
|
Backup = true;
|
|
MaxSizeBytes = 65536;
|
|
DeleteOld = true;
|
|
Age = 14;
|
|
AgeType = 0;
|
|
};
|
|
BitTorrent.Session = {
|
|
AddTorrentStopped = false;
|
|
Preallocation = true;
|
|
AddExtensionToIncompleteFiles = false;
|
|
DisableAutoTMMByDefault = false;
|
|
|
|
MaxConnections = 1000;
|
|
MaxConnectionsPerTorrent = 200;
|
|
MaxUploads = 64;
|
|
MaxUploadsPerTorrent = 26;
|
|
|
|
GlobalDLSpeedLimit = 6000;
|
|
GlobalUPSpeedLimit = 6000;
|
|
AlternativeGlobalDLSpeedLimit = 0;
|
|
AlternativeGlobalUPSpeedLimit = 0;
|
|
BandwidthSchedulerEnabled = true;
|
|
DefaultSavePath = "/storage/torrents";
|
|
|
|
MaxActiveCheckingTorrents = 1;
|
|
|
|
QueueingSystemEnabled = true;
|
|
MaxActiveDownloads = 3;
|
|
MaxActiveUploads = 10;
|
|
MaxActiveTorrents = 200;
|
|
IgnoreSlowTorrentsForQueueing = true;
|
|
SlowTorrentsDownloadRate = 500;
|
|
SlowTorrentsUploadRate = 100;
|
|
SlowTorrentsInactivityTimer = 60;
|
|
|
|
GlobalMaxRatio = -1;
|
|
GlobalMaxSeedingMinutes = -1;
|
|
GlobalMaxInactiveSeedingMinutes = -1;
|
|
ShareLimitAction = "Stop";
|
|
|
|
Interface = "";
|
|
InterfaceAddress = "";
|
|
InterfaceName = "";
|
|
};
|
|
Network = {
|
|
PortForwardingEnabled = false;
|
|
};
|
|
Preferences = {
|
|
General = {
|
|
Locale = "en";
|
|
StatusbarExternalIPDisplayed = true;
|
|
};
|
|
Scheduler = {
|
|
end_time = "@Variant(\\0\\0\\0\\xf\\x1\\x65\\xe@)"; # 02:00
|
|
start_time = "@Variant(\\0\\0\\0\\xf\\0m\\xdd\\0)"; # 06:30
|
|
};
|
|
WebUI = {
|
|
Address = "*";
|
|
Username = "admin";
|
|
Password_PBKDF2 = "@ByteArray(IM7ih6pLNXBv6it48lI1Lg==:VyczL0q0C89RNfXkzcvdZemfXjdG53xBSY66gqIl56dA0OcrvvxOQdW8jOzvY3lFjR+WDBG3Q/ejsG4w8O5RRA==)";
|
|
LocalHostAuth = false;
|
|
};
|
|
};
|
|
Core.AutoDeleteAddedTorrentFile = "never";
|
|
LegalNotice.Accepted = true;
|
|
};
|
|
};
|
|
radarr = {
|
|
enable = true;
|
|
settings = {
|
|
server.port = 15837;
|
|
};
|
|
};
|
|
sonarr = {
|
|
enable = true;
|
|
settings = {
|
|
server.port = 15838;
|
|
};
|
|
};
|
|
prowlarr = {
|
|
enable = true;
|
|
settings = {
|
|
server.port = 15839;
|
|
};
|
|
};
|
|
flaresolverr = {
|
|
enable = true;
|
|
port = 15840;
|
|
};
|
|
};
|
|
|
|
environment.variables.EDITOR = "nvim";
|
|
|
|
users = {
|
|
groups = {
|
|
media = { };
|
|
};
|
|
users = {
|
|
wekuz = {
|
|
isNormalUser = true;
|
|
extraGroups = [
|
|
"wheel"
|
|
"networkmanager"
|
|
"docker"
|
|
"media"
|
|
];
|
|
openssh.authorizedKeys.keys = [
|
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBs3aPxyJpVGytuVSO3va2WybKNFMR241o8DCJQbBEWV"
|
|
];
|
|
};
|
|
jellyfin = {
|
|
extraGroups = [
|
|
"media"
|
|
];
|
|
};
|
|
qbittorrent = {
|
|
extraGroups = [
|
|
"media"
|
|
];
|
|
};
|
|
radarr = {
|
|
extraGroups = [
|
|
"media"
|
|
];
|
|
};
|
|
sonarr = {
|
|
extraGroups = [
|
|
"media"
|
|
];
|
|
};
|
|
};
|
|
};
|
|
|
|
systemd.tmpfiles.rules = [
|
|
"d /storage 0755 root root -"
|
|
"d /storage/media 2775 wekuz media -"
|
|
"d /storage/media/movies 2775 wekuz media -"
|
|
"d /storage/media/tv 2775 wekuz media -"
|
|
"d /storage/torrents 2775 wekuz media -"
|
|
];
|
|
|
|
system.stateVersion = "26.05";
|
|
}
|