How to Set Up Nginx as a Reverse Proxy for Apache Solr

How to Set Up Nginx as a Reverse Proxy for Apache Solr

How to Set Up Nginx as a Reverse Proxy for Apache Solr

Apache Solr ships with an admin UI and a full REST-like API on port 8983, both completely open by default with no TLS and no authentication unless it’s explicitly configured. That’s a reasonable default for local development, but it’s a liability for anything reachable outside a trusted internal network. Putting Nginx in front of Solr adds TLS termination, a proper domain name, access control, and a layer where request-level restrictions (like blocking access to the admin UI from the public internet while still allowing the search API) can be enforced cleanly.

This guide walks through configuring Nginx as a reverse proxy for Solr, covering both single-node and SolrCloud considerations, along with the security precautions that matter most for this particular service.

Understanding How Solr Handles Proxying

Unlike NiFi or Superset, Solr doesn’t require much proxy-awareness configuration on its own side. Its REST API and admin UI generally work fine behind a reverse proxy without special headers, since Solr doesn’t generate a lot of absolute redirect URLs the way a full web framework does. The real work in this setup is on the Nginx side: correctly routing paths, handling the admin UI’s static assets, and — critically — deciding what should and shouldn’t be exposed externally at all.

The admin UI in particular is worth thinking about carefully. It offers direct access to core/collection management, schema editing, and query execution. Exposing it publicly without additional access control is a common misconfiguration that turns a search index into an open door for data exfiltration or index deletion.

Requirements

Install Nginx:

sudo apt update && sudo apt install nginx -y

Confirm Solr is running:

sudo ss -tlnp | grep 8983
curl http://127.0.0.1:8983/solr/admin/info/system

Step 1: Decide What Gets Exposed

Before writing the Nginx config, decide on the access model. Three common patterns:

  1. Full proxy — both the search API and the admin UI are reachable externally, protected by authentication. Suitable for small internal teams needing UI access for debugging.
  2. API-only proxy — only /solr/<collection>/select and similar query endpoints are exposed; the admin UI (/solr/#/) and core management endpoints are blocked entirely at the Nginx layer. This is the recommended pattern for anything customer-facing.
  3. Internal-only — Solr isn’t exposed externally at all, and Nginx is only used to add TLS for service-to-service communication within a private network.

The example configuration below implements pattern 2, since it’s the safest default, with notes on how to open it up to pattern 1 if needed.

Step 2: Write the Nginx Configuration

Create the config file:

sudo nano /etc/nginx/sites-available/solr.conf

Example configuration implementing the API-only pattern with basic auth as an extra layer:

server {
    listen 80;
    server_name solr.example.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name solr.example.com;

    ssl_certificate     /etc/letsencrypt/live/solr.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/solr.example.com/privkey.pem;
    ssl_protocols       TLSv1.2 TLSv1.3;
    ssl_ciphers         HIGH:!aNULL:!MD5;

    # Block the admin UI and core-management endpoints entirely
    location ~ ^/solr/(admin|.*\/admin)(/|$) {
        deny all;
        return 403;
    }

    location ~ ^/solr/#/ {
        deny all;
        return 403;
    }

    # Allow read-only query endpoints for known collections
    location ~ ^/solr/[^/]+/(select|query|get|suggest)$ {
        auth_basic "Solr API Access";
        auth_basic_user_file /etc/nginx/.solr_htpasswd;

        proxy_pass http://127.0.0.1:8983;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_read_timeout 60s;
        proxy_send_timeout 60s;
    }

    # Anything else under /solr/ is denied by default
    location /solr/ {
        deny all;
        return 403;
    }

    location / {
        return 404;
    }
}

Generate the htpasswd file for basic auth:

sudo apt install apache2-utils -y
sudo htpasswd -c /etc/nginx/.solr_htpasswd solr_reader

If the admin UI genuinely needs to be exposed to an internal team, replace the “deny all” admin block with an IP allowlist plus basic auth instead of a flat denial:

location /solr/ {
    allow 10.0.0.0/8;
    allow 203.0.113.42;
    deny all;

    auth_basic "Solr Admin";
    auth_basic_user_file /etc/nginx/.solr_htpasswd;

    proxy_pass http://127.0.0.1:8983;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

Enable and test:

sudo ln -s /etc/nginx/sites-available/solr.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Step 3: Testing the Setup

Test the query endpoint through the proxy:

curl -u solr_reader -k "https://solr.example.com/solr/mycollection/select?q=*:*&rows=1"

It should prompt for the basic auth password and return a JSON response with search results.

Confirm the admin UI is properly blocked (or properly restricted, depending on the chosen pattern):

curl -Ik https://solr.example.com/solr/#/

This should return a 403 if using the API-only pattern.

Verify core status endpoints used by monitoring tools still work, since some monitoring integrations query /solr/admin/cores or /solr/admin/collections directly — adjust the allow rules if internal monitoring needs specific endpoints.

Troubleshooting

502 Bad Gateway Confirm Solr is actually running and bound correctly:

sudo systemctl status solr
sudo ss -tlnp | grep 8983

403 Forbidden on legitimate query requests The regex in the location block matching allowed endpoints is strict by design. If the application uses an endpoint not covered (like /solr/mycollection/update for indexing, or a custom request handler), it needs to be explicitly added to the allowed pattern — don’t just open everything, add the specific handler.

SolrCloud queries fail intermittently In a SolrCloud setup, queries can be internally routed between nodes. If Nginx is only proxying to one node and that node is down or a shard has moved, requests can fail. Consider proxying to a load-balanced set of Solr nodes using an upstream block, or point the proxy at a dedicated Solr load balancer if one exists in the cluster.

Basic auth prompt appears repeatedly Usually a browser/cache issue, or credentials aren’t being cached because of a session/cookie policy mismatch. For programmatic API access, confirm the client is sending the Authorization header on every request, since HTTP basic auth doesn’t persist across requests without explicit client support.

Streaming/large result sets get cut off Increase proxy_read_timeout and check proxy_buffering settings; very large result sets (deep pagination, big faceting responses) can exceed default buffer sizes.

Security Considerations

Solr security deserves particular attention because its default state is genuinely open:

add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

Performance Tips

gzip on;
gzip_types application/json;
gzip_min_length 512;
upstream solr_backend {
    server 127.0.0.1:8983;
    keepalive 32;
}

Real-World Use Cases

Best Practices Checklist

Solr’s default openness makes it one of the more security-sensitive services to reverse proxy well. The Nginx configuration itself is straightforward, but the real work is deciding — deliberately, endpoint by endpoint — what gets exposed and what doesn’t, rather than proxying the entire service wholesale and hoping nothing important is reachable.

Exit mobile version