Skip to content

VLN-053 — CEDAR log indexer serves the entire security-alert corpus with no authentication

Classification: CONFIDENTIAL — Internal Use Only

Status: OPEN. Raised 2026-09-08. Not remediated, not mitigated.

http://172.16.0.13:9200 answers _cat, _count and _search with no credentials, over plain HTTP, leaving no record. Elasticsearch security is not misconfigured. It is switched off: "security": {"available": true, "enabled": false} — on an active basic licence, where authentication and TLS are free.

Corrected 2026-09-08 (v1.1). v1.0 of this page put the reachable set at "anything that can reach the subnet", including 113 WDC workstations. That was wrong — it read the GCP firewall and stopped, and CEDAR's host firewall is narrower. The real set is MAPLE plus the Cloud Run VPC connector (§4.1–§4.2). The finding stands; its blast radius was overstated and is corrected in §4.

This was drafted as VLN-TBD-CEDAR; the block it was avoiding no longer exists

This page was going to carry a placeholder id, on the standing belief that new VLN- ids were blocked behind a register reconciliation — VLN-009 used twice, and VLN-011 holding a page and a nav entry with no tracker row.

Checked against the live register 2026-09-08: neither is true any more. The tracker holds 52 rows with 52 distinct ids, no duplicates and no gaps, 1–52. VLN-011 has a tracker row at tracker.md:58. The duplicate was resolved on 2026-08-13 — see the register id mapping and the session log for that date; the chronyd row was renumbered to VLN-012, which is what a "remediated NTP row" recollection refers to.

So this finding takes the next free id, VLN-053, rather than a placeholder. Recorded because a placeholder here would have reproduced the exact defect the reconciliation existed to fix.


1. Summary

Finding ID VLN-053 (see the note above — drafted as a placeholder, assigned on checking the register)
Severity High — argued in §5, not computed. Rating unchanged by the v1.1 correction; see §5 for why
Affected CEDAR (172.16.0.13), Elasticsearch 8.19.13, cluster gpus-logging
Discovered 2026-09-08, incidentally, while measuring VLN-010 D6
Revised 2026-09-08 (v1.1) — reachability corrected; v1.0 overstated the blast radius (§4)
Revised 2026-09-08 (v1.2) — §4.1 replaced with the verbatim firewall artifact; §4.7 rebuilt with listener data
Revised 2026-09-08 (v1.3) — §7 Step 2 corrected: soc-backend is a second anonymous consumer; naming only the writer would have broken the SOC portal
Revised 2026-09-08 (v1.4) — --list-all-zones read on both hosts; §4.1 upgraded from "the active zone's rules" to all rules
Revised 2026-09-08 (v1.5) — §7 Step 1 corrected: it is not a no-op; the same rule carries 5140 (78% of cloud-logs) and MAPLE's carries 1514/1515
Revised 2026-09-08 (v1.6) — §4.7 corrected: 5141/udp is load-bearing, not stale; it carries MAPLE's Wazuh feed
Class Missing authentication on a security-telemetry datastore
Exploit requires Network reach only. No credential, no exploit, no vulnerability. curl
Remediated? No. Remediation is proposed in §7 and deliberately not implemented

How it was found, stated exactly. VLN-010 D6(b) and D6(c) were measured against this cluster without root and without credentials, because none were needed.

Those reads came from MAPLE (172.16.0.12) — confirmed from the command history, not from recollection: every query was issued as ssh maple "curl http://172.16.0.13:9200/...", and the scripts still sit on MAPLE at /tmp/d6*.sh. MAPLE is one of the two origins the host firewall permits, so this was the legitimate path and demonstrates no exposure by itself. A separate ssh cedar session was used only to read listening sockets and to check Kibana on 127.0.0.1 — a loopback call bypasses the firewall entirely and is not evidence of remote reachability.

What the measurement does show is narrower and still worth stating: an unprivileged cloudadmin shell on MAPLE, holding no Elasticsearch credential of any kind, read the estate's entire alert corpus. Authentication is what is missing, not network policy.


2. What was measured, and what was deliberately not

Every probe below is a read. GET only — _cat, _count, _search, _cluster/health, _xpack, _license. No write, update, delete or index operation was attempted at any point, including to confirm §4.4. That restraint is itself a limitation of this finding and is stated as one rather than papered over.

Reproduction, from MAPLE, as unprivileged cloudadmin:

