# Nginx Setup for Post-ERG This document explains how to set up nginx with security features and password protection for the admin panel. ## Prerequisites - Ubuntu/Debian server with root access - Nginx installed - PHP-FPM installed (PHP 8.2 or later) - Domain name pointed to your server ## Installation Steps ### 1. Install Required Packages ```bash # Install nginx and apache2-utils (for htpasswd) sudo apt update sudo apt install nginx apache2-utils php8.2-fpm # Install SSL certificate tool (optional, for HTTPS) sudo apt install certbot python3-certbot-nginx ``` ### 2. Create Password File for Admin Panel Create a password-protected admin area: ```bash # Create htpasswd file sudo htpasswd -c /etc/nginx/.htpasswd-posterg admin # You'll be prompted to enter a password # Enter a strong password (e.g., generated with: openssl rand -base64 32) # Add additional users (without -c flag) sudo htpasswd /etc/nginx/.htpasswd-posterg supervisor ``` **Important**: Store the username and password securely! ### 3. Copy Nginx Configuration ```bash # Copy the config file sudo cp nginx/posterg.conf /etc/nginx/sites-available/posterg # Update PHP-FPM socket path if needed (check your PHP version) # Edit the file and change php8.2-fpm.sock to match your version sudo nano /etc/nginx/sites-available/posterg # Create symlink to enable the site sudo ln -s /etc/nginx/sites-available/posterg /etc/nginx/sites-enabled/ # Remove default site (optional) sudo rm /etc/nginx/sites-enabled/default ``` ### 4. Update Domain Name Edit the configuration to use your domain: ```bash sudo nano /etc/nginx/sites-available/posterg # Change these lines: # server_name posterg.erg.be www.posterg.erg.be; # to your actual domain name ``` ### 5. Test and Reload Nginx ```bash # Test configuration sudo nginx -t # If test passes, reload nginx sudo systemctl reload nginx # Check nginx status sudo systemctl status nginx ``` ### 6. Set Up SSL/HTTPS (Production) ```bash # Get SSL certificate from Let's Encrypt sudo certbot --nginx -d posterg.erg.be -d www.posterg.erg.be # Follow the prompts # Certbot will automatically update your nginx config # Enable auto-renewal sudo systemctl enable certbot.timer sudo systemctl start certbot.timer # Test renewal sudo certbot renew --dry-run ``` ### 7. Configure PHP-FPM Optimize PHP-FPM for security and performance: ```bash sudo nano /etc/php/8.2/fpm/pool.d/www.conf ``` Update these settings: ```ini # Security php_admin_value[open_basedir] = /var/www/html:/tmp php_admin_flag[allow_url_fopen] = off # Performance pm = dynamic pm.max_children = 50 pm.start_servers = 5 pm.min_spare_servers = 5 pm.max_spare_servers = 35 # Uploads php_value[upload_max_filesize] = 50M php_value[post_max_size] = 100M php_value[max_execution_time] = 120 php_value[max_input_time] = 120 ``` Restart PHP-FPM: ```bash sudo systemctl restart php8.2-fpm ``` ### 8. Set Correct Permissions ```bash # Set ownership sudo chown -R www-data:www-data /var/www/html # Set directory permissions sudo find /var/www/html -type d -exec chmod 755 {} \; # Set file permissions sudo find /var/www/html -type f -exec chmod 644 {} \; # Make upload directories writable sudo chmod 775 /var/www/html/formulaire/data/theses sudo chmod 775 /var/www/html/formulaire/data/covers # Protect database sudo chmod 600 /var/www/html/database/posterg.db sudo chown www-data:www-data /var/www/html/database/posterg.db ``` ## Security Features Implemented ### 1. **Admin Panel Password Protection** - HTTP Basic Authentication on `/formulaire/` path - Only authorized users can access admin panel ### 2. **Rate Limiting** - General requests: 30 requests/minute - Search endpoint: 30 requests/minute - Admin panel: 10 requests/minute ### 3. **File Access Protection** - `.db` files blocked - `.md`, `.txt`, `.sql` files blocked - `shared/` directory blocked (PHP includes only) - `tests/` directory blocked - `cache/` directory blocked - Hidden files (`.git`, `.env`) blocked ### 4. **Security Headers** - `X-Frame-Options`: Prevent clickjacking - `X-Content-Type-Options`: Prevent MIME sniffing - `X-XSS-Protection`: Enable XSS filter - `Strict-Transport-Security`: Force HTTPS - `Referrer-Policy`: Control referrer information - `Permissions-Policy`: Disable unnecessary browser features ### 5. **SSL/TLS Configuration** - TLS 1.2 and 1.3 only - Strong cipher suites - OCSP stapling - HSTS enabled ### 6. **PHP Security** - `open_basedir` restriction - Upload size limits - Timeout limits - Server tokens disabled ## Testing ### Test Admin Password Protection ```bash # Should prompt for password curl -I https://posterg.erg.be/formulaire/ # With credentials curl -u admin:your_password https://posterg.erg.be/formulaire/ ``` ### Test Rate Limiting ```bash # Make multiple rapid requests (should get 429 Too Many Requests after limit) for i in {1..50}; do curl -I https://posterg.erg.be/ 2>&1 | grep HTTP; done ``` ### Test File Blocking ```bash # Should return 403 Forbidden curl -I https://posterg.erg.be/database/posterg.db curl -I https://posterg.erg.be/shared/Database.php curl -I https://posterg.erg.be/README.md ``` ### Test Security Headers ```bash # Check security headers curl -I https://posterg.erg.be/ | grep -E "X-Frame|X-Content|Strict-Transport" ``` ## Monitoring and Logs ```bash # Watch access logs sudo tail -f /var/log/nginx/posterg_access.log # Watch error logs sudo tail -f /var/log/nginx/posterg_error.log # Watch SSL access logs sudo tail -f /var/log/nginx/posterg_ssl_access.log # Check PHP-FPM logs sudo tail -f /var/log/php8.2-fpm.log ``` ## Troubleshooting ### "403 Forbidden" on admin panel - Check htpasswd file exists: `ls -l /etc/nginx/.htpasswd-posterg` - Check file permissions: `sudo chmod 644 /etc/nginx/.htpasswd-posterg` - Check credentials are correct ### "502 Bad Gateway" - Check PHP-FPM is running: `sudo systemctl status php8.2-fpm` - Check socket path in nginx config matches PHP-FPM config - Check PHP-FPM logs: `sudo tail /var/log/php8.2-fpm.log` ### "File not found" errors - Check root path in nginx config - Check file permissions - Check PHP-FPM open_basedir setting ### Rate limiting too strict - Adjust `rate=` values in nginx config - Adjust `burst=` values for each location ## Maintenance ### Change Admin Password ```bash # Change password for existing user sudo htpasswd /etc/nginx/.htpasswd-posterg admin # Remove a user sudo htpasswd -D /etc/nginx/.htpasswd-posterg old_user ``` ### Renew SSL Certificate ```bash # Manual renewal sudo certbot renew # Check expiry sudo certbot certificates ``` ### Update Configuration ```bash # After modifying config file sudo nginx -t sudo systemctl reload nginx ``` ## Performance Tuning ### Enable Gzip Compression Add to nginx config: ```nginx gzip on; gzip_vary on; gzip_proxied any; gzip_comp_level 6; gzip_types text/plain text/css text/xml text/javascript application/json application/javascript application/xml+rss application/rss+xml font/truetype font/opentype application/vnd.ms-fontobject image/svg+xml; ``` ### Enable FastCGI Cache For high-traffic sites, add FastCGI caching: ```nginx fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=POSTERG:100m inactive=60m; fastcgi_cache_key "$scheme$request_method$host$request_uri"; ``` ## Security Checklist - [ ] Admin password set and secured - [ ] SSL/HTTPS enabled and working - [ ] Database files not accessible via web - [ ] Sensitive files (.md, .sql, .env) blocked - [ ] Rate limiting configured - [ ] Security headers enabled - [ ] PHP open_basedir configured - [ ] File permissions correct (644 for files, 755 for dirs) - [ ] Logs monitored regularly - [ ] Backups automated ## Additional Hardening (Optional) ### Install Fail2Ban Protect against brute force attacks: ```bash sudo apt install fail2ban # Create jail for nginx sudo nano /etc/fail2ban/jail.local ``` Add: ```ini [nginx-limit-req] enabled = true filter = nginx-limit-req logpath = /var/log/nginx/posterg_error.log maxretry = 5 bantime = 3600 ``` ### Enable UFW Firewall ```bash sudo ufw allow 22/tcp sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw enable ``` ### Database Encryption Consider encrypting the SQLite database at rest using SQLCipher or dm-crypt/LUKS.