HTTPS Redirects

HTTPS Redirects

Nexus GSLB includes a built-in HTTP redirect service that lets you redirect traffic for any hostname in your zone to a target URL, with optional path and query string preservation. This is the same type of feature NS1 calls "Redirect Manager" — rules are stored in the database, replicated to all cluster nodes, and take effect immediately.

Common use cases:

  • Redirect http:// to https:// for all traffic on a domain

  • Redirect a retired domain or subdomain to its replacement

  • Redirect a vanity domain to a canonical URL

  • Serve a maintenance page redirect during incidents

License: HTTP redirects require the paid tier or above. The redirect listener is disabled at startup on free and unlicensed installations. Contact licensing@gslb.nexus to upgrade.


Prerequisites

  • Nexus GSLB is authoritative for your zone (e.g. gslb.cc)

  • Port 80 (or your chosen redirect port) is open on each Nexus node

  • The Nexus API is accessible


Step 1 — Enable the redirect listener

Edit /etc/gslb/config.yaml on each node:

redirect: enabled: true listenAddr: "0.0.0.0" port: 80

Restart each node:

systemctl restart gslbd

Verify the listener started:

systemctl status gslbd | grep "redirect listener"# Expected: redirect listener starting addr=0.0.0.0:80

If port 80 is already in use by Caddy or nginx, use a different port (e.g. 8880) and configure a proxy pass to it. See Behind a reverse proxy below.


Step 2 — Create a redirect rule

curl -X POST https://nexus-api.example.com/api/v1/redirects \ -H "Authorization: Bearer $GSLB_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "sourceFqdn": "old.gslb.cc", "targetUrl": "https://new.gslb.cc", "code": 301, "preservePath": true }'

Response:

{ "id": "a1b2c3d4...", "tenantId": "default", "sourceFqdn": "old.gslb.cc", "targetUrl": "https://new.gslb.cc", "code": 301, "preservePath": true, "createdAt": 1716100000}

The rule is live on all cluster nodes immediately — no restart needed.


Step 3 — Point DNS at the Nexus nodes

The redirect service handles the HTTP layer; DNS must point old.gslb.cc to the nodes running the listener.

Create a pool and service in the normal way:

# Create a pool for the redirect nodesPOOL=$(curl -sX POST https://nexus-api.example.com/api/v1/pools \ -H "Authorization: Bearer $GSLB_API_KEY" \ -d '{"name":"redirect-nodes"}' | jq -r .id)# Add the Nexus node IPs as memberscurl -X POST https://nexus-api.example.com/api/v1/pools/$POOL/members \ -H "Authorization: Bearer $GSLB_API_KEY" \ -d '{"name":"lon-01","ipAddress":"45.92.9.73","port":80,"weight":1}'curl -X POST https://nexus-api.example.com/api/v1/pools/$POOL/members \ -H "Authorization: Bearer $GSLB_API_KEY" \ -d '{"name":"eu-01","ipAddress":"65.21.14.204","port":80,"weight":1}'# Create the DNS servicecurl -X POST https://nexus-api.example.com/api/v1/services \ -H "Authorization: Bearer $GSLB_API_KEY" \ -d "{\"name\":\"old-redirect\",\"domain\":\"old.gslb.cc\",\"algorithm\":\"round-robin\",\"ttl\":60,\"poolId\":\"$POOL\"}"

Now old.gslb.cc resolves to a Nexus node IP, which serves the redirect.


Verifying the redirect

# Follow redirects and print the chaincurl -IL http://old.gslb.cc/docs/foo# Expected:# HTTP/1.1 301 Moved Permanently# Location: https://new.gslb.cc/docs/foo

Test from each node directly to verify cluster sync:

curl -s -o /dev/null -w "%{http_code} %{redirect_url}" \ http://45.92.9.73/ -H "Host: old.gslb.cc"# 301 https://new.gslb.cc/

Common patternsHTTP → HTTPS for a service

Redirect all HTTP traffic for admin.gslb.cc to HTTPS with path preservation:

{ "sourceFqdn": "admin.gslb.cc", "targetUrl": "https://admin.gslb.cc", "code": 301, "preservePath": true}

http://admin.gslb.cc/settings → https://admin.gslb.cc/settings

Domain migration (old → new)

{ "sourceFqdn": "legacy.gslb.cc", "targetUrl": "https://app.gslb.cc", "code": 301, "preservePath": true}

http://legacy.gslb.cc/v2/users → https://app.gslb.cc/v2/users

Vanity domain (no path)

{ "sourceFqdn": "go.gslb.cc", "targetUrl": "https://docs.gslb.cc/getting-started", "code": 301, "preservePath": false}

All requests to go.gslb.cc redirect to the fixed URL, ignoring the path.

Temporary maintenance redirect

{ "sourceFqdn": "app.gslb.cc", "targetUrl": "https://status.gslb.cc", "code": 302, "preservePath": false}

Use code 302 so clients don't cache the redirect. Delete the rule when maintenance ends.


Managing rules

List all rules:

curl https://nexus-api.example.com/api/v1/redirects \ -H "Authorization: Bearer $GSLB_API_KEY" | jq .

Delete a rule:

RULE_ID="a1b2c3d4..."curl -X DELETE https://nexus-api.example.com/api/v1/redirects/$RULE_ID \ -H "Authorization: Bearer $GSLB_API_KEY"

The rule is removed from the live handler immediately — no restart needed.


Behind a reverse proxy

If Caddy or nginx already listens on port 80, run the Nexus redirect service on a different port and proxy to it.

Config:

redirect: enabled: true listenAddr: "127.0.0.1" port: 8880

Caddyfile snippet:

http://old.gslb.cc {
reverse_proxy 127.0.0.1:8880
}

This passes the original Host header through unchanged, which the redirect service uses for rule lookup.

With nginx, ensure proxy_set_header Host $host; is set — it is not the default.


HTTPS source domains (redirect from HTTPS)

The redirect listener is HTTP only. To redirect HTTPS traffic (e.g. https://old.gslb.cc), a TLS-terminating reverse proxy (Caddy) must sit in front:

https://old.gslb.cc {
# Caddy obtains the certificate for old.gslb.cc via ACME.
# See docs/user/ACMECertificates.md for DNS-01 setup.
tls {
dns rfc2136 { ... }
}
reverse_proxy 127.0.0.1:8880
}

Caddy terminates TLS, then proxies the plaintext request to the Nexus redirect listener, which serves the 301/302.


Troubleshooting

connection refused on port 80

The redirect listener is not running. Check:

systemctl status gslbd# Look for: redirect listener starting addr=0.0.0.0:80

Ensure redirect.enabled: true and redirect.port is set in the config.

404 Not Found from the redirect service

No rule matches the Host header. Verify:

curl https://nexus-api.example.com/api/v1/redirects \ -H "Authorization: Bearer $GSLB_API_KEY" | jq '.[].sourceFqdn'

Check that sourceFqdn matches the hostname exactly (case-insensitive, no port, no trailing dot).

Redirect loop

If sourceFqdn and targetUrl resolve to the same host, browsers will loop. Check that targetUrl uses a different hostname or protocol from sourceFqdn.

Old redirect still cached in browser

301 redirects are cached by browsers indefinitely. During testing, use 302 or use a private/incognito window. Once confirmed working, switch to 301.


Related


Was this article helpful?