diff --git a/agenix.nix b/agenix.nix index 0c70114..c0aba61 100644 --- a/agenix.nix +++ b/agenix.nix @@ -38,10 +38,4 @@ group = "grafana"; mode = "0400"; }; - - age.secrets.minecraft-seed = { - file = ./secrets/minecraft-seed.age; - owner = "root"; - mode = "0400"; - }; } diff --git a/configuration.nix b/configuration.nix index ee25c38..960006b 100644 --- a/configuration.nix +++ b/configuration.nix @@ -1,8 +1,7 @@ -{ config, pkgs, inputs, modulesPath, ... }: +{ config, pkgs, inputs, ... }: { imports = [ - (modulesPath + "/profiles/qemu-guest.nix") ./agenix.nix ./modules/minecraft.nix ./modules/hardening.nix @@ -43,6 +42,16 @@ htop tmux rsync + + (writeShellScriptBin "mc-whitelist" '' + docker exec minecraft rcon-cli whitelist add "$1" + '') + (writeShellScriptBin "mc-cmd" '' + docker exec minecraft rcon-cli "$@" + '') + (writeShellScriptBin "mc-logs" '' + docker logs --tail "''${1:-100}" -f minecraft + '') ]; users.users.root.openssh.authorizedKeys.keys = [ diff --git a/flake.nix b/flake.nix index 877b947..1056b73 100644 --- a/flake.nix +++ b/flake.nix @@ -17,25 +17,19 @@ let system = "x86_64-linux"; pkgs = nixpkgs.legacyPackages.${system}; + serverHost = "root@compsigh-minecraft"; + deploy = pkgs.writeShellScriptBin "nhs" '' nh os switch --hostname compsigh-minecraft --target-host root@compsigh-minecraft path:. "$@" ''; - mcLogs = pkgs.writeShellScriptBin "mc-logs" '' - ssh root@compsigh-minecraft "docker logs --tail ''${1:-100} -f minecraft" + mcWhitelist = pkgs.writeShellScriptBin "mc-whitelist" '' + ssh ${serverHost} "docker exec minecraft rcon-cli whitelist add $1" ''; - bootstrap = pkgs.writeShellScriptBin "mc-bootstrap" '' - set -euo pipefail - IP="''${1:?Usage: mc-bootstrap }" - echo "==> Installing NixOS (bootstrap config with port 22 open)..." - nix run github:nix-community/nixos-anywhere -- --flake path:.#compsigh-minecraft-bootstrap "root@$IP" - echo "" - echo "==> Removing old host key..." - ssh-keygen -R "$IP" - echo "" - echo "==> Fetching new server host key..." - echo "Run: ssh root@$IP cat /etc/ssh/ssh_host_ed25519_key.pub" - echo "Then update secrets/secrets.nix with the new key and run: agenix -r" - echo "Then run: nhs" + mcCmd = pkgs.writeShellScriptBin "mc-cmd" '' + ssh ${serverHost} "docker exec minecraft rcon-cli $*" + ''; + mcLogs = pkgs.writeShellScriptBin "mc-logs" '' + ssh ${serverHost} "docker logs --tail ''${1:-100} -f minecraft" ''; in { @@ -50,25 +44,11 @@ ]; }; - # Bootstrap config: opens port 22 on public interface for initial setup - nixosConfigurations.compsigh-minecraft-bootstrap = nixpkgs.lib.nixosSystem { - inherit system; - specialArgs = { inherit inputs; }; - modules = [ - disko.nixosModules.disko - inputs.agenix.nixosModules.default - ./disk-config.nix - ./configuration.nix - { - networking.firewall.allowedTCPPorts = [ 22 ]; - } - ]; - }; - devShells.${system}.default = pkgs.mkShell { packages = [ deploy - bootstrap + mcWhitelist + mcCmd mcLogs pkgs.nh inputs.agenix.packages.${system}.default @@ -76,8 +56,9 @@ shellHook = '' echo "compsigh minecraft server" - echo " mc-bootstrap — first-time install (mc-bootstrap )" echo " nhs — deploy to server" + echo " mc-whitelist — add a player (mc-whitelist PlayerName)" + echo " mc-cmd — run rcon command (mc-cmd whitelist list)" echo " mc-logs — tail server logs" echo " agenix — manage secrets" ''; diff --git a/modules/caddy.nix b/modules/caddy.nix index 6c26b2c..5d240dc 100644 --- a/modules/caddy.nix +++ b/modules/caddy.nix @@ -12,8 +12,6 @@ in # minecraft.compsigh.club → redirect to git repo "${domain}" = { extraConfig = '' - redir /terms ${gitRepo}/blob/main/terms.txt permanent - redir /privacy ${gitRepo}/blob/main/privacy.txt permanent redir ${gitRepo} permanent ''; }; diff --git a/modules/discord.nix b/modules/discord.nix index 6ed876b..59ffa8d 100644 --- a/modules/discord.nix +++ b/modules/discord.nix @@ -27,17 +27,11 @@ in "channelId": "1482486447591391285", "consoleLogChannelId": "1482487413153464330", "useWebhook": true, - "updateChannelTopic": true, - "channelTopicUpdateInterval": 300000, - "allowedMentions": ["users", "roles"], - "broadcastPlayerCommandExecution": false, "announceServerStartStop": true, "announcePlayerJoinLeave": true, "announceDeathMessages": true, "announceAdvancements": true, "broadcastChatMessages": true, - "notifyUpdates": false, - "mentionAdminsForUpdates": false, "adminsIds": [ "1008533670426050704", "839601350865584158", diff --git a/modules/hardening.nix b/modules/hardening.nix index 9233354..9967e54 100644 --- a/modules/hardening.nix +++ b/modules/hardening.nix @@ -7,7 +7,6 @@ allowedTCPPorts = [ 80 443 25565 ]; # Caddy HTTP/HTTPS + Minecraft allowedUDPPorts = [ 24454 ]; # Simple Voice Chat trustedInterfaces = [ "tailscale0" ]; # Full access over Tailscale (SSH, etc.) - checkReversePath = "loose"; # Required for Tailscale logRefusedConnections = true; }; diff --git a/modules/minecraft.nix b/modules/minecraft.nix index 6770ba6..034d2b9 100644 --- a/modules/minecraft.nix +++ b/modules/minecraft.nix @@ -51,12 +51,10 @@ let # QoL "oneplayersleep" "netherportalfix" - "blossomlib" - "blossomtpa" - "double-shulker-shell-drops" - "afkplus" # Moderation + "luckperms" + "banhammer" "ledger" "styled-chat" @@ -105,19 +103,15 @@ in MEMORY = "2560M"; MAX_PLAYERS = "10"; DIFFICULTY = "hard"; - PVP = "FALSE"; VIEW_DISTANCE = "10"; SIMULATION_DISTANCE = "10"; ENABLE_WHITELIST = "TRUE"; ENFORCE_WHITELIST = "TRUE"; WHITELIST = "jetpham"; - OPS = "jetpham"; - MOTD = "meet cool people \\u00A7e\\u0026\\u0026\\u00A7r build cool things"; - OVERRIDE_ICON = "TRUE"; + MOTD = "meet cool people \\u0026\\u0026 build cool things"; MODRINTH_PROJECTS = modrinthMods; JVM_XX_OPTS = jvmFlags; }; - environmentFiles = [ "/run/minecraft-seed.env" ]; extraOptions = [ "--memory=3g" "--cpus=2" @@ -132,26 +126,14 @@ in "d ${mcDataDir} 0755 root root -" ]; - # Write seed env file and copy mod configs before container starts + # Copy Chunky config (concurrency: 1 for background generation) systemd.services.minecraft-mod-configs = { - description = "Set up mod configs and seed for Minecraft container"; + description = "Copy mod configs into Minecraft data volume"; wantedBy = [ "multi-user.target" ]; before = [ "docker-minecraft.service" ]; - after = [ "agenix.service" ]; serviceConfig = { Type = "oneshot"; ExecStart = pkgs.writeShellScript "setup-mod-configs" '' - set -euo pipefail - - # Write seed from agenix secret - SEED=$(cat ${config.age.secrets.minecraft-seed.path}) - printf 'SEED=%s\n' "$SEED" > /run/minecraft-seed.env - chmod 600 /run/minecraft-seed.env - - # Server icon - cp ${../server-icon.png} ${mcDataDir}/server-icon.png - - # Mod configs mkdir -p ${mcDataDir}/plugins/Chunky cp ${../configs/chunky.yml} ${mcDataDir}/plugins/Chunky/config.yml diff --git a/privacy.txt b/privacy.txt deleted file mode 100644 index 6c39b2a..0000000 --- a/privacy.txt +++ /dev/null @@ -1,45 +0,0 @@ -compsigh Minecraft — Privacy Policy - -Last updated: 2026-03-14 - -1. What We Collect - - Minecraft username and UUID (required to join the server) - - Discord username and user ID (used for chat bridging and admin - commands) - - Chat messages sent in-game and in the bridged Discord channel - (relayed between platforms in real time) - - In-game actions (block placement, breakage, chest access, etc.) - logged by the Ledger mod for grief prevention - - Server logs (connection IPs, join/leave times, errors) - -2. How Data Is Used - - Chat messages are bridged between Minecraft and Discord and are - visible in both platforms. - - Action logs are used solely for grief investigation and rollback. - - Server logs are used for debugging and moderation. - - Admin Discord user IDs are stored in the bot configuration to - control who can run server commands from Discord. - -3. Data Storage - - World data and action logs are stored on the server and backed up - to Backblaze B2 cloud storage. - - Chat messages are stored by Discord per their own retention - policies. The server does not independently archive chat. - - Server logs are stored on the server and rotate automatically. - -4. Data Sharing - We do not sell, share, or provide your data to any third party. - Backblaze B2 is used solely for encrypted backup storage. - -5. Data Retention - - World backups are retained per our Backblaze B2 lifecycle policy. - - Server logs are retained for up to 30 days. - - In-game action logs persist in the world data indefinitely. - -6. Your Rights - You may request to see what data we have about you or ask for its - deletion by contacting a server admin on Discord. Deleting your - data may require removing you from the whitelist. - -7. Contact - For privacy questions, reach out to a server admin on Discord. diff --git a/secrets/minecraft-seed.age b/secrets/minecraft-seed.age deleted file mode 100644 index 450536e..0000000 Binary files a/secrets/minecraft-seed.age and /dev/null differ diff --git a/secrets/secrets.nix b/secrets/secrets.nix index 6047b84..699f013 100644 --- a/secrets/secrets.nix +++ b/secrets/secrets.nix @@ -9,5 +9,4 @@ in "b2-application-key.age".publicKeys = [ server admin ]; "grafana-admin-password.age".publicKeys = [ server admin ]; "grafana-secret-key.age".publicKeys = [ server admin ]; - "minecraft-seed.age".publicKeys = [ server admin ]; } diff --git a/server-icon.png b/server-icon.png deleted file mode 100644 index f7a6e7d..0000000 Binary files a/server-icon.png and /dev/null differ diff --git a/terms.txt b/terms.txt deleted file mode 100644 index dcbde9b..0000000 --- a/terms.txt +++ /dev/null @@ -1,32 +0,0 @@ -compsigh Minecraft — Terms of Service - -Last updated: 2026-03-14 - -1. Acceptance - By joining the compsigh Minecraft server or interacting with the - compsigh Minecraft Discord bot, you agree to these terms and the - compsigh Code of Conduct: https://compsigh.club/docs/code-of-conduct - -2. Minecraft Server Rules - In addition to the compsigh Code of Conduct: - - No griefing, cheating, or exploiting. - - Server admins reserve the right to ban players at their discretion. - -3. Access - The server is whitelist-only. Access may be granted or revoked at - any time without notice. - -4. Availability - The server is provided as-is with no uptime guarantees. It may go - offline for maintenance, updates, or any other reason. - -5. Data - See our Privacy Policy for details on what data is collected and how - it is used. - -6. Changes - These terms may be updated at any time. Continued use of the server - constitutes acceptance of any changes. - -7. Contact - For questions, reach out to a server admin on Discord.