diff --git a/examples/route-proxy/main.go b/examples/route-proxy/main.go index 47d4f93..4a12f3a 100644 --- a/examples/route-proxy/main.go +++ b/examples/route-proxy/main.go @@ -732,6 +732,11 @@ func handler(held *table) http.Handler { // And since a host may now be routed only on some paths, those are a third thing: // saying "no route for this name" while listing that very name as served is a // contradiction an operator would have to disbelieve the proxy to get past. + // **Said in the log as well as to the client.** A name this mesh does not serve, asked + // for from outside, is what a scanner does, and the machine's intrusion prevention reads + // this proxy's log for exactly that line (novox/hq ADR 0179): the address last, as the + // jail's filter expects it. + log.Printf("refused: no route for %q, asked from %s", r.Host, r.RemoteAddr) w.Header().Set("Content-Type", "text/plain; charset=utf-8") w.WriteHeader(http.StatusNotFound) if !hidden && held.routed(r.Host) { diff --git a/internal/catalogue/seats.go b/internal/catalogue/seats.go index 3121db2..e4f2df7 100644 --- a/internal/catalogue/seats.go +++ b/internal/catalogue/seats.go @@ -99,7 +99,23 @@ var defaultSeats = []Seat{ {Name: "mesh-build-machine", Scope: ScopeMesh, Accepts: []string{"build"}, Emits: []string{"started", "built", "log.*"}, Decision: "novox/hq ADR 0121"}, {Name: "node-dns-resolver", Scope: ScopeNode, Decision: "novox/hq ADR 0121"}, - {Name: "node-intrusion-prevention", Scope: ScopeNode, Decision: "novox/hq ADR 0121"}, + // The intrusion prevention's verbs (novox/hq ADR 0179): what a person asks a machine's ban list + // whatever keeps it — who is banned and why, ban one address, let one go. Every holder serves all + // four; the jails themselves are composed from the modules the machine runs (to-be 31). + {Name: "node-intrusion-prevention", Scope: ScopeNode, Decision: "novox/hq ADR 0121", + Serves: []Verb{ + {Name: "status", Description: "Every jail on this machine with how many it is watching and " + + "holding now, and the totals since the jail started; one jail's detail when named.", + Input: schema(map[string]string{"jail": "one jail (optional)"}, nil)}, + {Name: "banned", Description: "Every address banned on this machine right now, with the jail " + + "that holds it and when the ban ends.", + Input: schema(map[string]string{"jail": "one jail (optional)"}, nil)}, + {Name: "ban", Description: "Ban one address in one jail now, for the jail's ban time — an " + + "operator's act on the live ban list, which the mesh never writes itself.", + Input: schema(map[string]string{"ip": "the address", "jail": "the jail to hold it"}, []string{"ip", "jail"})}, + {Name: "unban", Description: "Let one address go, from one jail or from every jail when none is named.", + Input: schema(map[string]string{"ip": "the address", "jail": "one jail (optional)"}, []string{"ip"})}, + }}, // The packet filter's verbs (novox/hq ADR 0170): what a person asks a machine's filter whatever // filter answers — the rules as enforced, reload the mesh's own, remove one thing the mesh did // not write. Every holder serves all three; what differs by filter is the holder's own tools.