Skip to content

luci-app-fwlive: add firewall live view - #8992

Open
lucas-albers-lz4 wants to merge 1 commit into
openwrt:masterfrom
lucas-albers-lz4:luci-app-fwlive-add
Open

lucas-albers-lz4 wants to merge 1 commit into
openwrt:masterfrom
lucas-albers-lz4:luci-app-fwlive-add

Conversation

@lucas-albers-lz4

@lucas-albers-lz4 lucas-albers-lz4 commented Aug 30, 2026

Copy link
Copy Markdown

Summary

Add luci-app-fwlive (Firewall Live View): a Status menu view that polls
firewall-only log lines via a dedicated rpcd plugin (rules, poll,
resolve, logging_status, enable_wan_logging, disable_wan_logging).

License: Apache-2.0 (PKG_LICENSE). This PR is a snapshot of
https://github.com/lucas-albers-lz4/fwlive (signed binary feed remains for
non-snapshot users), not a move.

Maintenance

fwlive stays the development home. This tree is a snapshot. On conflict, the
next snapshot from that repository replaces this copy — land fixes there
first. A PKG_SOURCE tarball was considered and declined: LuCI applications
are in-tree under applications/, and Weblate owns po/<lang>/ after merge.

Design notes

  • Sessions never get ubus log.read. The plugin filters logs as root
    under a narrow ACL (read/write scopes kept separate).
  • WAN log=1 is opt-in from the UI; prerm restores the saved baseline
    (fail-open).
  • This commit ships po/templates only. Locales can come from Weblate
    after merge. Please do not hand-add .po files in follow-ups that would
    clobber Weblate.
  • PKG_VERSION / PKG_RELEASE kept in lockstep with the out-of-tree app.
  • Generated shell/JS snapshots come from the fwlive monorepo generators;
    Node/core/ are not vendored here.
  • Depends: luci-base, logd, jsonfilter. Optional hostnames use
    BusyBox nslookup (stock image).

Review follow-up (second commit)

Addresses the first-round findings: rules map assembled in the current shell
(nft/iptables labels reach the client); reverse DNS via nslookup;
jsonfilter declared and no longer a silent empty table; poll classifier is
one awk pass; json_escape is self-contained for prerm; UCI names with
whitespace are not word-split.

Test plan

  • Build luci-app-fwlive against a current OpenWrt SDK / image builder
  • Install; confirm Status → Firewall Live View menu appears
  • With fw4/nft, confirm rules with log prefix / !fw4: comments show labels
  • Poll updates; busy WAN-logging does not stall the 1s interval
  • Opt-in WAN logging; confirm events; disable / uninstall restores baseline
  • Confirm session ACL cannot call log.read directly
  • Show hostnames: a PTR-backed IP resolves on a stock image (no extra pkgs)

@openwrt openwrt Bot added the add package Introduces a new package Makefile build script label Aug 30, 2026

@openwrt-ai openwrt-ai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 1 new commit (91b4629). The commit message matches the diff; no commit-level issues.

Two of the inline findings look like they break advertised features on a stock image rather than being polish: the rules map is assembled inside pipeline subshells so the nft/iptables log-prefix labels never reach the client (the __rulesmap_iptables selftest uses a redirect and so passes), and resolve calls getent, which is not present anywhere in OpenWrt. Worth confirming both against a real device before merge, since the current code fails silently in each case.


Generated by Claude Code

Comment thread applications/luci-app-fwlive/root/usr/libexec/rpcd/fwlive Outdated
Comment thread applications/luci-app-fwlive/root/usr/libexec/rpcd/fwlive Outdated
Comment thread applications/luci-app-fwlive/root/usr/libexec/rpcd/fwlive Outdated
Comment thread applications/luci-app-fwlive/root/usr/libexec/fwlive-logging.sh
Comment thread applications/luci-app-fwlive/root/usr/libexec/fwlive-log-filter.sh Outdated
Comment thread applications/luci-app-fwlive/Makefile Outdated
Comment thread applications/luci-app-fwlive/htdocs/luci-static/resources/fwlive/constants.js Outdated
Comment thread applications/luci-app-fwlive/README.md Outdated
lucas-albers-lz4 added a commit to lucas-albers-lz4/fwlive that referenced this pull request Aug 31, 2026
Replace getent with nslookup, move json_escape into logging.sh, declare
jsonfilter, skip whitespace-split UCI names, and rewrite the classifier
to one awk pass so a 2000-line poll stays inside budget.

