Ereshkigal
view release on metacpan or search on metacpan
docs/kurs/netscaler.md view on Meta::CPAN
reachable and auth works, it does not create the dataset. On the
NetScaler:
```
add policy dataset banned_ips ipv4
```
(or type `ipv6` / one dataset per family as your policies need), then
wire it into enforcement, e.g. a responder policy dropping matching
clients:
```
add responder policy kur_block "CLIENT.IP.SRC.EQUALS_ANY(\"banned_ips\")" DROP
bind lb vserver my_vserver -policyName kur_block -priority 10 -type REQUEST
```
Exactly how the dataset is consumed â responder policy, ACL
expression, vserver or global binding â is your design; the kur only
manages the membership.
A dedicated API user with just the permissions to manage dataset
bindings is preferable to `nsroot`.
## Requirements
- `LWP::UserAgent` installed, plus `LWP::Protocol::https` when
`scheme` is https (the default) â loaded only at runtime.
- Network reach to the appliance's NITRO endpoint.
## Settings
- `ports` / `protocols` â **not supported**; specifying either is a
fatal error at kur startup. Scoping lives in the policies consuming
the dataset.
- `enable_cidr` â this backend can **not** carry ranges (dataset
values are single IPs); a kur with it set logs a warning at startup
and answers range commands per `cidr_silent_drop`.
- `prefix` â only used in the default `dataset` name.
## Options
| option | default | what |
|--------------|-------------------|-------------------------------------------------------------------|
| `host` | *(required)* | hostname or IP of the appliance; `/^[a-zA-Z0-9.\-\[\]:]+$/` |
| `user` | *(unset)* | username for basic auth |
| `pass` | *(unset)* | password for basic auth |
| `auth` | *(unset)* | pre-base64ed `user:pass`, in place of user/pass (fail2ban `ns_auth` parity) |
| `dataset` | `<prefix>_<name>` | the policy dataset holding the IPs; `/^[a-zA-Z0-9_\-]+$/` |
| `scheme` | `https` | `http` or `https` |
| `ssl_verify` | `0` | verify the TLS certificate |
| `timeout` | `30` | HTTP timeout in seconds |
`host` is required, as is either `auth` or both `user` and `pass`.
Auth is sent as `Authorization: Basic <base64>` â built from
user/pass at request time, or your `auth` value verbatim.
`ssl_verify` defaults **off**, matching the fail2ban action's
`curl -k` (appliances commonly wear self-signed certificates). Off
means `verify_hostname => 0` â the connection is encrypted but the
peer unauthenticated; anything that can MITM the path can harvest the
credentials. Set `ssl_verify = 1` if the appliance has a real
certificate, and consider giving it one if not.
## What each operation does
| operation | API traffic |
|------------|--------------------------------------------------------------------------|
| `init` | `GET <scheme>://<host>/nitro/v1/config` â verifies reachability and auth |
| `ban` | the `PUT policydataset_value_binding` above |
| `unban` | `DELETE .../policydataset_value_binding/<dataset>?args=value:<ip>` |
| `list` | no API call â the kur's own ban book |
| `check` | same probe as init |
| `flush` | the DELETE per banned IP |
| `re_init` | teardown (best effort), init, re-PUT every banned IP |
| `teardown` | the DELETE per banned IP (ban book kept for re_init) |
HTTP-level failures die with the status and response body included â
but NITRO errors that arrive with HTTP 200 are not parsed, so a
misconfigured dataset name may only surface as a failed ban rather
than at init.
## self_heal and remote drift
`check` verifies the API answers and auth works â not that the
dataset exists or that individual bindings survive. A binding removed
on the appliance by hand stays removed until `re_init`; unlike the
cloudflare backend, unbanning an already-missing binding is an error
(the DELETE fails), which the kur logs and reports.
## Gotchas
- Every ban/unban is an API round trip; timed bans double that at
expiry. Mind the appliance's management-plane appetite with very
chatty ban sources.
- Both IPv4 and IPv6 values are accepted and passed through; make
sure the dataset's type (and the policies) match what you feed it.
- IPv6 IPs are lowercased before use.
- Errors carry Error::Helper flags (`optionInvalid`, â¦) â [`Net::Firewall::BlockerHelper::backends::netscaler`](https://metacpan.org/pod/Net::Firewall::BlockerHelper::backends::netscaler) has the full
table.
( run in 1.432 second using v1.01-cache-2.11-cpan-007c89162af )