rename posterg → xamxam throughout: nginx conf, scripts, PHP source, docs

This commit is contained in:
Pontoporeia
2026-04-30 10:50:23 +02:00
parent 3e35bbc40f
commit c949cf9481
31 changed files with 283 additions and 267 deletions

View File

@@ -41,8 +41,8 @@ just serve # http://localhost:8000 (public) and /admin/
Files are pushed to the server with rsync — there is no repo on the remote.
```bash
just deploy # rsync app files → posterg:/var/www/posterg/
just deploy-db # push local posterg.db → remote (only if remote DB is absent)
just deploy # rsync app files → xamxam:/var/www/xamxam/
just deploy-db # push local xamxam.db → remote (only if remote DB is absent)
```
`deploy-db` refuses to run if a database already exists on the server, to avoid
@@ -51,10 +51,10 @@ accidental overwrites of production data.
### First-time server setup
```bash
ssh posterg
sudo mkdir -p /var/www/posterg
sudo chown www-data:posterg /var/www/posterg
sudo chmod 775 /var/www/posterg
ssh xamxam
sudo mkdir -p /var/www/xamxam
sudo chown www-data:xamxam /var/www/xamxam
sudo chmod 775 /var/www/xamxam
exit
```
@@ -70,7 +70,7 @@ just deploy-nginx
```bash
just manage-admin-users
# Then on server:
ssh posterg "sudo bash /tmp/manage-admin-users.sh"
ssh xamxam "sudo bash /tmp/manage-admin-users.sh"
```
## Security notes

16
TODO.md
View File

@@ -32,6 +32,22 @@
- [x] Add missing favicon tags to all three `<head>` blocks in `partage/index.php` (error page, password gate, main form)
## Rename posterg → xamxam throughout codebase
- [x] Rename `nginx/posterg.conf``nginx/xamxam.conf` (+ `.conf.reference`)
- [x] Update nginx conf: `server_name`, log paths, htpasswd path, header comments
- [x] Update `justfile`: SSH host alias, group, DB filename, conf path, tmp paths
- [x] Update `scripts/deploy-server.sh`: group, conf paths, site names, URLs
- [x] Update `scripts/setup-server.sh`: APP_DIR, APP_GROUP, comments
- [x] Update `scripts/manage-admin-users.sh`: htpasswd path
- [x] Update `scripts/migrate.sh`: DB filename
- [x] Update `scripts/setup-dev.sh`: DB filename
- [x] Update `scripts/copy_crash_logs.sh`: log filenames, hostname
- [x] Update `README.md`: SSH host, paths, DB name
- [x] Update `nginx/README.md`, `nginx/SETUP.md`, and all `nginx/docs/*.md`
- [x] Update PHP source: `Database.php`, `SystemController.php`, `MediaController.php`, `LiveReloadController.php`, `SmtpRelay.php`, `live-reload.php`, export actions
- [x] Update `app/migrations/run.php`, `app/tests/README.md`, `app/storage/README.md`
## CSS refactor
- [x] Move semantic HTML element baseline styles into common.css

View File

@@ -5,14 +5,14 @@
*
* Usage: php app/migrations/run.php [DB_PATH]
*
* If no DB_PATH is given, defaults to storage/posterg.db.
* If no DB_PATH is given, defaults to storage/xamxam.db.
*
* Each migration in migrations/pending/ is applied in alphabetical order.
* After success, the file is moved to migrations/applied/.
*/
$root = dirname(__DIR__);
$dbPath = $argv[1] ?? ($root . '/storage/posterg.db');
$dbPath = $argv[1] ?? ($root . '/storage/xamxam.db');
if (!file_exists($dbPath)) {
die("Database not found: $dbPath\n");

View File

@@ -12,7 +12,7 @@ AdminAuth::requireLogin();
require_once APP_ROOT . '/src/Controllers/ExportController.php';
$controller = ExportController::create();
$filename = 'posterg-export-' . date('Y-m-d') . '.csv';
$filename = 'xamxam-export-' . date('Y-m-d') . '.csv';
header('Content-Type: text/csv; charset=UTF-8');
header('Content-Disposition: attachment; filename="' . $filename . '"');

View File

@@ -18,7 +18,7 @@ if (!file_exists($dbPath)) {
exit('Base de données introuvable.');
}
$filename = 'posterg-db-' . date('Y-m-d') . '.sqlite';
$filename = 'xamxam-db-' . date('Y-m-d') . '.sqlite';
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $filename . '"');

View File

@@ -38,7 +38,7 @@ foreach ($watchDirs as $dir) {
}
$fingerprint = md5($hash);
$stateFile = sys_get_temp_dir() . '/posterg-live-reload.txt';
$stateFile = sys_get_temp_dir() . '/xamxam-live-reload.txt';
$prev = file_exists($stateFile) ? file_get_contents($stateFile) : null;
// First visit: write baseline, don't fire a reload

View File

@@ -18,7 +18,7 @@ class LiveReloadController {
$appRoot . '/config',
$appRoot . '/templates',
];
$this->stateFile = sys_get_temp_dir() . '/posterg-live-reload.txt';
$this->stateFile = sys_get_temp_dir() . '/xamxam-live-reload.txt';
}
public function handle(): array {

View File

@@ -29,7 +29,7 @@ class MediaController
}
// 2. Resolve path + storage jail
$storageRoot = defined('STORAGE_ROOT') ? STORAGE_ROOT : '/var/www/posterg/storage';
$storageRoot = defined('STORAGE_ROOT') ? STORAGE_ROOT : '/var/www/xamxam/storage';
$fullPath = $storageRoot . '/' . $requestedPath;
$realStorage = realpath($storageRoot);

View File

@@ -23,17 +23,17 @@ class SystemController
// ── Constants ─────────────────────────────────────────────────────────────
public const LOG_FILES = [
'nginx_access' => ['label' => 'nginx — accès', 'path' => '/var/log/nginx/posterg_access.log'],
'nginx_error' => ['label' => 'nginx — erreurs', 'path' => '/var/log/nginx/posterg_error.log'],
'nginx_access' => ['label' => 'nginx — accès', 'path' => '/var/log/nginx/xamxam_access.log'],
'nginx_error' => ['label' => 'nginx — erreurs', 'path' => '/var/log/nginx/xamxam_error.log'],
'php_error' => ['label' => 'PHP-FPM — erreurs', 'path' => '/var/log/php8.4-fpm.log'],
];
public const ALLOWED_LINES = [50, 100, 200, 500];
/** Live deployed nginx config path. */
public const NGINX_CONFIG_LIVE = '/etc/nginx/sites-available/posterg';
public const NGINX_CONFIG_LIVE = '/etc/nginx/sites-available/xamxam';
/** Local reference copy used as fallback in dev. */
public const NGINX_CONFIG_LOCAL = APP_ROOT . '/nginx/posterg.conf';
public const NGINX_CONFIG_LOCAL = APP_ROOT . '/nginx/xamxam.conf';
// ── TTLs ──────────────────────────────────────────────────────────────────
private const TTL_STATUS = 120; // 2 minutes

View File

