Skip to content
WebShield Docs

Attacks straight at the server IP

If protection is on and the server is still under load, requests may be bypassing us and hitting its address. How to find where the address leaked and close the server to everyone except WebShield.

Proxying removes the server’s address from DNS but does not change it. If the address became known earlier or leaked another way, the server can be reached directly — past signatures, limits, bans and the browser check. One sign: Statistics look calm while the server is under load.

The fix is to find where the address leaked and make the server answer only requests carrying the secret header we add.

What you get: the server answers only requests that came through us; a direct request is refused before it reaches the application. You need: access to the web server configuration and a fallback way into the server — SSH or the hosting panel. Time: 20–30 minutes.

1. Make sure direct requests are the problem

Section titled “1. Make sure direct requests are the problem”

Compare the server log with Statistics for the same hour. If you have noticeably more requests than we passed to the server, the extra ones came around us. A quick test from any machine:

Terminal window
curl -sk -o /dev/null -w '%{http_code}\n' https://SERVER_ADDRESS/ -H 'Host: example.com'

A 200 means the site opens directly, and there is something to close.

You need to close the server either way, but plug the leaks too — otherwise a new address after a move leaks the same way.

  • DNS records. Subdomains like mail, ftp, cpanel, dev, old pointing at the same server without proxying. Check every A/AAAA in the zone.
  • Mail. Emails the site sends itself — sign-ups, password resets, orders — carry the server’s address in their headers. Send them through an external SMTP service.
  • A certificate on the bare IP. If the server answers https://ADDRESS/ with your certificate, certificate search engines (Censys, Shodan) can link the address to the domain. Make the server show nothing on a bare IP.
  • DNS history. DNS history services remember where the domain pointed before it came to us. That cannot be fixed — only the address can be changed.
  • Outgoing requests. Webhooks, link checks, fetching images by URL — anything the server downloads on a visitor’s request reveals the address to whoever asked.

We add a header with the host’s secret to every request to your server:

X-WebShield-Origin-Token: wso_…

A visitor cannot forge it — a header of theirs with the same name is replaced with ours. So the rule is simple: no header or a wrong one means refusal. No list of our addresses is needed — it changes along with the network, while the secret stays.

The value is in the panel: Hosts → host → Access only through WebShield. Each host has its own.

Before the change, make sure every site name has proxying on in DNS — otherwise you will lock out your own visitors.

nginx — in the site’s server block:

if ($http_x_webshield_origin_token != "wso_YOUR_TOKEN") { return 444; }

444 closes the connection silently without spending a byte on a reply. Apply: nginx -t && systemctl reload nginx.

Caddy:

example.com {
@direct not header X-WebShield-Origin-Token "wso_YOUR_TOKEN"
respond @direct 403
reverse_proxy localhost:3000
}

Apache — in the site config or .htaccess:

<If "%{HTTP:X-WebShield-Origin-Token} != 'wso_YOUR_TOKEN'">
Require all denied
</If>

IIS, Traefik, HAProxy and checks inside application code are in the reference Origin access through WebShield only.

The Let’s Encrypt certificate on the server keeps renewing: the challenge arrives at your domain, that is at us, and we pass it to the server with the same header. No exception for /.well-known/acme-challenge/ is needed.

The secret closes your site, but the server still completes the TLS handshake and shows the certificate — which is how the address gets found. Add a default site that shows nothing. For nginx 1.19.4 and newer:

server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
ssl_reject_handshake on;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
return 444;
}

Now https://ADDRESS/ breaks off the handshake without showing a certificate.

5. If the attack is volumetric — change the address

Section titled “5. If the attack is volumetric — change the address”

The secret cuts requests off at the web server, which is after the connection is established. Against a flood that saturates the link or the network stack it won’t help: the packets still fly to your address. If the attacker knows the address, the only reliable cure is to get a new one from your host, set it in DNS with us and show it to no one. Proxying hides it right away.

Terminal window
# Directly — refused (403 or a dropped connection).
curl -sk -o /dev/null -w '%{http_code}\n' https://SERVER_ADDRESS/ -H 'Host: example.com'
# Through us — a normal reply.
curl -s -o /dev/null -w '%{http_code}\n' https://example.com/

000 on the first line is exactly the dropped connection after 444.

Symptom Cause and fix
The site errors for everyone The token in the config does not match the panel, comes from another host, or was not updated on the server after Reissue.
A direct request still gets 200 The change did not apply — check the config (nginx -t) and reload the web server — or it sits in the wrong server block.
Direct requests hit another subdomain Each host has its own secret and its own server block — close every proxied name.
The server cannot reach its own site It goes to itself directly, for example through an /etc/hosts entry. Remove it so requests go through us, or allow 127.0.0.1 with a separate rule.