View Raw # 5q12-indexer secure nginx config with X-Accel-Redirect support and clean URL routing
server {
listen 5012;
server_name 5q12-indexer;
# Document root
root {WEB_PATH};
index index.php;
# CRITICAL: Internal location for X-Accel-Redirect file serving
# This allows nginx to serve files directly after PHP authorization
location /internal-files/ {
internal; # Only accessible via X-Accel-Redirect
alias {WEB_PATH}/files/; # Map to your actual files directory
# Optimize for large file downloads
sendfile on;
sendfile_max_chunk 1m;
tcp_nopush on;
tcp_nodelay on;
# Support range requests for resume capability
add_header Accept-Ranges bytes;
# No caching for downloads
expires off;
add_header Cache-Control "no-cache, no-store, must-revalidate";
add_header Pragma "no-cache";
}
# Allow CSS and font files from .indexer_files/local_api/style directory
location ~ ^/\.indexer_files/local_api/style/.*\.(css|woff2)$ {
# Set proper MIME types
location ~* \.css$ {
add_header Content-Type "text/css" always;
}
location ~* \.woff2$ {
add_header Content-Type "font/woff2" always;
}
# Cache static assets
expires 1d;
add_header Cache-Control "public, immutable" always;
add_header X-Content-Type-Options "nosniff" always;
try_files $uri =404;
}
# Allow PNG files from .indexer_files/icons directory
location ~ ^/\.indexer_files/icons/.*\.png$ {
# Set proper MIME type for images
add_header Content-Type "image/png" always;
# Cache icons
expires 7d;
add_header Cache-Control "public, immutable" always;
add_header X-Content-Type-Options "nosniff" always;
try_files $uri =404;
}
# Allow favicon files from .indexer_files/favicon directory
location ~ ^/\.indexer_files/favicon/.*\.(ico|png)$ {
# Set proper MIME types
location ~* \.ico$ {
add_header Content-Type "image/x-icon" always;
}
location ~* \.png$ {
add_header Content-Type "image/png" always;
}
# Cache favicons
expires 7d;
add_header Cache-Control "public, immutable" always;
add_header X-Content-Type-Options "nosniff" always;
try_files $uri =404;
}
# Explicitly deny access to other .indexer_files subdirectories
location ~ ^/\.indexer_files/(?!local_api/style/|icons/|favicon/) {
deny all;
return 404;
}
# Main indexer application - handle all requests through index.php with clean URLs
location / {
# Add security headers for non-download requests
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
# Route everything through index.php for clean URL handling
try_files $uri $uri/ /index.php$is_args$args;
}
# PHP handler with optimizations for downloads
location ~ \.php$ {
# Only allow index.php to be executed
if ($uri != "/index.php") {
return 404;
}
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
# Extended timeouts for large operations
fastcgi_read_timeout 7200; # 2 hours
fastcgi_send_timeout 7200; # 2 hours
# Disable buffering for downloads to allow X-Accel-Redirect
fastcgi_buffering off;
fastcgi_request_buffering off;
# Don't add security headers for downloads (they're added in location / block)
set $is_download 0;
if ($arg_download) {
set $is_download 1;
}
}
# Deny access to configuration and sensitive files
location ~ /\.(ht|git|env|log|sqlite|json)$ {
deny all;
return 404;
}
# Deny access to backup and temporary files
location ~ \.(bak|backup|old|tmp|temp|swp|swo|~)$ {
deny all;
return 404;
}
# Deny access to common sensitive filenames
location ~ ^/(config|configuration|settings|private|admin|api|\.well-known) {
deny all;
return 404;
}
# Block common attack patterns
location ~ /(wp-|wordpress|admin|phpmyadmin|mysql|database) {
deny all;
return 404;
}
# Increased limits for large file operations
client_max_body_size 200G;
client_body_buffer_size 128k;
client_header_buffer_size 4k;
large_client_header_buffers 8 8k;
# Rate limiting (optional - uncomment if needed)
# limit_req_zone $binary_remote_addr zone=indexer:10m rate=10r/s;
# limit_req zone=indexer burst=20 nodelay;
}