mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-11-01 03:15:13 +08:00
🗽 Sync 2026-09-12 10:51:28
This commit is contained in:
1 parent
401d0e8a16
commit
b63d71b4d0
11 files changed
+228
-153
No files matched your search
@@ -0,0 +1,124 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# Copyright 2025-2026 Lucas Albers <lucas.b.albers@gmail.com>
|
||||
#
|
||||
# GENERATED FILE — do not edit. Run: ./scripts/gen-all.sh
|
||||
# source: core/fwlive-log.js CLASSIFY_SPEC
|
||||
# Standalone awk program loaded by fwlive-is-firewall-event.sh.
|
||||
|
||||
function normalize(s, keys, n, i, k) {
|
||||
n = split("IN OUT SRC DST PROTO SPT DPT LEN MAC TYPE CODE TTL TOS PREC DF", keys, " ")
|
||||
for (i = 1; i <= n; i++) {
|
||||
k = keys[i]
|
||||
while (match(s, "[^[:space:]]" k "="))
|
||||
s = substr(s, 1, RSTART) " " substr(s, RSTART + 1)
|
||||
}
|
||||
return s
|
||||
}
|
||||
function trim(s) {
|
||||
sub(/^[[:space:]]+/, "", s)
|
||||
sub(/[[:space:]]+$/, "", s)
|
||||
return s
|
||||
}
|
||||
function has_kv(s, key) {
|
||||
return s ~ "(^|[^A-Za-z0-9_])" key "="
|
||||
}
|
||||
function has_hint(s, lc) {
|
||||
lc = tolower(s)
|
||||
return lc ~ "(^|[^a-z0-9_])(fw4|nft|iptables|kernel|firewall)([^a-z0-9_]|$)"
|
||||
}
|
||||
function non_fw_prefix(s, lc) {
|
||||
lc = tolower(s)
|
||||
return lc ~ "^(dnsmasq|procd|ubusd|netifd|odhcpd|logd|dropbear|uhttpd|hostapd|wpad)([^a-z0-9_]|$)"
|
||||
}
|
||||
function detect_action(s, words, n, i, w, wl, lc, start, pos, before, afterc, best, bestpos) {
|
||||
n = split("ACCEPT ALLOW PASS DROP REJECT DENY BLOCK", words, " ")
|
||||
lc = tolower(s)
|
||||
best = ""
|
||||
bestpos = length(s) + 1
|
||||
for (i = 1; i <= n; i++) {
|
||||
w = words[i]
|
||||
wl = tolower(w)
|
||||
start = 1
|
||||
while (start <= length(lc) && match(substr(lc, start), wl)) {
|
||||
pos = start + RSTART - 1
|
||||
before = (pos == 1) ? " " : substr(lc, pos - 1, 1)
|
||||
afterc = substr(lc, pos + length(wl), 1)
|
||||
if (before !~ /[a-z0-9_]/ && (afterc == "" || afterc !~ /[a-z0-9_]/)) {
|
||||
if (pos < bestpos) { bestpos = pos; best = w }
|
||||
break
|
||||
}
|
||||
start = pos + 1
|
||||
}
|
||||
}
|
||||
return best == "" ? "UNKNOWN" : best
|
||||
}
|
||||
function json_unhex4(h, n, i, c, v) {
|
||||
n = 0
|
||||
h = tolower(h)
|
||||
for (i = 1; i <= 4; i++) {
|
||||
c = substr(h, i, 1)
|
||||
v = index("0123456789abcdef", c)
|
||||
if (v == 0) return -1
|
||||
n = n * 16 + v - 1
|
||||
}
|
||||
return n
|
||||
}
|
||||
function json_get_msg(obj, s, i, c, esc, out, hex, n) {
|
||||
if (!match(obj, /"msg"[[:space:]]*:[[:space:]]*"/)) return ""
|
||||
s = substr(obj, RSTART + RLENGTH)
|
||||
out = ""
|
||||
esc = 0
|
||||
for (i = 1; i <= length(s); i++) {
|
||||
c = substr(s, i, 1)
|
||||
if (esc) {
|
||||
if (c == "n") out = out "\n"
|
||||
else if (c == "t") out = out "\t"
|
||||
else if (c == "r") out = out "\r"
|
||||
else if (c == "b") out = out "\b"
|
||||
else if (c == "f") out = out "\f"
|
||||
else if (c == "u") {
|
||||
hex = substr(s, i + 1, 4)
|
||||
n = (length(hex) == 4) ? json_unhex4(hex) : -1
|
||||
if (n >= 1 && n <= 255) out = out sprintf("%c", n)
|
||||
else if (n < 0) out = out "u"
|
||||
if (n >= 0) i += 4
|
||||
} else out = out c
|
||||
esc = 0
|
||||
} else if (c == "\\") {
|
||||
esc = 1
|
||||
} else if (c == "\"") {
|
||||
return out
|
||||
} else {
|
||||
out = out c
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
function is_fw(s, action) {
|
||||
s = trim(normalize(s))
|
||||
if (s == "") return 0
|
||||
if (non_fw_prefix(s)) return 0
|
||||
action = detect_action(s)
|
||||
if (has_kv(s, "SRC") && has_kv(s, "DST")) return 1
|
||||
if ((has_kv(s, "IN") || has_kv(s, "OUT")) && (has_kv(s, "SRC") || has_kv(s, "DST") || has_kv(s, "PROTO") || has_kv(s, "SPT") || has_kv(s, "DPT"))) return 1
|
||||
if (action != "UNKNOWN" && (has_kv(s, "IN") || has_kv(s, "OUT") || has_kv(s, "PROTO") || has_kv(s, "SRC") || has_kv(s, "DST"))) return 1
|
||||
if (has_hint(s) && action != "UNKNOWN") return 1
|
||||
if (has_hint(s) && (has_kv(s, "IN") || has_kv(s, "OUT") || has_kv(s, "SRC") || has_kv(s, "DST") || has_kv(s, "PROTO"))) return 1
|
||||
return 0
|
||||
}
|
||||
BEGIN { if (MODE != "json") ORS = "" }
|
||||
{
|
||||
if (MODE == "json") {
|
||||
msg = json_get_msg($0)
|
||||
if (is_fw(msg)) {
|
||||
if (out_n++) printf ","
|
||||
printf "%s", $0
|
||||
}
|
||||
next
|
||||
}
|
||||
buf = (NR == 1) ? $0 : buf "\n" $0
|
||||
}
|
||||
END {
|
||||
if (MODE != "json")
|
||||
print is_fw(buf) ? 1 : 0
|
||||
}
|
||||
@@ -7,127 +7,12 @@
|
||||
# Sourced library: do not add set -euo here (callers own strict mode, #291 C3).
|
||||
# One awk process classifies a batch (MODE=json) or one message (default).
|
||||
|
||||
# The caller sets FILTER_DIR when this file is sourced. Resolve the asset
|
||||
# once, not once per classification call.
|
||||
CLASSIFY_AWK="${FILTER_DIR:-${0%/*}}/fwlive-is-firewall-event.awk"
|
||||
|
||||
_fwlive_run_classify() {
|
||||
awk -v MODE="${1:-msg}" "$(cat <<'AWK'
|
||||
function normalize(s, keys, n, i, k) {
|
||||
n = split("IN OUT SRC DST PROTO SPT DPT LEN MAC TYPE CODE TTL TOS PREC DF", keys, " ")
|
||||
for (i = 1; i <= n; i++) {
|
||||
k = keys[i]
|
||||
while (match(s, "[^[:space:]]" k "="))
|
||||
s = substr(s, 1, RSTART) " " substr(s, RSTART + 1)
|
||||
}
|
||||
return s
|
||||
}
|
||||
function trim(s) {
|
||||
sub(/^[[:space:]]+/, "", s)
|
||||
sub(/[[:space:]]+$/, "", s)
|
||||
return s
|
||||
}
|
||||
function has_kv(s, key) {
|
||||
return s ~ "(^|[^A-Za-z0-9_])" key "="
|
||||
}
|
||||
function has_hint(s, lc) {
|
||||
lc = tolower(s)
|
||||
return lc ~ "(^|[^a-z0-9_])(fw4|nft|iptables|kernel|firewall)([^a-z0-9_]|$)"
|
||||
}
|
||||
function non_fw_prefix(s, lc) {
|
||||
lc = tolower(s)
|
||||
return lc ~ "^(dnsmasq|procd|ubusd|netifd|odhcpd|logd|dropbear|uhttpd|hostapd|wpad)([^a-z0-9_]|$)"
|
||||
}
|
||||
function detect_action(s, words, n, i, w, wl, lc, start, pos, before, afterc, best, bestpos) {
|
||||
n = split("ACCEPT ALLOW PASS DROP REJECT DENY BLOCK", words, " ")
|
||||
lc = tolower(s)
|
||||
best = ""
|
||||
bestpos = length(s) + 1
|
||||
for (i = 1; i <= n; i++) {
|
||||
w = words[i]
|
||||
wl = tolower(w)
|
||||
start = 1
|
||||
while (start <= length(lc) && match(substr(lc, start), wl)) {
|
||||
pos = start + RSTART - 1
|
||||
before = (pos == 1) ? " " : substr(lc, pos - 1, 1)
|
||||
afterc = substr(lc, pos + length(wl), 1)
|
||||
if (before !~ /[a-z0-9_]/ && (afterc == "" || afterc !~ /[a-z0-9_]/)) {
|
||||
if (pos < bestpos) { bestpos = pos; best = w }
|
||||
break
|
||||
}
|
||||
start = pos + 1
|
||||
}
|
||||
}
|
||||
return best == "" ? "UNKNOWN" : best
|
||||
}
|
||||
function json_unhex4(h, n, i, c, v) {
|
||||
n = 0
|
||||
h = tolower(h)
|
||||
for (i = 1; i <= 4; i++) {
|
||||
c = substr(h, i, 1)
|
||||
v = index("0123456789abcdef", c)
|
||||
if (v == 0) return -1
|
||||
n = n * 16 + v - 1
|
||||
}
|
||||
return n
|
||||
}
|
||||
function json_get_msg(obj, s, i, c, esc, out, hex, n) {
|
||||
if (!match(obj, /"msg"[[:space:]]*:[[:space:]]*"/)) return ""
|
||||
s = substr(obj, RSTART + RLENGTH)
|
||||
out = ""
|
||||
esc = 0
|
||||
for (i = 1; i <= length(s); i++) {
|
||||
c = substr(s, i, 1)
|
||||
if (esc) {
|
||||
if (c == "n") out = out "\n"
|
||||
else if (c == "t") out = out "\t"
|
||||
else if (c == "r") out = out "\r"
|
||||
else if (c == "b") out = out "\b"
|
||||
else if (c == "f") out = out "\f"
|
||||
else if (c == "u") {
|
||||
hex = substr(s, i + 1, 4)
|
||||
n = (length(hex) == 4) ? json_unhex4(hex) : -1
|
||||
if (n >= 1 && n <= 255) out = out sprintf("%c", n)
|
||||
else if (n < 0) out = out "u"
|
||||
if (n >= 0) i += 4
|
||||
} else out = out c
|
||||
esc = 0
|
||||
} else if (c == "\\") {
|
||||
esc = 1
|
||||
} else if (c == "\"") {
|
||||
return out
|
||||
} else {
|
||||
out = out c
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
function is_fw(s, action) {
|
||||
s = trim(normalize(s))
|
||||
if (s == "") return 0
|
||||
if (non_fw_prefix(s)) return 0
|
||||
action = detect_action(s)
|
||||
if (has_kv(s, "SRC") && has_kv(s, "DST")) return 1
|
||||
if ((has_kv(s, "IN") || has_kv(s, "OUT")) && (has_kv(s, "SRC") || has_kv(s, "DST") || has_kv(s, "PROTO") || has_kv(s, "SPT") || has_kv(s, "DPT"))) return 1
|
||||
if (action != "UNKNOWN" && (has_kv(s, "IN") || has_kv(s, "OUT") || has_kv(s, "PROTO") || has_kv(s, "SRC") || has_kv(s, "DST"))) return 1
|
||||
if (has_hint(s) && action != "UNKNOWN") return 1
|
||||
if (has_hint(s) && (has_kv(s, "IN") || has_kv(s, "OUT") || has_kv(s, "SRC") || has_kv(s, "DST") || has_kv(s, "PROTO"))) return 1
|
||||
return 0
|
||||
}
|
||||
BEGIN { if (MODE != "json") ORS = "" }
|
||||
{
|
||||
if (MODE == "json") {
|
||||
msg = json_get_msg($0)
|
||||
if (is_fw(msg)) {
|
||||
if (out_n++) printf ","
|
||||
printf "%s", $0
|
||||
}
|
||||
next
|
||||
}
|
||||
buf = (NR == 1) ? $0 : buf "\n" $0
|
||||
}
|
||||
END {
|
||||
if (MODE != "json")
|
||||
print is_fw(buf) ? 1 : 0
|
||||
}
|
||||
AWK
|
||||
)"
|
||||
awk -v MODE="${1:-msg}" -f "$CLASSIFY_AWK"
|
||||
}
|
||||
|
||||
is_firewall_event_msg() {
|
||||
|
||||
@@ -25,8 +25,12 @@ FILTER_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
# shellcheck disable=SC1091 # classifier is a sibling file next to this script
|
||||
. "$FILTER_DIR/fwlive-is-firewall-event.sh"
|
||||
|
||||
input="$(cat)"
|
||||
[ -n "$input" ] || input='{"log":[]}'
|
||||
# The classifier is a package asset, not generated at request time. Fail
|
||||
# closed if an incomplete install or a damaged package removed it (#321).
|
||||
if [ ! -r "$CLASSIFY_AWK" ]; then
|
||||
printf '%s' '{"log":[],"error":"classifier_missing"}'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
printf '%s' '{"log":['
|
||||
# Prefer stdin over -s: Linux MAX_ARG_STRLEN is 128KiB; a raised logd ring
|
||||
@@ -34,5 +38,5 @@ printf '%s' '{"log":['
|
||||
# while this script still printed {"log":[]} and exited 0 (#234).
|
||||
# jsonfilter miss / empty @.log is not fatal; must still close JSON (#220).
|
||||
# set -e + pipefail cannot apply to this pipeline (#291 C3).
|
||||
printf '%s' "$input" | jsonfilter -e '@.log[*]' 2>/dev/null | _fwlive_filter_json_entries || true
|
||||
jsonfilter -e '@.log[*]' 2>/dev/null | _fwlive_filter_json_entries || true
|
||||
printf '%s' ']}'
|
||||
Reference in new issue
Block a user