dutchcoders/transfer.sh · error

Forbidden

Error message

Forbidden

What it means

This is an HTTP 403 Forbidden response generated by the IP filter middleware: the client's remote IP (resolved via realip.FromRequest, typically checking X-Forwarded-For/X-Real-IP headers before RemoteAddr) was not accepted by the configured IPFilterOptions allow/deny rules, so the request is rejected before ever reaching the wrapped handler. It fires whenever a request originates from an IP that is not explicitly allowed (or is denied) by the filter configuration — a generic validation guard, with the faulting input being the client's remote address. The server returns the plain status text 'Forbidden' and stops processing; clients must connect from a whitelisted IP for requests to pass to the next handler.

Source

Thrown at server/ip_filter.go:204

	return &ipFilterMiddleware{ipFilter: f, next: next}
}

// WrapIPFilter is equivalent to newIPFilter(opts) then Wrap(next)
func WrapIPFilter(next http.Handler, opts *IPFilterOptions) http.Handler {
	return newIPFilter(opts).Wrap(next)
}

type ipFilterMiddleware struct {
	*ipFilter
	next http.Handler
}

func (m *ipFilterMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	remoteIP := realip.FromRequest(r)

	if !m.ipFilter.Allowed(remoteIP) {
		//show simple forbidden text
		http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
		return
	}

	//success!
	m.next.ServeHTTP(w, r)
}

View on GitHub (pinned to c37bfd9579)

Solutions

  1. Verify the client IP with `curl ifconfig.me` and add it (or its CIDR) to the IP filter config
  2. Behind a proxy, enable real IP extraction (X-Forwarded-For / X-Real-IP trusted proxy settings) so the filter sees the true client IP
  3. Use correct CIDR notation covering IPv6 if applicable
  4. Check config parsing — an invalid filter entry can behave as allow-none
  5. Temporarily test with the filter disabled to confirm it is the cause

Example fix

// before
--ip-filter-allowed-ips 10.0.0.0/8   # client is on IPv6
// after
--ip-filter-allowed-ips 10.0.0.0/8,2001:db8::/32
Defensive patterns

Strategy: validation

Validate before calling

# check whether your current IP passes the filter before calling the API
MY_IP=$(curl -s ifconfig.me)
grep -qE "(^|,)${MY_IP}(,|$)" ipfilter.conf || echo "IP $MY_IP not in allowlist"

Type guard

null

Try / catch

try {
  const res = await fetch(url);
  if (res.status === 403) {
    // client IP blocked: request allowlist change via admin channel
    throw new Error('Forbidden: IP not allowlisted');
  }
} catch (err) { /* escalate to network admin */ }

Prevention

When it happens

Trigger: Any request to the linx server when the client's resolved remote IP is not in the ip-filter allowlist (or is in the deny list), typically configured via the ip-filter-action/ip filter options.

Common situations: Server moved behind a reverse proxy so realip resolves to the proxy address instead of the client; allowlist contains stale IPs after client IP change; IPv6 client not covered by an IPv4-only allowlist; misformatted CIDR in config.

Understand the failure class


AI-assisted analysis of dutchcoders/transfer.sh@c37bfd9579 (2026-09-05). Data as JSON: /api/errors/69462624703a5c34. Report an issue: GitHub.