Files
xamxam/nginx/QUICK_REFERENCE.md
Théophile Gervreau-Mercier 467aced734 Restructure repository and implement secure search feature
Phase 1: Consolidate shared infrastructure
- Create shared/ directory for common code
- Consolidate Database.php from front-backend and formulaire into unified shared/Database.php
  - Smart path detection for test.db vs posterg.db
  - Secure search with wildcard escaping and input validation
  - Support both singleton and direct instantiation patterns
  - Full CRUD methods for admin functionality
- Move RateLimit.php to shared/ (30 requests/min)
- Update all require paths across apps to use shared/

Phase 2: Reorganize directory structure
- Rename front-backend/ → apps/public/
- Rename formulaire/ → apps/admin/
- Rename db/ → database/
- Update all file paths for new structure
- Create root .gitignore excluding databases, cache, logs

Implement secure search feature
- Add apps/public/search.php with full-text search across theses
- Search filters: query, year, orientation, AP program, keywords
- Security features:
  - SQL injection prevention (prepared statements)
  - Wildcard injection prevention (escape % and _)
  - Input validation (max 200 chars, year range 1900-2100)
  - Rate limiting (30 req/min per IP)
  - Pagination limited to 100 results/page
  - XSS protection (htmlspecialchars on output)

Add comprehensive test suite
- Create apps/public/tests/ with proper structure
  - tests/Integration/SearchTest.php - 12 search scenarios
  - tests/Security/SecurityTest.php - vulnerability testing
  - tests/Unit/RateLimitTest.php - rate limit behavior
- Create database/fixtures/CreateTestDatabase.php
- Add apps/public/run-tests.php test runner
- All tests passing (4/4 suites)

Update deployment configuration
- Rename justfile 'sync' recipe to 'deploy'
- Create deploy group with separate deploy-public and deploy-admin
- Add test-deploy recipe for test database
- Exclude *.db, tests/, cache/, *.md from production deploy
- Deploy shared/ to both public and admin locations

Stats: +4482 insertions, -654 deletions across 72 files
2026-02-02 18:53:58 +01:00

248 lines
5.4 KiB
Markdown

# Nginx Quick Reference - Post-ERG
## Setup Commands
```bash
# Make setup script executable
chmod +x nginx/setup-password.sh
# Run password setup (as root)
sudo ./nginx/setup-password.sh
# Copy nginx config
sudo cp nginx/posterg.conf /etc/nginx/sites-available/posterg
# Enable site
sudo ln -s /etc/nginx/sites-available/posterg /etc/nginx/sites-enabled/
# Test configuration
sudo nginx -t
# Reload nginx
sudo systemctl reload nginx
```
## Common Operations
### Password Management
```bash
# Add new user
sudo htpasswd /etc/nginx/.htpasswd-posterg username
# Change password for existing user
sudo htpasswd /etc/nginx/.htpasswd-posterg username
# Remove user
sudo htpasswd -D /etc/nginx/.htpasswd-posterg username
# List all users
sudo cut -d: -f1 /etc/nginx/.htpasswd-posterg
```
### Nginx Control
```bash
# Test configuration
sudo nginx -t
# Reload configuration (no downtime)
sudo systemctl reload nginx
# Restart nginx (brief downtime)
sudo systemctl restart nginx
# Stop nginx
sudo systemctl stop nginx
# Start nginx
sudo systemctl start nginx
# Check status
sudo systemctl status nginx
```
### View Logs
```bash
# Public site access log
sudo tail -f /var/log/nginx/posterg_access.log
# Public site errors
sudo tail -f /var/log/nginx/posterg_error.log
# SSL access log
sudo tail -f /var/log/nginx/posterg_ssl_access.log
# Search for specific pattern
sudo grep "404" /var/log/nginx/posterg_access.log
# Count requests by IP
sudo awk '{print $1}' /var/log/nginx/posterg_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
# Renew certificates
sudo certbot renew
# Check certificate expiry
sudo certbot certificates
# Test auto-renewal
sudo certbot renew --dry-run
```
## Testing
### Test Admin Authentication
```bash
# Should require password (returns 401)
curl -I https://posterg.erg.be/formulaire/
# With authentication
curl -u admin:password https://posterg.erg.be/formulaire/
```
### Test Rate Limiting
```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/
done
```
### Test File Protection
```bash
# Should return 403
curl -I https://posterg.erg.be/database/posterg.db
curl -I https://posterg.erg.be/shared/Database.php
curl -I https://posterg.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"
```
## Troubleshooting
### Common Issues
**403 Forbidden on admin**
```bash
# Check htpasswd file exists
sudo ls -l /etc/nginx/.htpasswd-posterg
# Check permissions
sudo chmod 644 /etc/nginx/.htpasswd-posterg
```
**502 Bad Gateway**
```bash
# Check PHP-FPM status
sudo systemctl status php8.2-fpm
# Restart PHP-FPM
sudo systemctl restart php8.2-fpm
# Check PHP-FPM logs
sudo tail /var/log/php8.2-fpm.log
```
**Configuration errors**
```bash
# Test config and show errors
sudo nginx -t
# Check nginx error log
sudo tail -50 /var/log/nginx/error.log
```
### Emergency Recovery
```bash
# Disable password protection temporarily
sudo nano /etc/nginx/sites-available/posterg
# Comment out these lines in /formulaire/ location:
# auth_basic "Admin Access - Post-ERG";
# auth_basic_user_file /etc/nginx/.htpasswd-posterg;
# Reload nginx
sudo nginx -t && sudo systemctl reload nginx
```
## Performance Monitoring
```bash
# Check active connections
sudo ss -tulpn | grep nginx
# Monitor nginx processes
watch -n 1 'ps aux | grep nginx'
# Check request rate
sudo tail -f /var/log/nginx/posterg_access.log | pv -l -r > /dev/null
# Disk usage of logs
sudo du -sh /var/log/nginx/*
```
## Maintenance
```bash
# Rotate logs manually
sudo nginx -s reopen
# Clear old logs (keep last 7 days)
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)
# Backup password file
sudo cp /etc/nginx/.htpasswd-posterg /etc/nginx/.htpasswd-posterg.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/database/posterg.db`
- [ ] Shared directory blocked: `curl -I https://posterg.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`
## 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`
- **PHP-FPM config**: `/etc/php/8.2/fpm/pool.d/www.conf`
- **PHP-FPM socket**: `/var/run/php/php8.2-fpm.sock`
## Rate Limits (Current Settings)
- **General requests**: 30 requests/minute
- **Search endpoint**: 30 requests/minute (burst: 10)
- **Admin panel**: 10 requests/minute (burst: 5)
To adjust, edit these lines in nginx config:
```nginx
limit_req_zone $binary_remote_addr zone=general:10m rate=30r/m;
limit_req_zone $binary_remote_addr zone=search:10m rate=30r/m;
limit_req_zone $binary_remote_addr zone=admin:10m rate=10r/m;
```