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. Files are pushed to the server with rsync — there is no repo on the remote.
```bash ```bash
just deploy # rsync app files → posterg:/var/www/posterg/ just deploy # rsync app files → xamxam:/var/www/xamxam/
just deploy-db # push local posterg.db → remote (only if remote DB is absent) 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 `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 ### First-time server setup
```bash ```bash
ssh posterg ssh xamxam
sudo mkdir -p /var/www/posterg sudo mkdir -p /var/www/xamxam
sudo chown www-data:posterg /var/www/posterg sudo chown www-data:xamxam /var/www/xamxam
sudo chmod 775 /var/www/posterg sudo chmod 775 /var/www/xamxam
exit exit
``` ```
@@ -70,7 +70,7 @@ just deploy-nginx
```bash ```bash
just manage-admin-users just manage-admin-users
# Then on server: # Then on server:
ssh posterg "sudo bash /tmp/manage-admin-users.sh" ssh xamxam "sudo bash /tmp/manage-admin-users.sh"
``` ```
## Security notes ## 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) - [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 ## CSS refactor
- [x] Move semantic HTML element baseline styles into common.css - [x] Move semantic HTML element baseline styles into common.css

View File

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

View File

@@ -12,7 +12,7 @@ AdminAuth::requireLogin();
require_once APP_ROOT . '/src/Controllers/ExportController.php'; require_once APP_ROOT . '/src/Controllers/ExportController.php';
$controller = ExportController::create(); $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-Type: text/csv; charset=UTF-8');
header('Content-Disposition: attachment; filename="' . $filename . '"'); header('Content-Disposition: attachment; filename="' . $filename . '"');

View File

@@ -18,7 +18,7 @@ if (!file_exists($dbPath)) {
exit('Base de données introuvable.'); 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-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $filename . '"'); header('Content-Disposition: attachment; filename="' . $filename . '"');

View File

@@ -38,7 +38,7 @@ foreach ($watchDirs as $dir) {
} }
$fingerprint = md5($hash); $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; $prev = file_exists($stateFile) ? file_get_contents($stateFile) : null;
// First visit: write baseline, don't fire a reload // First visit: write baseline, don't fire a reload

View File