Closes #218, Closes #219, Closes #220, Closes #222, Closes #224,
Closes #225, Closes #226
Refs #216
lucas-albers-lz4 added a commit to lucas-albers-lz4/fwlive that referenced this pull request Aug 31, 2026
Replace getent with nslookup, move json_escape into logging.sh, declare
jsonfilter, skip whitespace-split UCI names, and rewrite the classifier
to one awk pass so a 2000-line poll stays inside budget.

Closes #218, Closes #219, Closes #220, Closes #222, Closes #224,
Closes #225, Closes #226
Refs #216
lucas-albers-lz4 added a commit to lucas-albers-lz4/fwlive that referenced this pull request Aug 31, 2026
Replace getent with nslookup, move json_escape into logging.sh, declare
jsonfilter, skip whitespace-split UCI names, and rewrite the classifier
to one awk pass so a 2000-line poll stays inside budget.

Closes #218, Closes #219, Closes #220, Closes #222, Closes #224,
Closes #225, Closes #226
Refs #216
lucas-albers-lz4 added a commit to lucas-albers-lz4/fwlive that referenced this pull request Aug 31, 2026
Merged after human sign-off. Covers #218#220, #222, #224#226 and review folds. Stacked on #227.
lucas-albers-lz4 added a commit to lucas-albers-lz4/luci that referenced this pull request Aug 31, 2026
Re-cut from lucas-albers-lz4/fwlive after merging the openwrt#227/openwrt#228 review
wave: rules map delivery, poll clamp, nslookup resolver, jsonfilter declare,
classifier codegen, json_escape in logging.sh, and related host-test fixes.
Refresh the .pot via i18n-scan.pl.

Signed-off-by: Lucas Albers <lucas.b.albers@gmail.com>
lucas-albers-lz4 added a commit to lucas-albers-lz4/fwlive that referenced this pull request Aug 31, 2026
Fold the openwrt/luci#8992 review wave (#227/#228): rules map delivery,
poll clamp, nslookup resolver, jsonfilter declare, classifier codegen, and
related security fixes. Refresh the .pot after the upstream cut.
@lucas-albers-lz4

Copy link
Copy Markdown
Author

Re-cut from fwlive with the post-review follow-ups (BusyBox-safe WAN lock dir check, jsonfilter stdin for large rings, poll error surfaced in the UI, !fw4: label precedence, iptables-save timeout + rules map bounds).

Fork tip: lucas-albers-lz4/luci luci-app-fwlive-add @ 2defca544d.

@openwrt-ai openwrt-ai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 3 new commits since 91b4629.

The previous round's two functional findings are genuinely fixed: the rules map is now assembled in the current shell via <"$_rules_dump" redirects (and __rulesmap_iptables exercises the same two-pass path), and resolve uses BusyBox nslookup. poll_clamp_lines and the single-awk classifier both check out — I ran dash root/usr/libexec/rpcd/fwlive __selftest and _fwlive_filter_json_entries against a sample batch locally and they behave as documented. The stat -ctest -O + find -perm swap in #232 is correct for stock OpenWrt: BUSYBOX_DEFAULT_FEATURE_STAT_FORMAT is n while FEATURE_FIND_PERM, FEATURE_FIND_PAREN and FEATURE_FIND_PRUNE are all y in package/utils/busybox/Config-defaults.in.

One of the inline findings is a hard blocker for a feature the PR advertises: the nslookup resolver now works, but the client double-unwraps the reply (expect: { names: {} } and res.names), so hostnames are still never displayed. Worth confirming on a device before merge.

