Compare commits

..

No commits in common. "166325b13389de593c9af77cd77510e0f573d3f8" and "6c60d88f626e8904e0ec335cb36e3ec54bca4fda" have entirely different histories.

11 changed files with 307 additions and 60 deletions

View file

@ -25,4 +25,3 @@ a670de0f,59f372f,feature/pid-file-service-management,2025-09-07T14:58:01Z,michae
a670de0f,683d6e5,fix/validate-config-posix-regex,2025-09-07T16:00:48Z,michael,git,lua-api a670de0f,683d6e5,fix/validate-config-posix-regex,2025-09-07T16:00:48Z,michael,git,lua-api
a670de0f,24bd94d,feature/systemd-hardening,2025-09-07T16:40:47Z,michael,git,lua-api a670de0f,24bd94d,feature/systemd-hardening,2025-09-07T16:40:47Z,michael,git,lua-api
4ee95dbc,08b49d3,security/sanitize-test-scripts,2025-09-07T19:25:38Z,michael,git,lua-api 4ee95dbc,08b49d3,security/sanitize-test-scripts,2025-09-07T19:25:38Z,michael,git,lua-api
59c85431,8b78066,main,2025-09-10T10:20:50Z,michael,git,lua-api

161
README.md
View file

@ -1,83 +1,160 @@
# Furt API Gateway # Furt API Gateway
**Pure Lua HTTP-Server für digitale Souveränität** **HTTP-Server in Lua für Service-Integration**
## Überblick ## Überblick
Furt ist ein minimalistisches HTTP-Server in Lua 5.1 für Mail-Versendung über SMTP. Es bietet eine einfache JSON-API für Web-Integration und Multi-Tenant-Unterstützung über API-Keys. Furt ist ein HTTP-Server der verschiedene Services unter einer API vereint. Aktuell unterstützt es Mail-Versendung über SMTP und bietet eine einfache JSON-API für Web-Integration.
## Features ## Features
- HTTP-Server mit JSON-APIs - HTTP-Server mit JSON-APIs
- Multi-Tenant Mail-Routing über SMTP - Mail-Versendung über SMTP
- API-Key-basierte Authentifizierung - Request-Routing und Authentication
- Health-Check-Endpoints - Health-Check-Endpoints
- Rate-Limiting pro API-Key - Konfigurierbare Rate-Limiting
- CORS-Support für Frontend-Integration - Hugo/Website-Integration
## Quick Start ## Dependencies
**Dependencies installieren:** **Erforderlich:**
```bash - `lua` 5.4+
# OpenBSD - `lua-socket` (HTTP-Server)
doas pkg_add lua lua-socket lua-cjson luasec - `lua-cjson` (JSON-Verarbeitung)
# Debian/Ubuntu
sudo apt install lua5.1 lua-socket lua-cjson lua-sec
# Arch Linux
sudo pacman -S lua51 lua51-socket lua51-dkjson lua51-sec
```
**Installation:** **Installation:**
```bash ```bash
git clone https://smida.dragons-at-work.de/DAW/furt.git # Arch Linux
cd furt pacman -S lua lua-socket lua-cjson
sudo ./install.sh
# Ubuntu/Debian
apt install lua5.4 lua-socket lua-cjson
``` ```
**Server läuft auf:** http://127.0.0.1:7811 ## Installation
```bash
# Repository klonen
git clone <repository-url>
cd furt
# Scripts ausführbar machen
chmod +x scripts/*.sh
# Server starten
./scripts/start.sh
```
**Server läuft auf:** http://127.0.0.1:8080
## API-Endpoints ## API-Endpoints
**Health Check:** ### Health Check
```bash ```bash
curl http://127.0.0.1:7811/health GET /health
→ {"status":"healthy","service":"furt","version":"1.0.0"}
``` ```
**Mail senden:** ### Mail senden
```bash ```bash
curl -X POST http://127.0.0.1:7811/v1/mail/send \ POST /v1/mail/send
-H "X-API-Key: your-api-key" \ Content-Type: application/json
{
"name": "Name",
"email": "sender@example.com",
"message": "Nachricht"
}
→ {"success":true,"message":"Mail sent"}
```
## Konfiguration
**Environment Variables (.env):**
```bash
FURT_MAIL_HOST=mail.example.com
FURT_MAIL_PORT=587
FURT_MAIL_USERNAME=user@example.com
FURT_MAIL_PASSWORD=password
FURT_MAIL_TO=empfaenger@example.com
```
**Server-Config (config/server.lua):**
- Port und Host-Einstellungen
- API-Key-Konfiguration
- Rate-Limiting-Parameter
## Testing
**Automatische Tests:**
```bash
lua tests/test_http.lua
```
**Manuelle Tests:**
```bash
./scripts/test_curl.sh
# Oder direkt:
curl -X POST http://127.0.0.1:8080/v1/mail/send \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d '{"name":"Test","email":"test@example.com","subject":"Test","message":"Test-Nachricht"}' -d '{"name":"Test","email":"test@example.com","message":"Test"}'
``` ```
## Dokumentation ## Deployment
**Installation & Konfiguration:** [Furt Wiki](https://smida.dragons-at-work.de/DAW/furt/wiki) **OpenBSD:**
- rc.d-Script in `deployment/openbsd/`
- Systemd-Integration über Scripts
**Production-Setup:**
```bash
# Environment-Config kopieren
cp .env.example .env.production
# → SMTP-Credentials anpassen
# Production-Mode starten
export FURT_ENV=production
./scripts/start.sh
```
## Projektstruktur ## Projektstruktur
``` ```
furt/ furt/
├── src/ # Lua-Source-Code ├── src/ # Lua-Source-Code
├── config/ # Konfiguration │ ├── main.lua # HTTP-Server
├── scripts/ # Installation & Management │ ├── routes/ # API-Endpoints
└── deployment/ # System-Integration │ └── smtp.lua # Mail-Integration
├── config/ # Konfiguration
├── scripts/ # Start/Test-Scripts
├── tests/ # Test-Suite
└── deployment/ # System-Integration
``` ```
## Integration ## Hugo-Integration
**merkwerk:** Versionierte Furt-Deployment über [merkwerk](https://smida.dragons-at-work.de/DAW/merkwerk) **Shortcode-Beispiel:**
```html
<form action="http://your-server:8080/v1/mail/send" method="POST">
<input name="name" type="text" required>
<input name="email" type="email" required>
<textarea name="message" required></textarea>
<button type="submit">Senden</button>
</form>
```
## License ## Development
ISC - Siehe [LICENSE](LICENSE) für Details. **Code-Struktur:**
- Module unter 200 Zeilen
- Funktionen unter 50 Zeilen
- Klare Fehlerbehandlung
- Testbare Komponenten
## Links **Dependencies minimal halten:**
- Nur lua-socket und lua-cjson
- **Repository:** [Forgejo](https://smida.dragons-at-work.de/DAW/furt) - Keine externen HTTP-Libraries
- **Dokumentation:** [Wiki](https://smida.dragons-at-work.de/DAW/furt/wiki) - Standard-Lua-Funktionen bevorzugen
- **Projekt:** [Dragons@Work](https://dragons-at-work.de)

176
docs/setup-guide.md Normal file
View file

@ -0,0 +1,176 @@
# Multi-Tenant furt Setup-Anleitung
## Installation
### 1. Dateien platzieren
```bash
# OpenBSD/FreeBSD
mkdir -p /usr/local/etc/furt
mkdir -p /usr/local/share/furt
# Oder Linux
mkdir -p /etc/furt
mkdir -p /usr/local/share/furt
# Source code
cp -r src/ /usr/local/share/furt/
cp -r config/ /usr/local/share/furt/
```
### 2. Konfiguration erstellen
```bash
# Beispiel-Config kopieren und anpassen
# OpenBSD/FreeBSD:
cp furt.conf.example /usr/local/etc/furt/furt.conf
# Linux:
cp furt.conf.example /etc/furt/furt.conf
# Config editieren
vi /usr/local/etc/furt/furt.conf # oder /etc/furt/furt.conf
```
### 3. Start-Script
```bash
#!/bin/sh
# /usr/local/bin/furt
cd /usr/local/share/furt
lua src/main.lua
```
## Multi-Tenant Konfiguration
### Beispiel für 3 Websites
```ini
[server]
host = 127.0.0.1
port = 8080
[smtp_default]
host = mail.dragons-at-work.de
port = 465
user = noreply@dragons-at-work.de
password = your-smtp-password
# Website 1: Dragons@Work
[api_key "daw-key-abc123"]
name = "Dragons@Work Website"
permissions = mail:send
allowed_ips = 1.2.3.4/32, 10.0.0.0/8
mail_to = admin@dragons-at-work.de
mail_from = noreply@dragons-at-work.de
mail_subject_prefix = "[DAW] "
# Website 2: Biocodie (gleiche SMTP, andere Empfänger)
[api_key "bio-key-def456"]
name = "Biocodie Website"
permissions = mail:send
allowed_ips = 5.6.7.8/32
mail_to = contact@biocodie.de
mail_from = noreply@biocodie.de
mail_subject_prefix = "[Biocodie] "
# Website 3: Kunde mit eigenem SMTP
[api_key "kunde-key-ghi789"]
name = "Kunde X Website"
permissions = mail:send
allowed_ips = 9.10.11.12/32
mail_to = info@kunde-x.de
mail_from = noreply@kunde-x.de
mail_smtp_host = mail.kunde-x.de
mail_smtp_user = noreply@kunde-x.de
mail_smtp_pass = kunde-smtp-password
```
## Admin-Workflow
### Neue Website hinzufügen
1. **Config editieren:**
```bash
vi /usr/local/etc/furt/furt.conf
```
2. **Neuen API-Key-Block hinzufügen:**
```ini
[api_key "neue-website-key"]
name = "Neue Website"
permissions = mail:send
allowed_ips = 12.34.56.78/32
mail_to = contact@neue-website.de
mail_from = noreply@neue-website.de
```
3. **furt neu starten:**
```bash
systemctl restart furt
# oder
pkill -f "lua.*main.lua" && /usr/local/bin/furt &
```
### Website testen
```bash
# Test mit curl
curl -X POST http://localhost:8080/v1/mail/send \
-H "X-API-Key: neue-website-key" \
-H "Content-Type: application/json" \
-d '{
"name": "Test User",
"email": "test@example.com",
"subject": "Test Message",
"message": "This is a test message"
}'
```
## Vorteile des Multi-Tenant-Systems
### ✅ Ein Server, viele Websites
- Alle Websites nutzen eine furt-Instanz
- Jede Website hat eigenen API-Key
- Verschiedene Empfänger-Adressen
- Verschiedene SMTP-Server möglich
### ✅ Admin-freundlich
- Nginx-style Config-Format
- Einfach neue Websites hinzufügen
- Klare Struktur pro Website
- Kommentare möglich
### ✅ Sicher
- IP-Restrictions pro Website
- Permissions pro API-Key
- Separate SMTP-Credentials möglich
- Rate-Limiting bleibt erhalten
### ✅ Flexibel
- Default SMTP + website-spezifische SMTP
- Subject-Prefix pro Website
- Verschiedene Mail-Adressen
- Beliebig viele Websites
## Backward Compatibility
Das neue System ist **vollständig kompatibel** mit der alten config/server.lua API. Bestehende Module (auth.lua, main.lua, etc.) funktionieren ohne Änderungen.
## Troubleshooting
### Config-Parsing-Fehler
```bash
# Config-Syntax prüfen
lua -e "require('src.config_parser').parse_file('/usr/local/etc/furt/furt.conf')"
```
### Mail-Routing testen
```bash
# Logs anschauen
tail -f /var/log/furt.log
# Debug-Mode
FURT_DEBUG=true lua src/main.lua
```

View file

@ -102,7 +102,7 @@ else
echo "" echo ""
echo "Next steps:" echo "Next steps:"
echo "1. Edit configuration file:" echo "1. Edit configuration file:"
if [ "$(uname)" = "OpenBSD" ]; then if [ "$(uname)" = "OpenBSD" ] || [ "$(uname)" = "FreeBSD" ]; then
echo " /usr/local/etc/furt/furt.conf" echo " /usr/local/etc/furt/furt.conf"
else else
echo " /etc/furt/furt.conf" echo " /etc/furt/furt.conf"

View file

@ -15,25 +15,25 @@ if [ "$(uname)" = "OpenBSD" ]; then
echo "Error: deployment/openbsd/rc.d-furt template not found" echo "Error: deployment/openbsd/rc.d-furt template not found"
exit 1 exit 1
fi fi
cp deployment/openbsd/rc.d-furt /etc/rc.d/furt cp deployment/openbsd/rc.d-furt /etc/rc.d/furt
chmod +x /etc/rc.d/furt chmod +x /etc/rc.d/furt
echo "furt_flags=" >> /etc/rc.conf.local echo "furt_flags=" >> /etc/rc.conf.local
rcctl enable furt rcctl enable furt
echo "OpenBSD service created and enabled using repository template" echo "OpenBSD service created and enabled using repository template"
elif [ "$(uname)" = "Linux" ]; then elif [ "$(uname)" = "Linux" ]; then
# Use systemd template from repository # Use systemd template from repository
if [ ! -f "deployment/linux/furt.service" ]; then if [ ! -f "deployment/linux/furt.service" ]; then
echo "Error: deployment/linux/furt.service template not found" echo "Error: deployment/linux/furt.service template not found"
exit 1 exit 1
fi fi
cp deployment/linux/furt.service /etc/systemd/system/ cp deployment/linux/furt.service /etc/systemd/system/
systemctl daemon-reload systemctl daemon-reload
systemctl enable furt systemctl enable furt
echo "Linux systemd service created and enabled using repository template" echo "Linux systemd service created and enabled using repository template"
else else
echo "Unsupported operating system for service creation" echo "Unsupported operating system for service creation"
exit 1 exit 1

View file

@ -4,7 +4,7 @@
set -e set -e
# Detect operating system for config directory # Detect operating system for config directory
if [ "$(uname)" = "OpenBSD" ]; then if [ "$(uname)" = "OpenBSD" ] || [ "$(uname)" = "FreeBSD" ]; then
CONFIG_DIR="/usr/local/etc/furt" CONFIG_DIR="/usr/local/etc/furt"
USER="_furt" USER="_furt"
GROUP="_furt" GROUP="_furt"

View file

@ -4,7 +4,7 @@
set -e set -e
# Detect operating system # Detect operating system
if [ "$(uname)" = "OpenBSD" ]; then if [ "$(uname)" = "OpenBSD" ] || [ "$(uname)" = "FreeBSD" ]; then
# BSD systems use _furt user convention # BSD systems use _furt user convention
groupadd _furt 2>/dev/null || true groupadd _furt 2>/dev/null || true
useradd -g _furt -s /bin/false -d /var/empty _furt 2>/dev/null || true useradd -g _furt -s /bin/false -d /var/empty _furt 2>/dev/null || true

View file

@ -17,7 +17,7 @@ echo -e "${GREEN}=== Furt Lua HTTP-Server Startup ===${NC}"
LUA_COMMAND="" LUA_COMMAND=""
# Config check first # Config check first
if [ "$(uname)" = "OpenBSD" ]; then if [ "$(uname)" = "OpenBSD" ] || [ "$(uname)" = "FreeBSD" ]; then
CONFIG_FILE="/usr/local/etc/furt/furt.conf" CONFIG_FILE="/usr/local/etc/furt/furt.conf"
PID_FILE="/var/run/furt/furt.pid" PID_FILE="/var/run/furt/furt.pid"
else else

View file

@ -24,13 +24,8 @@ cp -r integrations/ "$TARGET/"
[ -f "VERSION" ] && cp VERSION "$TARGET/" [ -f "VERSION" ] && cp VERSION "$TARGET/"
[ -f ".version_history" ] && cp .version_history "$TARGET/" [ -f ".version_history" ] && cp .version_history "$TARGET/"
# Set proper permissions based on operating system # Set proper permissions
if [ "$(uname)" = "OpenBSD" ]; then chown -R root:wheel "$TARGET" 2>/dev/null || chown -R root:root "$TARGET"
chown -R root:wheel "$TARGET"
else
chown -R root:root "$TARGET"
fi
chmod -R 644 "$TARGET" chmod -R 644 "$TARGET"
find "$TARGET" -type d -exec chmod 755 {} \; find "$TARGET" -type d -exec chmod 755 {} \;
chmod +x "$TARGET/scripts/start.sh" chmod +x "$TARGET/scripts/start.sh"

View file

@ -4,7 +4,7 @@
set -e set -e
# Detect config file location # Detect config file location
if [ "$(uname)" = "OpenBSD" ]; then if [ "$(uname)" = "OpenBSD" ] || [ "$(uname)" = "FreeBSD" ]; then
CONFIG_FILE="/usr/local/etc/furt/furt.conf" CONFIG_FILE="/usr/local/etc/furt/furt.conf"
else else
CONFIG_FILE="/etc/furt/furt.conf" CONFIG_FILE="/etc/furt/furt.conf"

View file

@ -215,7 +215,7 @@ end
function ConfigParser.load_config() function ConfigParser.load_config()
-- Try different locations based on OS -- Try different locations based on OS
local config_paths = { local config_paths = {
"/usr/local/etc/furt/furt.conf", -- OpenBSD "/usr/local/etc/furt/furt.conf", -- OpenBSD/FreeBSD
"/etc/furt/furt.conf", -- Linux "/etc/furt/furt.conf", -- Linux
"config/furt.conf", -- Development "config/furt.conf", -- Development
"furt.conf" -- Current directory "furt.conf" -- Current directory