Learn how to detect bypassed proxies and origin-direct requests with 11 practical checks, log queries, and scripts. Protect your site from proxy-bypass attacks and harden your origin using defensive best practices.
Introduction
When a CDN or proxy (like Cloudflare) sits in front of your site, you expect incoming traffic to be filtered and inspected before it reaches your origin. If an attacker or misconfiguration allows requests to hit your origin directly (bypassing the proxy), those requests skip the edge protections and can be dangerous. This guide teaches how to detect bypassed proxies using logs, headers, IP checks, TLS checks, and monitoring — plus ready-to-use detection scripts you can run now.
Why detecting proxy bypass matters
If traffic reaches your origin directly it can:
- Evade your edge WAF, rate limits, and bot filtering.
- Reveal your server IP and open you to direct scans or DDoS.
- Allow brute force or exploitation attempts against admin endpoints.
Blocking or detecting bypasses early reduces risk and helps you respond quickly.
Quick checklist — 11 signs that a proxy was bypassed
- Missing proxy-specific headers (e.g.,
CF-Connecting-IP,CF-Ray). Cloudflare Docs - Source IP not in the proxy’s published IP ranges (compare request IPs to provider IP list). Cloudflare
- Host header or SNI equals your origin IP (attacker called the server IP directly).
- Requests arriving on ports you don’t expose publicly (e.g., direct HTTP when you expect only HTTPS via proxy).
- Unexpected TLS behaviour — missing client certs when mTLS (Authenticated Origin Pulls) is enabled. Cloudflare Docs+1
- Traffic spikes from few IPs that aren’t in proxy ranges.
- Requests with forged proxy headers but from non-proxy IPs — headers can be faked; combine header checks with IP checks.
- Admin or internal endpoints being accessed from unknown IPs.
- Requests with SNI or Host mismatches (hostname ≠ expected domain).
- Logs show normal client IPs but no corresponding entry in proxy logs (cross-check edge logs vs origin logs).
- Outgoing server behavior differs from proxied requests (e.g., different response times or missing edge cache headers).
1 — Check headers first (fastest single test)
Proxies add identifying HTTP headers to proxied traffic. For Cloudflare, for example, CF-Connecting-IP and CF-Ray are common and should be present on proxied requests; their absence is a red flag. However, headers can be forged, so use this check together with IP allowlisting. Cloudflare Docs
Example (nginx combined log grep for missing CF-Connecting-IP):
# show lines that don't include CF-Connecting-IP
grep -v "CF-Connecting-IP" /var/log/nginx/access.log | head -n 50
2 — Verify source IPs against your proxy provider’s published IP ranges
Every major proxy/CDN publishes the IP ranges its edge uses. Flag any request whose remote IP is not within those ranges. For Cloudflare, download https://www.cloudflare.com/ips-v4 and ips-v6 and compare. Automate this check nightly. Cloudflare+1
Simple one-liner example to list unique remote IPs from nginx:
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head
Then compare that list to your provider IP list (automated script shown below).
3 — Cross-check edge logs vs origin logs
If your proxy provides logs (Logpush, edge logs, or dashboard logs), match any suspicious origin log entry with the proxy’s logs — if the proxy never saw it, the request likely hit origin directly. Maintain synchronized timestamps (UTC) to make correlation reliable.
4 — TLS / mTLS checks (strong, low-false-positive signal)
If you use authenticated origin pulls (mTLS) or other client-certificate-based controls between the proxy and your origin, then a direct HTTPS connection without the proxy’s client cert will fail verification. Enforce and monitor failed TLS client-auth attempts on the origin. This is one of the most reliable defensive methods. Cloudflare Docs+1
5 — Host header and SNI inspection
Search your logs for requests where the Host: header or TLS SNI equals the origin IP or an unexpected hostname. Attackers and scripts often connect to the IP or alternate hostnames when bypassing a proxy.
Example (nginx logs containing Host header — requires that you log the header):
grep "Host: " /var/log/nginx/access.log | grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}"
6 — Detect forged headers: trust IPs + headers, not headers alone
Because an attacker can craft CF-Connecting-IP or similar headers, never rely on headers alone. Combine header checks with IP-range allowlisting or mTLS to avoid false negatives.
7 — Practical detection script (defensive)
Save this defensive Python script as detect_proxy_bypass.py. It downloads the provider IP lists (example uses Cloudflare URLs) and flags log lines whose remote IP is outside the provider ranges or that lack expected proxy headers.
Note: adjust
LOG_PATHandEXPECTED_HEADERSfor your environment. This script is diagnostic only.
#!/usr/bin/env python3
# Defensive scanner: flags origin log lines not coming from provider edges or missing expected headers.
import sys, urllib.request, ipaddress, re
LOG_PATH = "/var/log/nginx/access.log" # change to your log path
PROVIDER_IPV4 = "https://www.cloudflare.com/ips-v4"
PROVIDER_IPV6 = "https://www.cloudflare.com/ips-v6"
EXPECTED_HEADERS = ["CF-Connecting-IP", "CF-Ray"] # change per provider
def fetch_cidr_list(url):
out = []
for line in urllib.request.urlopen(url, timeout=30):
s = line.decode().strip()
if s:
out.append(ipaddress.ip_network(s))
return out
def in_provider(ip, nets):
try:
a = ipaddress.ip_address(ip)
except:
return False
return any(a in n for n in nets)
def parse_line(line):
# naive parser: first token is remote IP, entire line may contain headers (if logged)
parts = line.split()
ip = parts[0] if parts else None
has_header = any(h in line for h in EXPECTED_HEADERS)
return ip, has_header, line.strip()
def main():
ipv4s = fetch_cidr_list(PROVIDER_IPV4)
ipv6s = fetch_cidr_list(PROVIDER_IPV6)
provider_nets = ipv4s + ipv6s
suspects = []
with open(LOG_PATH, 'r', errors='replace') as f:
for ln in f:
ip, has_header, raw = parse_line(ln)
if not ip: continue
if (not in_provider(ip, provider_nets)) or (not has_header):
suspects.append((ip, has_header, raw))
if not suspects:
print("No suspicious lines found.")
else:
print(f"Suspicious entries found: {len(suspects)} (showing up to 50)")
for s in suspects[:50]:
print(s)
if __name__ == '__main__':
main()
8 — Automation & alerts (operationalize detection)
- Daily job: run the script above nightly, email or Slack alerts on suspicious IPs.
- SIEM rules: create rules to alert on requests missing proxy headers, requests to admin endpoints from non-proxy IPs, or TLS client-auth failures.
- Fail2ban: ban IPs that repeatedly access admin endpoints or generate 4xx/444 responses from origin (configure carefully to avoid banning legitimate traffic).
9 — Stronger prevention (so detection is less needed)
While this guide focuses on detection, prevention reduces incidents:
- Enforce provider IP allowlists at the host firewall or cloud security group (only accept connections from the proxy’s IP ranges on 80/443). Cloudflare
- Enable authenticated origin pulls (mTLS) so the origin accepts requests only when your proxy presents the client certificate. This stops direct HTTPS connections. Cloudflare Docs+1
- Consider tunneling solutions (e.g., Argo Tunnel) or private networking so your origin isn’t directly addressable. (These reduce origin-exposure risk.)
10 — Response playbook when you detect bypassed traffic
- Identify and isolate the offending IPs and block them at the firewall.
- Confirm whether the request succeeded — check application logs for suspicious activity (logins, file writes, DB changes).
- Rotate credentials and secrets if admin endpoints or APIs were probed.
- Enable stricter measures: Authenticated Origin Pulls, IP allowlisting, or Argo Tunnel.
- Perform a forensic snapshot (logs, file checksums) and consider a deeper security scan if you suspect compromise.
FAQ (short)
Q: Can headers alone prove a bypass?
A: No. Headers can be forged. Combine header checks with IP-range verification and mTLS to reach high confidence. Cloudflare Docs+1
Q: What’s the most reliable prevention?
A: mTLS/Authenticated Origin Pulls or restricting origin access to provider IP ranges — both significantly raise the bar for attackers. Cloudflare Docs+1
Q: Are these checks Cloudflare-specific?
A: The techniques apply to any proxy/CDN. Replace Cloudflare URLs with your provider’s IP lists and expected headers.
Suggested images & alt text
- Image 1: Diagram showing proxy → edge → origin with a bypassed arrow.
Alt: “Diagram of proxy bypass detection: edge vs origin traffic”. - Image 2: Screenshot of a log snippet highlighting missing proxy headers.
Alt: “Log lines showing missing CF-Connecting-IP header”.
Suggested internal/external links
- Internal: link to your site’s “Server Hardening Checklist” or “Incident Response Playbook”.
- External (authoritative): Cloudflare Authenticated Origin Pulls docs; Cloudflare IP ranges page; proxy HTTP header reference. Cloudflare Docs+2Cloudflare+2
Closing / CTA
Detecting bypassed proxies is a combination of quick checks (headers, IPs) and stronger controls (mTLS, firewall allowlists). If you want, I can now:
- generate a ready-to-run firewall script (safe, with lockout protections) that fetches provider IPs and applies allowlist rules, or
- produce a tailored log scanner tuned to your nginx/apache log format and email/Slack alerts.