Commit checks

  • 05a223d2 "luci-app-fwlive: sync #8992 with fwlive master" — the message does not match the diff. It claims "Refresh the .pot via i18n-scan.pl", but the commit touches no po/ file (only fwlive-is-firewall-event.sh, fwlive-logging.sh, rpcd/fwlive). It also credits itself with "rules map delivery, poll clamp, nslookup resolver, jsonfilter declare, classifier codegen, json_escape in logging.sh" — all of which landed in the preceding commit 79019f0; jsonfilter declare is a Makefile change this commit does not contain. What it actually does is add the _fwlive_tmp_dir_ok sticky-bit gate on /tmp, strip the trailing dot in the Address N: branch of parse_nslookup_name, add the __tmp_dir_ok CLI hook, and reorder the selftest so run_logging_selftest runs before the jshn-gated early return. Please rewrite the body to describe that.

Generated by Claude Code

Comment thread applications/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js Outdated
Comment thread applications/luci-app-fwlive/root/usr/libexec/fwlive-logging.sh Outdated
async loadRulesMap() {
try {
const res = await callFwliveRules();
this.rulesMap = (res && res.rules) || {};

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: build_rules_map now emits an error field (mktemp_failed from _fwlive_mktemp, or rules_truncated once RULES_MAP_MAX_KEYS/RULES_MAP_MAX_BYTES trip — see rpcd/fwlive:324-330), but nothing here reads it: a truncated or empty map renders identically to a router with no labelled rules.

That is the inverse of what this same commit did for poll, where expect was dropped specifically so reply.error could reach the banner (#233). Truncation is reachable in practice — map_uci_rule_names adds up to two keys per UCI rule before any nft prefix is seen, so ~256 firewall rules exhaust the 512-key budget and every nft log prefix label is dropped silently. Worth surfacing the same way the poll error is, or at least logging it to the console.


Generated by Claude Code

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed, thanks — solved by surfacing lastRulesError in the #fwlive-backend span (plus a console.warn) rather than in the poll banner.


Generated by Claude Code

Comment thread applications/luci-app-fwlive/Makefile Outdated
@lucas-albers-lz4

Copy link
Copy Markdown
Author

Round-5 follow-up is in snapshot commit d7d4586.

classList.toggle: dropped the inaccurate 21.02-era compatibility notes. updateBackendUi and updateMessageLayoutUi now use the two-argument classList.toggle(name, force) API that LuCI core already relies on (e.g. switch-vlan). Behaviour unchanged; .pot unchanged (150 msgids).

Development home: lucas-albers-lz4/fwlive PR #258.

openwrt-ai

This comment was marked as resolved.

lucas-albers-lz4 added a commit to lucas-albers-lz4/fwlive that referenced this pull request Sep 3, 2026
openwrt-ai round-6 nit on openwrt/luci#8992: updateMessageLayoutUi computed
`this.messageLayout === 'oneline'` twice under two names (onelineLayout
inside the scroll block, oneline four lines below). Hoist one const above
the `if (scroll)` block and use it in both places.

Refs openwrt/luci#8992
openwrt-ai

This comment was marked as resolved.

lucas-albers-lz4 added a commit to lucas-albers-lz4/fwlive that referenced this pull request Sep 4, 2026
lucas-albers-lz4 added a commit to lucas-albers-lz4/fwlive that referenced this pull request Sep 4, 2026
Bugbot on #262: step order pushed luci before verifying openwrt/luci#8992
still open; audit regex missed github.com .../pull/N closing forms.
lucas-albers-lz4 added a commit to lucas-albers-lz4/fwlive that referenced this pull request Sep 4, 2026
Bugbot on #262: step order pushed luci before verifying openwrt/luci#8992
still open; audit regex missed github.com .../pull/N closing forms.
@feckert

feckert commented Sep 7, 2026

Copy link
Copy Markdown
Member

Could you please add a few screenshots so we can see what it looks like?

@lucas-albers-lz4

Copy link
Copy Markdown
Author

Screenshots as part of the documentation :
https://github.com/lucas-albers-lz4/fwlive/blob/master/docs/user/using-the-ui.md
https://github.com/lucas-albers-lz4/fwlive/blob/master/docs/user/README.md

@lucas-albers-lz4

Copy link
Copy Markdown
Author

any remaining concerns @hauke , @feckert ?

@BKPepe

BKPepe commented Sep 14, 2026

Copy link
Copy Markdown
Member

Why in this PR there is 10 commits? Can you squash them, please?

Comment thread applications/luci-app-fwlive/README.md Outdated
Comment thread applications/luci-app-fwlive/htdocs/luci-static/resources/fwlive/buffer.js Outdated
@lucas-albers-lz4

Copy link
Copy Markdown
Author

Squashed to a single commit

@openwrt-ai openwrt-ai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 1 new commit; two inline.


Generated by Claude Code

Comment thread applications/luci-app-fwlive/root/usr/libexec/fwlive-is-firewall-event.sh Outdated
Comment thread applications/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js Outdated
lucas-albers-lz4 added a commit to lucas-albers-lz4/fwlive that referenced this pull request Sep 15, 2026
Comment #N auto-links to the luci tracker. Keep ids in tests, CHANGELOG,
and commit messages. The cut also strips leftover ids from generated
classifier headers.

Refs openwrt/luci#8992
lucas-albers-lz4 added a commit to lucas-albers-lz4/fwlive that referenced this pull request Sep 15, 2026
* fix: luci-cut README and drop #43 from shipped comments

LuCI review asked not to name an out-of-tree winner in the in-tree README,
and comment #43 auto-links to the wrong tracker. Keep tracker ids in tests
and CHANGELOG.

Refs openwrt/luci#8992

* docs: record wave 6 as fwlive#337

* fix: strip tracker ids from shipped luci comments

Comment #N auto-links to the luci tracker. Keep ids in tests, CHANGELOG,
and commit messages. The cut also strips leftover ids from generated
classifier headers.

Refs openwrt/luci#8992

* test: scan // comments in upstream-cut tracker gate

Align the cut comment gate with upstream-cut.sh, which already
sanitizes JavaScript // lines for leftover tracker ids.

@openwrt-ai openwrt-ai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commit checks

  • 5dce0f66 "luci-app-fwlive: add firewall live view" — "First commit ships po/templates only" is left over from the pre-squash series; there is only one commit now. Reword to "This commit ships po/templates only".

Generated by Claude Code

Comment thread applications/luci-app-fwlive/root/usr/libexec/rpcd/fwlive Outdated
Add a Status menu view that polls firewall-only log lines via a dedicated
rpcd plugin (rules, poll, resolve, logging_status, enable/disable WAN
logging). Sessions never receive ubus log.read; the plugin filters as root
under a narrow ACL.

WAN zone log=1 is opt-in from the UI and restored on package removal
(prerm). This commit ships po/templates only; Weblate can add locales
after merge. License: Apache-2.0 (PKG_LICENSE). This tree is a snapshot
for the luci feed.

Signed-off-by: Lucas Albers <lucas.b.albers@gmail.com>
@lucas-albers-lz4

Copy link
Copy Markdown
Author

Snapshot head is now b69e117 (still one FormalityCheck commit).

Generated headers are labels only (no out-of-tree repo, no do-not-edit). Sticky-dir lock comment rewrapped. Commit and Design notes say this commit ships po/templates only.

@openwrt-ai openwrt-ai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 1 new commit; one nit inline.


Generated by Claude Code

Comment on lines +566 to +571
# Wall-clock budget clock starts at the TRUE function entry: the
# budget must bound the whole call — including
# read_rpc_input (stalled stdin must not escape the budget) and json
# parsing. `date +%s` can jump under NTP sync — accepted (worst case
# the budget over- or under-runs by the jump; worker starvation is
# still prevented).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: dropping the parenthetical left the block unwrapped, so it now has short ragged lines instead of the ~75-column fill the rest of the file uses. Same leftovers at lines 485, 672 and 700 in this file and at fwlive-logging.sh lines 122 and 593.

Suggested change
# Wall-clock budget clock starts at the TRUE function entry: the
# budget must bound the whole call — including
# read_rpc_input (stalled stdin must not escape the budget) and json
# parsing. `date +%s` can jump under NTP sync — accepted (worst case
# the budget over- or under-runs by the jump; worker starvation is
# still prevented).
# Wall-clock budget clock starts at the TRUE function entry: the budget
# must bound the whole call — including read_rpc_input (stalled stdin
# must not escape the budget) and json parsing. `date +%s` can jump
# under NTP sync — accepted (worst case the budget over- or under-runs
# by the jump; worker starvation is still prevented).

Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

add package Introduces a new package Makefile build script

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants