servewaf answers rproxy's question about each request and takes its report (closes #170)
check / check (push) Successful in 4m27s
check / check (push) Successful in 4m27s
`smallwebwaf servewaf` runs today's checks on the visitor's request a question carries and answers allow, deny or close, instead of passing it to an app. rproxy's report then counts the bytes toward the byte limits and adds the request to the client's history. SPEC.md gives the exact question, answer and report, which rproxy follows. `smallwebwaf` with no command is unchanged. Judgement call: a third disposition, close, since closing the question's connection would read as servewaf down and let the request through. Judgement call: allow can answer a new request id, since a visitor behind a trusted proxy can choose its own. Model: opus-5-5
This commit is contained in:
@@ -150,13 +150,16 @@ type Params struct {
|
||||
|
||||
// Alert is one alert, as the webhook is sent it and alerts.json holds it,
|
||||
// with the fields of "The JSON object" in docs/alerts.md. ASN, ASName and
|
||||
// Country are, for a ban, the client's as the ban's notes give them.
|
||||
// Country are, for a ban, the client's as the ban's notes give them. Host is
|
||||
// the site of the request that raised the alert, while one servewaf serves
|
||||
// many sites, and "" otherwise.
|
||||
//
|
||||
//nolint:tagliatelle // docs/alerts.md names the alert's fields in snake_case
|
||||
type Alert struct {
|
||||
Instance string `json:"instance"`
|
||||
Time time.Time `json:"time"`
|
||||
Event string `json:"event"`
|
||||
Host string `json:"host,omitempty"`
|
||||
Client netip.Addr `json:"client"`
|
||||
Netblock netip.Prefix `json:"netblock"`
|
||||
ASN string `json:"asn"`
|
||||
@@ -899,12 +902,16 @@ func title(alert *Alert) string {
|
||||
}
|
||||
|
||||
// text returns the text of alert in Slack and ntfy: its reason, then a
|
||||
// line for each of its client, netblock and country, the file, source,
|
||||
// error and mode its detail gives, and its suppressed repeats, that it
|
||||
// has.
|
||||
// line for each of its host, client, netblock and country, the file,
|
||||
// source, error and mode its detail gives, and its suppressed repeats, that
|
||||
// it has.
|
||||
func text(alert *Alert) string {
|
||||
lines := []string{alert.Reason}
|
||||
|
||||
if alert.Host != "" {
|
||||
lines = append(lines, "host: "+alert.Host)
|
||||
}
|
||||
|
||||
if alert.Client.IsValid() {
|
||||
lines = append(lines, "client: "+alert.Client.String())
|
||||
}
|
||||
|
||||
@@ -1284,9 +1284,11 @@ func anAlertForEachEvent() []eventMessage {
|
||||
Event: alerts.EventWAFBlock, Client: netip.MustParseAddr("192.0.2.1"),
|
||||
Netblock: netip.MustParsePrefix("192.0.2.1/32"),
|
||||
Reason: "refused by the Core Rule Set",
|
||||
Host: "app.example",
|
||||
},
|
||||
"fsn1app1/gitea: waf_block", "default shield",
|
||||
"refused by the Core Rule Set\nclient: 192.0.2.1\nnetblock: 192.0.2.1/32",
|
||||
"refused by the Core Rule Set\nhost: app.example\nclient: 192.0.2.1\n" +
|
||||
"netblock: 192.0.2.1/32",
|
||||
},
|
||||
{
|
||||
alerts.Alert{
|
||||
|
||||
Reference in New Issue
Block a user