curl -s http://172.16.0.13:9200/
curl -s "http://172.16.0.13:9200/_cat/indices?h=index,docs.count&s=index"
curl -s "http://172.16.0.13:9200/wazuh-alerts-2026.09.07/_search?size=1"
curl -s "http://172.16.0.13:9200/_xpack?categories=features"

None of these carry a credential. All of them succeed.


3. What is exposed

Not counts. Contents.

GET /wazuh-alerts-2026.09.07/_search?size=1 returns full _source documents — @timestamp, host.name, rule.description, rule.id, rule.level, agent identifiers and the decoded event body. A reader can retrieve, filter and aggregate every security alert the estate has generated.

Index family Scale Contents
wazuh-alerts-* 155 daily indices, earliest 2026-04-07 Every Wazuh alert: auditd, SELinux, file-integrity, authentication, the LOLBin baselines
cloud-logs-* present Cloud-side logging
.internal.alerts-* 15 indices, 0 docs Kibana alerting framework, currently empty
Total 339 indices Cluster health yellow, 360 active / 324 unassigned shards, single node

Why a security-alert corpus is worse than an ordinary log store. It is a map of what the estate detects and — by omission — what it does not. It names hosts, users and file paths, records which rules fire and at what level, and shows exactly when an agent stopped reporting. An attacker reading it learns the detection coverage before deciding what to do, and can confirm afterwards whether they were seen. Reconnaissance value here is higher than the raw sensitivity of any single document.


4. Reachability — corrected 2026-09-08

v1.0 of this page OVERSTATED the blast radius. This section is the correction.

v1.0 said the corpus was readable from "anything that can reach the subnet" and put 113 WDC workstations in the exposed population, reasoning from the GCP firewall rule cedar-ingress alone.

That was wrong. It read one layer and stopped. CEDAR runs a host firewall that is narrower than the GCP rule, and the host firewall is what actually decides. Workstations on 192.168.120.0/23 are permitted 5140/tcp and ICMP — not 9200. They cannot read the corpus.

The finding itself is unchanged and still stands (§4.6). Only its radius was wrong. A finding that overstates its blast radius gets dismissed, and this one is real — so the overstatement is corrected here rather than quietly edited away.

4.1 Who can actually reach 172.16.0.13:9200

Two sources. That is the whole list.

Captured 2026-09-08 as root on CEDAR and reproduced verbatim — this is the artifact, not a transcription of it. An earlier revision of this page paraphrased the two 9200 rules as port="9200"; the real syntax is port port="9200" protocol="tcp". Same meaning, but a paraphrase is not a record:

drop (active)
  target: DROP
  icmp-block-inversion: no
  interfaces: eth0
  sources:
  services:
  ports:
  protocols:
  forward: no
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:
    rule family="ipv4" source address="172.16.0.0/24" port port="5140" protocol="tcp" accept
    rule family="ipv4" source address="172.16.0.0/24" protocol value="icmp" accept
    rule family="ipv4" source address="192.168.120.0/23" port port="5140" protocol="tcp" accept
    rule family="ipv4" source address="10.8.0.0/28" port port="22" protocol="tcp" accept
    rule family="ipv4" source address="10.8.0.0/28" port port="5601" protocol="tcp" accept
    rule family="ipv4" source address="172.16.0.12" port port="9200" protocol="tcp" accept
    rule family="ipv4" source address="192.168.120.0/23" protocol value="icmp" accept
    rule family="ipv4" source address="172.16.0.12" port port="5141" protocol="udp" accept
    rule family="ipv4" source address="10.8.0.0/28" port port="10000" protocol="tcp" accept
    rule family="ipv4" source address="172.16.0.12" port port="5141" protocol="tcp" accept
    rule family="ipv4" source address="172.16.0.12" port port="9100" protocol="tcp" accept
    rule family="ipv4" source address="10.8.0.0/28" protocol value="icmp" accept
    rule family="ipv4" source address="172.16.0.12" port port="5140" protocol="tcp" accept
    rule family="ipv4" source address="172.16.0.0/24" port port="22" protocol="tcp" accept
    rule family="ipv4" source address="10.8.0.0/28" port port="9200" protocol="tcp" accept
    rule family="ipv4" source address="192.168.124.0/24" port port="22" protocol="tcp" accept

Read it for what is absent. The zone carries no services: and no ports: — every permission is a rich rule, and target: DROP catches everything else on eth0. There is no rule granting 192.168.120.0/23 anything but 5140/tcp and ICMP. The WDC LAN cannot reach 9200. That is now confirmed from the artifact rather than from a relay of it.

