chore(minecraft): mounts

This commit is contained in:
arcnmx 2024-09-17 12:42:18 -07:00
parent 33b18bc348
commit 75b123776b
15 changed files with 402 additions and 54 deletions

View file

@ -487,6 +487,57 @@ jobs:
command: ci-build-cache
quiet: false
stdin: ${{ runner.temp }}/ci.build.cache
minecraft:
name: nodes-minecraft
runs-on: ubuntu-latest
steps:
- id: checkout
name: git clone
uses: actions/checkout@v4
with:
submodules: false
- id: nix-install
name: nix install
uses: arcnmx/ci/actions/nix/install@v0.7
- id: ci-dirty
name: nix test dirty
uses: arcnmx/ci/actions/nix/run@v0.7
with:
attrs: ci.job.minecraft.run.test
command: ci-build-dirty
quiet: false
stdout: ${{ runner.temp }}/ci.build.dirty
- id: ci-test
name: nix test build
uses: arcnmx/ci/actions/nix/run@v0.7
with:
attrs: ci.job.minecraft.run.test
command: ci-build-realise
ignore-exit-code: true
quiet: false
stdin: ${{ runner.temp }}/ci.build.dirty
- env:
CI_EXIT_CODE: ${{ steps.ci-test.outputs.exit-code }}
id: ci-summary
name: nix test results
uses: arcnmx/ci/actions/nix/run@v0.7
with:
attrs: ci.job.minecraft.run.test
command: ci-build-summarise
quiet: false
stdin: ${{ runner.temp }}/ci.build.dirty
stdout: ${{ runner.temp }}/ci.build.cache
- env:
CACHIX_SIGNING_KEY: ${{ secrets.CACHIX_SIGNING_KEY }}
id: ci-cache
if: always()
name: nix test cache
uses: arcnmx/ci/actions/nix/run@v0.7
with:
attrs: ci.job.minecraft.run.test
command: ci-build-cache
quiet: false
stdin: ${{ runner.temp }}/ci.build.cache
packages:
name: nodes-packages
runs-on: ubuntu-latest

View file

