Announcement
Subashi Pro now matches geo and ASN locally
When we announced the wind-down of 7x we said that enterprise products depending on it would be updated to decouple from the service while fully preserving their functionality, and that there would be nothing for customers to do in the meantime.
This is us delivering that for Subashi Pro, the enterprise WAF middleware for Kipchak. Version 1.25 resolves both country and ASN entirely in-process, from databases shipped with the middleware itself.
No API key, and nothing on the wire
Previously, a geo_country or asn rule meant an HTTP call to the 7x geolocation API for every new client address, with an API key to provision and a timeout to tune. Now the lookup happens against local database files.
The practical difference is that geo and ASN rules cost a walk through an in-memory data structure rather than a network round trip. Under FrankenPHP worker mode the database readers are opened once when the worker boots and reused for its lifetime, so there is no per-request setup either. There is also nothing left to fail: no upstream to be slow, no key to expire, no timeout to fall back from.
Two databases behind every lookup
Each lookup type is backed by two independent databases, consulted in order:
| Lookup | First | Second |
|---|---|---|
| Country | DB-IP IP to Country Lite | iptoasn.com |
| ASN | iptoasn.com | DB-IP IP to ASN Lite |
If the first has no record for an address, the second is tried. If neither does, the condition simply does not match and the request is let through — the firewall never blocks on the basis of data it does not have.
The ordering is deliberate. iptoasn leads on ASN because it is derived from BGP announcements and rebuilt daily, so it reflects what is actually routed. DB-IP leads on country because it places addresses by observed location rather than by registration, which matters for anycast ranges.
Kept current automatically
The databases live in a separate package, kipchak/data-geo-asn, which a pipeline rebuilds and republishes every week. Refreshing your data is a composer update.
That pipeline will not publish data it cannot vouch for. Every build re-downloads from upstream and then checks that each database is fresh for its publication cadence, is the size it ought to be, covers IPv6, and returns the right answers for a fixed set of known addresses. If any check fails the build stops rather than releasing. A quietly truncated database would fail open across every deployment at once, so this is not a step we were willing to leave to chance.
Client IP resolution is now yours to configure
Every rule that depends on who is calling — ip, geo_country, asn, and per-IP rate limiting — is evaluated against one resolved address, and until now Subashi Pro decided how to work that out on your behalf. In 1.25 you configure it:
'client_ip' => [
'sources' => ['header:X-Forwarded-For', 'remote_addr'],
'trusted_proxies' => ['10.0.0.0/8'],
'chain_position' => 'first',
],
Sources are tried in order and the first that yields a valid address wins, so you can put a CDN header such as CF-Connecting-IP ahead of everything else and keep remote_addr as a backstop.
Forwarding headers are only read when the direct peer is a configured trusted proxy, given as addresses or CIDR ranges in either address family. Anyone on the internet can send an X-Forwarded-For header, so a firewall that believed one unconditionally would be taking the caller’s word for who the caller is. The default configuration trusts nothing and uses the connecting address.
X-Forwarded-For is also a chain rather than a single value:
X-Forwarded-For: 203.0.113.9, 70.41.3.18, 150.172.238.178
chain_position chooses which end to read — the leftmost entry, which is what you want when your edge proxy overwrites the header, or the rightmost, which cannot be spoofed but is your own proxy’s address once there is more than one hop in front. Port suffixes, bracketed IPv6 and zone identifiers are stripped, and entries that are not addresses at all are skipped rather than failing the lookup.
Seeing what the firewall sees
Configuring any of the above correctly means knowing which headers actually reach your application and what your proxies put in them — which is exactly the thing you cannot observe from outside. So 1.25 adds a diagnostics dump:
'diagnostics' => [
'enabled' => true,
'query_param' => 'kipchak-waf-debug',
'token' => env('SUBASHI_DIAGNOSTICS_TOKEN', ''),
],
Add the parameter to any route and the middleware answers with the dump rather than passing the request on:
https://api.example.com/v1/anything?kipchak-waf-debug=your-token
It reports the address it resolved and which source produced it, whether your connecting peer counted as a trusted proxy, the country and ASN along with which of the four databases answered, and every header on the request:
{
"client_ip": {
"resolved": "212.58.244.20",
"resolved_from": "header:X-Forwarded-For",
"remote_addr": "10.1.2.3",
"peer_is_trusted_proxy": true
},
"geo": {
"country": { "value": "GB", "database": "dbip-country.mmdb" },
"asn": { "value": "2818", "organisation": "BBC Internet Services, UK", "database": "iptoasn-asn.mmdb" }
}
}
The check runs ahead of every rule, and ahead of the master enabled switch, so you can still ask why the firewall sees you as a particular address on a request that would otherwise be blocked.
It is off by default and stays inert until you set a token, because the dump shows a caller their own headers and describes your proxy topology. Server parameters are deliberately limited to a fixed list of network keys — on most runtimes that array carries the process environment, and a debugging aid should not be a route to your database password. Every use is logged.
Upgrading
composer require kipchak/middleware-subashi-pro:^1.25
The geolocation.api_key, base_url, timeout_seconds and cache_ttl settings no longer do anything and can be removed. Keep geolocation.enabled as it is; your existing geo_country and asn rules need no changes and will start resolving again against the bundled data.
If Subashi Pro sits behind a load balancer, ingress controller or CDN, this is a good moment to set client_ip explicitly. Without it, resolution falls back to the connecting address, which will be your proxy rather than your visitor. Turning on diagnostics for a few minutes is the quickest way to confirm you have it right.
Full details are in the Subashi Pro documentation.
IP geolocation by DB-IP, used under CC BY 4.0. ASN and country data from iptoasn.com, released into the public domain under PDDL 1.0.