Every rule is family="ipv4". Three services bind IPv6 as well (§4.2), so IPv6 is covered only by the zone's DROP target and by no rich rule at all. That is safe today — and it means any future change to the zone target loses IPv6 protection with nothing underneath it.

These are ALL the rules — confirmed 2026-09-08 via --list-all-zones

firewall-cmd --list-all shows only the active zone, so this section originally claimed "the active zone's rules" rather than "all rules". firewall-cmd --list-all-zones was then read on both hosts and closes the gap: of the eleven zones defined (block, dmz, drop, external, home, internal, nm-shared, public, trusted, work), only drop has an interface bound — eth0 — and every other zone has both interfaces: and sources: empty. A firewalld zone with neither cannot match traffic, so none of them is reachable. The rules above are the complete effective set.

Two inert definitions are worth knowing about anyway, because they are one interface assignment away from mattering: trusted has target: ACCEPT with no rules at all, and six zones (dmz, external, home, internal, public, work) permit the ssh service unconditionally, with no source restriction. If eth0 were ever moved out of drop — or a second interface appeared and landed in the default zone — the posture would change wholesale rather than incrementally. Same shape as §4.3: a standing permission that is harmless only because something else currently holds.

Source What is behind it
172.16.0.12 MAPLE — the Wazuh manager, which must write here
10.8.0.0/28 The gpus-vpc-connector — see §4.2

4.2 What actually sits in 10.8.0.0/28 — enumerated, not assumed

The connector is not a host; it is the shared egress path for Cloud Run. 5 of the 10 Cloud Run services in gpus-infra are attached to it, and all five are the backends — the static frontends are not attached and cannot reach 9200:

Service Connector Egress Ingress
gpus-forms-backend gpus-vpc-connector private-ranges-only all
gpus-forms-clamav-worker gpus-vpc-connector private-ranges-only all
gpus-security-backend gpus-vpc-connector all-traffic all
gpus-soc-backend gpus-vpc-connector all-traffic all
gpus-status-backend gpus-vpc-connector all-traffic all
gpus-forms-frontend, gpus-mkdocs-portal, gpus-security-site, gpus-soc-site, gpus-status-site none all

private-ranges-only and all-traffic differ only in whether public traffic also takes the connector; both route RFC1918 destinations through it. So all five reach 172.16.0.13:9200 identically.

The chain worth naming, stated at its real strength. All five are ingress: all (cf. VLN-018), so they are internet-reachable services whose egress lands inside a firewall exception for an unauthenticated datastore. This is not a claim that the internet can reach 9200 — it cannot. It is a claim that the distance between the internet and the estate's complete alert corpus is one server-side request-forgery or code-execution defect in any one of five services, with no credential to steal and nothing logged afterwards. gpus-forms-backend is the sharpest of them: it carries an unauthenticated /metrics and a reflected-origin CORS defect already recorded as VLN-042.

4.3 The two firewall layers disagree, and that is the latent risk

The GCP rule cedar-ingress (priority 900, gpus-vpc) permits tcp:9200 from three ranges — 172.16.0.0/24, 10.8.0.0/28 and 192.168.120.0/23. The host firewall permits it from one address and one /28.

The host firewall is the narrower of the two, so it is the effective control — and it is the only thing standing between the WDC LAN and the corpus. 192.168.120.0/23 contains, per the IAR, 113 end-user workstations. They are not exposed today. They become exposed the moment firewalld is stopped, flushed, or has its zone default changed — because the cloud layer behind it is already open to them.

That is not a hypothetical worth dismissing: a host firewall is routinely stopped during troubleshooting. The two layers should agree, and today the outer one is a standing permission that nothing else revokes.

4.4 Are write and delete also unauthenticated?

Almost certainly yes — and this was NOT tested, by choice.

The reasoning is structural rather than empirical: xpack.security.enabled is false, so the cluster has no authentication and no authorisation subsystem at all. There is no mechanism present that could distinguish a GET from a DELETE, or one caller from another. Read access is not permitted by a policy that happens to be read-only; it is permitted because no policy layer exists.

This is stated as a reasoned inference and explicitly flagged as untested. The way to confirm it safely is a DELETE against a scratch index created for the purpose in a maintenance window — not against wazuh-alerts-*.

