catarina: split services to modules
This commit is contained in:
parent
1ad29e30d2
commit
0da77d6559
2
.secrets
2
.secrets
@ -1 +1 @@
|
|||||||
Subproject commit d4a686b321770dbe16130e31966e87143440469e
|
Subproject commit 3d189e205d5fc4194726010e5f31178235c1c046
|
@ -18,7 +18,6 @@
|
|||||||
|
|
||||||
outputs = inputs @ { self, nixpkgs, home-manager, crane, nixgl, simple-nixos-mailserver, sops-nix, ... }: {
|
outputs = inputs @ { self, nixpkgs, home-manager, crane, nixgl, simple-nixos-mailserver, sops-nix, ... }: {
|
||||||
|
|
||||||
|
|
||||||
lib = import ./lib {};
|
lib = import ./lib {};
|
||||||
|
|
||||||
nixosConfigurations = {
|
nixosConfigurations = {
|
||||||
@ -41,6 +40,7 @@
|
|||||||
self.nixosModules.spoofdpi
|
self.nixosModules.spoofdpi
|
||||||
simple-nixos-mailserver.nixosModules.mailserver
|
simple-nixos-mailserver.nixosModules.mailserver
|
||||||
sops-nix.nixosModules.sops
|
sops-nix.nixosModules.sops
|
||||||
|
self.nixosModules.papermc
|
||||||
];
|
];
|
||||||
specialArgs = { inherit inputs self; };
|
specialArgs = { inherit inputs self; };
|
||||||
};
|
};
|
||||||
@ -50,6 +50,8 @@
|
|||||||
bonfire = import ./nixosModules/bonfire.nix;
|
bonfire = import ./nixosModules/bonfire.nix;
|
||||||
|
|
||||||
spoofdpi = import ./nixosModules/spoofdpi { inherit self; };
|
spoofdpi = import ./nixosModules/spoofdpi { inherit self; };
|
||||||
|
|
||||||
|
papermc = import ./nixosModules/papermc { inherit self; };
|
||||||
};
|
};
|
||||||
|
|
||||||
templates = {
|
templates = {
|
||||||
|
@ -2,7 +2,11 @@
|
|||||||
rec {
|
rec {
|
||||||
system.stateVersion = "23.11";
|
system.stateVersion = "23.11";
|
||||||
|
|
||||||
imports = [ ./hardware.nix ./users.nix ];
|
imports = [
|
||||||
|
./hardware.nix ./users.nix
|
||||||
|
./services/papermc.nix
|
||||||
|
./services/gitea.nix
|
||||||
|
];
|
||||||
|
|
||||||
# Nix settings
|
# Nix settings
|
||||||
nix = {
|
nix = {
|
||||||
@ -47,7 +51,6 @@ rec {
|
|||||||
autoSuspend = false;
|
autoSuspend = false;
|
||||||
};
|
};
|
||||||
desktopManager.gnome.enable = true;
|
desktopManager.gnome.enable = true;
|
||||||
windowManager.awesome.enable = true;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
services.printing.enable = true;
|
services.printing.enable = true;
|
||||||
@ -100,7 +103,7 @@ rec {
|
|||||||
certs = {
|
certs = {
|
||||||
"elnafo.ru" = {
|
"elnafo.ru" = {
|
||||||
domain = "elnafo.ru";
|
domain = "elnafo.ru";
|
||||||
extraDomainNames = [ "*.elnafo.ru" ];
|
extraDomainNames = [ "www.elnafo.ru" "vcs.elnafo.ru" "media.elnafo.ru" "mc.elnafo.ru" "map.mc.elnafo.ru"];
|
||||||
dnsProvider = "webnames";
|
dnsProvider = "webnames";
|
||||||
credentialsFile = config.sops.secrets."dns".path;
|
credentialsFile = config.sops.secrets."dns".path;
|
||||||
webroot = null;
|
webroot = null;
|
||||||
@ -131,12 +134,6 @@ rec {
|
|||||||
globalRedirect = "elnafo.ru";
|
globalRedirect = "elnafo.ru";
|
||||||
};
|
};
|
||||||
|
|
||||||
"vcs.elnafo.ru" = {
|
|
||||||
forceSSL = true;
|
|
||||||
useACMEHost = "elnafo.ru";
|
|
||||||
locations."/".proxyPass = "http://127.0.0.1:3001";
|
|
||||||
};
|
|
||||||
|
|
||||||
"media.elnafo.ru" = {
|
"media.elnafo.ru" = {
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
useACMEHost = "elnafo.ru";
|
useACMEHost = "elnafo.ru";
|
||||||
@ -144,81 +141,6 @@ rec {
|
|||||||
locations."/".proxyPass = "http://127.0.0.1:8096";
|
locations."/".proxyPass = "http://127.0.0.1:8096";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
services.postgresql = {
|
|
||||||
enable = true;
|
|
||||||
authentication = ''
|
|
||||||
# Type Database DB-User Auth-Method Ident-Map(optional)
|
|
||||||
local git all ident map=gitea-users
|
|
||||||
'';
|
|
||||||
identMap = ''
|
|
||||||
# MapName System-User DB-User
|
|
||||||
gitea-users git git
|
|
||||||
'';
|
|
||||||
ensureDatabases = [ "git" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
services.gitea = {
|
|
||||||
enable = true;
|
|
||||||
|
|
||||||
user = "git";
|
|
||||||
group = "gitea";
|
|
||||||
stateDir = "/var/lib/gitea";
|
|
||||||
|
|
||||||
settings = {
|
|
||||||
server = {
|
|
||||||
DOMAIN = "vcs.elnafo.ru";
|
|
||||||
ROOT_URL = "https://vcs.elnafo.ru/";
|
|
||||||
HTTP_ADDRESS = "127.0.0.1";
|
|
||||||
HTTP_PORT = 3001;
|
|
||||||
};
|
|
||||||
|
|
||||||
session.COOKIE_SECURE = true;
|
|
||||||
|
|
||||||
mailer = {
|
|
||||||
ENABLED = true;
|
|
||||||
FROM = "git@elnafo.ru";
|
|
||||||
PROTOCOL = "smtps";
|
|
||||||
SMTP_ADDR = "smtp.elnafo.ru";
|
|
||||||
SMTP_PORT = 465;
|
|
||||||
USER = "git";
|
|
||||||
USE_CLIENT_CERT = true;
|
|
||||||
CLIENT_CERT_FILE = "${config.security.acme.certs."elnafo.ru".directory}/cert.pem";
|
|
||||||
CLIENT_KEY_FILE = "${config.security.acme.certs."elnafo.ru".directory}/key.pem";
|
|
||||||
};
|
|
||||||
|
|
||||||
service.DISABLE_REGISTRATION = true;
|
|
||||||
|
|
||||||
other = {
|
|
||||||
SHOW_FOOTER_VERSION = false;
|
|
||||||
SHOW_FOOTER_TEMPLATE_LOAD_TIME = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
mailerPasswordFile = config.sops.secrets."gitea/mail".path;
|
|
||||||
|
|
||||||
database = {
|
|
||||||
type = "postgres";
|
|
||||||
passwordFile = config.sops.secrets."database/git".path;
|
|
||||||
name = "git";
|
|
||||||
user = "git";
|
|
||||||
};
|
|
||||||
|
|
||||||
lfs.enable = true;
|
|
||||||
|
|
||||||
appName = "Elnafo VCS";
|
|
||||||
};
|
|
||||||
|
|
||||||
users.users.${services.gitea.user} = {
|
|
||||||
description = "Gitea Service";
|
|
||||||
home = services.gitea.stateDir;
|
|
||||||
useDefaultShell = true;
|
|
||||||
group = services.gitea.group;
|
|
||||||
extraGroups = [ "nginx" ];
|
|
||||||
isSystemUser = true;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
mailserver = {
|
mailserver = {
|
||||||
@ -238,24 +160,6 @@ rec {
|
|||||||
openFirewall = true;
|
openFirewall = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
services.minecraft-server = {
|
|
||||||
enable = true;
|
|
||||||
eula = true;
|
|
||||||
declarative = true;
|
|
||||||
openFirewall = true;
|
|
||||||
serverProperties = {
|
|
||||||
server-port = 25565;
|
|
||||||
gamemode = "survival";
|
|
||||||
motd = "NixOS Minecraft Server";
|
|
||||||
max-players = 10;
|
|
||||||
level-seed = "66666666";
|
|
||||||
enable-status = true;
|
|
||||||
enforce-secure-profile = false;
|
|
||||||
difficulty = "normal";
|
|
||||||
online-mode = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.spoofdpi.enable = true;
|
services.spoofdpi.enable = true;
|
||||||
|
|
||||||
# Packages
|
# Packages
|
||||||
|
@ -109,7 +109,7 @@
|
|||||||
|
|
||||||
firewall = {
|
firewall = {
|
||||||
enable = true;
|
enable = true;
|
||||||
allowedTCPPorts = [ 80 443 3001 ];
|
allowedTCPPorts = [ 80 443 3001 25600 ];
|
||||||
};
|
};
|
||||||
|
|
||||||
interfaces.enp9s0.ipv4.addresses = [ {
|
interfaces.enp9s0.ipv4.addresses = [ {
|
||||||
|
81
nixosConfigurations/catarina/services/gitea.nix
Normal file
81
nixosConfigurations/catarina/services/gitea.nix
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
{
|
||||||
|
services.postgresql = {
|
||||||
|
enable = true;
|
||||||
|
authentication = ''
|
||||||
|
# Type Database DB-User Auth-Method Ident-Map(optional)
|
||||||
|
local git all ident map=gitea-users
|
||||||
|
'';
|
||||||
|
identMap = ''
|
||||||
|
# MapName System-User DB-User
|
||||||
|
gitea-users git git
|
||||||
|
'';
|
||||||
|
ensureDatabases = [ "git" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
services.gitea = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
user = "git";
|
||||||
|
group = "gitea";
|
||||||
|
stateDir = "/var/lib/gitea";
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
server = {
|
||||||
|
DOMAIN = "vcs.elnafo.ru";
|
||||||
|
ROOT_URL = "https://vcs.elnafo.ru/";
|
||||||
|
HTTP_ADDRESS = "127.0.0.1";
|
||||||
|
HTTP_PORT = 3001;
|
||||||
|
};
|
||||||
|
|
||||||
|
session.COOKIE_SECURE = true;
|
||||||
|
|
||||||
|
mailer = {
|
||||||
|
ENABLED = true;
|
||||||
|
FROM = "git@elnafo.ru";
|
||||||
|
PROTOCOL = "smtps";
|
||||||
|
SMTP_ADDR = "smtp.elnafo.ru";
|
||||||
|
SMTP_PORT = 465;
|
||||||
|
USER = "git";
|
||||||
|
USE_CLIENT_CERT = true;
|
||||||
|
CLIENT_CERT_FILE = "${config.security.acme.certs."elnafo.ru".directory}/cert.pem";
|
||||||
|
CLIENT_KEY_FILE = "${config.security.acme.certs."elnafo.ru".directory}/key.pem";
|
||||||
|
};
|
||||||
|
|
||||||
|
service.DISABLE_REGISTRATION = true;
|
||||||
|
|
||||||
|
other = {
|
||||||
|
SHOW_FOOTER_VERSION = false;
|
||||||
|
SHOW_FOOTER_TEMPLATE_LOAD_TIME = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
mailerPasswordFile = config.sops.secrets."gitea/mail".path;
|
||||||
|
|
||||||
|
database = {
|
||||||
|
type = "postgres";
|
||||||
|
passwordFile = config.sops.secrets."database/git".path;
|
||||||
|
name = "git";
|
||||||
|
user = "git";
|
||||||
|
};
|
||||||
|
|
||||||
|
lfs.enable = true;
|
||||||
|
|
||||||
|
appName = "Elnafo VCS";
|
||||||
|
};
|
||||||
|
|
||||||
|
users.users.${config.services.gitea.user} = {
|
||||||
|
description = "Gitea Service";
|
||||||
|
home = config.services.gitea.stateDir;
|
||||||
|
useDefaultShell = true;
|
||||||
|
group = config.services.gitea.group;
|
||||||
|
extraGroups = [ "nginx" ];
|
||||||
|
isSystemUser = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.nginx.virtualHosts."vcs.elnafo.ru" = {
|
||||||
|
forceSSL = true;
|
||||||
|
useACMEHost = "elnafo.ru";
|
||||||
|
locations."/".proxyPass = "http://127.0.0.1:3001";
|
||||||
|
};
|
||||||
|
}
|
165
nixosConfigurations/catarina/services/papermc.nix
Normal file
165
nixosConfigurations/catarina/services/papermc.nix
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
let
|
||||||
|
inherit (pkgs) stdenv fetchurl;
|
||||||
|
|
||||||
|
playerlist = [
|
||||||
|
{
|
||||||
|
name = "L_Nafaryus";
|
||||||
|
uuid = "02c47438-79eb-3938-b5e0-d7c03cb5709f";
|
||||||
|
level = 4;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name = "AfroPriest";
|
||||||
|
uuid = "6fa9251d-11a5-33ad-ada3-312f0632eab1";
|
||||||
|
level = 3;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
operators = lib.filter (player: player.level > 0) playerlist;
|
||||||
|
whitelist = map (player: removeAttrs player [ "level" ]) playerlist;
|
||||||
|
|
||||||
|
# Plugins
|
||||||
|
|
||||||
|
passky = stdenv.mkDerivation rec {
|
||||||
|
pname = "Passky";
|
||||||
|
version = "2.1.1";
|
||||||
|
src = fetchurl {
|
||||||
|
url = "https://hangarcdn.papermc.io/plugins/Black1_TV/Passky/versions/${version}/PAPER/Passky-${version}.jar";
|
||||||
|
hash = "sha256-D5NpFrkGLgZNMS5WlMRM3Uv07hPsI9Hdsii2whTAZ2o=";
|
||||||
|
};
|
||||||
|
meta.homepage = "https://hangar.papermc.io/Black1_TV/Passky";
|
||||||
|
phases = [ "installPhase" ];
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out/bin
|
||||||
|
cp $src $out/bin/${pname}.jar
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
grimAnticheat = stdenv.mkDerivation rec {
|
||||||
|
pname = "GrimAC";
|
||||||
|
version = "2.3.46";
|
||||||
|
src = fetchurl {
|
||||||
|
url = "https://hangarcdn.papermc.io/plugins/GrimAnticheat/GrimAnticheat/versions/${version}/PAPER/grimac-${version}.jar";
|
||||||
|
hash = "sha256-tG8pBDMU4N/Ijn5RfdsQrtY4/gEhN1wEDCopqOSIqB4=";
|
||||||
|
};
|
||||||
|
meta.homepage = "https://hangar.papermc.io/GrimAnticheat/GrimAnticheat";
|
||||||
|
phases = [ "installPhase" ];
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out/bin
|
||||||
|
cp $src $out/bin/${pname}.jar
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
viaVersion = stdenv.mkDerivation rec {
|
||||||
|
pname = "ViaVersion";
|
||||||
|
version = "4.9.2";
|
||||||
|
src = fetchurl {
|
||||||
|
url = "https://hangarcdn.papermc.io/plugins/ViaVersion/ViaVersion/versions/${version}/PAPER/ViaVersion-${version}.jar";
|
||||||
|
hash = "sha256-dvcyqCpIjArKCnUAD/L+lG/5gRQ9fLMKcl/+o8sLmYs=";
|
||||||
|
};
|
||||||
|
meta.homepage = "https://hangar.papermc.io/ViaVersion/ViaVersion";
|
||||||
|
phases = [ "installPhase" ];
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out/bin
|
||||||
|
cp $src $out/bin/${pname}.jar
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
directionHUD = stdenv.mkDerivation rec {
|
||||||
|
pname = "DirectionHUD";
|
||||||
|
version = "1.2.2";
|
||||||
|
src = fetchurl {
|
||||||
|
url = "https://hangarcdn.papermc.io/plugins/other/DirectionHUD/versions/${version}%2B1.18-1.20.2/PAPER/directionhud-spigot-${version}%2B1.18-1.20.2.jar";
|
||||||
|
hash = "sha256-F+86Q58+3VoqNoD8P38bu8u1Hx8Si0lxNXZnF/R4hAg=";
|
||||||
|
};
|
||||||
|
meta.homepage = "https://hangar.papermc.io/other/DirectionHUD";
|
||||||
|
phases = [ "installPhase" ];
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out/bin
|
||||||
|
cp $src $out/bin/${pname}.jar
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
miniMOTD = stdenv.mkDerivation rec {
|
||||||
|
pname = "MiniMOTD";
|
||||||
|
version = "2.0.14";
|
||||||
|
src = fetchurl {
|
||||||
|
url = "https://hangarcdn.papermc.io/plugins/jmp/MiniMOTD/versions/${version}/PAPER/minimotd-bukkit-${version}.jar";
|
||||||
|
hash = "sha256-d7l/pZGxteS2A9c9PIZASDTACGev8HY5SHZRvcxBc5A=";
|
||||||
|
};
|
||||||
|
meta.homepage = "https://hangar.papermc.io/jmp/MiniMOTD";
|
||||||
|
phases = [ "installPhase" ];
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out/bin
|
||||||
|
cp $src $out/bin/${pname}.jar
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
skinRestorer = stdenv.mkDerivation rec {
|
||||||
|
pname = "SkinRestorer";
|
||||||
|
version = "15.0.2";
|
||||||
|
src = fetchurl {
|
||||||
|
url = "https://github.com/SkinsRestorer/SkinsRestorerX/releases/download/${version}/SkinsRestorer.jar";
|
||||||
|
hash = "sha256-fhAegFtl22xKXMi5MbsXCYOjbfqOlQTnILoEJxCDbkc=";
|
||||||
|
};
|
||||||
|
meta.homepage = "https://hangar.papermc.io/SRTeam/SkinsRestorer";
|
||||||
|
phases = [ "installPhase" ];
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out/bin
|
||||||
|
cp $src $out/bin/${pname}.jar
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
squaremap = stdenv.mkDerivation rec {
|
||||||
|
pname = "squaremap";
|
||||||
|
version = "1.2.2";
|
||||||
|
src = fetchurl {
|
||||||
|
url = "https://hangarcdn.papermc.io/plugins/jmp/squaremap/versions/${version}/PAPER/squaremap-paper-mc1.20.2-${version}.jar";
|
||||||
|
hash = "sha256-Z8AWzZLlZavF8YYs1kslhtCvzq5fZ7O97mTx3hCgj78=";
|
||||||
|
};
|
||||||
|
meta.homepage = "https://hangar.papermc.io/jmp/squaremap";
|
||||||
|
phases = [ "installPhase" ];
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out/bin
|
||||||
|
cp $src $out/bin/${pname}.jar
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
plugins = [
|
||||||
|
passky grimAnticheat viaVersion directionHUD miniMOTD skinRestorer squaremap
|
||||||
|
];
|
||||||
|
|
||||||
|
in {
|
||||||
|
services.papermc = {
|
||||||
|
enable = true;
|
||||||
|
eula = true;
|
||||||
|
openFirewall = true;
|
||||||
|
serverProperties = {
|
||||||
|
server-port = 25565;
|
||||||
|
gamemode = "survival";
|
||||||
|
motd = "NixOS Paper Server";
|
||||||
|
max-players = 10;
|
||||||
|
level-seed = "66666666";
|
||||||
|
enable-status = true;
|
||||||
|
enforce-secure-profile = false;
|
||||||
|
difficulty = "normal";
|
||||||
|
online-mode = false;
|
||||||
|
enable-rcon = true;
|
||||||
|
"rcon.port" = 25600;
|
||||||
|
white-list = true;
|
||||||
|
};
|
||||||
|
rconPasswordFile = config.sops.secrets."papermc/rcon".path;
|
||||||
|
whitelist = whitelist;
|
||||||
|
ops = operators;
|
||||||
|
extraPreStart = ''
|
||||||
|
mkdir -p ${builtins.concatStringsSep " " (map (v: "plugins/${v.pname}") plugins)}
|
||||||
|
'' + builtins.concatStringsSep "\n" (map (v: "ln -s ${v.outPath}/bin/${v.pname}.jar plugins/") plugins)
|
||||||
|
;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.nginx.virtualHosts."map.mc.elnafo.ru" = {
|
||||||
|
forceSSL = true;
|
||||||
|
useACMEHost = "elnafo.ru";
|
||||||
|
locations."/".proxyPass = "http://127.0.0.1:8088";
|
||||||
|
};
|
||||||
|
}
|
237
nixosModules/papermc/default.nix
Normal file
237
nixosModules/papermc/default.nix
Normal file
@ -0,0 +1,237 @@
|
|||||||
|
{ self, ... }:
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.services.papermc;
|
||||||
|
|
||||||
|
eulaFile = builtins.toFile "eula.txt" ''
|
||||||
|
# eula.txt managed by NixOS Configuration
|
||||||
|
eula=true
|
||||||
|
'';
|
||||||
|
|
||||||
|
whitelistFile = pkgs.writeText "whitelist.json"
|
||||||
|
(builtins.toJSON cfg.whitelist);
|
||||||
|
|
||||||
|
opsFile = pkgs.writeText "whitelist.json"
|
||||||
|
(builtins.toJSON cfg.ops);
|
||||||
|
|
||||||
|
cfgToString = v: if builtins.isBool v then boolToString v else toString v;
|
||||||
|
|
||||||
|
serverPropertiesFile = let
|
||||||
|
serverProperties' = if (cfg.rconPasswordFile == null) then cfg.serverProperties else
|
||||||
|
(removeAttrs cfg.serverProperties [ "rcon.password" ]);
|
||||||
|
in pkgs.writeText "server.properties" (''
|
||||||
|
# server.properties managed by NixOS configuration
|
||||||
|
'' + concatStringsSep "\n" (mapAttrsToList
|
||||||
|
(n: v: "${n}=${cfgToString v}") serverProperties') +
|
||||||
|
lib.optionalString (cfg.rconPasswordFile != null) "\nrcon.password=#rconpass#");
|
||||||
|
|
||||||
|
stopScript = pkgs.writeShellScript "minecraft-server-stop" ''
|
||||||
|
echo stop > ${config.systemd.sockets.papermc.socketConfig.ListenFIFO}
|
||||||
|
|
||||||
|
# Wait for the PID of the minecraft server to disappear before
|
||||||
|
# returning, so systemd doesn't attempt to SIGKILL it.
|
||||||
|
while kill -0 "$1" 2> /dev/null; do
|
||||||
|
sleep 1s
|
||||||
|
done
|
||||||
|
'';
|
||||||
|
|
||||||
|
defaultServerPort = 25565;
|
||||||
|
|
||||||
|
serverPort = cfg.serverProperties.server-port or defaultServerPort;
|
||||||
|
|
||||||
|
rconPort = if cfg.serverProperties.enable-rcon or false
|
||||||
|
then cfg.serverProperties."rcon.port" or 25575
|
||||||
|
else null;
|
||||||
|
|
||||||
|
queryPort = if cfg.serverProperties.enable-query or false
|
||||||
|
then cfg.serverProperties."query.port" or 25565
|
||||||
|
else null;
|
||||||
|
|
||||||
|
in {
|
||||||
|
options.services.papermc = {
|
||||||
|
enable = mkEnableOption "Enables the PaperMC service.";
|
||||||
|
|
||||||
|
openFirewall = mkOption rec {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Whether to open ports in the firewall for the server.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
eula = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Whether you agree to [Mojangs EULA](https://account.mojang.com/documents/minecraft_eula).
|
||||||
|
This option must be set to `true` to run Minecraft server.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
dataDir = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
default = "/var/lib/papermc";
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Directory to store Minecraft database and other state/data files.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
whitelist = mkOption {
|
||||||
|
type = types.listOf types.attrs;
|
||||||
|
default = {};
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
This is a mapping from Minecraft usernames to UUIDs.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
ops = mkOption {
|
||||||
|
type = types.listOf types.attrs;
|
||||||
|
default = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
serverProperties = mkOption {
|
||||||
|
type = with types; attrsOf (oneOf [ bool int str ]);
|
||||||
|
default = {
|
||||||
|
"rcon.password" = mkIf (cfg.rconPasswordFile != null) "#rconpass#";
|
||||||
|
};
|
||||||
|
example = literalExpression ''
|
||||||
|
{
|
||||||
|
server-port = 43000;
|
||||||
|
difficulty = 3;
|
||||||
|
gamemode = 1;
|
||||||
|
max-players = 5;
|
||||||
|
motd = "NixOS Minecraft server!";
|
||||||
|
white-list = true;
|
||||||
|
enable-rcon = true;
|
||||||
|
"rcon.password" = "hunter2";
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Minecraft server properties for the server.properties file. See
|
||||||
|
<https://minecraft.gamepedia.com/Server.properties#Java_Edition_3>
|
||||||
|
for documentation on these values.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
rconPasswordFile = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
example = "/var/lib/secrets/papermc/rconpw";
|
||||||
|
};
|
||||||
|
|
||||||
|
package = mkPackageOption pkgs "papermc" {
|
||||||
|
example = "papermc_6_6_6";
|
||||||
|
};
|
||||||
|
|
||||||
|
jvmOpts = mkOption {
|
||||||
|
type = types.separatedString " ";
|
||||||
|
default = "-Xmx2048M -Xms2048M";
|
||||||
|
# Example options from https://minecraft.gamepedia.com/Tutorials/Server_startup_script
|
||||||
|
example = "-Xms4092M -Xmx4092M -XX:+UseG1GC -XX:+CMSIncrementalPacing "
|
||||||
|
+ "-XX:+CMSClassUnloadingEnabled -XX:ParallelGCThreads=2 "
|
||||||
|
+ "-XX:MinHeapFreeRatio=5 -XX:MaxHeapFreeRatio=10";
|
||||||
|
description = lib.mdDoc "JVM options for the Minecraft server.";
|
||||||
|
};
|
||||||
|
|
||||||
|
extraPreStart = mkOption {
|
||||||
|
type = types.lines;
|
||||||
|
default = '''';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
users.users.papermc = {
|
||||||
|
description = "Minecraft server service user";
|
||||||
|
home = cfg.dataDir;
|
||||||
|
createHome = true;
|
||||||
|
isSystemUser = true;
|
||||||
|
group = "papermc";
|
||||||
|
};
|
||||||
|
users.groups.papermc = {};
|
||||||
|
|
||||||
|
systemd.sockets.papermc = {
|
||||||
|
bindsTo = [ "papermc.service" ];
|
||||||
|
socketConfig = {
|
||||||
|
ListenFIFO = "/run/papermc.stdin";
|
||||||
|
SocketMode = "0660";
|
||||||
|
SocketUser = "papermc";
|
||||||
|
SocketGroup = "papermc";
|
||||||
|
RemoveOnStop = true;
|
||||||
|
FlushPending = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.papermc = {
|
||||||
|
description = "PaperMC Service";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
requires = [ "papermc.socket" ];
|
||||||
|
after = [ "network.target" "papermc.socket" ];
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = "${cfg.package}/bin/minecraft-server ${cfg.jvmOpts}";
|
||||||
|
ExecStop = "${stopScript} $MAINPID";
|
||||||
|
Restart = "always";
|
||||||
|
User = "papermc";
|
||||||
|
WorkingDirectory = cfg.dataDir;
|
||||||
|
|
||||||
|
StandardInput = "socket";
|
||||||
|
StandardOutput = "journal";
|
||||||
|
StandardError = "journal";
|
||||||
|
|
||||||
|
# Hardening
|
||||||
|
CapabilityBoundingSet = [ "" ];
|
||||||
|
DeviceAllow = [ "" ];
|
||||||
|
LockPersonality = true;
|
||||||
|
PrivateDevices = true;
|
||||||
|
PrivateTmp = true;
|
||||||
|
PrivateUsers = true;
|
||||||
|
ProtectClock = true;
|
||||||
|
ProtectControlGroups = true;
|
||||||
|
ProtectHome = true;
|
||||||
|
ProtectHostname = true;
|
||||||
|
ProtectKernelLogs = true;
|
||||||
|
ProtectKernelModules = true;
|
||||||
|
ProtectKernelTunables = true;
|
||||||
|
ProtectProc = "invisible";
|
||||||
|
RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
|
||||||
|
RestrictNamespaces = true;
|
||||||
|
RestrictRealtime = true;
|
||||||
|
RestrictSUIDSGID = true;
|
||||||
|
SystemCallArchitectures = "native";
|
||||||
|
UMask = "0077";
|
||||||
|
};
|
||||||
|
|
||||||
|
preStart = let
|
||||||
|
replaceSecretBin = "${pkgs.replace-secret}/bin/replace-secret";
|
||||||
|
in ''
|
||||||
|
ln -sf ${eulaFile} eula.txt
|
||||||
|
|
||||||
|
cp -b --suffix=.stateful ${whitelistFile} whitelist.json
|
||||||
|
cp -b --suffix=.stateful ${opsFile} ops.json
|
||||||
|
cp -b --suffix=.stateful ${serverPropertiesFile} server.properties
|
||||||
|
|
||||||
|
chmod +w whitelist.json ops.json server.properties
|
||||||
|
|
||||||
|
${lib.optionalString (cfg.rconPasswordFile != null) ''
|
||||||
|
${replaceSecretBin} '#rconpass#' '${cfg.rconPasswordFile}' server.properties
|
||||||
|
''}
|
||||||
|
'' + cfg.extraPreStart;
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.firewall = mkIf cfg.openFirewall ({
|
||||||
|
allowedUDPPorts = [ serverPort ];
|
||||||
|
allowedTCPPorts = [ serverPort ]
|
||||||
|
++ optional (queryPort != null) queryPort
|
||||||
|
++ optional (rconPort != null) rconPort;
|
||||||
|
});
|
||||||
|
|
||||||
|
assertions = [
|
||||||
|
{ assertion = cfg.eula;
|
||||||
|
message = "You must agree to Mojangs EULA to run minecraft-server."
|
||||||
|
+ " Read https://account.mojang.com/documents/minecraft_eula and"
|
||||||
|
+ " set `services.minecraft-server.eula` to `true` if you agree.";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user