@@ -35,7 +35,7 @@ class Database {
/**
* Determine database path.
* Priority: explicit override → APP_ROOT /storage/posterg.db.
* Priority: explicit override → APP_ROOT /storage/xamxam.db.
* APP_ROOT is defined by bootstrap.php before any controller loads Database.
*/
private function determineDatabasePath($customPath = null): string {
@@ -44,7 +44,7 @@ class Database {
}
$root = defined('APP_ROOT') ? APP_ROOT : __DIR__ . '/..';
return $root . '/storage/posterg.db';
return $root . '/storage/xamxam.db';
}
/**

View File

@@ -118,7 +118,7 @@ class SmtpRelay {
}
// Build MIME message
$boundary = 'posterg_' . bin2hex(random_bytes(8));
$boundary = 'xamxam_' . bin2hex(random_bytes(8));
$date = date('r');
$fromHdr = ($s['from_name'] ?? '') !== ''
? "=?UTF-8?B?" . base64_encode($s['from_name']) . "?= <{$s['from_email']}>"

View File

@@ -188,7 +188,7 @@ Query `v_theses_public` view with filters:
## 🛠️ Development Workflow
### Local Development
1. Use `posterg.db` for development
1. Use `xamxam.db` for development
2. Create via `just init-db`
3. Test queries before deployment

View File

@@ -125,7 +125,7 @@ try {
## 🔧 Test Database
Tests use the main database at `storage/posterg.db`.
Tests use the main database at `storage/xamxam.db`.
### Setup Test Database

View File

@@ -30,7 +30,7 @@ logs:
[group('deploy')]
deploy:
rsync -vur --progress --delete \
--chown="www-data:posterg" \
--chown="www-data:xamxam" \
--exclude 'vendor' \
--exclude 'tests' \
--exclude '*.md' \
@@ -39,7 +39,7 @@ deploy:
--exclude '.claude' \
--exclude '.pi' \
--exclude '.DS_Store' \
--exclude 'storage/posterg.db' \
--exclude 'storage/xamxam.db' \
--exclude 'storage/theses' \
--exclude 'storage/covers' \
--exclude 'storage/backup_*' \
@@ -48,12 +48,12 @@ deploy:
--exclude 'storage/docs' \
--exclude 'var/cache/*' \
--exclude 'var/logs/*' \
app/ posterg:/var/www/xamxam/
ssh posterg "mkdir -p /var/www/xamxam/var/{cache,logs,tmp}"
app/ xamxam:/var/www/xamxam/
ssh xamxam "mkdir -p /var/www/xamxam/var/{cache,logs,tmp}"
[group('deploy')]
setup-server:
rsync -v scripts/setup-server.sh posterg:/tmp/setup-server.sh
rsync -v scripts/setup-server.sh xamxam:/tmp/setup-server.sh
@echo ""
@echo "Script uploaded. SSH into the server and run:"
@echo ""
@@ -62,7 +62,7 @@ setup-server:
[group('deploy')]
manage-admin-users:
rsync -v scripts/manage-admin-users.sh posterg:/tmp/manage-admin-users.sh
rsync -v scripts/manage-admin-users.sh xamxam:/tmp/manage-admin-users.sh
@echo ""
@echo "Script uploaded. SSH into the server and run:"
@echo ""
@@ -71,8 +71,8 @@ manage-admin-users:
[group('deploy')]
deploy-nginx:
rsync -v nginx/posterg.conf posterg:/tmp/posterg.conf
rsync -v scripts/deploy-server.sh posterg:/tmp/deploy-server.sh
rsync -v nginx/xamxam.conf xamxam:/tmp/xamxam.conf
rsync -v scripts/deploy-server.sh xamxam:/tmp/deploy-server.sh
@echo ""
@echo "Files uploaded. SSH into the server and run:"
@echo ""
@@ -82,9 +82,9 @@ deploy-nginx:
[group('deploy')]
deploy-db:
@ssh posterg '[ ! -f /var/www/xamxam/storage/posterg.db ]' || (echo "ERROR: remote database already exists. Remove it manually if you intend to overwrite." && exit 1)
rsync -v --progress app/storage/posterg.db posterg:/var/www/xamxam/storage/posterg.db
ssh posterg "chown www-data:posterg /var/www/xamxam/storage/posterg.db && chmod 660 /var/www/xamxam/storage/posterg.db"
@ssh xamxam '[ ! -f /var/www/xamxam/storage/xamxam.db ]' || (echo "ERROR: remote database already exists. Remove it manually if you intend to overwrite." && exit 1)
rsync -v --progress app/storage/xamxam.db xamxam:/var/www/xamxam/storage/xamxam.db
ssh xamxam "chown www-data:xamxam /var/www/xamxam/storage/xamxam.db && chmod 660 /var/www/xamxam/storage/xamxam.db"
# ============================================================================
# Testing
@@ -123,25 +123,25 @@ migrate:
[group('database')]
init-db:
@sqlite3 app/storage/posterg.db < app/storage/schema.sql
@sqlite3 app/storage/posterg.db "SELECT COUNT(*) || ' tables' FROM sqlite_master WHERE type='table';"
@sqlite3 app/storage/xamxam.db < app/storage/schema.sql
@sqlite3 app/storage/xamxam.db "SELECT COUNT(*) || ' tables' FROM sqlite_master WHERE type='table';"
[group('database')]
reset-db:
@rm -f app/storage/posterg.db
@rm -f app/storage/xamxam.db
@just init-db
[group('database')]
query:
@sqlite3 app/storage/posterg.db
@sqlite3 app/storage/xamxam.db
[group('database')]
show id:
@sqlite3 -column -header app/storage/posterg.db "SELECT * FROM v_theses_full WHERE id = {{id}};";
@sqlite3 -column -header app/storage/xamxam.db "SELECT * FROM v_theses_full WHERE id = {{id}};"
[group('database')]
backup:
@sqlite3 app/storage/posterg.db .dump > app/storage/backup_$(date +%Y%m%d_%H%M%S).sql
@sqlite3 app/storage/xamxam.db .dump > app/storage/backup_$(date +%Y%m%d_%H%M%S).sql
# ============================================================================
# Utils
@@ -151,7 +151,7 @@ backup:
clean:
@rm -f app/error.log
@rm -rf app/storage/cache/rate_limit/*
@rm -f /tmp/posterg-*.log /tmp/posterg-*.pid
@rm -f /tmp/xamxam-*.log /tmp/xamxam-*.pid
[group('utils')]
setup-dirs:

View File

@@ -4,7 +4,7 @@ This directory contains nginx configuration and documentation for the Post-ERG t
## 📁 Files
- **`posterg.conf`** - Complete nginx configuration file
- **`xamxam.conf`** - Complete nginx configuration file
- **`docs/`** - Documentation
- `PRODUCTION_DEPLOYMENT.md` - Deployment guide
- `QUICK_REFERENCE.md` - Command reference
@@ -23,13 +23,13 @@ This directory contains nginx configuration and documentation for the Post-ERG t
just deploy-nginx
# Then on the server:
ssh posterg
ssh xamxam
sudo bash /tmp/deploy-server.sh
sudo systemctl reload nginx
```
The deployment script will:
- ✅ Fix file permissions (www-data:posterg)
- ✅ Fix file permissions (www-data:xamxam)
- ✅ Install nginx configuration
- ✅ Test and reload nginx
- ✅ Verify PHP-FPM is running
@@ -38,7 +38,7 @@ The deployment script will:
```bash
just manage-admin-users
ssh posterg "sudo bash /tmp/manage-admin-users.sh"
ssh xamxam "sudo bash /tmp/manage-admin-users.sh"
```
## 🔒 Security Features
@@ -80,20 +80,20 @@ ssh posterg "sudo bash /tmp/manage-admin-users.sh"
```bash
# Test admin authentication
curl -I https://posterg.erg.be/admin/
curl -I https://xamxam.erg.be/admin/
# Test file protection
curl -I https://posterg.erg.be/storage/test.db
curl -I https://xamxam.erg.be/storage/test.db
# Test security headers
curl -I https://posterg.erg.be/ | grep -E "X-|Strict-Transport"
curl -I https://xamxam.erg.be/ | grep -E "X-|Strict-Transport"
```
## 🆘 Quick Help
### Admin can't log in
```bash
sudo htpasswd /etc/nginx/.htpasswd-posterg admin
sudo htpasswd /etc/nginx/.htpasswd-xamxam admin
```
### 502 Bad Gateway
@@ -111,8 +111,8 @@ sudo nginx -t
```bash
# Watch logs
sudo tail -f /var/log/nginx/posterg_access.log
sudo tail -f /var/log/nginx/posterg_error.log
sudo tail -f /var/log/nginx/xamxam_access.log
sudo tail -f /var/log/nginx/xamxam_error.log
# Check nginx status
sudo systemctl status nginx

View File

@@ -20,7 +20,7 @@ just deploy-nginx
### 2. Apply on the server
```bash
ssh posterg
ssh xamxam
sudo bash /tmp/deploy-server.sh
sudo systemctl reload nginx
```
@@ -29,7 +29,7 @@ sudo systemctl reload nginx
```bash
just manage-admin-users
ssh posterg "sudo bash /tmp/manage-admin-users.sh"
ssh xamxam "sudo bash /tmp/manage-admin-users.sh"
```
## Manual Setup Steps
@@ -46,14 +46,14 @@ sudo apt install nginx apache2-utils php8.4-fpm
```bash
just manage-admin-users
# Then on the server:
ssh posterg "sudo bash /tmp/manage-admin-users.sh"
ssh xamxam "sudo bash /tmp/manage-admin-users.sh"
```
### 3. Copy Nginx Configuration
```bash
sudo cp nginx/posterg.conf /etc/nginx/sites-available/posterg
sudo ln -s /etc/nginx/sites-available/posterg /etc/nginx/sites-enabled/
sudo cp nginx/xamxam.conf /etc/nginx/sites-available/xamxam
sudo ln -s /etc/nginx/sites-available/xamxam /etc/nginx/sites-enabled/
sudo rm -f /etc/nginx/sites-enabled/default
```
@@ -71,32 +71,32 @@ sudo systemctl status nginx
```bash
# Should return 401
curl -I https://posterg.erg.be/admin/
curl -I https://xamxam.erg.be/admin/
# With credentials
curl -u admin:password https://posterg.erg.be/admin/
curl -u admin:password https://xamxam.erg.be/admin/
```
### Test File Protection
```bash
# Should return 403
curl -I https://posterg.erg.be/storage/test.db
curl -I https://posterg.erg.be/src/Database.php
curl -I https://xamxam.erg.be/storage/test.db
curl -I https://xamxam.erg.be/src/Database.php
```
### Test Security Headers
```bash
curl -I https://posterg.erg.be/ | grep -E "X-|Strict-Transport"
curl -I https://xamxam.erg.be/ | grep -E "X-|Strict-Transport"
```
## Troubleshooting
### 403 Forbidden on admin
```bash
sudo ls -l /etc/nginx/.htpasswd-posterg
sudo chmod 644 /etc/nginx/.htpasswd-posterg
sudo ls -l /etc/nginx/.htpasswd-xamxam
sudo chmod 644 /etc/nginx/.htpasswd-xamxam
```
### 502 Bad Gateway
@@ -114,7 +114,7 @@ sudo nginx -t
### Change Admin Password
```bash
sudo htpasswd /etc/nginx/.htpasswd-posterg admin
sudo htpasswd /etc/nginx/.htpasswd-xamxam admin
```
### Reload Configuration

View File

@@ -13,7 +13,7 @@ Quick guide to manage admin users for the Post-ERG admin panel.
just manage-admin-users
# Then on the server
ssh posterg
ssh xamxam
sudo bash /tmp/manage-admin-users.sh
```
@@ -31,15 +31,15 @@ This gives you an interactive menu to:
### List Current Users
```bash
ssh posterg
sudo cut -d: -f1 /etc/nginx/.htpasswd-posterg
ssh xamxam
sudo cut -d: -f1 /etc/nginx/.htpasswd-xamxam
```
### Change Password for Existing User
```bash
ssh posterg
sudo htpasswd /etc/nginx/.htpasswd-posterg username_here
ssh xamxam
sudo htpasswd /etc/nginx/.htpasswd-xamxam username_here
```
You'll be prompted to enter the new password twice.
@@ -47,22 +47,22 @@ You'll be prompted to enter the new password twice.
### Add New User
```bash
ssh posterg
sudo htpasswd /etc/nginx/.htpasswd-posterg new_username
ssh xamxam
sudo htpasswd /etc/nginx/.htpasswd-xamxam new_username
```
### Delete User
```bash
ssh posterg
sudo htpasswd -D /etc/nginx/.htpasswd-posterg username_to_delete
ssh xamxam
sudo htpasswd -D /etc/nginx/.htpasswd-xamxam username_to_delete
```
### Reset Everything (Start Fresh)
```bash
ssh posterg
sudo htpasswd -c /etc/nginx/.htpasswd-posterg new_username
ssh xamxam
sudo htpasswd -c /etc/nginx/.htpasswd-xamxam new_username
```
⚠️ **Warning:** The `-c` flag creates a new file, deleting all existing users!
@@ -78,7 +78,7 @@ To upload the interactive management script to the server:
just manage-admin-users
# Or manually:
rsync -v scripts/manage-admin-users.sh posterg:/tmp/manage-admin-users.sh
rsync -v scripts/manage-admin-users.sh xamxam:/tmp/manage-admin-users.sh
```
---
@@ -86,7 +86,7 @@ rsync -v scripts/manage-admin-users.sh posterg:/tmp/manage-admin-users.sh
## 🔑 Current Setup
After deployment, your admin panel has:
- **URL:** https://posterg.erg.be/admin/
- **URL:** https://xamxam.erg.be/admin/
- **Current user:** `test_posterg_22@`
- **Password:** Set during initial deployment
@@ -97,8 +97,8 @@ After deployment, your admin panel has:
### Scenario 1: Change Current Password
```bash
ssh posterg
sudo htpasswd /etc/nginx/.htpasswd-posterg test_posterg_22@
ssh xamxam
sudo htpasswd /etc/nginx/.htpasswd-xamxam test_posterg_22@
# Enter new password when prompted
```
@@ -107,28 +107,28 @@ sudo htpasswd /etc/nginx/.htpasswd-posterg test_posterg_22@
Since you can't rename users, you need to:
```bash
ssh posterg
ssh xamxam
# Add new user
sudo htpasswd /etc/nginx/.htpasswd-posterg new_username
sudo htpasswd /etc/nginx/.htpasswd-xamxam new_username
# Delete old user
sudo htpasswd -D /etc/nginx/.htpasswd-posterg test_posterg_22@
sudo htpasswd -D /etc/nginx/.htpasswd-xamxam test_posterg_22@
```
### Scenario 3: Forgot Username
```bash
ssh posterg
sudo cut -d: -f1 /etc/nginx/.htpasswd-posterg
ssh xamxam
sudo cut -d: -f1 /etc/nginx/.htpasswd-xamxam
```
### Scenario 4: Multiple Admins
```bash
ssh posterg
ssh xamxam
# Add second admin
sudo htpasswd /etc/nginx/.htpasswd-posterg admin2
sudo htpasswd /etc/nginx/.htpasswd-xamxam admin2
# Add third admin
sudo htpasswd /etc/nginx/.htpasswd-posterg admin3
sudo htpasswd /etc/nginx/.htpasswd-xamxam admin3
```
All users can log into `/admin/` with their own credentials.
@@ -136,9 +136,9 @@ All users can log into `/admin/` with their own credentials.
### Scenario 5: Start Over with New Username
```bash
ssh posterg
ssh xamxam
# This will DELETE ALL existing users and create a new one
sudo htpasswd -c /etc/nginx/.htpasswd-posterg new_admin
sudo htpasswd -c /etc/nginx/.htpasswd-xamxam new_admin
```
---
@@ -149,11 +149,11 @@ After changing users/passwords:
```bash
# Test that password is required
curl -I https://posterg.erg.be/admin/
curl -I https://xamxam.erg.be/admin/
# Should return: 401 Unauthorized
# Test with credentials
curl -u username:password https://posterg.erg.be/admin/
curl -u username:password https://xamxam.erg.be/admin/
# Should return: 200 OK
```
@@ -163,7 +163,7 @@ No nginx reload needed - changes take effect immediately!
## 📊 Password File Details
**Location:** `/etc/nginx/.htpasswd-posterg`
**Location:** `/etc/nginx/.htpasswd-xamxam`
**Format:** Standard Apache htpasswd format
```
@@ -172,7 +172,7 @@ username:$apr1$encrypted_password_hash
**Permissions:**
```bash
-rw-r--r-- root root /etc/nginx/.htpasswd-posterg
-rw-r--r-- root root /etc/nginx/.htpasswd-xamxam
```
---
@@ -187,7 +187,7 @@ username:$apr1$encrypted_password_hash
2. **Avoid Common Usernames**
- ❌ Bad: `admin`, `administrator`, `root`
- ✅ Good: `posterg_admin`, `erg_webmaster`
- ✅ Good: `xamxam_admin`, `erg_webmaster`
3. **Regular Password Changes**
- Change passwords every 3-6 months
@@ -196,14 +196,14 @@ username:$apr1$encrypted_password_hash
4. **Monitor Access**
```bash
# Check who's accessing the admin panel
ssh posterg
sudo grep "admin" /var/log/nginx/posterg_access.log
ssh xamxam
sudo grep "admin" /var/log/nginx/xamxam_access.log
```
5. **Backup Password File**
```bash
ssh posterg
sudo cp /etc/nginx/.htpasswd-posterg /etc/nginx/.htpasswd-posterg.backup
ssh xamxam
sudo cp /etc/nginx/.htpasswd-xamxam /etc/nginx/.htpasswd-xamxam.backup
```
---
@@ -214,25 +214,25 @@ username:$apr1$encrypted_password_hash
**Check file exists:**
```bash
ssh posterg
ls -la /etc/nginx/.htpasswd-posterg
ssh xamxam
ls -la /etc/nginx/.htpasswd-xamxam
```
**Verify user exists:**
```bash
sudo cat /etc/nginx/.htpasswd-posterg
sudo cat /etc/nginx/.htpasswd-xamxam
```
**Check nginx config:**
```bash
sudo grep -A 5 "auth_basic" /etc/nginx/sites-available/posterg
sudo grep -A 5 "auth_basic" /etc/nginx/sites-available/xamxam
```
### Can't change password - "command not found"
**Install apache2-utils:**
```bash
ssh posterg
ssh xamxam
sudo apt update
sudo apt install apache2-utils
```
@@ -241,8 +241,8 @@ sudo apt install apache2-utils
**Recreate it:**
```bash
ssh posterg
sudo htpasswd -c /etc/nginx/.htpasswd-posterg new_admin
ssh xamxam
sudo htpasswd -c /etc/nginx/.htpasswd-xamxam new_admin
```
---
@@ -252,11 +252,11 @@ sudo htpasswd -c /etc/nginx/.htpasswd-posterg new_admin
| Task | Command |
|------|---------|
| **Interactive menu** | `sudo bash /tmp/manage-admin-users.sh` |
| **List users** | `sudo cut -d: -f1 /etc/nginx/.htpasswd-posterg` |
| **Change password** | `sudo htpasswd /etc/nginx/.htpasswd-posterg username` |
| **Add user** | `sudo htpasswd /etc/nginx/.htpasswd-posterg newuser` |
| **Delete user** | `sudo htpasswd -D /etc/nginx/.htpasswd-posterg username` |
| **Reset all** | `sudo htpasswd -c /etc/nginx/.htpasswd-posterg newuser` |
| **List users** | `sudo cut -d: -f1 /etc/nginx/.htpasswd-xamxam` |
| **Change password** | `sudo htpasswd /etc/nginx/.htpasswd-xamxam username` |
| **Add user** | `sudo htpasswd /etc/nginx/.htpasswd-xamxam newuser` |
| **Delete user** | `sudo htpasswd -D /etc/nginx/.htpasswd-xamxam username` |
| **Reset all** | `sudo htpasswd -c /etc/nginx/.htpasswd-xamxam newuser` |
| **Generate password** | `openssl rand -base64 32` |
---
@@ -267,7 +267,7 @@ No action needed! Changes to the password file take effect immediately.
You can verify with:
```bash
curl -u username:password https://posterg.erg.be/admin/
curl -u username:password https://xamxam.erg.be/admin/
```
---

View File

@@ -4,11 +4,11 @@
> directives that nginx **silently ignores**. None of the rules were active
> in production.
> **Status:** Migrated into `nginx/posterg.conf`
> **Status:** Migrated into `nginx/xamxam.conf`
---
## Rules migrated into `nginx/posterg.conf`
## Rules migrated into `nginx/xamxam.conf`
| Apache `.htaccess` rule | nginx equivalent | Location |
|---|---|---|

View File

@@ -10,7 +10,7 @@ The admin panel uses **two independent authentication layers** with a single UX
| Layer | Mechanism | Configured by |
|-------|-----------|---------------|
| **1st** | nginx HTTP Basic Auth | `/etc/nginx/.htpasswd-posterg` (see `ADMIN_USERS.md`) |
| **1st** | nginx HTTP Basic Auth | `/etc/nginx/.htpasswd-xamxam` (see `ADMIN_USERS.md`) |
| **2nd** | PHP session guard (`src/AdminAuth.php`) | `config/admin_credentials.php` |
The user only sees **one prompt** (the browser Basic Auth dialog). PHP reads the

View File

@@ -4,10 +4,10 @@ This guide covers deploying the production nginx configuration with proper secur
## 🎯 Overview
- **Server**: posterg.erg.be (internal IP: 192.168.6.125)
- **Server**: xamxam.erg.be (internal IP: 192.168.6.125)
- **PHP Version**: 8.4
- **SSL/TLS**: Handled by upstream reverse proxy
- **Document Root**: `/var/www/posterg/public/`
- **Document Root**: `/var/www/xamxam/public/`
## 🚀 Quick Deployment
@@ -18,13 +18,13 @@ From your local machine:
just deploy-nginx
# Then on the server:
ssh posterg
ssh xamxam
sudo bash /tmp/deploy-server.sh
sudo systemctl reload nginx
```
This uploads:
- `nginx/posterg.conf``/tmp/posterg.conf`
- `nginx/xamxam.conf``/tmp/xamxam.conf`
- `scripts/deploy-server.sh``/tmp/deploy-server.sh`
## 📋 Step-by-Step Deployment
@@ -32,8 +32,8 @@ This uploads:
### 1. Set Up Admin Password (First Time Only)
```bash
ssh posterg
sudo htpasswd -c /etc/nginx/.htpasswd-posterg admin
ssh xamxam
sudo htpasswd -c /etc/nginx/.htpasswd-xamxam admin
# Enter a strong password when prompted
```
@@ -54,7 +54,7 @@ sudo systemctl reload nginx
```
The script will:
- ✅ Fix file permissions (set to www-data:posterg)
- ✅ Fix file permissions (set to www-data:xamxam)
- ✅ Install nginx configuration
- ✅ Test nginx configuration
- ✅ Check PHP-FPM status
@@ -64,10 +64,10 @@ The script will:
### Step 1: Fix Permissions
```bash
ssh posterg
ssh xamxam
# Set correct ownership
sudo chown -R www-data:posterg /var/www/posterg/
sudo chown -R www-data:xamxam /var/www/xamxam/
# Set directory permissions
sudo find /var/www/posterg -type d -exec chmod 755 {} \;
@@ -76,21 +76,21 @@ sudo find /var/www/posterg -type d -exec chmod 755 {} \;
sudo find /var/www/posterg -type f -exec chmod 644 {} \;
# Make storage writable
sudo chmod 775 /var/www/posterg/storage
sudo chmod 775 /var/www/xamxam/storage
# Protect database
sudo chmod 660 /var/www/posterg/storage/test.db
sudo chown www-data:posterg /var/www/posterg/storage/test.db
sudo chmod 660 /var/www/xamxam/storage/test.db
sudo chown www-data:xamxam /var/www/xamxam/storage/test.db
```
### Step 2: Deploy Nginx Config
```bash
# Copy config
sudo cp /tmp/posterg.conf /etc/nginx/sites-available/posterg
sudo cp /tmp/xamxam.conf /etc/nginx/sites-available/xamxam
# Enable site and disable default
sudo ln -sf /etc/nginx/sites-available/posterg /etc/nginx/sites-enabled/posterg
sudo ln -sf /etc/nginx/sites-available/xamxam /etc/nginx/sites-enabled/xamxam
sudo rm -f /etc/nginx/sites-enabled/default
# Test and reload
@@ -104,32 +104,32 @@ sudo systemctl reload nginx
```bash
# Should return 200 OK
curl -I https://posterg.erg.be/
curl -I https://xamxam.erg.be/
```
### Test Admin Protection
```bash
# Should return 401 Unauthorized
curl -I https://posterg.erg.be/admin/
curl -I https://xamxam.erg.be/admin/
# With credentials
curl -u admin:your_password https://posterg.erg.be/admin/
curl -u admin:your_password https://xamxam.erg.be/admin/
```
### Test File Protection
```bash
# Should return 403 Forbidden
curl -I https://posterg.erg.be/storage/test.db
curl -I https://posterg.erg.be/src/Database.php
curl -I https://posterg.erg.be/config/bootstrap.php
curl -I https://xamxam.erg.be/storage/test.db
curl -I https://xamxam.erg.be/src/Database.php
curl -I https://xamxam.erg.be/config/bootstrap.php
```
### Test Security Headers
```bash
curl -I https://posterg.erg.be/ | grep -E "X-Frame|X-Content|Strict-Transport"
curl -I https://xamxam.erg.be/ | grep -E "X-Frame|X-Content|Strict-Transport"
```
## 🔍 Troubleshooting
@@ -138,8 +138,8 @@ curl -I https://posterg.erg.be/ | grep -E "X-Frame|X-Content|Strict-Transport"
**Check file permissions:**
```bash
ls -la /var/www/posterg/public/index.php
groups www-data # Should include posterg
ls -la /var/www/xamxam/public/index.php
groups www-data # Should include xamxam
```
### 502 Bad Gateway
@@ -153,15 +153,15 @@ sudo systemctl restart php8.4-fpm
### Admin Password Not Working
```bash
sudo htpasswd /etc/nginx/.htpasswd-posterg admin
sudo htpasswd /etc/nginx/.htpasswd-xamxam admin
```
## 📊 Monitoring
```bash
# Watch logs
sudo tail -f /var/log/nginx/posterg_access.log
sudo tail -f /var/log/nginx/posterg_error.log
sudo tail -f /var/log/nginx/xamxam_access.log
sudo tail -f /var/log/nginx/xamxam_error.log
# Check status
sudo systemctl status nginx
@@ -171,7 +171,7 @@ sudo systemctl status nginx
After deployment, verify:
- [ ] Public site accessible at https://posterg.erg.be/
- [ ] Public site accessible at https://xamxam.erg.be/
- [ ] Admin panel requires password
- [ ] Database files return 403 Forbidden
- [ ] Source files return 403 Forbidden
@@ -185,19 +185,19 @@ After deployment, verify:
just deploy
# Reload nginx if config changed
ssh posterg "sudo systemctl reload nginx"
ssh xamxam "sudo systemctl reload nginx"
```
## 🆘 Emergency Recovery
```bash
# Restore default nginx config
ssh posterg
sudo rm /etc/nginx/sites-enabled/posterg
ssh xamxam
sudo rm /etc/nginx/sites-enabled/xamxam
sudo systemctl reload nginx
# Reset permissions
sudo chown -R www-data:posterg /var/www/posterg/
sudo chown -R www-data:xamxam /var/www/xamxam/
sudo find /var/www/posterg -type d -exec chmod 755 {} \;
sudo find /var/www/posterg -type f -exec chmod 644 {} \;
```

View File

@@ -4,8 +4,8 @@
```bash
# Copy nginx config
sudo cp nginx/posterg.conf /etc/nginx/sites-available/posterg
sudo ln -s /etc/nginx/sites-available/posterg /etc/nginx/sites-enabled/
sudo cp nginx/xamxam.conf /etc/nginx/sites-available/xamxam
sudo ln -s /etc/nginx/sites-available/xamxam /etc/nginx/sites-enabled/
sudo rm -f /etc/nginx/sites-enabled/default
# Test and reload
@@ -23,16 +23,16 @@ sudo bash /tmp/manage-admin-users.sh
# Or manual commands:
# Add new user
sudo htpasswd /etc/nginx/.htpasswd-posterg username
sudo htpasswd /etc/nginx/.htpasswd-xamxam username
# Change password for existing user
sudo htpasswd /etc/nginx/.htpasswd-posterg username
sudo htpasswd /etc/nginx/.htpasswd-xamxam username
# Remove user
sudo htpasswd -D /etc/nginx/.htpasswd-posterg username
sudo htpasswd -D /etc/nginx/.htpasswd-xamxam username
# List all users
sudo cut -d: -f1 /etc/nginx/.htpasswd-posterg
sudo cut -d: -f1 /etc/nginx/.htpasswd-xamxam
```
### Nginx Control
@@ -61,26 +61,26 @@ sudo systemctl status nginx
```bash
# Public site access log
sudo tail -f /var/log/nginx/posterg_access.log
sudo tail -f /var/log/nginx/xamxam_access.log
# Public site errors
sudo tail -f /var/log/nginx/posterg_error.log
sudo tail -f /var/log/nginx/xamxam_error.log
# SSL access log
sudo tail -f /var/log/nginx/posterg_ssl_access.log
sudo tail -f /var/log/nginx/xamxam_ssl_access.log
# Search for specific pattern
sudo grep "404" /var/log/nginx/posterg_access.log
sudo grep "404" /var/log/nginx/xamxam_access.log
# Count requests by IP
sudo awk '{print $1}' /var/log/nginx/posterg_access.log | sort | uniq -c | sort -nr | head
sudo awk '{print $1}' /var/log/nginx/xamxam_access.log | sort | uniq -c | sort -nr | head
```
### SSL/HTTPS
```bash
# Get SSL certificate (Let's Encrypt)
sudo certbot --nginx -d posterg.erg.be -d www.posterg.erg.be
sudo certbot --nginx -d xamxam.erg.be -d www.xamxam.erg.be
# Renew certificates
sudo certbot renew
@@ -98,10 +98,10 @@ sudo certbot renew --dry-run
```bash
# Should require password (returns 401)
curl -I https://posterg.erg.be/admin/
curl -I https://xamxam.erg.be/admin/
# With authentication
curl -u admin:password https://posterg.erg.be/admin/
curl -u admin:password https://xamxam.erg.be/admin/
```
### Test Rate Limiting
@@ -109,7 +109,7 @@ curl -u admin:password https://posterg.erg.be/admin/
```bash
# Should show increasing 429 responses after limit
for i in {1..50}; do
curl -s -o /dev/null -w "%{http_code}\n" https://posterg.erg.be/
curl -s -o /dev/null -w "%{http_code}\n" https://xamxam.erg.be/
done
```
@@ -117,16 +117,16 @@ done
```bash
# Should return 403
curl -I https://posterg.erg.be/storage/posterg.db
curl -I https://posterg.erg.be/shared/Database.php
curl -I https://posterg.erg.be/.env
curl -I https://xamxam.erg.be/storage/xamxam.db
curl -I https://xamxam.erg.be/shared/Database.php
curl -I https://xamxam.erg.be/.env
```
### Test Security Headers
```bash
# Check all security headers
curl -I https://posterg.erg.be/ 2>&1 | grep -E "X-|Strict-Transport|Referrer|Permissions"
curl -I https://xamxam.erg.be/ 2>&1 | grep -E "X-|Strict-Transport|Referrer|Permissions"
```
## Troubleshooting
@@ -136,10 +136,10 @@ curl -I https://posterg.erg.be/ 2>&1 | grep -E "X-|Strict-Transport|Referrer|Per
**403 Forbidden on admin**
```bash
# Check htpasswd file exists
sudo ls -l /etc/nginx/.htpasswd-posterg
sudo ls -l /etc/nginx/.htpasswd-xamxam
# Check permissions
sudo chmod 644 /etc/nginx/.htpasswd-posterg
sudo chmod 644 /etc/nginx/.htpasswd-xamxam
```
**502 Bad Gateway**
@@ -167,10 +167,10 @@ sudo tail -50 /var/log/nginx/error.log
```bash
# Disable password protection temporarily
sudo nano /etc/nginx/sites-available/posterg
sudo nano /etc/nginx/sites-available/xamxam
# Comment out these lines in /admin/ location:
# auth_basic "Admin Access - Post-ERG";
# auth_basic_user_file /etc/nginx/.htpasswd-posterg;
# auth_basic_user_file /etc/nginx/.htpasswd-xamxam;
# Reload nginx
sudo nginx -t && sudo systemctl reload nginx
@@ -186,7 +186,7 @@ sudo ss -tulpn | grep nginx
watch -n 1 'ps aux | grep nginx'
# Check request rate
sudo tail -f /var/log/nginx/posterg_access.log | pv -l -r > /dev/null
sudo tail -f /var/log/nginx/xamxam_access.log | pv -l -r > /dev/null
# Disk usage of logs
sudo du -sh /var/log/nginx/*
@@ -202,29 +202,29 @@ sudo nginx -s reopen
sudo find /var/log/nginx -name "*.log" -mtime +7 -delete
# Backup configuration
sudo cp /etc/nginx/sites-available/posterg /etc/nginx/sites-available/posterg.backup.$(date +%Y%m%d)
sudo cp /etc/nginx/sites-available/xamxam /etc/nginx/sites-available/xamxam.backup.$(date +%Y%m%d)
# Backup password file
sudo cp /etc/nginx/.htpasswd-posterg /etc/nginx/.htpasswd-posterg.backup.$(date +%Y%m%d)
sudo cp /etc/nginx/.htpasswd-xamxam /etc/nginx/.htpasswd-xamxam.backup.$(date +%Y%m%d)
```
## Security Checklist
- [ ] Admin password set: `sudo ls -l /etc/nginx/.htpasswd-posterg`
- [ ] SSL enabled: `curl -I https://posterg.erg.be/`
- [ ] Database blocked: `curl -I https://posterg.erg.be/storage/posterg.db`
- [ ] Shared directory blocked: `curl -I https://posterg.erg.be/shared/Database.php`
- [ ] Admin password set: `sudo ls -l /etc/nginx/.htpasswd-xamxam`
- [ ] SSL enabled: `curl -I https://xamxam.erg.be/`
- [ ] Database blocked: `curl -I https://xamxam.erg.be/storage/xamxam.db`
- [ ] Shared directory blocked: `curl -I https://xamxam.erg.be/shared/Database.php`
- [ ] Rate limiting working: Test with curl loop
- [ ] Security headers present: `curl -I https://posterg.erg.be/ | grep X-`
- [ ] Logs accessible: `sudo tail /var/log/nginx/posterg_access.log`
- [ ] Security headers present: `curl -I https://xamxam.erg.be/ | grep X-`
- [ ] Logs accessible: `sudo tail /var/log/nginx/xamxam_access.log`
## Configuration Paths
- **Nginx config**: `/etc/nginx/sites-available/posterg`
- **Password file**: `/etc/nginx/.htpasswd-posterg`
- **SSL certificates**: `/etc/letsencrypt/live/posterg.erg.be/`
- **Access logs**: `/var/log/nginx/posterg_access.log`
- **Error logs**: `/var/log/nginx/posterg_error.log`
- **Nginx config**: `/etc/nginx/sites-available/xamxam`
- **Password file**: `/etc/nginx/.htpasswd-xamxam`
- **SSL certificates**: `/etc/letsencrypt/live/xamxam.erg.be/`
- **Access logs**: `/var/log/nginx/xamxam_access.log`
- **Error logs**: `/var/log/nginx/xamxam_error.log`
- **PHP-FPM config**: `/etc/php/8.2/fpm/pool.d/www.conf`
- **PHP-FPM socket**: `/var/run/php/php8.2-fpm.sock`

View File

@@ -1,4 +1,4 @@
# Security Headers — nginx/posterg.conf
# Security Headers — nginx/xamxam.conf
## Headers in use (main server block — all pages)
@@ -18,7 +18,7 @@
These were previously declared in `public/admin/.htaccess` as Apache
`mod_headers` directives, which nginx silently ignores. They are now
properly configured in `nginx/posterg.conf`.
properly configured in `nginx/xamxam.conf`.
enforced directly; see `HTACCESS_TO_NGINX.md` for the full migration log.
## Intentionally omitted headers

View File

@@ -13,7 +13,7 @@ just deploy-db
This automatically:
1. ✅ Checks remote DB doesn't exist (safety check)
2. ✅ Uploads `storage/test.db` to the server
3. ✅ Sets correct permissions (660, www-data:posterg)
3. ✅ Sets correct permissions (660, www-data:xamxam)
---
@@ -22,7 +22,7 @@ This automatically:
### 1. Install PHP SQLite Extension
```bash
ssh posterg
ssh xamxam
sudo apt update
sudo apt install php8.4-sqlite3
sudo systemctl restart php8.4-fpm
@@ -31,7 +31,7 @@ sudo systemctl restart php8.4-fpm
### 2. Verify Installation
```bash
ssh posterg
ssh xamxam
php -m | grep sqlite3
# Should output: pdo_sqlite, sqlite3
```
@@ -58,20 +58,20 @@ just deploy-db
### 3. Test the Site
Visit: https://posterg.erg.be/
Visit: https://xamxam.erg.be/
### 4. Check What Database is Being Used
```bash
ssh posterg
php -r "require_once '/var/www/posterg/src/Database.php'; echo 'Using: ' . Database::getInstance()->getDatabasePath() . PHP_EOL;"
ssh xamxam
php -r "require_once '/var/www/xamxam/src/Database.php'; echo 'Using: ' . Database::getInstance()->getDatabasePath() . PHP_EOL;"
```
### 5. Switch Back to Production
```bash
ssh posterg
rm /var/www/posterg/storage/test.db
ssh xamxam
rm /var/www/xamxam/storage/test.db
```
---
@@ -79,11 +79,11 @@ rm /var/www/posterg/storage/test.db
## 🔒 Permissions Explained
```
/var/www/posterg/storage/
drwxrwxr-x www-data posterg # 775 - group writable
/var/www/xamxam/storage/
drwxrwxr-x www-data xamxam # 775 - group writable
/var/www/posterg/storage/test.db
-rw-rw---- www-data posterg # 660 - owner/group read/write
/var/www/xamxam/storage/test.db
-rw-rw---- www-data xamxam # 660 - owner/group read/write
```
---
@@ -93,7 +93,7 @@ drwxrwxr-x www-data posterg # 775 - group writable
### "could not find driver"
```bash
ssh posterg
ssh xamxam
sudo apt install php8.4-sqlite3
sudo systemctl restart php8.4-fpm
```
@@ -101,18 +101,18 @@ sudo systemctl restart php8.4-fpm
### "unable to open database file"
```bash
ssh posterg
chown www-data:posterg /var/www/posterg/storage/test.db
chmod 660 /var/www/posterg/storage/test.db
chmod 775 /var/www/posterg/storage/
ssh xamxam
chown www-data:xamxam /var/www/xamxam/storage/test.db
chmod 660 /var/www/xamxam/storage/test.db
chmod 775 /var/www/xamxam/storage/
```
### "attempt to write a readonly database"
```bash
ssh posterg
chmod 775 /var/www/posterg/storage/
rm -f /var/www/posterg/storage/test.db-*
ssh xamxam
chmod 775 /var/www/xamxam/storage/
rm -f /var/www/xamxam/storage/test.db-*
```
---
@@ -126,8 +126,8 @@ rm -f /var/www/posterg/storage/test.db-*
### Backup Production Database
```bash
ssh posterg
cp /var/www/posterg/storage/posterg.db /var/www/posterg/storage/posterg.db.backup.$(date +%Y%m%d)
ssh xamxam
cp /var/www/xamxam/storage/posterg.db /var/www/xamxam/storage/posterg.db.backup.$(date +%Y%m%d)
```
---
@@ -146,7 +146,7 @@ cp /var/www/posterg/storage/posterg.db /var/www/posterg/storage/posterg.db.backu
After running `just deploy-db`, verify:
- [ ] Database file exists: `ssh posterg "ls -la /var/www/posterg/storage/test.db"`
- [ ] Correct permissions: `-rw-rw---- www-data posterg`
- [ ] Site loads: Visit https://posterg.erg.be/
- [ ] No errors in logs: `ssh posterg "tail /var/log/nginx/posterg_error.log"`
- [ ] Database file exists: `ssh xamxam "ls -la /var/www/xamxam/storage/test.db"`
- [ ] Correct permissions: `-rw-rw---- www-data xamxam`
- [ ] Site loads: Visit https://xamxam.erg.be/
- [ ] No errors in logs: `ssh xamxam "tail /var/log/nginx/xamxam_error.log"`

View File

@@ -1,6 +1,6 @@
# Nginx configuration for Post-ERG thesis website (Production)
# Place this in /etc/nginx/sites-available/posterg
# Then symlink: ln -s /etc/nginx/sites-available/posterg /etc/nginx/sites-enabled/
# Nginx configuration for XAMXAM thesis website (Production)
# Place this in /etc/nginx/sites-available/xamxam
# Then symlink: ln -s /etc/nginx/sites-available/xamxam /etc/nginx/sites-enabled/
# Rate limiting zones
limit_req_zone $binary_remote_addr zone=general:10m rate=30r/m;
@@ -15,7 +15,7 @@ server {
listen 80 default_server;
listen [::]:80 default_server;
server_name posterg.erg.be www.posterg.erg.be;
server_name xamxam.erg.be www.xamxam.erg.be;
# Document root points to /public (only web-accessible files)
# Deployed structure: /var/www/xamxam/
@@ -49,8 +49,8 @@ server {
client_body_timeout 120s;
# Logging
access_log /var/log/nginx/posterg_access.log;
error_log /var/log/nginx/posterg_error.log warn;
access_log /var/log/nginx/xamxam_access.log;
error_log /var/log/nginx/xamxam_error.log warn;
# Block access to hidden files (except .well-known for Let's Encrypt)
location ~ /\.(?!well-known).* {
@@ -115,7 +115,7 @@ server {
location ^~ /admin/ {
# HTTP Basic Authentication (first layer)
auth_basic "Admin Access - Post-ERG";
auth_basic_user_file /etc/nginx/.htpasswd-posterg;
auth_basic_user_file /etc/nginx/.htpasswd-xamxam;
# Rate limiting for admin
limit_req zone=admin burst=20 nodelay;

View File

@@ -1,7 +1,7 @@
# Nginx configuration for Post-ERG thesis website (Production)
# Updated for new directory structure
# Place this in /etc/nginx/sites-available/posterg
# Then symlink: ln -s /etc/nginx/sites-available/posterg /etc/nginx/sites-enabled/
# Place this in /etc/nginx/sites-available/xamxam
# Then symlink: ln -s /etc/nginx/sites-available/xamxam /etc/nginx/sites-enabled/
# Rate limiting zones
limit_req_zone $binary_remote_addr zone=general:10m rate=30r/m;
@@ -13,10 +13,10 @@ server {
listen 80 default_server;
listen [::]:80 default_server;
server_name posterg.erg.be www.posterg.erg.be;
server_name xamxam.erg.be www.xamxam.erg.be;
# Document root points to /public (only web-accessible files)
# Project structure: /var/www/posterg/
# Project structure: /var/www/xamxam/
# /config - Configuration (outside webroot)
# /docs - Documentation (outside webroot)
# /nginx - Server configs (outside webroot)
@@ -28,7 +28,7 @@ server {
# /storage - SQLite databases (outside webroot)
# /templates - PHP templates (outside webroot)
# /tests - Test suites (outside webroot)
root /var/www/posterg/public;
root /var/www/xamxam/public;
# Add index.php to the list
index index.php index.html index.htm;
@@ -49,8 +49,8 @@ server {
client_body_timeout 120s;
# Logging
access_log /var/log/nginx/posterg_access.log;
error_log /var/log/nginx/posterg_error.log warn;
access_log /var/log/nginx/xamxam_access.log;
error_log /var/log/nginx/xamxam_error.log warn;
# Block access to hidden files (except .well-known for Let's Encrypt)
location ~ /\.(?!well-known).* {
@@ -115,7 +115,7 @@ server {
location ^~ /admin/ {
# HTTP Basic Authentication (first layer)
auth_basic "Admin Access - Post-ERG";
auth_basic_user_file /etc/nginx/.htpasswd-posterg;
auth_basic_user_file /etc/nginx/.htpasswd-xamxam;
# Rate limiting for admin
limit_req zone=admin burst=5 nodelay;

View File

@@ -8,12 +8,12 @@ echo "Creating investigation directory..."
mkdir -p ~/crash_investigation
echo "Copying nginx logs..."
sudo cp /var/log/nginx/posterg_error.log ~/crash_investigation/
sudo cp /var/log/nginx/posterg_error.log.1 ~/crash_investigation/ 2>/dev/null || true
sudo cp /var/log/nginx/posterg_access.log ~/crash_investigation/
sudo cp /var/log/nginx/posterg_access.log.1 ~/crash_investigation/ 2>/dev/null || true
sudo cp /var/log/nginx/posterg_error.log.2.gz ~/crash_investigation/ 2>/dev/null || true
sudo cp /var/log/nginx/posterg_access.log.2.gz ~/crash_investigation/ 2>/dev/null || true
sudo cp /var/log/nginx/xamxam_error.log ~/crash_investigation/
sudo cp /var/log/nginx/xamxam_error.log.1 ~/crash_investigation/ 2>/dev/null || true
sudo cp /var/log/nginx/xamxam_access.log ~/crash_investigation/
sudo cp /var/log/nginx/xamxam_access.log.1 ~/crash_investigation/ 2>/dev/null || true
sudo cp /var/log/nginx/xamxam_error.log.2.gz ~/crash_investigation/ 2>/dev/null || true
sudo cp /var/log/nginx/xamxam_access.log.2.gz ~/crash_investigation/ 2>/dev/null || true
echo "Exporting journal from previous boot..."
sudo journalctl -b -1 --no-pager > ~/crash_investigation/journal_previous_boot.log 2>&1
@@ -50,4 +50,4 @@ echo "Total size:"
du -sh ~/crash_investigation/
echo ""
echo "To download to your local machine, run:"
echo " scp -P 3274 -r theophile@posterg.erg.be:~/crash_investigation/ ."
echo " scp -P 3274 -r theophile@xamxam.erg.be:~/crash_investigation/ ."

View File

@@ -1,6 +1,6 @@
#!/bin/bash
# Deploy production nginx configuration for Post-ERG
# Fixes permissions and installs /tmp/posterg.conf into nginx sites-available.
# Deploy production nginx configuration for XAMXAM
# Fixes permissions and installs /tmp/xamxam.conf into nginx sites-available.
#
# Usage: just deploy-nginx (uploads script + config, then runs this)
# or: sudo bash /tmp/deploy-server.sh
@@ -27,8 +27,8 @@ printf "==================================\n\n"
printf "📋 Step 1: Fixing file permissions...\n"
echo "--------------------------------------"
chown -R www-data:posterg /var/www/xamxam/
ok "Ownership: www-data:posterg"
chown -R www-data:xamxam /var/www/xamxam/
ok "Ownership: www-data:xamxam"
find /var/www/xamxam -type d -exec chmod 2775 {} \;
ok "Directories: 2775 (setgid)"
@@ -44,30 +44,30 @@ fi
# Ensure writable cache subdirectories exist for php-fpm (www-data)
mkdir -p /var/www/xamxam/storage/cache/rate_limit
chown -R www-data:posterg /var/www/xamxam/storage/cache
chown -R www-data:xamxam /var/www/xamxam/storage/cache
chmod -R 2775 /var/www/xamxam/storage/cache
ok "Cache dirs: created and owned by www-data:posterg"
ok "Cache dirs: created and owned by www-data:xamxam"
# ── Step 2: Nginx config ──────────────────────────────────────────────────────
printf "\n📋 Step 2: Deploying nginx configuration...\n"
echo "--------------------------------------------"
if [ ! -f "/tmp/posterg.conf" ]; then
err "/tmp/posterg.conf not found — run: just deploy-nginx"
if [ ! -f "/tmp/xamxam.conf" ]; then
err "/tmp/xamxam.conf not found — run: just deploy-nginx"
exit 1
fi
if [ -f "/etc/nginx/sites-available/posterg" ]; then
cp /etc/nginx/sites-available/posterg \
"/etc/nginx/sites-available/posterg.backup.$(date +%Y%m%d_%H%M%S)"
if [ -f "/etc/nginx/sites-available/xamxam" ]; then
cp /etc/nginx/sites-available/xamxam \
"/etc/nginx/sites-available/xamxam.backup.$(date +%Y%m%d_%H%M%S)"
ok "Backed up existing config"
fi
cp /tmp/posterg.conf /etc/nginx/sites-available/posterg
cp /tmp/xamxam.conf /etc/nginx/sites-available/xamxam
ok "Installed new nginx config"
if [ ! -L "/etc/nginx/sites-enabled/posterg" ]; then
ln -s /etc/nginx/sites-available/posterg /etc/nginx/sites-enabled/posterg
if [ ! -L "/etc/nginx/sites-enabled/xamxam" ]; then
ln -s /etc/nginx/sites-available/xamxam /etc/nginx/sites-enabled/xamxam
ok "Created sites-enabled symlink"
fi
@@ -79,8 +79,8 @@ if nginx -t 2>&1; then
ok "Nginx configuration is valid"
else
err "Nginx configuration has errors — restoring backup"
latest=$(ls -t /etc/nginx/sites-available/posterg.backup.* 2>/dev/null | head -1)
[ -n "$latest" ] && cp "$latest" /etc/nginx/sites-available/posterg
latest=$(ls -t /etc/nginx/sites-available/xamxam.backup.* 2>/dev/null | head -1)
[ -n "$latest" ] && cp "$latest" /etc/nginx/sites-available/xamxam
exit 1
fi
@@ -99,6 +99,6 @@ ok "Nginx config installed"
ok "Configuration validated"
ok "Nginx reloaded"
printf "\nVerify:\n"
printf " https://posterg.erg.be/\n"
printf " https://posterg.erg.be/admin/\n"
printf " https://posterg.erg.be/storage/posterg.db (should 403/404)\n"
printf " https://xamxam.erg.be/\n"
printf " https://xamxam.erg.be/admin/\n"
printf " https://xamxam.erg.be/storage/xamxam.db (should 403/404)\n"

View File

@@ -10,7 +10,7 @@ YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
PASSWORD_FILE="/etc/nginx/.htpasswd-posterg"
PASSWORD_FILE="/etc/nginx/.htpasswd-xamxam"
# Check if running as root
if [ "$EUID" -ne 0 ]; then

View File

@@ -2,14 +2,14 @@
# Initialise the Post-ERG SQLite database from schema.sql.
# Safe to run on existing databases — schema uses IF NOT EXISTS / INSERT OR IGNORE.
# Usage:
# scripts/migrate.sh # posterg.db (default)
# scripts/migrate.sh # xamxam.db (default)
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
APP_DIR="$REPO_ROOT/app"
SCHEMA="$APP_DIR/storage/schema.sql"
PROD_DB="$APP_DIR/storage/posterg.db"
PROD_DB="$APP_DIR/storage/xamxam.db"
init_db() {
local db="$1"
@@ -19,4 +19,4 @@ init_db() {
echo " [$label] done"
}
init_db "$PROD_DB" "posterg.db"
init_db "$PROD_DB" "xamxam.db"

View File

@@ -34,12 +34,12 @@ else
echo "✓ Cloned php-live-reload"
fi
# Create posterg.db if needed
if [ ! -f "storage/posterg.db" ]; then
# Create xamxam.db if needed
if [ ! -f "storage/xamxam.db" ]; then
echo ""
echo "📊 Creating posterg.db…"
sqlite3 storage/posterg.db < storage/schema.sql
echo "✓ Created posterg.db"
echo "📊 Creating xamxam.db…"
sqlite3 storage/xamxam.db < storage/schema.sql
echo "✓ Created xamxam.db"
fi
# Create data directories

View File

@@ -22,18 +22,18 @@ die() { printf "${RED}✗${NC} %s\n" "$*" >&2; exit 1; }
# ── Config ────────────────────────────────────────────────────────────────────
# DEPLOY_USER is passed explicitly by the justfile (read from ~/.ssh/config via
# `ssh -G posterg`). Falls back to $SUDO_USER if run manually with sudo.
# `ssh -G xamxam`). Falls back to $SUDO_USER if run manually with sudo.
DEPLOY_USER="${DEPLOY_USER:-${SUDO_USER}}"
[ -n "$DEPLOY_USER" ] || die "DEPLOY_USER is not set. Pass it explicitly: sudo DEPLOY_USER=youruser bash $0"
APP_DIR="/var/www/posterg"
APP_GROUP="posterg"
APP_DIR="/var/www/xamxam"
APP_GROUP="xamxam"
WEB_USER="www-data"
# ─────────────────────────────────────────────────────────────────────────────
printf "🔧 Post-ERG Server Setup\n"
printf "========================\n\n"
# ── 1. Create posterg group ───────────────────────────────────────────────────
# ── 1. Create xamxam group ───────────────────────────────────────────────────
if ! getent group "$APP_GROUP" >/dev/null; then
groupadd "$APP_GROUP"
ok "Created group: $APP_GROUP"
@@ -65,9 +65,9 @@ ok "Ownership: $WEB_USER:$APP_GROUP on $APP_DIR"
# ── 5. Set directory permissions with setgid ──────────────────────────────────
# 2775 = rwxrwsr-x
# - owner (www-data) and group (posterg) can read/write/execute
# - setgid bit ensures new files/dirs inherit the posterg group
# - this is what allows rsync --chown=www-data:posterg to succeed
# - owner (www-data) and group (xamxam) can read/write/execute
# - setgid bit ensures new files/dirs inherit the xamxam group
# - this is what allows rsync --chown=www-data:xamxam to succeed
find "$APP_DIR" -type d -exec chmod 2775 {} \;
ok "Directories: 2775 (setgid) on $APP_DIR/**"