If it holds, the consequence is anti-forensic, not merely confidential. The same anonymous caller who can read alerts can delete the indices containing them. An intruder who reaches the WDC LAN can erase the record of their own intrusion, and §4.5 means nothing would show who did it.

4.5 Does anything log the access?

No.

  • Elasticsearch audit logging is a security feature and requires xpack.security.enabled. With security off, the audit subsystem cannot run. Consistent with that, GET /_cat/indices/*audit* returns nothing.
  • Elasticsearch does not log successful search requests by default.
  • firewalld on CEDAR logs drops, not accepts — a permitted connection to 9200 leaves no entry.

So an anonymous read of the entire corpus is invisible after the fact. There is no way to determine whether this has already been done, by whom, or how often. This finding cannot be scoped retrospectively, and no claim that "nothing has happened" is available.

4.6 What is actually holding the line

firewalld — and only firewalld.

Kibana makes the point precisely, and v1.0 got it half wrong. Kibana is running and bound to 0.0.0.0:5601 and answers HTTP 200 on 127.0.0.1:5601. A TCP connection from MAPLE to 5601 is refused, with a simultaneous connection to 9200 succeeding as a control — so v1.0 concluded "firewalld blocks it from the network".

That was too generous. MAPLE is not on the 5601 allow-list, but 10.8.0.0/28 is (§4.7). Kibana is not blocked from the network; it is blocked from MAPLE, and reachable from the connector — the same origin 9200 is reachable from. Two ports, one exposed origin, and a browsable UI over the same data.

The entire access control for the indexer is one firewalld port decision, with no authentication behind it. A change to that ruleset — or a foothold in any host inside the permitted ranges — is the whole of the defence.

The transport layer is correctly bound: 9300 listens on 127.0.0.1 only. The HTTP layer is not: 9200 listens on *. https://172.16.0.13:9200 fails with curl rc 35, confirming there is no TLS on the HTTP layer either — traffic is plaintext across the VPN and the VPC.


4.7 The complete port picture — derived from the §4.1 artifact

Every permission on CEDAR, read off the rich rules rather than summarised:

Port Permitted from Listener (ss -tlnp) Note
22/tcp 172.16.0.0/24, 10.8.0.0/28, 192.168.124.0/24 sshd, 0.0.0.0 + [::] Three SSH origins
5140/tcp 172.16.0.0/24, 192.168.120.0/23, 172.16.0.12 java (Logstash), 0.0.0.0 Syslog ingest — the WDC LAN's real permission
5141/tcp + 5141/udp 172.16.0.12 java (Logstash) on UDP 5141/udp is load-bearing — MAPLE's entire Wazuh feed. 5141/tcp has no listener
5601/tcp 10.8.0.0/28 node (Kibana), 0.0.0.0 UI over the same corpus
9100/tcp 172.16.0.12 node_exporter, * Prometheus scrape from MAPLE
9200/tcp 172.16.0.12, 10.8.0.0/28 java (Elasticsearch), * This finding
9300/tcp (no rule) java, [::ffff:127.0.0.1] Transport correctly loopback-only
9600/tcp (no rule) java (Logstash API), 127.0.0.1 Correctly loopback-only
10000/tcp 10.8.0.0/28 miniserv.pl (Webmin), 0.0.0.0 + [::] Root-capable — VLN-054
ICMP 172.16.0.0/24, 192.168.120.0/23, 10.8.0.0/28

Only two services bind loopback: 9300 and 9600. Every other listener binds 0.0.0.0 or * and depends entirely on firewalld to not be reachable. That is the §4.6 point stated as a measurement: the host firewall is not a layer, it is the only layer, for seven listening ports.

CORRECTED 2026-09-08 — 5141 was called stale. 5141/udp is load-bearing.

An earlier revision recorded 5141 as "permitted and nothing is listening on it… a control that survives the thing it was written for". That was wrong, and the error is instructive: it was drawn from ss -tlnp, which enumerates TCP only. The caveat was even written down at the time — "5141/udp is unconfirmed either way" — and the conclusion was stated anyway.

Logstash's second pipeline is input { udp { port => 5141 } }, and MAPLE's entire Wazuh alert feed arrives on it. Those events carry no type, so they skip the syslog filter block, and they are ~30% of cloud-logs-*. Removing that rule would have destroyed the cloud-side Wazuh record.

5141/**tcp** does appear to have no listener. That half of the original claim stands, and it is the half that matters least.

The lesson is the one this page keeps re-learning: a negative from an instrument that cannot see the thing being asked about is not a negative. ss -tlnp answers a TCP question; it was asked a UDP one.

Nothing in this ruleset was changed. The finding reports it.


5. Severity — argued

High.

Why not Critical: reachability is bounded, and more tightly than v1.0 thought. CEDAR has no external IP and no internet path, and the host firewall admits exactly two origins (§4.1). An attacker needs code execution on MAPLE or inside one of five Cloud Run services — adjacent network, not remote.

Why not Medium — and this is the test of whether the finding was real, since it has to survive the §4 correction. The exposure is not read-only in effect (§4.4); it covers the estate's complete detection record rather than a sample; it is invisible (§4.5), so it can be neither detected nor scoped after the fact; and the reachable set is not a set of trusted operators but five internet-facing (ingress: all) Cloud Run services, separated from the corpus only by the absence of an SSRF or RCE defect in their own code (§4.2). Confidentiality, integrity and availability are all unauthenticated on the same port. Separately, the outer cloud firewall is already open to 113 workstations and only the host firewall withholds them (§4.3).

What the correction changed, stated plainly: v1.0 argued this severity partly from a population of 113 workstations that turns out not to have access. The rating does not move, because none of the reasons above depended on that number — but the number is withdrawn, and a severity resting on it would have had to fall.

No CVSS is computed here, consistent with VLN-010's footnote: CVSS scores a weakness, and this is an absent control rather than a defect in one.

It is a basic-licence choice, not a licence limitation. The cluster runs an active basic licence, and native authentication plus TLS have been free on basic since 6.8. Elasticsearch 8 ships with security enabled by default and generates credentials on first start. Somebody turned it off.


6. What this does not claim

  • It does not claim data has been exfiltrated. §4.5 means that is unknowable in either direction. The absence of evidence here is the absence of a logging facility, not evidence of absence.
  • It does not claim writes succeed. §4.4 is reasoned, not measured.
  • It does not assess Kibana, though 5601 is reachable. v1.0 claimed Kibana was unreachable from the network; that was wrong — it is unreachable from MAPLE, and permitted from 10.8.0.0/28 (§4.6, §4.7). Whether it authenticates was not tested. A UI over the same corpus, on the same exposed origin, deserves its own assessment.
  • It does not assess Webmin on 10000/tcp (§4.7), also connector-reachable and root-capable. Not tested; needs its own id.
  • It does not claim the 113 workstations are exposed. They are not, today. §4.3 records only that the cloud layer already permits them and that the host firewall is the sole thing withholding it.
  • It does not cover WIND, the WDC ELK cluster. Whether the same posture exists there is untested and should be checked before this is closed.

7. Proposed remediation — NOT implemented

Ordering matters, and doing these in the wrong order breaks alert ingestion.

CEDAR is the indexer; MAPLE is the Wazuh manager and the writer. Turning on authentication changes the contract for whatever ships alerts from MAPLE. If auth is enabled without giving the writer credentials first, alert ingestion stops — and per VLN-010's own lesson, a silent stop looks exactly like success on a dashboard measuring alert volume.

Step 1 — make the cloud firewall agree with the host firewall.

This is NOT a no-op, and an earlier revision of this page said it was

v1.0–v1.4 described removing 192.168.120.0/23 from cedar-ingress as "a no-op today, worth doing precisely because it is". That was wrong, and acting on it would have broken production logging.

cedar-ingress is a single allow-list covering six ports22, 5140, 5601, 9200, 10000, 9100 — applied to all three of its source ranges. A GCP firewall rule cannot say "this range gets only port X". So removing 192.168.120.0/23 removes it from 5140 as well, and 5140 is Logstash's syslog input, which the WDC estate actively uses.

Measured 2026-09-08 — source addresses in cloud-logs-2026.09.08:

Source Docs today Host
192.168.120.3 4,804 SUN
172.16.0.12 2,694 MAPLE
192.168.120.1 2,644 SKY
192.168.120.2 1,744 RAIN

9,192 documents today from the WDC range — about 78% of the index. Stripping that range would have stopped on-prem syslog ingestion, and per VLN-010 a silent stop looks exactly like success.

The correct change is a split, not a removal. Create the narrow rule first, verify, then narrow the broad one — reversing that order opens a window with no syslog path:

  1. Create cedar-ingress-wdc-syslog — source 192.168.120.0/23, tcp:5140, target tag cedar-logging, priority 900.
  2. Verify WDC syslog still arrives (see acceptance below).
  3. Then modify cedar-ingress to source ranges 10.8.0.0/28 and 172.16.0.0/24 only.

That leaves the WDC LAN with exactly the access CEDAR's host firewall already grants it — 5140 — and removes the standing cloud-layer permission on 9200, 5601, 10000 and 9100 that §4.3 identifies as the latent trap. SSH is unaffected: it comes from allow-onprem-via-vpn (priority 1000, tcp:22 from both 192.168.120.0/23 and 192.168.124.0/24), not from this rule.

MAPLE carries the identical trap and it is worse. maple-ingress spans 22, 9090, 3000, 10000, 1514, 1515, 9100 across the same three ranges, and 1514/1515 are the Wazuh agent channel. All four WDC hosts are live agents — wind 1,018, sky 370, rain 362, sun 341 alerts on 2026-09-08, ~77% of that day's total. Stripping the range there would blind the SIEM for the entire on-prem estate. Same split applies: a maple-ingress-wdc-agents rule for tcp:1514,1515 first, then narrow maple-ingress.

Acceptance — measured, not assumed. After each host's change: WDC source addresses still appear in cloud-logs-* (CEDAR), and *.wdc.us.gl3 agents still appear in wazuh-alerts-* (MAPLE), at their established daily rates. Absence of either is the failure mode.

Ownership: this is ours to change. cedar-ingress and maple-ingress are on projects/gpus-infra/global/networks/gpus-vpc, and gcloud compute shared-vpc get-host-project gpus-infra returns empty — the project is not a shared-VPC service project. These rules are not in gl5-core and do not need GPI or a third-party owner to change.

Step 1b — decide about 5601 and 10000 from 10.8.0.0/28 (§4.7). Not part of this finding's remediation; 10000 is covered by VLN-054 and the pattern by GOV-038.

Step 2 — enable xpack.security in its own window. Native realm plus TLS on the HTTP layer, credentials issued before the cluster is flipped.

There are TWO consumers, not one. An earlier revision of this page named only the writer.

v1.0–v1.2 said "credentials issued to the MAPLE writer". That is incomplete, and acting on it would break the SOC portal.

soc-backend reads this cluster anonymously. servers.py defines CEDAR_ES_URL = "http://172.16.0.13:9200" and soc-backend/app.py calls it at :78 and :408 — over plain HTTP, with no credential, because none exists to supply. It is a Cloud Run service reaching CEDAR through the 10.8.0.0/28 rule in §4.1.

So enabling authentication breaks both the ingestion path from MAPLE and the read path from soc-backend. Both need credentials staged first. A third consumer, PROMETHEUS_CLOUD at soc-backend/app.py:298, points at MAPLE :9090 and is unaffected by this change — listed so it is not mistaken for one.

Acceptance must be measured the way VLN-010 D6 was: alert volume continues at its established daily rate after the change, verified in the index, and the SOC portal's Wazuh panels still render — verified in the portal, not inferred from the service being up. A drop to zero on either side is the failure mode, and per VLN-010 a silent stop looks exactly like success.

Step 3 — enable audit logging, which only becomes possible once step 2 is done. Until then §4.5 stands and no access is attributable.

Do not do steps 1 and 2 in the same window. If ingestion breaks, you need to know which change did it.


8. Open items

  • ~~The complete firewall-cmd --list-all output, verbatim~~ — done 2026-09-08. §4.1 now carries the artifact. The transcription it replaced rendered the two 9200 rules as port="9200" where the real syntax is port port="9200" protocol="tcp" — the meaning was right and the record was not.
  • ~~10000/tcp (Webmin)~~ — raised as VLN-054, covering CEDAR and MAPLE.
  • ~~firewall-cmd --list-all-zones has not been read~~ — done 2026-09-08 on both hosts. Only drop binds an interface; all ten other zones have empty interfaces: and sources: and cannot match traffic. §4.1 now claims all rules, not "the active zone's rules".
  • Whether an unauthenticated GET to Webmin rewrites miniserv.conf. Its mtime moved to 15:10:54 UTC within a minute of the author's probe. Deliberately not re-tested — re-testing would be a write to CEDAR. Resolve from /var/webmin/miniserv.log, not by repeating it.
  • Confirm §4.4 safely, against a scratch index, in a maintenance window.
  • Check WIND for the same posture.
  • ~~Assign a real VLN- id~~ — done: VLN-053. The register was already reconciled on 2026-08-13.