@@ -18,7 +18,7 @@ class LiveReloadController {
$appRoot . '/config', $appRoot . '/config',
$appRoot . '/templates', $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 { public function handle(): array {

View File

@@ -29,7 +29,7 @@ class MediaController
} }
// 2. Resolve path + storage jail // 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; $fullPath = $storageRoot . '/' . $requestedPath;
$realStorage = realpath($storageRoot); $realStorage = realpath($storageRoot);

View File

@@ -23,17 +23,17 @@ class SystemController
// ── Constants ───────────────────────────────────────────────────────────── // ── Constants ─────────────────────────────────────────────────────────────
public const LOG_FILES = [ public const LOG_FILES = [
'nginx_access' => ['label' => 'nginx — accès', 'path' => '/var/log/nginx/posterg_access.log'], 'nginx_access' => ['label' => 'nginx — accès', 'path' => '/var/log/nginx/xamxam_access.log'],
'nginx_error' => ['label' => 'nginx — erreurs', 'path' => '/var/log/nginx/posterg_error.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'], 'php_error' => ['label' => 'PHP-FPM — erreurs', 'path' => '/var/log/php8.4-fpm.log'],
]; ];
public const ALLOWED_LINES = [50, 100, 200, 500]; public const ALLOWED_LINES = [50, 100, 200, 500];
/** Live deployed nginx config path. */ /** 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. */ /** 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 ────────────────────────────────────────────────────────────────── // ── TTLs ──────────────────────────────────────────────────────────────────
private const TTL_STATUS = 120; // 2 minutes private const TTL_STATUS = 120; // 2 minutes

View File

@@ -35,7 +35,7 @@ class Database {
/** /**
* Determine database path. * 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. * APP_ROOT is defined by bootstrap.php before any controller loads Database.
*/ */
private function determineDatabasePath($customPath = null): string { private function determineDatabasePath($customPath = null): string {
@@ -44,7 +44,7 @@ class Database {
} }
$root = defined('APP_ROOT') ? APP_ROOT : __DIR__ . '/..'; $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 // Build MIME message
$boundary = 'posterg_' . bin2hex(random_bytes(8)); $boundary = 'xamxam_' . bin2hex(random_bytes(8));
$date = date('r'); $date = date('r');
$fromHdr = ($s['from_name'] ?? '') !== '' $fromHdr = ($s['from_name'] ?? '') !== ''
? "=?UTF-8?B?" . base64_encode($s['from_name']) . "?= <{$s['from_email']}>" ? "=?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 ## 🛠️ Development Workflow
### Local Development ### Local Development
1. Use `posterg.db` for development 1. Use `xamxam.db` for development
2. Create via `just init-db` 2. Create via `just init-db`
3. Test queries before deployment 3. Test queries before deployment

View File

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

View File

@@ -30,7 +30,7 @@ logs:
[group('deploy')] [group('deploy')]
deploy: deploy:
rsync -vur --progress --delete \ rsync -vur --progress --delete \
--chown="www-data:posterg" \ --chown="www-data:xamxam" \
--exclude 'vendor' \ --exclude 'vendor' \
--exclude 'tests' \ --exclude 'tests' \
--exclude '*.md' \ --exclude '*.md' \
@@ -39,7 +39,7 @@ deploy:
--exclude '.claude' \ --exclude '.claude' \
--exclude '.pi' \ --exclude '.pi' \
--exclude '.DS_Store' \ --exclude '.DS_Store' \
--exclude 'storage/posterg.db' \ --exclude 'storage/xamxam.db' \
--exclude 'storage/theses' \ --exclude 'storage/theses' \
--exclude 'storage/covers' \ --exclude 'storage/covers' \
--exclude 'storage/backup_*' \ --exclude 'storage/backup_*' \
@@ -48,12 +48,12 @@ deploy:
--exclude 'storage/docs' \ --exclude 'storage/docs' \
--exclude 'var/cache/*' \ --exclude 'var/cache/*' \
--exclude 'var/logs/*' \ --exclude 'var/logs/*' \
app/ posterg:/var/www/xamxam/ app/ xamxam:/var/www/xamxam/
ssh posterg "mkdir -p /var/www/xamxam/var/{cache,logs,tmp}" ssh xamxam "mkdir -p /var/www/xamxam/var/{cache,logs,tmp}"
[group('deploy')] [group('deploy')]
setup-server: 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 ""
@echo "Script uploaded. SSH into the server and run:" @echo "Script uploaded. SSH into the server and run:"
@echo "" @echo ""
@@ -62,7 +62,7 @@ setup-server:
[group('deploy')] [group('deploy')]
manage-admin-users: 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 ""
@echo "Script uploaded. SSH into the server and run:" @echo "Script uploaded. SSH into the server and run:"
@echo "" @echo ""
@@ -71,8 +71,8 @@ manage-admin-users:
[group('deploy')] [group('deploy')]
deploy-nginx: deploy-nginx:
rsync -v nginx/posterg.conf posterg:/tmp/posterg.conf rsync -v nginx/xamxam.conf xamxam:/tmp/xamxam.conf
rsync -v scripts/deploy-server.sh posterg:/tmp/deploy-server.sh rsync -v scripts/deploy-server.sh xamxam:/tmp/deploy-server.sh
@echo "" @echo ""
@echo "Files uploaded. SSH into the server and run:" @echo "Files uploaded. SSH into the server and run:"
@echo "" @echo ""
@@ -82,9 +82,9 @@ deploy-nginx:
[group('deploy')] [group('deploy')]
deploy-db: 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) @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/posterg.db posterg:/var/www/xamxam/storage/posterg.db rsync -v --progress app/storage/xamxam.db xamxam:/var/www/xamxam/storage/xamxam.db
ssh posterg "chown www-data:posterg /var/www/xamxam/storage/posterg.db && chmod 660 /var/www/xamxam/storage/posterg.db" ssh xamxam "chown www-data:xamxam /var/www/xamxam/storage/xamxam.db && chmod 660 /var/www/xamxam/storage/xamxam.db"
# ============================================================================ # ============================================================================
# Testing # Testing
@@ -123,25 +123,25 @@ migrate:
[group('database')] [group('database')]
init-db: init-db:
@sqlite3 app/storage/posterg.db < app/storage/schema.sql @sqlite3 app/storage/xamxam.db < app/storage/schema.sql
@sqlite3 app/storage/posterg.db "SELECT COUNT(*) || ' tables' FROM sqlite_master WHERE type='table';" @sqlite3 app/storage/xamxam.db "SELECT COUNT(*) || ' tables' FROM sqlite_master WHERE type='table';"
[group('database')] [group('database')]
reset-db: reset-db:
@rm -f app/storage/posterg.db @rm -f app/storage/xamxam.db
@just init-db @just init-db
[group('database')] [group('database')]
query: query:
@sqlite3 app/storage/posterg.db @sqlite3 app/storage/xamxam.db
[group('database')] [group('database')]
show id: 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')] [group('database')]
backup: 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 # Utils
@@ -151,7 +151,7 @@ backup:
clean: clean:
@rm -f app/error.log @rm -f app/error.log
@rm -rf app/storage/cache/rate_limit/* @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')] [group('utils')]
setup-dirs: setup-dirs:

View File

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

View File

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

View File

@@ -13,7 +13,7 @@ Quick guide to manage admin users for the Post-ERG admin panel.
just manage-admin-users just manage-admin-users
# Then on the server # Then on the server
ssh posterg ssh xamxam
sudo bash /tmp/manage-admin-users.sh sudo bash /tmp/manage-admin-users.sh
``` ```
@@ -31,15 +31,15 @@ This gives you an interactive menu to:
### List Current Users ### List Current Users
```bash ```bash
ssh posterg ssh xamxam
sudo cut -d: -f1 /etc/nginx/.htpasswd-posterg sudo cut -d: -f1 /etc/nginx/.htpasswd-xamxam
``` ```
### Change Password for Existing User ### Change Password for Existing User
```bash ```bash
ssh posterg ssh xamxam
sudo htpasswd /etc/nginx/.htpasswd-posterg username_here sudo htpasswd /etc/nginx/.htpasswd-xamxam username_here
``` ```
You'll be prompted to enter the new password twice. 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 ### Add New User
```bash ```bash
ssh posterg ssh xamxam
sudo htpasswd /etc/nginx/.htpasswd-posterg new_username sudo htpasswd /etc/nginx/.htpasswd-xamxam new_username
``` ```
### Delete User ### Delete User
```bash ```bash
ssh posterg ssh xamxam
sudo htpasswd -D /etc/nginx/.htpasswd-posterg username_to_delete sudo htpasswd -D /etc/nginx/.htpasswd-xamxam username_to_delete
``` ```
### Reset Everything (Start Fresh) ### Reset Everything (Start Fresh)
```bash ```bash
ssh posterg ssh xamxam
sudo htpasswd -c /etc/nginx/.htpasswd-posterg new_username sudo htpasswd -c /etc/nginx/.htpasswd-xamxam new_username
``` ```
⚠️ **Warning:** The `-c` flag creates a new file, deleting all existing users! ⚠️ **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 just manage-admin-users
# Or manually: # 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 ## 🔑 Current Setup
After deployment, your admin panel has: After deployment, your admin panel has:
- **URL:** https://posterg.erg.be/admin/ - **URL:** https://xamxam.erg.be/admin/
- **Current user:** `test_posterg_22@` - **Current user:** `test_posterg_22@`
- **Password:** Set during initial deployment - **Password:** Set during initial deployment
@@ -97,8 +97,8 @@ After deployment, your admin panel has:
### Scenario 1: Change Current Password ### Scenario 1: Change Current Password
```bash ```bash
ssh posterg ssh xamxam
sudo htpasswd /etc/nginx/.htpasswd-posterg test_posterg_22@ sudo htpasswd /etc/nginx/.htpasswd-xamxam test_posterg_22@
# Enter new password when prompted # 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: Since you can't rename users, you need to:
```bash ```bash
ssh posterg ssh xamxam
# Add new user # Add new user
sudo htpasswd /etc/nginx/.htpasswd-posterg new_username sudo htpasswd /etc/nginx/.htpasswd-xamxam new_username
# Delete old user # 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 ### Scenario 3: Forgot Username
```bash ```bash
ssh posterg ssh xamxam
sudo cut -d: -f1 /etc/nginx/.htpasswd-posterg sudo cut -d: -f1 /etc/nginx/.htpasswd-xamxam
``` ```
### Scenario 4: Multiple Admins ### Scenario 4: Multiple Admins
```bash ```bash
ssh posterg ssh xamxam
# Add second admin # Add second admin
sudo htpasswd /etc/nginx/.htpasswd-posterg admin2 sudo htpasswd /etc/nginx/.htpasswd-xamxam admin2
# Add third admin # 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. 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 ### Scenario 5: Start Over with New Username
```bash ```bash
ssh posterg ssh xamxam
# This will DELETE ALL existing users and create a new one # 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 ```bash
# Test that password is required # Test that password is required
curl -I https://posterg.erg.be/admin/ curl -I https://xamxam.erg.be/admin/
# Should return: 401 Unauthorized # Should return: 401 Unauthorized
# Test with credentials # 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 # Should return: 200 OK
``` ```
@@ -163,7 +163,7 @@ No nginx reload needed - changes take effect immediately!
## 📊 Password File Details ## 📊 Password File Details
**Location:** `/etc/nginx/.htpasswd-posterg` **Location:** `/etc/nginx/.htpasswd-xamxam`
**Format:** Standard Apache htpasswd format **Format:** Standard Apache htpasswd format
``` ```
@@ -172,7 +172,7 @@ username:$apr1$encrypted_password_hash
**Permissions:** **Permissions:**
```bash ```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** 2. **Avoid Common Usernames**
- ❌ Bad: `admin`, `administrator`, `root` - ❌ Bad: `admin`, `administrator`, `root`
- ✅ Good: `posterg_admin`, `erg_webmaster` - ✅ Good: `xamxam_admin`, `erg_webmaster`
3. **Regular Password Changes** 3. **Regular Password Changes**
- Change passwords every 3-6 months - Change passwords every 3-6 months
@@ -196,14 +196,14 @@ username:$apr1$encrypted_password_hash
4. **Monitor Access** 4. **Monitor Access**
```bash ```bash
# Check who's accessing the admin panel # Check who's accessing the admin panel
ssh posterg ssh xamxam
sudo grep "admin" /var/log/nginx/posterg_access.log sudo grep "admin" /var/log/nginx/xamxam_access.log
``` ```
5. **Backup Password File** 5. **Backup Password File**
```bash ```bash
ssh posterg ssh xamxam
sudo cp /etc/nginx/.htpasswd-posterg /etc/nginx/.htpasswd-posterg.backup sudo cp /etc/nginx/.htpasswd-xamxam /etc/nginx/.htpasswd-xamxam.backup
``` ```
--- ---
@@ -214,25 +214,25 @@ username:$apr1$encrypted_password_hash
**Check file exists:** **Check file exists:**
```bash ```bash
ssh posterg ssh xamxam
ls -la /etc/nginx/.htpasswd-posterg ls -la /etc/nginx/.htpasswd-xamxam
``` ```
**Verify user exists:** **Verify user exists:**
```bash ```bash
sudo cat /etc/nginx/.htpasswd-posterg sudo cat /etc/nginx/.htpasswd-xamxam
``` ```
**Check nginx config:** **Check nginx config:**
```bash ```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" ### Can't change password - "command not found"
**Install apache2-utils:** **Install apache2-utils:**
```bash ```bash
ssh posterg ssh xamxam
sudo apt update sudo apt update
sudo apt install apache2-utils sudo apt install apache2-utils
``` ```
@@ -241,8 +241,8 @@ sudo apt install apache2-utils
**Recreate it:** **Recreate it:**
```bash ```bash
ssh posterg ssh xamxam
sudo htpasswd -c /etc/nginx/.htpasswd-posterg new_admin sudo htpasswd -c /etc/nginx/.htpasswd-xamxam new_admin
``` ```
--- ---
@@ -252,11 +252,11 @@ sudo htpasswd -c /etc/nginx/.htpasswd-posterg new_admin
| Task | Command | | Task | Command |
|------|---------| |------|---------|
| **Interactive menu** | `sudo bash /tmp/manage-admin-users.sh` | | **Interactive menu** | `sudo bash /tmp/manage-admin-users.sh` |
| **List users** | `sudo cut -d: -f1 /etc/nginx/.htpasswd-posterg` | | **List users** | `sudo cut -d: -f1 /etc/nginx/.htpasswd-xamxam` |
| **Change password** | `sudo htpasswd /etc/nginx/.htpasswd-posterg username` | | **Change password** | `sudo htpasswd /etc/nginx/.htpasswd-xamxam username` |
| **Add user** | `sudo htpasswd /etc/nginx/.htpasswd-posterg newuser` | | **Add user** | `sudo htpasswd /etc/nginx/.htpasswd-xamxam newuser` |
| **Delete user** | `sudo htpasswd -D /etc/nginx/.htpasswd-posterg username` | | **Delete user** | `sudo htpasswd -D /etc/nginx/.htpasswd-xamxam username` |
| **Reset all** | `sudo htpasswd -c /etc/nginx/.htpasswd-posterg newuser` | | **Reset all** | `sudo htpasswd -c /etc/nginx/.htpasswd-xamxam newuser` |
| **Generate password** | `openssl rand -base64 32` | | **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: You can verify with:
```bash ```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 > directives that nginx **silently ignores**. None of the rules were active
> in production. > 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 | | 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 | | 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` | | **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 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 ## 🎯 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 - **PHP Version**: 8.4
- **SSL/TLS**: Handled by upstream reverse proxy - **SSL/TLS**: Handled by upstream reverse proxy
- **Document Root**: `/var/www/posterg/public/` - **Document Root**: `/var/www/xamxam/public/`
## 🚀 Quick Deployment ## 🚀 Quick Deployment
@@ -18,13 +18,13 @@ From your local machine:
just deploy-nginx just deploy-nginx
# Then on the server: # Then on the server:
ssh posterg ssh xamxam
sudo bash /tmp/deploy-server.sh sudo bash /tmp/deploy-server.sh
sudo systemctl reload nginx sudo systemctl reload nginx
``` ```
This uploads: This uploads:
- `nginx/posterg.conf``/tmp/posterg.conf` - `nginx/xamxam.conf``/tmp/xamxam.conf`
- `scripts/deploy-server.sh``/tmp/deploy-server.sh` - `scripts/deploy-server.sh``/tmp/deploy-server.sh`
## 📋 Step-by-Step Deployment ## 📋 Step-by-Step Deployment
@@ -32,8 +32,8 @@ This uploads:
### 1. Set Up Admin Password (First Time Only) ### 1. Set Up Admin Password (First Time Only)
```bash ```bash
ssh posterg ssh xamxam
sudo htpasswd -c /etc/nginx/.htpasswd-posterg admin sudo htpasswd -c /etc/nginx/.htpasswd-xamxam admin
# Enter a strong password when prompted # Enter a strong password when prompted
``` ```
@@ -54,7 +54,7 @@ sudo systemctl reload nginx
``` ```
The script will: The script will:
- ✅ Fix file permissions (set to www-data:posterg) - ✅ Fix file permissions (set to www-data:xamxam)
- ✅ Install nginx configuration - ✅ Install nginx configuration
- ✅ Test nginx configuration - ✅ Test nginx configuration
- ✅ Check PHP-FPM status - ✅ Check PHP-FPM status
@@ -64,10 +64,10 @@ The script will:
### Step 1: Fix Permissions ### Step 1: Fix Permissions
```bash ```bash
ssh posterg ssh xamxam
# Set correct ownership # Set correct ownership
sudo chown -R www-data:posterg /var/www/posterg/ sudo chown -R www-data:xamxam /var/www/xamxam/
# Set directory permissions # Set directory permissions
sudo find /var/www/posterg -type d -exec chmod 755 {} \; 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 {} \; sudo find /var/www/posterg -type f -exec chmod 644 {} \;
# Make storage writable # Make storage writable
sudo chmod 775 /var/www/posterg/storage sudo chmod 775 /var/www/xamxam/storage
# Protect database # Protect database
sudo chmod 660 /var/www/posterg/storage/test.db sudo chmod 660 /var/www/xamxam/storage/test.db
sudo chown www-data:posterg /var/www/posterg/storage/test.db sudo chown www-data:xamxam /var/www/xamxam/storage/test.db
``` ```
### Step 2: Deploy Nginx Config ### Step 2: Deploy Nginx Config
```bash ```bash
# Copy config # 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 # 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 sudo rm -f /etc/nginx/sites-enabled/default
# Test and reload # Test and reload
@@ -104,32 +104,32 @@ sudo systemctl reload nginx
```bash ```bash
# Should return 200 OK # Should return 200 OK
curl -I https://posterg.erg.be/ curl -I https://xamxam.erg.be/
``` ```
### Test Admin Protection ### Test Admin Protection
```bash ```bash
# Should return 401 Unauthorized # Should return 401 Unauthorized
curl -I https://posterg.erg.be/admin/ curl -I https://xamxam.erg.be/admin/
# With credentials # 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 ### Test File Protection
```bash ```bash
# Should return 403 Forbidden # Should return 403 Forbidden
curl -I https://posterg.erg.be/storage/test.db curl -I https://xamxam.erg.be/storage/test.db
curl -I https://posterg.erg.be/src/Database.php curl -I https://xamxam.erg.be/src/Database.php
curl -I https://posterg.erg.be/config/bootstrap.php curl -I https://xamxam.erg.be/config/bootstrap.php
``` ```
### Test Security Headers ### Test Security Headers
```bash ```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 ## 🔍 Troubleshooting
@@ -138,8 +138,8 @@ curl -I https://posterg.erg.be/ | grep -E "X-Frame|X-Content|Strict-Transport"
**Check file permissions:** **Check file permissions:**
```bash ```bash
ls -la /var/www/posterg/public/index.php ls -la /var/www/xamxam/public/index.php
groups www-data # Should include posterg groups www-data # Should include xamxam
``` ```
### 502 Bad Gateway ### 502 Bad Gateway
@@ -153,15 +153,15 @@ sudo systemctl restart php8.4-fpm
### Admin Password Not Working ### Admin Password Not Working
```bash ```bash
sudo htpasswd /etc/nginx/.htpasswd-posterg admin sudo htpasswd /etc/nginx/.htpasswd-xamxam admin
``` ```
## 📊 Monitoring ## 📊 Monitoring
```bash ```bash
# Watch logs # Watch logs
sudo tail -f /var/log/nginx/posterg_access.log sudo tail -f /var/log/nginx/xamxam_access.log
sudo tail -f /var/log/nginx/posterg_error.log sudo tail -f /var/log/nginx/xamxam_error.log
# Check status # Check status
sudo systemctl status nginx sudo systemctl status nginx
@@ -171,7 +171,7 @@ sudo systemctl status nginx
After deployment, verify: After deployment, verify:
- [ ] Public site accessible at https://posterg.erg.be/ - [ ] Public site accessible at https://xamxam.erg.be/
- [ ] Admin panel requires password - [ ] Admin panel requires password
- [ ] Database files return 403 Forbidden - [ ] Database files return 403 Forbidden
- [ ] Source files return 403 Forbidden - [ ] Source files return 403 Forbidden
@@ -185,19 +185,19 @@ After deployment, verify:
just deploy just deploy
# Reload nginx if config changed # Reload nginx if config changed
ssh posterg "sudo systemctl reload nginx" ssh xamxam "sudo systemctl reload nginx"
``` ```
## 🆘 Emergency Recovery ## 🆘 Emergency Recovery
```bash ```bash
# Restore default nginx config # Restore default nginx config
ssh posterg ssh xamxam
sudo rm /etc/nginx/sites-enabled/posterg sudo rm /etc/nginx/sites-enabled/xamxam
sudo systemctl reload nginx sudo systemctl reload nginx
# Reset permissions # 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 d -exec chmod 755 {} \;
sudo find /var/www/posterg -type f -exec chmod 644 {} \; sudo find /var/www/posterg -type f -exec chmod 644 {} \;
``` ```

View File

@@ -4,8 +4,8 @@
```bash ```bash
# Copy nginx config # Copy nginx config
sudo cp nginx/posterg.conf /etc/nginx/sites-available/posterg sudo cp nginx/xamxam.conf /etc/nginx/sites-available/xamxam
sudo ln -s /etc/nginx/sites-available/posterg /etc/nginx/sites-enabled/ sudo ln -s /etc/nginx/sites-available/xamxam /etc/nginx/sites-enabled/
sudo rm -f /etc/nginx/sites-enabled/default sudo rm -f /etc/nginx/sites-enabled/default
# Test and reload # Test and reload
@@ -23,16 +23,16 @@ sudo bash /tmp/manage-admin-users.sh
# Or manual commands: # Or manual commands:
# Add new user # Add new user
sudo htpasswd /etc/nginx/.htpasswd-posterg username sudo htpasswd /etc/nginx/.htpasswd-xamxam username
# Change password for existing user # Change password for existing user
sudo htpasswd /etc/nginx/.htpasswd-posterg username sudo htpasswd /etc/nginx/.htpasswd-xamxam username
# Remove user # Remove user
sudo htpasswd -D /etc/nginx/.htpasswd-posterg username sudo htpasswd -D /etc/nginx/.htpasswd-xamxam username
# List all users # List all users
sudo cut -d: -f1 /etc/nginx/.htpasswd-posterg sudo cut -d: -f1 /etc/nginx/.htpasswd-xamxam
``` ```
### Nginx Control ### Nginx Control
@@ -61,26 +61,26 @@ sudo systemctl status nginx
```bash ```bash
# Public site access log # 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 # Public site errors
sudo tail -f /var/log/nginx/posterg_error.log sudo tail -f /var/log/nginx/xamxam_error.log
# SSL access 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 # 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 # 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 ### SSL/HTTPS
```bash ```bash
# Get SSL certificate (Let's Encrypt) # 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 # Renew certificates
sudo certbot renew sudo certbot renew
@@ -98,10 +98,10 @@ sudo certbot renew --dry-run
```bash ```bash
# Should require password (returns 401) # Should require password (returns 401)
curl -I https://posterg.erg.be/admin/ curl -I https://xamxam.erg.be/admin/
# With authentication # With authentication
curl -u admin:password https://posterg.erg.be/admin/ curl -u admin:password https://xamxam.erg.be/admin/
``` ```
### Test Rate Limiting ### Test Rate Limiting
@@ -109,7 +109,7 @@ curl -u admin:password https://posterg.erg.be/admin/
```bash ```bash
# Should show increasing 429 responses after limit # Should show increasing 429 responses after limit
for i in {1..50}; do 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 done
``` ```
@@ -117,16 +117,16 @@ done
```bash ```bash
# Should return 403 # Should return 403
curl -I https://posterg.erg.be/storage/posterg.db curl -I https://xamxam.erg.be/storage/xamxam.db
curl -I https://posterg.erg.be/shared/Database.php curl -I https://xamxam.erg.be/shared/Database.php
curl -I https://posterg.erg.be/.env curl -I https://xamxam.erg.be/.env
``` ```
### Test Security Headers ### Test Security Headers
```bash ```bash
# Check all security headers # 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 ## Troubleshooting
@@ -136,10 +136,10 @@ curl -I https://posterg.erg.be/ 2>&1 | grep -E "X-|Strict-Transport|Referrer|Per
**403 Forbidden on admin** **403 Forbidden on admin**
```bash ```bash
# Check htpasswd file exists # Check htpasswd file exists
sudo ls -l /etc/nginx/.htpasswd-posterg sudo ls -l /etc/nginx/.htpasswd-xamxam
# Check permissions # Check permissions
sudo chmod 644 /etc/nginx/.htpasswd-posterg sudo chmod 644 /etc/nginx/.htpasswd-xamxam
``` ```
**502 Bad Gateway** **502 Bad Gateway**
@@ -167,10 +167,10 @@ sudo tail -50 /var/log/nginx/error.log
```bash ```bash
# Disable password protection temporarily # 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: # Comment out these lines in /admin/ location:
# auth_basic "Admin Access - Post-ERG"; # auth_basic "Admin Access - Post-ERG";
# auth_basic_user_file /etc/nginx/.htpasswd-posterg; # auth_basic_user_file /etc/nginx/.htpasswd-xamxam;
# Reload nginx # Reload nginx
sudo nginx -t && sudo systemctl 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' watch -n 1 'ps aux | grep nginx'
# Check request rate # 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 # Disk usage of logs
sudo du -sh /var/log/nginx/* sudo du -sh /var/log/nginx/*
@@ -202,29 +202,29 @@ sudo nginx -s reopen
sudo find /var/log/nginx -name "*.log" -mtime +7 -delete sudo find /var/log/nginx -name "*.log" -mtime +7 -delete
# Backup configuration # 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 # 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 ## Security Checklist
- [ ] Admin password set: `sudo ls -l /etc/nginx/.htpasswd-posterg` - [ ] Admin password set: `sudo ls -l /etc/nginx/.htpasswd-xamxam`
- [ ] SSL enabled: `curl -I https://posterg.erg.be/` - [ ] SSL enabled: `curl -I https://xamxam.erg.be/`
- [ ] Database blocked: `curl -I https://posterg.erg.be/storage/posterg.db` - [ ] Database blocked: `curl -I https://xamxam.erg.be/storage/xamxam.db`
- [ ] Shared directory blocked: `curl -I https://posterg.erg.be/shared/Database.php` - [ ] Shared directory blocked: `curl -I https://xamxam.erg.be/shared/Database.php`
- [ ] Rate limiting working: Test with curl loop - [ ] Rate limiting working: Test with curl loop
- [ ] Security headers present: `curl -I https://posterg.erg.be/ | grep X-` - [ ] Security headers present: `curl -I https://xamxam.erg.be/ | grep X-`
- [ ] Logs accessible: `sudo tail /var/log/nginx/posterg_access.log` - [ ] Logs accessible: `sudo tail /var/log/nginx/xamxam_access.log`
## Configuration Paths ## Configuration Paths
- **Nginx config**: `/etc/nginx/sites-available/posterg` - **Nginx config**: `/etc/nginx/sites-available/xamxam`
- **Password file**: `/etc/nginx/.htpasswd-posterg` - **Password file**: `/etc/nginx/.htpasswd-xamxam`
- **SSL certificates**: `/etc/letsencrypt/live/posterg.erg.be/` - **SSL certificates**: `/etc/letsencrypt/live/xamxam.erg.be/`
- **Access logs**: `/var/log/nginx/posterg_access.log` - **Access logs**: `/var/log/nginx/xamxam_access.log`
- **Error logs**: `/var/log/nginx/posterg_error.log` - **Error logs**: `/var/log/nginx/xamxam_error.log`
- **PHP-FPM config**: `/etc/php/8.2/fpm/pool.d/www.conf` - **PHP-FPM config**: `/etc/php/8.2/fpm/pool.d/www.conf`
- **PHP-FPM socket**: `/var/run/php/php8.2-fpm.sock` - **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) ## Headers in use (main server block — all pages)
@@ -18,7 +18,7 @@
These were previously declared in `public/admin/.htaccess` as Apache These were previously declared in `public/admin/.htaccess` as Apache
`mod_headers` directives, which nginx silently ignores. They are now `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. enforced directly; see `HTACCESS_TO_NGINX.md` for the full migration log.
## Intentionally omitted headers ## Intentionally omitted headers

View File

@@ -13,7 +13,7 @@ just deploy-db
This automatically: This automatically:
1. ✅ Checks remote DB doesn't exist (safety check) 1. ✅ Checks remote DB doesn't exist (safety check)
2. ✅ Uploads `storage/test.db` to the server 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 ### 1. Install PHP SQLite Extension
```bash ```bash
ssh posterg ssh xamxam
sudo apt update sudo apt update
sudo apt install php8.4-sqlite3 sudo apt install php8.4-sqlite3
sudo systemctl restart php8.4-fpm sudo systemctl restart php8.4-fpm
@@ -31,7 +31,7 @@ sudo systemctl restart php8.4-fpm
### 2. Verify Installation ### 2. Verify Installation
```bash ```bash
ssh posterg ssh xamxam
php -m | grep sqlite3 php -m | grep sqlite3
# Should output: pdo_sqlite, sqlite3 # Should output: pdo_sqlite, sqlite3
``` ```
@@ -58,20 +58,20 @@ just deploy-db
### 3. Test the Site ### 3. Test the Site
Visit: https://posterg.erg.be/ Visit: https://xamxam.erg.be/
### 4. Check What Database is Being Used ### 4. Check What Database is Being Used
```bash ```bash
ssh posterg ssh xamxam
php -r "require_once '/var/www/posterg/src/Database.php'; echo 'Using: ' . Database::getInstance()->getDatabasePath() . PHP_EOL;" php -r "require_once '/var/www/xamxam/src/Database.php'; echo 'Using: ' . Database::getInstance()->getDatabasePath() . PHP_EOL;"
``` ```
### 5. Switch Back to Production ### 5. Switch Back to Production
```bash ```bash
ssh posterg ssh xamxam
rm /var/www/posterg/storage/test.db rm /var/www/xamxam/storage/test.db
``` ```
--- ---
@@ -79,11 +79,11 @@ rm /var/www/posterg/storage/test.db
## 🔒 Permissions Explained ## 🔒 Permissions Explained
``` ```
/var/www/posterg/storage/ /var/www/xamxam/storage/
drwxrwxr-x www-data posterg # 775 - group writable drwxrwxr-x www-data xamxam # 775 - group writable
/var/www/posterg/storage/test.db /var/www/xamxam/storage/test.db
-rw-rw---- www-data posterg # 660 - owner/group read/write -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" ### "could not find driver"
```bash ```bash
ssh posterg ssh xamxam
sudo apt install php8.4-sqlite3 sudo apt install php8.4-sqlite3
sudo systemctl restart php8.4-fpm sudo systemctl restart php8.4-fpm
``` ```
@@ -101,18 +101,18 @@ sudo systemctl restart php8.4-fpm
### "unable to open database file" ### "unable to open database file"
```bash ```bash
ssh posterg ssh xamxam
chown www-data:posterg /var/www/posterg/storage/test.db chown www-data:xamxam /var/www/xamxam/storage/test.db
chmod 660 /var/www/posterg/storage/test.db chmod 660 /var/www/xamxam/storage/test.db
chmod 775 /var/www/posterg/storage/ chmod 775 /var/www/xamxam/storage/
``` ```
### "attempt to write a readonly database" ### "attempt to write a readonly database"
```bash ```bash
ssh posterg ssh xamxam
chmod 775 /var/www/posterg/storage/ chmod 775 /var/www/xamxam/storage/
rm -f /var/www/posterg/storage/test.db-* rm -f /var/www/xamxam/storage/test.db-*
``` ```
--- ---
@@ -126,8 +126,8 @@ rm -f /var/www/posterg/storage/test.db-*
### Backup Production Database ### Backup Production Database
```bash ```bash
ssh posterg ssh xamxam
cp /var/www/posterg/storage/posterg.db /var/www/posterg/storage/posterg.db.backup.$(date +%Y%m%d) 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: After running `just deploy-db`, verify:
- [ ] Database file exists: `ssh posterg "ls -la /var/www/posterg/storage/test.db"` - [ ] Database file exists: `ssh xamxam "ls -la /var/www/xamxam/storage/test.db"`
- [ ] Correct permissions: `-rw-rw---- www-data posterg` - [ ] Correct permissions: `-rw-rw---- www-data xamxam`
- [ ] Site loads: Visit https://posterg.erg.be/ - [ ] Site loads: Visit https://xamxam.erg.be/
- [ ] No errors in logs: `ssh posterg "tail /var/log/nginx/posterg_error.log"` - [ ] 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) # Nginx configuration for XAMXAM thesis website (Production)
# Place this in /etc/nginx/sites-available/posterg # Place this in /etc/nginx/sites-available/xamxam
# Then symlink: ln -s /etc/nginx/sites-available/posterg /etc/nginx/sites-enabled/ # Then symlink: ln -s /etc/nginx/sites-available/xamxam /etc/nginx/sites-enabled/
# Rate limiting zones # Rate limiting zones
limit_req_zone $binary_remote_addr zone=general:10m rate=30r/m; 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;
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) # Document root points to /public (only web-accessible files)
# Deployed structure: /var/www/xamxam/ # Deployed structure: /var/www/xamxam/
@@ -49,8 +49,8 @@ server {
client_body_timeout 120s; client_body_timeout 120s;
# Logging # Logging
access_log /var/log/nginx/posterg_access.log; access_log /var/log/nginx/xamxam_access.log;
error_log /var/log/nginx/posterg_error.log warn; error_log /var/log/nginx/xamxam_error.log warn;
# Block access to hidden files (except .well-known for Let's Encrypt) # Block access to hidden files (except .well-known for Let's Encrypt)
location ~ /\.(?!well-known).* { location ~ /\.(?!well-known).* {
@@ -115,7 +115,7 @@ server {
location ^~ /admin/ { location ^~ /admin/ {
# HTTP Basic Authentication (first layer) # HTTP Basic Authentication (first layer)
auth_basic "Admin Access - Post-ERG"; 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 # Rate limiting for admin
limit_req zone=admin burst=20 nodelay; limit_req zone=admin burst=20 nodelay;

View File

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

View File

@@ -8,12 +8,12 @@ echo "Creating investigation directory..."
mkdir -p ~/crash_investigation mkdir -p ~/crash_investigation
echo "Copying nginx logs..." echo "Copying nginx logs..."
sudo cp /var/log/nginx/posterg_error.log ~/crash_investigation/ sudo cp /var/log/nginx/xamxam_error.log ~/crash_investigation/
sudo cp /var/log/nginx/posterg_error.log.1 ~/crash_investigation/ 2>/dev/null || true sudo cp /var/log/nginx/xamxam_error.log.1 ~/crash_investigation/ 2>/dev/null || true
sudo cp /var/log/nginx/posterg_access.log ~/crash_investigation/ sudo cp /var/log/nginx/xamxam_access.log ~/crash_investigation/
sudo cp /var/log/nginx/posterg_access.log.1 ~/crash_investigation/ 2>/dev/null || true sudo cp /var/log/nginx/xamxam_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/xamxam_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_access.log.2.gz ~/crash_investigation/ 2>/dev/null || true
echo "Exporting journal from previous boot..." echo "Exporting journal from previous boot..."
sudo journalctl -b -1 --no-pager > ~/crash_investigation/journal_previous_boot.log 2>&1 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/ du -sh ~/crash_investigation/
echo "" echo ""
echo "To download to your local machine, run:" 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 #!/bin/bash
# Deploy production nginx configuration for Post-ERG # Deploy production nginx configuration for XAMXAM
# Fixes permissions and installs /tmp/posterg.conf into nginx sites-available. # Fixes permissions and installs /tmp/xamxam.conf into nginx sites-available.
# #
# Usage: just deploy-nginx (uploads script + config, then runs this) # Usage: just deploy-nginx (uploads script + config, then runs this)
# or: sudo bash /tmp/deploy-server.sh # or: sudo bash /tmp/deploy-server.sh
@@ -27,8 +27,8 @@ printf "==================================\n\n"
printf "📋 Step 1: Fixing file permissions...\n" printf "📋 Step 1: Fixing file permissions...\n"
echo "--------------------------------------" echo "--------------------------------------"
chown -R www-data:posterg /var/www/xamxam/ chown -R www-data:xamxam /var/www/xamxam/
ok "Ownership: www-data:posterg" ok "Ownership: www-data:xamxam"
find /var/www/xamxam -type d -exec chmod 2775 {} \; find /var/www/xamxam -type d -exec chmod 2775 {} \;
ok "Directories: 2775 (setgid)" ok "Directories: 2775 (setgid)"
@@ -44,30 +44,30 @@ fi
# Ensure writable cache subdirectories exist for php-fpm (www-data) # Ensure writable cache subdirectories exist for php-fpm (www-data)
mkdir -p /var/www/xamxam/storage/cache/rate_limit 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 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 ────────────────────────────────────────────────────── # ── Step 2: Nginx config ──────────────────────────────────────────────────────
printf "\n📋 Step 2: Deploying nginx configuration...\n" printf "\n📋 Step 2: Deploying nginx configuration...\n"
echo "--------------------------------------------" echo "--------------------------------------------"
if [ ! -f "/tmp/posterg.conf" ]; then if [ ! -f "/tmp/xamxam.conf" ]; then
err "/tmp/posterg.conf not found — run: just deploy-nginx" err "/tmp/xamxam.conf not found — run: just deploy-nginx"
exit 1 exit 1
fi fi
if [ -f "/etc/nginx/sites-available/posterg" ]; then if [ -f "/etc/nginx/sites-available/xamxam" ]; then
cp /etc/nginx/sites-available/posterg \ cp /etc/nginx/sites-available/xamxam \
"/etc/nginx/sites-available/posterg.backup.$(date +%Y%m%d_%H%M%S)" "/etc/nginx/sites-available/xamxam.backup.$(date +%Y%m%d_%H%M%S)"
ok "Backed up existing config" ok "Backed up existing config"
fi fi
cp /tmp/posterg.conf /etc/nginx/sites-available/posterg cp /tmp/xamxam.conf /etc/nginx/sites-available/xamxam
ok "Installed new nginx config" ok "Installed new nginx config"
if [ ! -L "/etc/nginx/sites-enabled/posterg" ]; then if [ ! -L "/etc/nginx/sites-enabled/xamxam" ]; then
ln -s /etc/nginx/sites-available/posterg /etc/nginx/sites-enabled/posterg ln -s /etc/nginx/sites-available/xamxam /etc/nginx/sites-enabled/xamxam
ok "Created sites-enabled symlink" ok "Created sites-enabled symlink"
fi fi
@@ -79,8 +79,8 @@ if nginx -t 2>&1; then
ok "Nginx configuration is valid" ok "Nginx configuration is valid"
else else
err "Nginx configuration has errors — restoring backup" err "Nginx configuration has errors — restoring backup"
latest=$(ls -t /etc/nginx/sites-available/posterg.backup.* 2>/dev/null | head -1) latest=$(ls -t /etc/nginx/sites-available/xamxam.backup.* 2>/dev/null | head -1)
[ -n "$latest" ] && cp "$latest" /etc/nginx/sites-available/posterg [ -n "$latest" ] && cp "$latest" /etc/nginx/sites-available/xamxam
exit 1 exit 1
fi fi
@@ -99,6 +99,6 @@ ok "Nginx config installed"
ok "Configuration validated" ok "Configuration validated"
ok "Nginx reloaded" ok "Nginx reloaded"
printf "\nVerify:\n" printf "\nVerify:\n"
printf " https://posterg.erg.be/\n" printf " https://xamxam.erg.be/\n"
printf " https://posterg.erg.be/admin/\n" printf " https://xamxam.erg.be/admin/\n"
printf " https://posterg.erg.be/storage/posterg.db (should 403/404)\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' BLUE='\033[0;34m'
NC='\033[0m' NC='\033[0m'
PASSWORD_FILE="/etc/nginx/.htpasswd-posterg" PASSWORD_FILE="/etc/nginx/.htpasswd-xamxam"
# Check if running as root # Check if running as root
if [ "$EUID" -ne 0 ]; then if [ "$EUID" -ne 0 ]; then

View File

@@ -2,14 +2,14 @@
# Initialise the Post-ERG SQLite database from schema.sql. # Initialise the Post-ERG SQLite database from schema.sql.
# Safe to run on existing databases — schema uses IF NOT EXISTS / INSERT OR IGNORE. # Safe to run on existing databases — schema uses IF NOT EXISTS / INSERT OR IGNORE.
# Usage: # Usage:
# scripts/migrate.sh # posterg.db (default) # scripts/migrate.sh # xamxam.db (default)
set -euo pipefail set -euo pipefail
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
APP_DIR="$REPO_ROOT/app" APP_DIR="$REPO_ROOT/app"
SCHEMA="$APP_DIR/storage/schema.sql" SCHEMA="$APP_DIR/storage/schema.sql"
PROD_DB="$APP_DIR/storage/posterg.db" PROD_DB="$APP_DIR/storage/xamxam.db"
init_db() { init_db() {
local db="$1" local db="$1"
@@ -19,4 +19,4 @@ init_db() {
echo " [$label] done" 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" echo "✓ Cloned php-live-reload"
fi fi
# Create posterg.db if needed # Create xamxam.db if needed
if [ ! -f "storage/posterg.db" ]; then if [ ! -f "storage/xamxam.db" ]; then
echo "" echo ""
echo "📊 Creating posterg.db…" echo "📊 Creating xamxam.db…"
sqlite3 storage/posterg.db < storage/schema.sql sqlite3 storage/xamxam.db < storage/schema.sql
echo "✓ Created posterg.db" echo "✓ Created xamxam.db"
fi fi
# Create data directories # Create data directories

View File

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