Skip to content

Commit bea3696

Browse files
committed
Upd expressions docs
1 parent b1cc3e7 commit bea3696

File tree

1 file changed

+114
-0
lines changed

1 file changed

+114
-0
lines changed

docs/docs/admin/configuration/expressions.mdx

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,27 @@ This is best applied when doing explicit block rules, eg:
233233

234234
It seems counter-intuitive to allow known bad clients through sometimes, but this allows you to confuse attackers by making Anubis' behavior random. Adjust the thresholds and numbers as facts and circumstances demand.
235235

236+
### `regexSafe`
237+
238+
Available in `bot` expressions.
239+
240+
```ts
241+
function regexSafe(input: string): string;
242+
```
243+
244+
`regexSafe` takes a string and escapes it for safe use inside of a regular expression. This is useful when you are creating regular expressions from headers or variables such as `remoteAddress`.
245+
246+
| Input | Output |
247+
| :------------------------ | :------------------------------ |
248+
| `regexSafe("1.2.3.4")` | `1\\.2\\.3\\.4` |
249+
| `regexSafe("techaro.lol")` | `techaro\\.lol` |
250+
| `regexSafe("star*")` | `star\\*` |
251+
| `regexSafe("plus+")` | `plus\\+` |
252+
| `regexSafe("{braces}")` | `\\{braces\\}` |
253+
| `regexSafe("start^")` | `start\\^` |
254+
| `regexSafe("back\\slash")` | `back\\\\slash` |
255+
| `regexSafe("dash-dash")` | `dash\\-dash` |
256+
236257
### `segments`
237258

238259
Available in `bot` expressions.
@@ -266,6 +287,99 @@ This is useful if you want to write rules that allow requests that have no query
266287
- size(segments(path)) < 2
267288
```
268289

290+
### DNS Functions
291+
292+
Anubis can also perform DNS lookups as a part of its expression evaluation. This can be useful for doing things like checking for a valid [Forward-confirmed reverse DNS (FCrDNS)](https://en.wikipedia.org/wiki/Forward-confirmed_reverse_DNS) record.
293+
294+
#### `arpaReverseIP`
295+
296+
Available in `bot` expressions.
297+
298+
```ts
299+
function arpaReverseIP(ip: string): string;
300+
```
301+
302+
`arpaReverseIP` takes an IP address and returns its value in [ARPA notation](https://www.ietf.org/rfc/rfc2317.html). This can be useful when matching PTR record patterns.
303+
304+
| Input | Output |
305+
| :----------------------------- | :------------------------------------------------------------------- |
306+
| `arpaReverseIP("1.2.3.4")` | `4.3.2.1` |
307+
| `arpaReverseIP("2001:db8::1")` | `1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2` |
308+
309+
#### `lookupHost`
310+
311+
Available in `bot` expressions.
312+
313+
```ts
314+
function lookupHost(host: string): string[];
315+
```
316+
317+
`lookupHost` performs a DNS lookup for the given hostname and returns a list of IP addresses.
318+
319+
```yaml
320+
- name: cloudflare-ip-in-host-header
321+
action: DENY
322+
expression: '"104.16.0.0" in lookupHost(headers["Host"])'
323+
```
324+
325+
#### `reverseDNS`
326+
327+
Available in `bot` expressions.
328+
329+
```ts
330+
function reverseDNS(ip: string): string[];
331+
```
332+
333+
`reverseDNS` takes an IP address and returns the DNS names associated with it. This is useful when you want to check PTR records of an IP address.
334+
335+
```yaml
336+
- name: allow-googlebot
337+
action: ALLOW
338+
expression: 'reverseDNS(remoteAddress).endsWith(".googlebot.com")'
339+
```
340+
341+
::: warning
342+
343+
Do not use this for validating the legitimacy of an IP address. It is possible for DNS records to be out of date or otherwise manipulated. Use [`verifyFCrDNS`](#verifyfcrdns) instead for a more reliable result.
344+
345+
:::
346+
347+
#### `verifyFCrDNS`
348+
349+
Available in `bot` expressions.
350+
351+
```ts
352+
function verifyFCrDNS(ip: string): bool;
353+
function verifyFCrDNS(ip: string, pattern: string): bool;
354+
```
355+
356+
`verifyFCrDNS` checks if the reverse DNS of an IP address matches its forward DNS. This is a common technique to filter out spam and bot traffic. `verifyFCrDNS` comes in two forms:
357+
358+
- `verifyFCrDNS(remoteAddress)` will check that the reverse DNS of the remote address resolves back to the remote address.
359+
- `verifyFCrDNS(remoteAddress, pattren)` will check that the reverse DNS of the remote address is matching with pattern and that name resolves back to the remote address.
360+
361+
This is best used in rules like this:
362+
363+
```yaml
364+
- name: require-fcrdns-for-post
365+
action: DENY
366+
expression:
367+
all:
368+
- method == "POST"
369+
- "!verifyFCrDNS(remoteAddress)"
370+
```
371+
372+
Here is an another example that allows requests from telegram:
373+
374+
```yaml
375+
- name: telegrambot
376+
action: ALLOW
377+
expression:
378+
all:
379+
- userAgent.matches("TelegramBot")
380+
- verifyFCrDNS(remoteAddress, "ptr\\.telegram\\.org$")
381+
```
382+
269383
## Life advice
270384

271385
Expressions are very powerful. This is a benefit and a burden. If you are not careful with your expression targeting, you will be liable to get yourself into trouble. If you are at all in doubt, throw a `CHALLENGE` over a `DENY`. Legitimate users can easily work around a `CHALLENGE` result with a [proof of work challenge](../../design/why-proof-of-work.mdx). Bots are less likely to be able to do this.

0 commit comments

Comments
 (0)