# 🐡 Crumbcore FreeBSD Naked Setup Guide

**Version:** 1.0  
**Target:** Production RZ mit BSI/ISO Requirements  
**Philosophy:** Minimalistisch, Sicher, Transparent  

> *"In FreeBSD fließt das Grundwasser klar - jede Konfiguration ist sichtbar, jede Entscheidung bewusst."* 🦉

---

## 📋 Inhaltsverzeichnis

1. [Einleitung](#einleitung)
2. [Base System Installation](#base-system-installation)
3. [Encrypted Home Setup](#encrypted-home-setup)
4. [SSH Hardening](#ssh-hardening)
5. [Key Management & Agent](#key-management--agent)
6. [Netzwerk ohne DHCP](#netzwerk-ohne-dhcp)
7. [Crumbcore Integration](#crumbcore-integration)
8. [Security Checkliste](#security-checkliste)

---

## 🎯 Einleitung

### Warum FreeBSD für Crumbcore?

**Technische Gründe:**
- 🔒 Security by default (jails, MAC framework)
- 📜 Klare Dokumentation (man pages sind Bibel)
- 🛡️ ZFS native (snapshots, encryption)
- ⚙️ Ports/Packages transparent
- 🧪 Predictable behavior (kein systemd!)

**Philosophische Gründe:**
- 💎 "Code is read more than written"
- 🌲 Unix-Philosophie pur
- 🦉 Langfristige Stabilität
- 📊 Ideal für kritische Infrastruktur

### Voraussetzungen

```bash
Hardware:
- CPU: x86_64 (amd64)
- RAM: min. 2GB (empfohlen 4GB+)
- Disk: min. 20GB (empfohlen SSD)
- Network: Ethernet (kein WLAN für RZ!)

Skills:
- Unix Grundlagen
- Vi/Vim Basics
- Netzwerk Basics (CIDR, Routing)
```

---

## 🔧 Base System Installation

### 1. FreeBSD Installer starten

```bash
# Boot von USB/ISO
# Installer-Menü erscheint

# Wähle: Install
# Keymap: German (de.kbd) oder US
# Hostname: crumbcore-rz01.local
```

### 2. Partitionierung (Manual/ZFS)

**Für BSI/ISO Setup: ZFS mit Encryption!**

```bash
# ZFS Auto-Setup wählen:
# → Encrypt Disks? YES
# → Encryption Algorithm: AES-256-GCM
# → Pool name: zroot

# Partition Layout:
ada0
├── freebsd-boot  (512KB)  # GPT boot
├── efi           (200MB)  # EFI System Partition
└── freebsd-zfs   (Rest)   # ZFS pool (encrypted)

# Encryption Passphrase eingeben!
# WICHTIG: Sicher aufbewahren (nicht im System!)
```

**ZFS Pool Struktur:**
```
zroot
├── ROOT/default           # OS
├── home                   # User homes (extra encrypted!)
├── var
│   ├── log
│   ├── tmp
│   └── audit              # BSI requirement!
└── usr/local              # Packages
```

### 3. Base System Konfiguration

```bash
# Nach Installation, vor erstem Boot:

# Root Password setzen
passwd

# Network: SPÄTER (kein DHCP!)
# Skip für jetzt

# Time Zone
tzsetup
# → Europe/Berlin

# Services aktivieren
sysrc sshd_enable="YES"
sysrc ntpd_enable="YES"
sysrc ntpd_sync_on_start="YES"

# Security Services
sysrc sendmail_enable="NONE"
sysrc sendmail_submit_enable="NO"
sysrc sendmail_outbound_enable="NO"
sysrc sendmail_msp_queue_enable="NO"

# System Hardening (gleich aktivieren!)
sysrc clear_tmp_enable="YES"
sysrc icmp_drop_redirect="YES"
sysrc icmp_log_redirect="YES"
```

---

## 🔐 Encrypted Home Setup

### Warum Extra Encryption?

```
ZFS-Encryption    → Schutz bei Disk-Diebstahl
GELI für /home    → Schutz bei laufendem System
SSH Key-Phrase    → Schutz bei Mem-Dump

= Defense in Depth! 🛡️
```

### Setup mit GELI (alternative zu ZFS native encryption)

```bash
# 1. GELI Provider erstellen
zfs create -V 50G zroot/home-encrypted

# 2. GELI initialisieren
geli init -s 4096 -l 256 /dev/zvol/zroot/home-encrypted
# → Passphrase eingeben (STARK!)

# 3. GELI Provider attachen
geli attach /dev/zvol/zroot/home-encrypted
# → Passphrase eingeben

# 4. Filesystem erstellen
newfs -U /dev/zvol/zroot/home-encrypted.eli

# 5. Mounten
mount /dev/zvol/zroot/home-encrypted.eli /home

# 6. /etc/fstab Eintrag
echo '/dev/zvol/zroot/home-encrypted.eli /home ufs rw,noatime 2 2' >> /etc/fstab
```

### User erstellen

```bash
# Admin User (wheel group!)
pw useradd crumbadmin -m -G wheel -s /bin/sh -d /home/crumbadmin
passwd crumbadmin

# Service User (für Crumbcore)
pw useradd crumbcore -m -s /usr/sbin/nologin -d /home/crumbcore -c "Crumbcore Service User"

# Permissions
chmod 700 /home/crumbadmin
chmod 700 /home/crumbcore
```

---

## 🔑 SSH Hardening

### 1. SSH Config (`/etc/ssh/sshd_config`)

```bash
# Backup original
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.orig

# Edit config
vi /etc/ssh/sshd_config
```

**Minimale BSI-konforme Config:**

```conf
# /etc/ssh/sshd_config - Crumbcore Production

# Network
Port 22
AddressFamily inet
ListenAddress 0.0.0.0

# Authentication
PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication no
PermitEmptyPasswords no
ChallengeResponseAuthentication no
UsePAM yes

# Crypto (BSI TR-02102-4 konform)
KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group16-sha512
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes256-ctr
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com

# Limits
LoginGraceTime 60
MaxAuthTries 3
MaxSessions 3
MaxStartups 3:50:10

# Security
X11Forwarding no
PrintMotd no
PrintLastLog yes
TCPKeepAlive yes
ClientAliveInterval 300
ClientAliveCountMax 2
UseDNS no
PermitUserEnvironment no
StrictModes yes

# Logging (BSI requirement!)
SyslogFacility AUTH
LogLevel VERBOSE

# AllowUsers (Whitelist!)
AllowUsers crumbadmin

# Subsystem
Subsystem sftp /usr/libexec/sftp-server
```

### 2. SSH Service starten

```bash
# Syntax check
sshd -t

# Start SSH
service sshd start

# Check status
service sshd status
sockstat -4l | grep :22
```

---

## 🔐 Key Management & Agent

### 1. SSH Keys generieren (auf Client!)

```bash
# Auf deinem Admin-Laptop/Workstation:

# ED25519 (modern, sicher, schnell)
ssh-keygen -t ed25519 -C "crumbadmin@crumbcore-rz01" -f ~/.ssh/crumbcore-rz01

# Passphrase: JA! (Defense in depth)
Enter passphrase (empty for no passphrase): [strong passphrase!]

# Output:
~/.ssh/crumbcore-rz01      # Private key (NIEMALS teilen!)
~/.ssh/crumbcore-rz01.pub  # Public key (geht auf Server)
```

### 2. Public Key auf Server kopieren

**Methode 1: ssh-copy-id (wenn Passwort noch aktiv)**
```bash
# Vom Client:
ssh-copy-id -i ~/.ssh/crumbcore-rz01.pub crumbadmin@<SERVER-IP>
```

**Methode 2: Manuell (sicherer für Production)**
```bash
# 1. Public Key anzeigen (auf Client)
cat ~/.ssh/crumbcore-rz01.pub

# 2. Auf Server einloggen (noch mit Passwort)
ssh crumbadmin@<SERVER-IP>

# 3. .ssh Verzeichnis erstellen
mkdir -p ~/.ssh
chmod 700 ~/.ssh

# 4. authorized_keys erstellen
vi ~/.ssh/authorized_keys
# → Public Key einfügen (EINE Zeile!)

# 5. Permissions setzen
chmod 600 ~/.ssh/authorized_keys

# 6. Verifizieren
cat ~/.ssh/authorized_keys

# 7. Logout
exit
```

### 3. SSH Config (auf Client)

```bash
# ~/.ssh/config auf deinem Client:

Host crumbcore-rz01
    HostName 192.168.1.100
    User crumbadmin
    IdentityFile ~/.ssh/crumbcore-rz01
    IdentitiesOnly yes
    ServerAliveInterval 60
    ServerAliveCountMax 3
    
    # Optional: Jump Host
    # ProxyJump bastion@gateway.example.com
    
    # Security
    StrictHostKeyChecking yes
    HashKnownHosts yes
```

### 4. SSH Agent Setup

**FreeBSD Server-side (für sudo/doas):**

```bash
# ~/.shrc oder ~/.profile für crumbadmin:

# SSH Agent startup
if [ -z "$SSH_AUTH_SOCK" ]; then
    eval $(ssh-agent -s)
    ssh-add ~/.ssh/id_ed25519 2>/dev/null
fi

# Agent forwarding (NUR wenn nötig!)
# Meistens NICHT empfohlen im RZ!
```

**Client-side (dein Laptop):**

```bash
# Fish Shell (~/.config/fish/config.fish):
if test -z "$SSH_AUTH_SOCK"
    eval (ssh-agent -c)
    ssh-add ~/.ssh/crumbcore-rz01
end

# Bash (~/.bashrc):
if [ -z "$SSH_AUTH_SOCK" ]; then
    eval $(ssh-agent -s)
    ssh-add ~/.ssh/crumbcore-rz01
fi
```

### 5. Test & Disable Password Auth

```bash
# Test key-based login (vom Client):
ssh crumbcore-rz01
# → Sollte mit Key funktionieren!

# Wenn erfolgreich: Password Auth deaktivieren
# Auf Server als root:
vi /etc/ssh/sshd_config
# → PasswordAuthentication no (bereits gesetzt!)

# SSH reload
service sshd reload

# Ab jetzt: NUR noch Keys! 🔐
```

---

## 🌐 Netzwerk ohne DHCP

### 1. Interface identifizieren

```bash
# Interfaces anzeigen
ifconfig

# Typisch:
# em0, igb0, re0 = Ethernet
# lo0 = Loopback

# Welches Interface? Im BIOS/Bootmeldung prüfen!
# Oder: dmesg | grep -i ethernet
```

### 2. Statische IP konfigurieren

**Szenario: RZ Netzwerk**
```
IP:       192.168.100.50
Netmask:  255.255.255.0 (/24)
Gateway:  192.168.100.1
DNS:      192.168.100.10, 8.8.8.8
```

**`/etc/rc.conf` editieren:**

```bash
# Network configuration
ifconfig_em0="inet 192.168.100.50 netmask 255.255.255.0"
defaultrouter="192.168.100.1"

# Hostname
hostname="crumbcore-rz01.example.com"

# IPv6 (falls benötigt)
ipv6_activate_all_interfaces="NO"

# Optional: VLAN (häufig im RZ!)
# vlans_em0="100"
# ifconfig_em0_100="inet 10.100.1.50/24"
```

**`/etc/resolv.conf` editieren:**

```bash
# DNS Configuration
search example.com
nameserver 192.168.100.10
nameserver 8.8.8.8
nameserver 8.8.4.4

# Timeout (BSI recommendation)
options timeout:2 attempts:2
```

### 3. Network Service starten

```bash
# Interface up (sofort aktiv)
service netif start em0

# Routing starten
service routing start

# Test
ping -c 3 192.168.100.1    # Gateway
ping -c 3 8.8.8.8          # Internet
ping -c 3 google.com       # DNS resolution

# Status prüfen
ifconfig em0
netstat -rn
```

### 4. Firewall Setup (PF)

**BSI-Anforderung: Host-based Firewall!**

```bash
# PF aktivieren
sysrc pf_enable="YES"
sysrc pf_rules="/etc/pf.conf"
sysrc pflog_enable="YES"
```

**`/etc/pf.conf` (Minimal):**

```conf
# /etc/pf.conf - Crumbcore Production

# Interfaces
ext_if = "em0"
int_net = "192.168.100.0/24"

# Services
ssh_port = "22"
http_port = "80"
https_port = "443"

# Options
set skip on lo0
set block-policy drop
set loginterface $ext_if

# Normalization
scrub in all

# Default: Block everything
block log all

# Allow loopback
pass quick on lo0

# Allow SSH from internal network only
pass in on $ext_if proto tcp from $int_net to ($ext_if) port $ssh_port keep state

# Allow outbound (DNS, NTP, Updates)
pass out on $ext_if proto tcp to any port { 80, 443 } keep state
pass out on $ext_if proto udp to any port { 53, 123 } keep state
pass out on $ext_if proto icmp all keep state

# Allow established connections
pass in on $ext_if proto tcp from any to ($ext_if) port { $http_port, $https_port } keep state

# Rate limiting SSH (anti-brute-force)
pass in on $ext_if proto tcp from any to ($ext_if) port $ssh_port \
    keep state (max-src-conn 5, max-src-conn-rate 3/60, overload <bruteforce> flush global)

# Block table for brute force
table <bruteforce> persist
block quick from <bruteforce>
```

**PF starten:**

```bash
# Syntax check
pfctl -nf /etc/pf.conf

# Start PF
service pf start
service pflog start

# Status
pfctl -si
pfctl -sr  # Rules
pfctl -ss  # States
```

---

## 🦉 Crumbcore Integration

### 1. Basis-Pakete installieren

```bash
# Package Manager setup
pkg update
pkg upgrade

# Essential tools
pkg install -y \
    bash \
    git \
    curl \
    wget \
    htop \
    tmux \
    vim \
    rsync \
    ca_root_nss

# Python (für Crumbcore)
pkg install -y python311 py311-pip py311-virtualenv

# Docker (optional, für Container)
pkg install -y docker docker-compose
sysrc docker_enable="YES"
service docker start
```

### 2. Crumbcore User Environment

```bash
# Als crumbcore user:
su - crumbcore

# Home Structure
mkdir -p ~/crumbcore/{app,data,logs,config}
mkdir -p ~/crumbcore/data/{uploads,outputs,vector-db}

# Python venv
cd ~/crumbcore/app
python3.11 -m venv venv
source venv/bin/activate

# Dependencies (Beispiel)
pip install --upgrade pip
pip install fastapi uvicorn qdrant-client anthropic
```

### 3. Crumbcore Config

```bash
# ~/crumbcore/config/.env
cat > ~/crumbcore/config/.env << 'EOF'
# Crumbcore Production Config

# Application
CRUMBCORE_ENV=production
CRUMBCORE_HOST=0.0.0.0
CRUMBCORE_PORT=8000

# Security
CORS_ORIGINS=https://crumbcore.example.com
RATE_LIMIT_PER_MINUTE=5
MAX_CONTENT_LENGTH=2000

# Paths
DATA_DIR=/home/crumbcore/crumbcore/data
UPLOAD_DIR=/home/crumbcore/crumbcore/data/uploads
OUTPUT_DIR=/home/crumbcore/crumbcore/data/outputs

# Qdrant
QDRANT_HOST=localhost
QDRANT_PORT=6333
QDRANT_COLLECTION=crumbcore_docs

# OpenRouter API
OPENROUTER_API_KEY=sk-or-v1-your-key-here

# Logging (BSI requirement!)
LOG_LEVEL=INFO
LOG_FILE=/home/crumbcore/crumbcore/logs/crumbcore.log
AUDIT_LOG=/home/crumbcore/crumbcore/logs/audit.log
EOF

# Permissions
chmod 600 ~/crumbcore/config/.env
```

### 4. Systemd Alternative: rc.d Script

**FreeBSD benutzt rc.d statt systemd!**

```bash
# /usr/local/etc/rc.d/crumbcore
cat > /usr/local/etc/rc.d/crumbcore << 'EOF'
#!/bin/sh
#
# PROVIDE: crumbcore
# REQUIRE: DAEMON NETWORKING
# KEYWORD: shutdown
#
# Add to /etc/rc.conf:
# crumbcore_enable="YES"

. /etc/rc.subr

name="crumbcore"
rcvar=crumbcore_enable

load_rc_config $name

: ${crumbcore_enable:="NO"}
: ${crumbcore_user:="crumbcore"}
: ${crumbcore_dir:="/home/crumbcore/crumbcore/app"}
: ${crumbcore_env:="/home/crumbcore/crumbcore/config/.env"}
: ${crumbcore_log:="/home/crumbcore/crumbcore/logs/crumbcore.log"}

pidfile="/var/run/${name}.pid"
command="/usr/sbin/daemon"
command_args="-P ${pidfile} -r -o ${crumbcore_log} \
    /home/crumbcore/crumbcore/app/venv/bin/python \
    /home/crumbcore/crumbcore/app/main.py"

start_precmd="${name}_prestart"

crumbcore_prestart()
{
    # Source environment
    . ${crumbcore_env}
    
    # Check directories
    if [ ! -d "${crumbcore_dir}" ]; then
        echo "Error: ${crumbcore_dir} does not exist"
        return 1
    fi
    
    # Set permissions
    chown ${crumbcore_user} ${crumbcore_log}
}

run_rc_command "$1"
EOF

# Executable machen
chmod +x /usr/local/etc/rc.d/crumbcore

# In /etc/rc.conf aktivieren
sysrc crumbcore_enable="YES"

# Start
service crumbcore start

# Status
service crumbcore status
```

---

## ✅ Security Checkliste

### Pre-Deployment

```bash
# [ ] Base System
☑ FreeBSD latest stable installiert
☑ ZFS mit Encryption aktiv
☑ Root Passwort stark (20+ chars)
☑ Timezone gesetzt (Europe/Berlin)

# [ ] Users & Permissions
☑ Admin user (wheel group) erstellt
☑ Service user (nologin) erstellt
☑ /home encrypted (GELI)
☑ Permissions: 700 für home dirs

# [ ] SSH
☑ SSH Keys generiert (ED25519)
☑ authorized_keys konfiguriert
☑ PasswordAuthentication disabled
☑ PermitRootLogin no
☑ Strong crypto (BSI TR-02102-4)
☑ SSH Config getestet

# [ ] Network
☑ Statische IP konfiguriert
☑ Gateway erreichbar
☑ DNS funktioniert
☑ PF Firewall aktiv
☑ SSH nur aus int_net erlaubt

# [ ] Logging
☑ syslogd konfiguriert
☑ /var/log/auth.log monitoring
☑ /var/log/messages monitoring
☑ Audit logs aktiviert

# [ ] Services
☑ Unnötige Services disabled
☑ sendmail deaktiviert
☑ NTP synchronisiert
☑ Crumbcore service aktiv
```

### Post-Deployment

```bash
# Täglich:
☑ Log review (auth.log, messages)
☑ Disk usage check (zpool status)
☑ Service health (service crumbcore status)

# Wöchentlich:
☑ Security updates (pkg upgrade)
☑ Backup verification
☑ User activity audit

# Monatlich:
☑ Key rotation review
☑ Firewall rule audit
☑ Performance metrics
☑ Capacity planning
```

---

## 🛡️ BSI IT-Grundschutz Mapping

| Baustein | Umsetzung | Status |
|----------|-----------|--------|
| **SYS.1.3** (Server) | FreeBSD Hardening | ✅ |
| **NET.1.2** (Firewall) | PF mit logging | ✅ |
| **APP.3.1** (Web) | TLS, HSTS (Nginx) | ⏳ |
| **OPS.1.1.5** (Logging) | syslog, audit | ✅ |
| **CON.1** (Crypto) | ED25519, AES-256 | ✅ |
| **ORP.4** (Identity) | SSH Keys, MFA ready | ✅ |

---

## 📚 Weiterführende Dokumentation

### FreeBSD Handbook
```bash
# Online:
https://docs.freebsd.org/en/books/handbook/

# Lokal (nach pkg install freebsd-doc):
man 7 security
man 8 geli
man 5 pf.conf
man 5 rc.conf
```

### Crumbcore Docs
```bash
# Im Repo:
/docs/SECURITY.md
/docs/DEPLOYMENT.md
/docs/BSI-COMPLIANCE.md
```

### BSI Guidelines
```
BSI TR-02102-4: Kryptographische Verfahren
BSI IT-Grundschutz: SYS.1.3 (Server)
```

---

## 🦉 Schlusswort

> *"Ein naked Setup ist wie ein Baum ohne Blätter - man sieht jede Verzweigung, jeden Ast, jede Entscheidung. In dieser Transparenz liegt die wahre Sicherheit."*
>
> — Krümeleule, Hüterin des Crumbforests 💚

### Der Crumbcore-Weg

1. **Minimalistisch:** Nur was nötig ist
2. **Transparent:** Jede Config verstehen
3. **Sicher:** Defense in Depth
4. **Dokumentiert:** Für die Nachwelt
5. **Wartbar:** Auch in 5 Jahren

**Welcome to the Crumbforest on FreeBSD!** 🌲🐡

---

**Version History:**
- v1.0 (2024-12-05): Initial release basierend auf RZ-Erfahrung Tag 1-3

**Maintainer:** Crumbforest Team 🦉🦊🐛  
**License:** MIT (for Open Source community)  
**Status:** Production Ready

---

*WUHUUUU! Möge dein ZFS immer scrubben, dein SSH niemals bruteforced werden, und deine Bits stets bewacht bleiben!* 🦉💚🛡️