@ -245,6 +245,24 @@
}
}
},
"minecraft": {
"network": {
"hostName": "minecraft",
"networks": {
"int": null,
"local": {
"address4": "10.1.1.51",
"address6": "fd0a::be24:11ff:fec4:66ad",
"macAddress": "BC:24:11:C4:66:AD"
},
"tail": {
"address4": "100.73.157.122",
"address6": "fd7a:115c:a1e0::1f01:9d7a",
"macAddress": null
}
}
}
},
"nue": {
"network": {
"hostName": "nue",

View file

@ -32,6 +32,7 @@ aya:: `10.1.1.47`
keycloak:: `10.1.1.48`
kasen:: `10.1.1.49`
sakuya:: `10.1.1.50`
minecraft:: `10.1.1.51`
nue:: `10.1.1.62`
logistics:: `10.1.1.63`

View file

@ -0,0 +1,150 @@
{
config,
lib,
pkgs,
...
}: let
inherit (lib.options) mkOption mkEnableOption mkPackageOption;
inherit (lib.modules) mkIf mkMerge mkOptionDefault;
inherit (lib.strings) concatStringsSep;
inherit (lib.meta) getExe;
cfg = config.services.minecraft-katsink-server;
in {
options.services.minecraft-katsink-server = with lib.types; {
enable = mkEnableOption "kat-kitchen-sink";
openFirewall = mkOption {
type = bool;
default = false;
};
port = mkOption {
type = port;
default = 25565;
};
jre.package = mkPackageOption pkgs "jre" {};
dataDir = mkOption {
type = path;
default = "/var/lib/minecraft-katsink";
description = ''
Directory to store Minecraft database and other state/data files.
'';
};
argsFiles = mkOption {
type = listOf str;
default = [ "user_jvm_args.txt" ];
};
jvmOpts = mkOption {
type = listOf str;
default = [];
example = ["-Xmx4G"];
};
user = mkOption {
type = str;
default = "minecraft-bedrock";
};
group = mkOption {
type = str;
default = cfg.user;
};
};
config = let
confService.services.minecraft-katsink-server = {
};
conf.users = mkIf (cfg.user == "minecraft-bedrock") {
users.${cfg.user} = {
inherit (cfg) group;
description = "Minecraft server service user";
home = cfg.dataDir;
createHome = true;
isSystemUser = true;
};
groups.${cfg.group} = {};
};
conf.systemd.services.minecraft-katsink-server = let
execStart = concatStringsSep " " ([
"${getExe cfg.jre.package}"
] ++ map (argsFile: "@${argsFile}") cfg.argsFiles
++ cfg.jvmOpts);
execStop = pkgs.writeShellScriptBin "minecraft-katsink-stop" ''
echo /stop > ${config.systemd.sockets.minecraft-katsink-server.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
'';
in {
description = "Minecraft Kat Kitchen Server";
wantedBy = ["multi-user.target"];
requires = ["minecraft-katsink-server.socket"];
after = ["network.target" "minecraft-katsink-server.socket"];
serviceConfig = {
ExecStart = [execStart];
ExecStop = "${getExe execStop} $MAINPID";
Restart = "on-failure";
User = cfg.user;
WorkingDirectory = cfg.dataDir;
/*LogFilterPatterns = [
"~.*minecraft:trial_chambers/chamber/end"
"~Running AutoCompaction"
];*/
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" "AF_UNIX" ];
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
SystemCallArchitectures = "native";
UMask = "0077";
};
};
conf.systemd.sockets.minecraft-katsink-server = {
bindsTo = [ "minecraft-katsink-server.service" ];
socketConfig = {
ListenFIFO = "/run/minecraft-katsink.stdin";
SocketMode = "0660";
SocketUser = mkOptionDefault cfg.user;
SocketGroup = mkOptionDefault cfg.group;
RemoveOnStop = true;
FlushPending = true;
};
};
conf.networking.firewall = mkIf cfg.openFirewall {
allowedUDPPorts = cfg.port;
};
in
mkMerge [
confService
(mkIf cfg.enable conf)
];
}

View file

@ -0,0 +1,37 @@
{
config,
lib,
...
}: let
inherit (lib.modules) mkIf mkDefault;
cfg = config.services.minecraft-katsink-server;
in {
services.minecraft-katsink-server = {
enable = mkDefault true;
argsFiles = [
"user_jvm_args.txt"
"libraries/net/neoforged/neoforge/21.1.54/unix_args.txt"
];
};
users = mkIf cfg.enable {
users.${cfg.user}.uid = 913;
groups.${cfg.group}.gid = config.users.users.${cfg.user}.uid;
};
systemd = mkIf cfg.enable {
services.minecraft-katsink-server = {
# TODO: confinement.enable = true;
gensokyo-zone.sharedMounts."minecraft/katsink/kat-kitchen-server" = {config, ...}: {
root = config.rootDir + "/minecraft/katsink";
path = mkDefault cfg.dataDir;
};
};
sockets.minecraft-katsink-server = {
socketConfig.SocketGroup = "admin";
};
};
networking.firewall = mkIf cfg.enable {
interfaces.tailscale0.allowedTCPPorts = [cfg.port];
interfaces.local.allowedTCPPorts = [cfg.port];
};
}

View file

@ -4,6 +4,8 @@
"/rpool/shared/nix/store nix/store none bind,create=dir",
"/rpool/shared/nix/var nix/var none bind,create=dir",
"/rpool/shared/minecraft/bedrock mnt/shared/minecraft/bedrock none bind,optional,create=dir",
"/rpool/shared/minecraft/katsink mnt/shared/minecraft/katsink none bind,optional,create=dir",
"/mnt/kyuuto-data/minecraft mnt/kyuuto-data/minecraft none bind,optional,create=dir",
"/dev/net/tun dev/net/tun none bind,optional,create=file"
],
"lxc.idmap": [

View file

@ -11,8 +11,8 @@ _: {
];
network.networks = {
tail = {
address4 = "100.70.124.79";
address6 = "fd7a:115c:a1e0::b001:7c4f";
address4 = "100.73.157.122";
address6 = "fd7a:115c:a1e0::1f01:9d7a";
};
};
exports = {

View file

@ -1,8 +1,22 @@
{
"lxc": {
"lxc.mount.entry": [
"/rpool/shared/minecraft/katsink mnt/shared/minecraft/katsink none bind,optional,create=dir",
"/mnt/kyuuto-data/minecraft mnt/kyuuto-data/minecraft none bind,optional,create=dir",
"/mnt/kyuuto-minecraft mnt/kyuuto-minecraft none bind,optional,create=dir",
"/dev/net/tun dev/net/tun none bind,optional,create=file"
],
"lxc.idmap": [
"u 0 100000 8000",
"g 0 100000 8000",
"u 8000 8000 128",
"g 8000 8000 256",
"u 8128 108128 57406",
"g 8256 108256 57278",
"u 65534 65534 1",
"g 65534 65534 1",
"u 65535 165535 1",
"g 65535 165535 1"
]
}
}

View file

@ -1,20 +1,21 @@
{meta, pkgs, ...}:{
{
meta,
config,
...
}: {
imports = let
inherit (meta) nixos;
in [
nixos.sops
nixos.reisen-ct
nixos.tailscale
nixos.minecraft.katsink
];
environment.systemPackages = with pkgs; [
jre
tmux
environment.systemPackages = [
config.services.minecraft-katsink-server.jre.package
];
networking.firewall.interfaces.tailscale0.allowedTCPPorts = [ 25565 ];
networking.firewall.interfaces.local.allowedTCPPorts = [ 25565 ];
sops = {
defaultSopsFile = ./secrets.yaml;
secrets.tailscale-key.key = "tailscale-key";

View file

@ -1,6 +1,6 @@
_: {
proxmox = {
vm.id = 106;
vm.id = 109;
container = {
enable = true;
lxc.configJsonFile = ./lxc.json;
@ -8,11 +8,10 @@ _: {
network.interfaces = {
net0 = {
mdns.enable = true;
macAddress = "BC:24:11:C4:66:AB";
address4 = "dhcp";
macAddress = "BC:24:11:C4:66:AD";
address4 = "10.1.1.51/24";
address6 = "auto";
};
net1.internal.enable = true;
};
};
}

View file

@ -100,31 +100,51 @@ if [[ ! -d /rpool/caches ]]; then
zfs create rpool/caches
fi
mkrpool() {
local SHARED_PATH SHARED_MODE SHARED_OWNER SHARED_GROUP
SHARED_PATH=$1
SHARED_OWNER=$2
SHARED_GROUP=$3
SHARED_MODE=$4
mkzfs() {
local ZFS_PATH ZFS_MODE ZFS_OWNER ZFS_GROUP
ZFS_PATH=$1
ZFS_OWNER=$2
ZFS_GROUP=$3
ZFS_MODE=$4
shift 4
if [[ ! -d "/rpool/$SHARED_PATH" ]]; then
zfs create "rpool/$SHARED_PATH"
ZFS_NAME=${ZFS_PATH#/}
if [[ $# -gt 0 ]]; then
ZFS_NAME=$1
shift
fi
chmod "$SHARED_MODE" "/rpool/$SHARED_PATH"
chown "$SHARED_OWNER:$SHARED_GROUP" "/rpool/$SHARED_PATH"
ZFS_ARGS=("$@")
if [[ $ZFS_NAME != ${ZFS_PATH#/} ]]; then
ZFS_ARGS+=(-o "mountpoint=$ZFS_PATH")
fi
if [[ ! -d "$ZFS_PATH" ]]; then
zfs create "$ZFS_NAME" ${ZFS_ARGS[@]+"${ZFS_ARGS[@]}"}
fi
chmod "$ZFS_MODE" "$ZFS_PATH"
chown "$ZFS_OWNER:$ZFS_GROUP" "$ZFS_PATH"
}
mkshared() {
local SHARED_PATH=$1
shift
mkrpool "shared/$SHARED_PATH" "$@"
mkzfs "/rpool/shared/$SHARED_PATH" "$@"
}
mkcache() {
local SHARED_PATH=$1
local CACHE_PATH=$1
shift
mkrpool "caches/$SHARED_PATH" "$@"
mkzfs "/rpool/caches/$CACHE_PATH" "$@"
}
mkkyuuto() {
local KYUUTO_PATH KYUUTO_ARGS=()
KYUUTO_NAME=$1
KYUUTO_ARGS=("$2" "$3" "$4")
shift 4
mkzfs "/mnt/kyuuto-$KYUUTO_NAME" "${KYUUTO_ARGS[@]}" "kyuuto/$KYUUTO_NAME" "$@"
}
mkshared nix 0 0 0755
@ -163,6 +183,15 @@ mkshared zigbee2mqtt 100317 100317 0700
mkshared vaultwarden 100915 100915 0750
mkshared minecraft 100913 100913 0750
mkshared minecraft/bedrock 100913 100913 0750
mkshared minecraft/katsink 100913 100913 0750
mkkyuuto data 0 0 0755 -o compression=on
mkkyuuto data/minecraft 0 8126 0775
if [[ ! -d /mnt/kyuuto-data/minecraft/simplebackups ]]; then
mkdir -p /mnt/kyuuto-data/minecraft/simplebackups
fi
chown 100913:8126 /mnt/kyuuto-data/minecraft/simplebackups
chmod 0775 /mnt/kyuuto-data/minecraft/simplebackups
ln -sf /lib/systemd/system/auth-rpcgss-module.service /etc/systemd/system/
mkdir -p /etc/systemd/system/auth-rpcgss-module.service.d

View file

@ -151,6 +151,24 @@
}
}
},
"minecraft": {
"hostName": "minecraft",
"network": {
"networks": {
"int": null,
"local": {
"address4": "10.1.1.51",
"address6": "fd0a::be24:11ff:fec4:66ad",
"macAddress": "BC:24:11:C4:66:AD"
},
"tail": {
"address4": "100.73.157.122",
"address6": "fd7a:115c:a1e0::1f01:9d7a",
"macAddress": null
}
}
}
},
"reimu": {
"hostName": "reimu",
"network": {

View file

@ -92,6 +92,13 @@ module "aya_system_records" {
]
}
module "minecraft_system_records" {
source = "./system/records"
zone_id = cloudflare_zone.gensokyo-zone_zone.id
zone_zone = cloudflare_zone.gensokyo-zone_zone.zone
net_data = local.systems.minecraft.network
}
module "tewi_system_records" {
source = "./system/records"
zone_id = cloudflare_zone.gensokyo-zone_zone.id

View file

@ -784,15 +784,8 @@ EOT
address = "auto"
}
ipv4 {
address = "dhcp"
}
}
ip_config {
ipv6 {
address = "${cidrhost(local.reisen_int_prefix6, local.proxmox_minecraft_vm_id - local.reisen_int_offset)}/64"
}
ipv4 {
address = "${cidrhost(local.reisen_int_prefix4, local.proxmox_minecraft_vm_id - local.reisen_int_offset)}/24"
address = "10.1.1.51/24"
gateway = "10.1.1.1"
}
}
}
@ -807,11 +800,6 @@ EOT
name = "eth0"
mac_address = "BC:24:11:C4:66:AD"
}
network_interface {
name = "eth9"
mac_address = "BC:24:19:C4:66:AD"
bridge = proxmox_virtual_environment_network_linux_bridge.internal.name
}
operating_system {
template_file_id = var.proxmox_container_template

View file

@ -2,6 +2,7 @@ locals {
tailscale_tag_infra = "tag:infrastructure"
tailscale_tag_genso = "tag:gensokyo"
tailscale_tag_reisen = "tag:reisen"
tailscale_tag_minecraft = "tag:minecraft"
tailscale_tag_arc = "tag:arc"
tailscale_tag_arc_deploy = "tag:arc-deploy"
@ -11,7 +12,14 @@ locals {
tailscale_user_arc = "arc@${var.tailscale_tailnet}"
tailscale_user_kat = "kat@${var.tailscale_tailnet}"
tailscale_group_member = "autogroup:member"
tailscale_group_admin = "autogroup:admin"
tailscale_tags_genso = [local.tailscale_tag_infra, local.tailscale_tag_genso]
tailscale_tags_reisen = concat(local.tailscale_tags_genso, [local.tailscale_tag_reisen])
tailscale_tags_arc = [local.tailscale_user_arc, local.tailscale_tag_arc]
tailscale_tags_kat = [local.tailscale_user_kat, local.tailscale_tag_kat]
tailscale_tags_peeps = concat(local.tailscale_tags_arc, local.tailscale_tags_kat)
}
resource "tailscale_acl" "tailnet" {
@ -20,6 +28,7 @@ resource "tailscale_acl" "tailnet" {
"${local.tailscale_tag_infra}" : [local.tailscale_group_admin],
"${local.tailscale_tag_reisen}" : [local.tailscale_group_admin, local.tailscale_tag_infra],
"${local.tailscale_tag_genso}" : [local.tailscale_group_admin, local.tailscale_tag_arc_deploy, local.tailscale_tag_kat_deploy],
"${local.tailscale_tag_minecraft}" : [local.tailscale_group_admin, local.tailscale_tag_infra],
"${local.tailscale_tag_arc}" : [local.tailscale_user_arc, local.tailscale_tag_arc_deploy],
"${local.tailscale_tag_arc_deploy}" : [local.tailscale_user_arc],
"${local.tailscale_tag_kat}" : [local.tailscale_user_kat, local.tailscale_tag_kat_deploy],
@ -27,10 +36,34 @@ resource "tailscale_acl" "tailnet" {
}
acls = [
{
# Allow all connections
action = "accept"
src = [local.tailscale_group_admin]
dst = ["*:*"]
},
{
action = "accept"
src = [local.tailscale_tag_reisen]
dst = ["${local.tailscale_tag_reisen}:*"]
},
{
action = "accept"
src = concat([local.tailscale_tag_genso], local.tailscale_tags_peeps)
dst = [
"${local.tailscale_tag_genso}:*",
]
},
{
action = "accept"
src = ["*"]
dst = ["*:*"]
dst = [
"autogroup:self:*",
"${local.tailscale_tag_minecraft}:19132,19133,25565",
]
},
{
action = "accept"
src = [local.tailscale_group_member]
dst = ["autogroup:internet:*"]
},
]
# Define users and devices that can use Tailscale SSH.
@ -38,7 +71,7 @@ resource "tailscale_acl" "tailnet" {
# Allow all users to SSH into their own devices in check mode.
{
action = "check",
src = ["autogroup:member"],
src = [local.tailscale_group_member],
dst = ["autogroup:self"],
users = ["autogroup:nonroot", "root"],
},
@ -51,7 +84,7 @@ resource "tailscale_tailnet_key" "reisen" {
ephemeral = false
preauthorized = true
description = "Reisen VM"
tags = [local.tailscale_tag_infra, local.tailscale_tag_genso, local.tailscale_tag_reisen]
tags = local.tailscale_tags_reisen
depends_on = [tailscale_acl.tailnet]
}
@ -60,7 +93,7 @@ resource "tailscale_tailnet_key" "gensokyo" {
ephemeral = false
preauthorized = true
description = "Reisen VM"
tags = [local.tailscale_tag_infra, local.tailscale_tag_genso]
tags = local.tailscale_tags_genso
depends_on = [tailscale_acl.tailnet]
}