server { listen 80; server_name otp.intaleqapp.com; return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; server_name otp.intaleqapp.com; # SSL — Let's Encrypt ssl_certificate /etc/letsencrypt/live/otp.intaleqapp.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/otp.intaleqapp.com/privkey.pem; # SSL Hardening ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384; ssl_prefer_server_ciphers off; ssl_session_cache shared:SSL:10m; ssl_session_timeout 1d; ssl_session_tickets off; # HSTS add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always; # Document root root /var/www/otp.intaleqapp.com/public; index index.php; # Logging access_log /var/log/nginx/otp.intaleqapp.com.access.log; error_log /var/log/nginx/otp.intaleqapp.com.error.log; # API endpoints — route to PHP files location /api/ { try_files $uri $uri/ /api$uri.php?$query_string; # PHP handling location ~ \.php$ { include fastcgi_params; fastcgi_pass unix:/var/run/php/php8.1-fpm.sock; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_read_timeout 30; } } # Block direct access to includes/ location /includes/ { deny all; return 404; } # Block access to config location /config.php { deny all; return 404; } # Block access to hidden files location ~ /\. { deny all; return 404; } # Block access to SQL files location ~ \.sql$ { deny all; return 404; } # Block access to log files location ~ \.log$ { deny all; return 404; } # Health check endpoint location /health { access_log off; return 200 '{"status":"ok"}'; add_header Content-Type application/json; } # Default PHP handling location ~ \.php$ { include fastcgi_params; fastcgi_pass unix:/var/run/php/php8.1-fpm.sock; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } # Deny everything else location / { return 404; } }