initial opencode commit
This commit is contained in:
146
README.md
Normal file
146
README.md
Normal file
@@ -0,0 +1,146 @@
|
||||
# Hardened Fedora Minecraft Server (Ansible)
|
||||
|
||||
Ansible playbook that turns a fresh **Fedora 42** server into a hardened,
|
||||
containerized **Minecraft** game server — Java *and* Bedrock clients —
|
||||
running with **rootless Podman** via systemd Quadlet units.
|
||||
|
||||
Everything is managed declaratively from `harden_fedora_minecraft.yml`:
|
||||
OS hardening, firewall, SELinux, SSH access control, the Podman runtime,
|
||||
and the Minecraft/Geyser containers are all deployed by one command.
|
||||
|
||||
## Features
|
||||
|
||||
- 🔒 **[Hardening]** SELinux enforcing, firewalld default-DROP policy, password
|
||||
policy (pwquality + aging), root account locked, automatic security updates
|
||||
(`dnf-automatic`).
|
||||
- 🔑 **[SSH]** Key-only authentication for a dedicated admin user, root login
|
||||
disabled, `AllowUsers` restriction, and a `fail2ban` SSH jail.
|
||||
- 🐳 **[Runtime]** Rootless Podman with user lingering, subuid/subgid ranges,
|
||||
IPv4 forwarding, and the overlay storage driver.
|
||||
- ⛏️ **[Minecraft]** Portable Java server built from
|
||||
[`itzg/docker-minecraft-server`](https://github.com/itzg/docker-minecraft-server)
|
||||
(PAPER by default, version/memory/difficulty configurable).
|
||||
- 🪨 **[Geyser]** A second container, [`geysermc/geyser`](https://github.com/GeyserMC/geyser-docker),
|
||||
in the same pod so **Bedrock** (phone/console) players can join the Java world.
|
||||
- 🗄️ **[Data]** World data and backups live on the host in `/srv/minecraft`
|
||||
with correct SELinux labels.
|
||||
|
||||
## Architecture
|
||||
|
||||
Both game containers run in a single Podman **pod** (shared network
|
||||
namespace) as the non-root user `mcadmin`:
|
||||
|
||||
```
|
||||
Internet
|
||||
│
|
||||
┌───────┴────────┐
|
||||
│ firewall (DROP)│ only the ports below are allowed
|
||||
└───────┬────────┘
|
||||
│
|
||||
pod: minecraft (rootless, user mcadmin)
|
||||
├── minecraft-server JVM on 0.0.0.0:25565 (Java clients)
|
||||
│ └── world data → /srv/minecraft/data
|
||||
└── geyser Bedrock listener :19132/udp
|
||||
└── config → /srv/minecraft/geyser
|
||||
└── forwards Bedrock players to 127.0.0.1:25565
|
||||
```
|
||||
|
||||
| Port | Protocol | Purpose |
|
||||
|------|----------|---------|
|
||||
| `22` | TCP | SSH (configurable via `ssh_port`) |
|
||||
| `25565` | TCP | Minecraft Java server |
|
||||
| `25565` | UDP | Optional Java server UDP (game query) |
|
||||
| `19132` | UDP | Bedrock (Geyser), when `enable_geyser: true` |
|
||||
|
||||
## Repository layout
|
||||
|
||||
```
|
||||
.
|
||||
├── harden_fedora_minecraft.yml # entry point: hosts: external-apps → 7 roles
|
||||
├── inventory.yml # target host definition
|
||||
├── ansible.cfg # inventory + role path + pipelining
|
||||
├── requirements.yml # Ansible collections (ansible.posix)
|
||||
├── group_vars/all.yml # shared variables
|
||||
├── host_vars/external-apps.yml # per-server settings (IP, SSH key, MC tuning)
|
||||
└── roles/
|
||||
├── packages/ # base + container tooling, full dnf update, dnf-automatic
|
||||
├── firewall/ # firewalld: DROP target, open SSH + Minecraft + Geyser
|
||||
├── selinux/ # enforcing mode + container_file_t context for /srv/minecraft
|
||||
├── auth/ # admin user, SSH key, sudoers, password policy, lock root
|
||||
├── ssh_harden/ # sshd drop-in + fail2ban jail
|
||||
├── podman/ # socket, linger, subuid/subgid, ip_forward, storage
|
||||
└── minecraft/ # data dirs, Quadlet pod/container units, image pulls
|
||||
```
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Ansible control node (this repo) with Ansible Core ≥ 2.14 and `ansible.posix`
|
||||
- A Fedora 42 target server reachable over SSH with an account that has sudo
|
||||
- The `ansible.user` in the inventory must be able to `become` root on the target
|
||||
|
||||
## Quick start
|
||||
|
||||
```bash
|
||||
# 1. Install the required collection
|
||||
ansible-galaxy collection install -r requirements.yml
|
||||
|
||||
# 2. Configure the target server (REQUIRED before first run)
|
||||
# - host_vars/external-apps.yml
|
||||
# * ansible_host: real IP or DNS name
|
||||
# * admin_user_ssh_key: your real SSH public key
|
||||
# * game settings to taste (version, memory, whitelist…)
|
||||
|
||||
# 3. Run the playbook
|
||||
ansible-playbook harden_fedora_minecraft.yml
|
||||
```
|
||||
|
||||
> ⚠️ `admin_user_ssh_key` **must** be a real key before the first run —
|
||||
> the playbook disables SSH password authentication and root login once
|
||||
> the `ssh_harden` role executes.
|
||||
|
||||
## Configuration
|
||||
|
||||
All tunables live in `host_vars/external-apps.yml` (per server) and
|
||||
`group_vars/all.yml` (cluster-wide). Highlights:
|
||||
|
||||
| Variable | Default | Meaning |
|
||||
|----------|---------|---------|
|
||||
| `admin_user` | `mcadmin` | Non-root user running the containers |
|
||||
| `minecraft_version` | `LATEST` | Server version (`1.21.1`, …) |
|
||||
| `minecraft_server_type` | `PAPER` | PAPER / VANILLA / FABRIC / FORGE |
|
||||
| `minecraft_memory` | `2G` | JVM memory limit |
|
||||
| `minecraft_whitelist` | `""` | Comma-separated allowed usernames (empty = off) |
|
||||
| `enable_geyser` | `true` | Deploy the Bedrock bridge |
|
||||
| `geyser_port` | `19132` | Bedrock UDP port |
|
||||
| `geyser_auth_type` | `online` | `offline` only with a paired Floodgate key |
|
||||
| `ssh_port` | `22` | SSH port used by firewall + sshd |
|
||||
|
||||
## Operations
|
||||
|
||||
After the playbook has run, manage the servers as `mcadmin`:
|
||||
|
||||
```bash
|
||||
sudo machinectl shell mcadmin@ -- systemctl --user status minecraft-server geyser
|
||||
sudo machinectl shell mcadmin@ -- systemctl --user restart minecraft-server
|
||||
sudo machinectl shell mcadmin@ -- podman ps # container list
|
||||
sudo machinectl shell mcadmin@ -- journalctl --user-unit minecraft-server -f
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
- [Ansible Documentation](https://docs.ansible.com/)
|
||||
- [Fedora Project](https://fedoraproject.org/)
|
||||
- [Podman](https://podman.io/)
|
||||
- [Podman Quadlet (systemd.unit) man page](https://docs.podman.io/en/latest/markdown/podman-systemd.unit.5.html)
|
||||
- [Rootless Podman tutorial](https://github.com/containers/podman/blob/main/docs/tutorials/rootless_tutorial.md)
|
||||
- [itzg/docker-minecraft-server](https://github.com/itzg/docker-minecraft-server)
|
||||
- [GeyserMC — Bedrock ↔ Java bridge](https://geysermc.dev/)
|
||||
- [GeyserMC/Geyser](https://github.com/GeyserMC/Geyser)
|
||||
- [Geyser docker image](https://github.com/GeyserMC/geyser-docker)
|
||||
- [Firewalld](https://firewalld.org/)
|
||||
- [fail2ban](https://github.com/fail2ban/fail2ban)
|
||||
- [SELinux quick docs (Fedora)](https://docs.fedoraproject.org/en-US/quick-docs/selinux-getting-started/)
|
||||
|
||||
## License
|
||||
|
||||
[MIT](./LICENSE)
|
||||
Reference in New Issue
Block a user