<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Vox Pulveris</title><link>https://vox.app.home/</link><description>Recent content on Vox Pulveris</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><atom:link href="https://vox.app.home/index.xml" rel="self" type="application/rss+xml"/><item><title>Month 2 - Vocabulary List</title><link>https://vox.app.home/posts/lingua-latina/month-2/</link><pubDate>Mon, 31 Aug 2026 13:10:42 +0000</pubDate><guid>https://vox.app.home/posts/lingua-latina/month-2/</guid><description>&lt;h2 id="nouns"&gt;Nouns&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;ager&lt;/strong&gt;, &lt;em&gt;-ī&lt;/em&gt; (&lt;em&gt;m.&lt;/em&gt;) - field&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;fīlius&lt;/strong&gt;, &lt;em&gt;-ī&lt;/em&gt; (&lt;em&gt;m.&lt;/em&gt;) - son&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;fīlia&lt;/strong&gt;, &lt;em&gt;-ae&lt;/em&gt; (&lt;em&gt;f.&lt;/em&gt;) - daugther&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;liber&lt;/strong&gt;, &lt;em&gt;-rī&lt;/em&gt; (&lt;em&gt;m.&lt;/em&gt;) - book&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;magister&lt;/strong&gt;, &lt;em&gt;-rī&lt;/em&gt; (&lt;em&gt;m.&lt;/em&gt;) - teacher&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;puer&lt;/strong&gt;, &lt;em&gt;-ī&lt;/em&gt; (&lt;em&gt;m.&lt;/em&gt;) - boy&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;vir&lt;/strong&gt;, &lt;em&gt;-ī&lt;/em&gt; (&lt;em&gt;m.&lt;/em&gt;) - man&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;fluvius&lt;/strong&gt;, &lt;em&gt;-ī&lt;/em&gt; (&lt;em&gt;m.&lt;/em&gt;) - river&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;īnsula&lt;/strong&gt;, &lt;em&gt;-ae&lt;/em&gt; (&lt;em&gt;f.&lt;/em&gt;) - island&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;odium&lt;/strong&gt;, &lt;em&gt;-ī&lt;/em&gt; (&lt;em&gt;n.&lt;/em&gt;) - hatred&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;vīta&lt;/strong&gt;, &lt;em&gt;-ae&lt;/em&gt; (&lt;em&gt;f.&lt;/em&gt;) - life&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;sacrāmentum&lt;/strong&gt;, &lt;em&gt;-ī&lt;/em&gt; (&lt;em&gt;n.&lt;/em&gt;) - oath&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;caelum&lt;/strong&gt;, &lt;em&gt;-ī&lt;/em&gt; (&lt;em&gt;n.&lt;/em&gt;) - sky&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;terra&lt;/strong&gt;, &lt;em&gt;-ae&lt;/em&gt; (&lt;em&gt;f.&lt;/em&gt;) - earth&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;templum&lt;/strong&gt; &lt;em&gt;-ī&lt;/em&gt; (&lt;em&gt;n.&lt;/em&gt;) - temple&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;domina&lt;/strong&gt;, &lt;em&gt;-ae&lt;/em&gt; (&lt;em&gt;f.&lt;/em&gt;) - lady of the house, mistress&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;mēnsa&lt;/strong&gt;, &lt;em&gt;-ae&lt;/em&gt; (&lt;em&gt;f.&lt;/em&gt;) - table&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;cāseus&lt;/strong&gt;, &lt;em&gt;-ī&lt;/em&gt; (&lt;em&gt;m.&lt;/em&gt;) - cheese&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;pōnum&lt;/strong&gt;, &lt;em&gt;-ī&lt;/em&gt; (&lt;em&gt;n.&lt;/em&gt;) - fruit&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;hōra&lt;/strong&gt;, &lt;em&gt;-ae&lt;/em&gt; (&lt;em&gt;f.&lt;/em&gt;) - hour&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;matella&lt;/strong&gt;, &lt;em&gt;-ae&lt;/em&gt; (&lt;em&gt;f.&lt;/em&gt;) - chamberpot, toliet&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;lucerna&lt;/strong&gt;, &lt;em&gt;-ae&lt;/em&gt; (&lt;em&gt;f.&lt;/em&gt;) - lantern&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;māne&lt;/strong&gt;, &lt;em&gt;indeclinable&lt;/em&gt; (&lt;em&gt;n.&lt;/em&gt;) - morning&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="adjectives"&gt;Adjectives&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;asper&lt;/strong&gt;, &lt;em&gt;-a, -um&lt;/em&gt; - rough&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Graecus&lt;/strong&gt;, &lt;em&gt;-a, -um&lt;/em&gt; - Greek&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;līber&lt;/strong&gt;, &lt;em&gt;-a, -um&lt;/em&gt; - free&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;miser&lt;/strong&gt;, &lt;em&gt;-a, -um&lt;/em&gt; - miserable&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;niger&lt;/strong&gt;, &lt;em&gt;-ra, -rum&lt;/em&gt; - black&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;noster&lt;/strong&gt;, &lt;em&gt;-ra, -rum&lt;/em&gt; - our&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;pulcher&lt;/strong&gt;, &lt;em&gt;-ra, -rum&lt;/em&gt; - beautiful&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rōmānus&lt;/strong&gt;, &lt;em&gt;-a, -um&lt;/em&gt; - Roman&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;tener&lt;/strong&gt;, &lt;em&gt;-a, -um&lt;/em&gt; - tender&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;vester&lt;/strong&gt;, &lt;em&gt;-ra, -rum&lt;/em&gt; - your (pl.)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;parvus&lt;/strong&gt;, &lt;em&gt;-a, -um&lt;/em&gt; - small&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;multus&lt;/strong&gt;, &lt;em&gt;-a, -um&lt;/em&gt; - many&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;paucus&lt;/strong&gt;, &lt;em&gt;-a, -um&lt;/em&gt; - few&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;malus&lt;/strong&gt;, &lt;em&gt;-a, -um&lt;/em&gt; - bad&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;periūrus&lt;/strong&gt;, &lt;em&gt;-a, -um&lt;/em&gt; - sweare falsely, perjured&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;optimus&lt;/strong&gt;, &lt;em&gt;-a, -um&lt;/em&gt; - best&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;maximus&lt;/strong&gt;, &lt;em&gt;-a, -um&lt;/em&gt; - greatest&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;propitius&lt;/strong&gt;, &lt;em&gt;-a, -um&lt;/em&gt; - favourable&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="prepositions"&gt;Prepositions&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;ā, ab&lt;/strong&gt; &lt;em&gt;(Abl.)&lt;/em&gt; - from, away from, in respect of&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ad&lt;/strong&gt; &lt;em&gt;(Acc.)&lt;/em&gt; - to, for the purpose of&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;cum&lt;/strong&gt; &lt;em&gt;(Abl.)&lt;/em&gt; - with, (accompaniment)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;dē&lt;/strong&gt; &lt;em&gt;(Abl.)&lt;/em&gt; - from, about, for (reason)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ē, ex&lt;/strong&gt; &lt;em&gt;(Abl.)&lt;/em&gt; - out of&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;sine&lt;/strong&gt; &lt;em&gt;(Abl.)&lt;/em&gt; - without&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;in&lt;/strong&gt; &lt;em&gt;(Acc.)&lt;/em&gt; - into (in sense of moving into a state)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;in&lt;/strong&gt; &lt;em&gt;(Abl.)&lt;/em&gt; - in, on, (in sense of being in a state)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;per&lt;/strong&gt; &lt;em&gt;(Acc.)&lt;/em&gt; - through (space/time), by mean of (mean), for sake of (cause)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;trāns&lt;/strong&gt; &lt;em&gt;(Acc.)&lt;/em&gt; - across, over&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="conjunctions"&gt;Conjunctions&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;sī&lt;/strong&gt; - if&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;sive&lt;/strong&gt; - whether (&lt;em&gt;sive &amp;hellip; sive &amp;hellip;&lt;/em&gt; - enumerating alternatives)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;aut&lt;/strong&gt; - or&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ut&lt;/strong&gt; - so that&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;tunc&lt;/strong&gt; - then&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;quoniam&lt;/strong&gt; - since&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;sic&lt;/strong&gt; - therefore&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;enim&lt;/strong&gt; - for (explanetory), (in the 2nd/3rd word of the clause)&lt;/li&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="adverbs"&gt;Adverbs&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;quoque&lt;/strong&gt; - also, too&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;saepe&lt;/strong&gt; - often&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;māne&lt;/strong&gt;, - in the morning&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="numerals"&gt;Numerals&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;quattuor&lt;/strong&gt; (&lt;em&gt;indeclinable&lt;/em&gt;) - four&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;quīnque&lt;/strong&gt; (&lt;em&gt;indeclinable&lt;/em&gt;) - five&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;sex&lt;/strong&gt; (&lt;em&gt;indeclinable&lt;/em&gt;) - six&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;septem&lt;/strong&gt; (&lt;em&gt;indeclinable&lt;/em&gt;) - seven&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="verbs"&gt;Verbs&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: center"&gt;I&lt;/th&gt;
&lt;th style="text-align: center"&gt;II&lt;/th&gt;
&lt;th style="text-align: center"&gt;III&lt;/th&gt;
&lt;th style="text-align: center"&gt;IV&lt;/th&gt;
&lt;th style="text-align: left"&gt;Tran.&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;cōgitō&lt;/td&gt;
&lt;td style="text-align: center"&gt;cōgitāre&lt;/td&gt;
&lt;td style="text-align: center"&gt;cōgitāvī&lt;/td&gt;
&lt;td style="text-align: center"&gt;cogitātum&lt;/td&gt;
&lt;td style="text-align: left"&gt;think, ponder, consider&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;dēbeō&lt;/td&gt;
&lt;td style="text-align: center"&gt;dēbēre&lt;/td&gt;
&lt;td style="text-align: center"&gt;dēbuī&lt;/td&gt;
&lt;td style="text-align: center"&gt;dēbitum&lt;/td&gt;
&lt;td style="text-align: left"&gt;to owe, ought, must, should&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;errō&lt;/td&gt;
&lt;td style="text-align: center"&gt;errāre&lt;/td&gt;
&lt;td style="text-align: center"&gt;errāvī&lt;/td&gt;
&lt;td style="text-align: center"&gt;errātum&lt;/td&gt;
&lt;td style="text-align: left"&gt;to wander, err, go astray&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;servō&lt;/td&gt;
&lt;td style="text-align: center"&gt;servāre&lt;/td&gt;
&lt;td style="text-align: center"&gt;servāvī&lt;/td&gt;
&lt;td style="text-align: center"&gt;servātum&lt;/td&gt;
&lt;td style="text-align: left"&gt;to preserve, save, keep, guard&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;cōnservō&lt;/td&gt;
&lt;td style="text-align: center"&gt;cōnsērvāre&lt;/td&gt;
&lt;td style="text-align: center"&gt;cōnservāvī&lt;/td&gt;
&lt;td style="text-align: center"&gt;cōnservātum&lt;/td&gt;
&lt;td style="text-align: left"&gt;to preserve, conserve, maintain&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;terrō&lt;/td&gt;
&lt;td style="text-align: center"&gt;terrēre&lt;/td&gt;
&lt;td style="text-align: center"&gt;terruī&lt;/td&gt;
&lt;td style="text-align: center"&gt;territum&lt;/td&gt;
&lt;td style="text-align: left"&gt;to frighten, terrify&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;valeō&lt;/td&gt;
&lt;td style="text-align: center"&gt;valēre&lt;/td&gt;
&lt;td style="text-align: center"&gt;valuī&lt;/td&gt;
&lt;td style="text-align: center"&gt;valitus&lt;/td&gt;
&lt;td style="text-align: left"&gt;be strong, have power, be well&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;vocō&lt;/td&gt;
&lt;td style="text-align: center"&gt;vocāre&lt;/td&gt;
&lt;td style="text-align: center"&gt;vocāvī&lt;/td&gt;
&lt;td style="text-align: center"&gt;vocātum&lt;/td&gt;
&lt;td style="text-align: left"&gt;to call, to summon&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;peccō&lt;/td&gt;
&lt;td style="text-align: center"&gt;peccāre&lt;/td&gt;
&lt;td style="text-align: center"&gt;peccāvī&lt;/td&gt;
&lt;td style="text-align: center"&gt;peccātum&lt;/td&gt;
&lt;td style="text-align: left"&gt;to sin, to make mistake (deliberately)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;culpō&lt;/td&gt;
&lt;td style="text-align: center"&gt;culpāre&lt;/td&gt;
&lt;td style="text-align: center"&gt;culpāvī&lt;/td&gt;
&lt;td style="text-align: center"&gt;culpātum&lt;/td&gt;
&lt;td style="text-align: left"&gt;to blame&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;agō&lt;/td&gt;
&lt;td style="text-align: center"&gt;agere&lt;/td&gt;
&lt;td style="text-align: center"&gt;egī&lt;/td&gt;
&lt;td style="text-align: center"&gt;āctum&lt;/td&gt;
&lt;td style="text-align: left"&gt;to drive, to lead&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;faciō&lt;/td&gt;
&lt;td style="text-align: center"&gt;facere&lt;/td&gt;
&lt;td style="text-align: center"&gt;fēcī&lt;/td&gt;
&lt;td style="text-align: center"&gt;factum&lt;/td&gt;
&lt;td style="text-align: left"&gt;do&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;neglegō&lt;/td&gt;
&lt;td style="text-align: center"&gt;neglegere&lt;/td&gt;
&lt;td style="text-align: center"&gt;neglēxī&lt;/td&gt;
&lt;td style="text-align: center"&gt;neglēctum&lt;/td&gt;
&lt;td style="text-align: left"&gt;to neglect, ignore&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;dīligō&lt;/td&gt;
&lt;td style="text-align: center"&gt;dīligere&lt;/td&gt;
&lt;td style="text-align: center"&gt;dīlēxi&lt;/td&gt;
&lt;td style="text-align: center"&gt;dīlēctum&lt;/td&gt;
&lt;td style="text-align: left"&gt;like&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;sciō&lt;/td&gt;
&lt;td style="text-align: center"&gt;scīre&lt;/td&gt;
&lt;td style="text-align: center"&gt;scīvī&lt;/td&gt;
&lt;td style="text-align: center"&gt;scītum&lt;/td&gt;
&lt;td style="text-align: left"&gt;to know&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;iūrō&lt;/td&gt;
&lt;td style="text-align: center"&gt;iūrāre&lt;/td&gt;
&lt;td style="text-align: center"&gt;iūrāvī&lt;/td&gt;
&lt;td style="text-align: center"&gt;iūrātum&lt;/td&gt;
&lt;td style="text-align: left"&gt;to swear&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;periūrō&lt;/td&gt;
&lt;td style="text-align: center"&gt;periūrāre&lt;/td&gt;
&lt;td style="text-align: center"&gt;periūrāvī&lt;/td&gt;
&lt;td style="text-align: center"&gt;periūrātum&lt;/td&gt;
&lt;td style="text-align: left"&gt;to swear falsely&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;inveniō&lt;/td&gt;
&lt;td style="text-align: center"&gt;invenīre&lt;/td&gt;
&lt;td style="text-align: center"&gt;invenī&lt;/td&gt;
&lt;td style="text-align: center"&gt;inventum&lt;/td&gt;
&lt;td style="text-align: left"&gt;to find, discover, invent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;crēdō&lt;/td&gt;
&lt;td style="text-align: center"&gt;crēdere&lt;/td&gt;
&lt;td style="text-align: center"&gt;crēdidī&lt;/td&gt;
&lt;td style="text-align: center"&gt;crēditum&lt;/td&gt;
&lt;td style="text-align: left"&gt;to believe&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;salūtō&lt;/td&gt;
&lt;td style="text-align: center"&gt;salūtāre&lt;/td&gt;
&lt;td style="text-align: center"&gt;salūtāvī&lt;/td&gt;
&lt;td style="text-align: center"&gt;salūtātum&lt;/td&gt;
&lt;td style="text-align: left"&gt;to greet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;accipiō&lt;/td&gt;
&lt;td style="text-align: center"&gt;accipere&lt;/td&gt;
&lt;td style="text-align: center"&gt;accēpī&lt;/td&gt;
&lt;td style="text-align: center"&gt;accēptum&lt;/td&gt;
&lt;td style="text-align: left"&gt;to receive&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;faenerō&lt;/td&gt;
&lt;td style="text-align: center"&gt;faenerāre&lt;/td&gt;
&lt;td style="text-align: center"&gt;faenrāvī&lt;/td&gt;
&lt;td style="text-align: center"&gt;faenerātum&lt;/td&gt;
&lt;td style="text-align: left"&gt;to lend&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;cognōscō&lt;/td&gt;
&lt;td style="text-align: center"&gt;cognōscere&lt;/td&gt;
&lt;td style="text-align: center"&gt;cognōvī&lt;/td&gt;
&lt;td style="text-align: center"&gt;cognitum&lt;/td&gt;
&lt;td style="text-align: left"&gt;ro recognize&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;quaerō&lt;/td&gt;
&lt;td style="text-align: center"&gt;quaerere&lt;/td&gt;
&lt;td style="text-align: center"&gt;quaesīvī&lt;/td&gt;
&lt;td style="text-align: center"&gt;quaesītum&lt;/td&gt;
&lt;td style="text-align: left"&gt;to find, look for, search for&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;cēnō&lt;/td&gt;
&lt;td style="text-align: center"&gt;cēnāre&lt;/td&gt;
&lt;td style="text-align: center"&gt;cēnāvī&lt;/td&gt;
&lt;td style="text-align: center"&gt;cēnātum&lt;/td&gt;
&lt;td style="text-align: left"&gt;eat for dinner, eat, dine&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;impōnō&lt;/td&gt;
&lt;td style="text-align: center"&gt;impōnere&lt;/td&gt;
&lt;td style="text-align: center"&gt;imponsuī&lt;/td&gt;
&lt;td style="text-align: center"&gt;impositum&lt;/td&gt;
&lt;td style="text-align: left"&gt;to put in, lay on, impose&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;praecīdō&lt;/td&gt;
&lt;td style="text-align: center"&gt;praecīdere&lt;/td&gt;
&lt;td style="text-align: center"&gt;praecīdī&lt;/td&gt;
&lt;td style="text-align: center"&gt;praecīsum&lt;/td&gt;
&lt;td style="text-align: left"&gt;to cut, damage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;dormiō&lt;/td&gt;
&lt;td style="text-align: center"&gt;dormīre&lt;/td&gt;
&lt;td style="text-align: center"&gt;dormīvī&lt;/td&gt;
&lt;td style="text-align: center"&gt;dormītum&lt;/td&gt;
&lt;td style="text-align: left"&gt;to sleep, alseep&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="irregulars"&gt;Irregulars&lt;/h2&gt;
&lt;h3 id="eō-ire-iīīvī-itum---to-go"&gt;&lt;em&gt;eō, ire, iī/īvī, itum&lt;/em&gt; - to go&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Present&lt;/th&gt;
&lt;th&gt;Future&lt;/th&gt;
&lt;th&gt;Perfect&lt;/th&gt;
&lt;th&gt;Imperative Present&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1s&lt;/td&gt;
&lt;td&gt;eō&lt;/td&gt;
&lt;td&gt;ībō&lt;/td&gt;
&lt;td&gt;īvī&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2s&lt;/td&gt;
&lt;td&gt;īs&lt;/td&gt;
&lt;td&gt;ībis&lt;/td&gt;
&lt;td&gt;īvistī&lt;/td&gt;
&lt;td&gt;i&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3s&lt;/td&gt;
&lt;td&gt;īt&lt;/td&gt;
&lt;td&gt;ībit&lt;/td&gt;
&lt;td&gt;ivit&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1p&lt;/td&gt;
&lt;td&gt;īmus&lt;/td&gt;
&lt;td&gt;ībimus&lt;/td&gt;
&lt;td&gt;ivimus&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2p&lt;/td&gt;
&lt;td&gt;ītis&lt;/td&gt;
&lt;td&gt;ībitis&lt;/td&gt;
&lt;td&gt;īvistis&lt;/td&gt;
&lt;td&gt;īte&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3p&lt;/td&gt;
&lt;td&gt;eunt&lt;/td&gt;
&lt;td&gt;ībunt&lt;/td&gt;
&lt;td&gt;ivērunt&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="hic-haec-hoc---this--these"&gt;&lt;em&gt;hic, haec, hoc&lt;/em&gt; - this / these&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Mas.sg.&lt;/th&gt;
&lt;th&gt;Fem.sg.&lt;/th&gt;
&lt;th&gt;Neu.sg.&lt;/th&gt;
&lt;th&gt;Mas.pl.&lt;/th&gt;
&lt;th&gt;Fem.pl.&lt;/th&gt;
&lt;th&gt;Neu.pl.&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Nom&lt;/td&gt;
&lt;td&gt;hic&lt;/td&gt;
&lt;td&gt;haec&lt;/td&gt;
&lt;td&gt;hoc&lt;/td&gt;
&lt;td&gt;hī&lt;/td&gt;
&lt;td&gt;hae&lt;/td&gt;
&lt;td&gt;haec&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Voc&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Acc&lt;/td&gt;
&lt;td&gt;hunc&lt;/td&gt;
&lt;td&gt;hanc&lt;/td&gt;
&lt;td&gt;hoc&lt;/td&gt;
&lt;td&gt;hōs&lt;/td&gt;
&lt;td&gt;hās&lt;/td&gt;
&lt;td&gt;haec&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gen&lt;/td&gt;
&lt;td&gt;huius&lt;/td&gt;
&lt;td&gt;huius&lt;/td&gt;
&lt;td&gt;huius&lt;/td&gt;
&lt;td&gt;hōrum&lt;/td&gt;
&lt;td&gt;hārum&lt;/td&gt;
&lt;td&gt;hōrum&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dat&lt;/td&gt;
&lt;td&gt;huic&lt;/td&gt;
&lt;td&gt;huic&lt;/td&gt;
&lt;td&gt;huic&lt;/td&gt;
&lt;td&gt;hīs&lt;/td&gt;
&lt;td&gt;hīs&lt;/td&gt;
&lt;td&gt;hīs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Abl&lt;/td&gt;
&lt;td&gt;hōc&lt;/td&gt;
&lt;td&gt;hāc&lt;/td&gt;
&lt;td&gt;hōc&lt;/td&gt;
&lt;td&gt;hīs&lt;/td&gt;
&lt;td&gt;hīs&lt;/td&gt;
&lt;td&gt;hīs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="ille-illa-illud---that--those"&gt;&lt;em&gt;ille, illa, illud&lt;/em&gt; - that / those&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Mas.sg.&lt;/th&gt;
&lt;th&gt;Fem.sg.&lt;/th&gt;
&lt;th&gt;Neu.sg.&lt;/th&gt;
&lt;th&gt;Mas.pl.&lt;/th&gt;
&lt;th&gt;Fem.pl.&lt;/th&gt;
&lt;th&gt;Neu.pl.&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Nom&lt;/td&gt;
&lt;td&gt;ille&lt;/td&gt;
&lt;td&gt;illa&lt;/td&gt;
&lt;td&gt;illud&lt;/td&gt;
&lt;td&gt;illī&lt;/td&gt;
&lt;td&gt;illae&lt;/td&gt;
&lt;td&gt;illa&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Voc&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Acc&lt;/td&gt;
&lt;td&gt;illum&lt;/td&gt;
&lt;td&gt;illam&lt;/td&gt;
&lt;td&gt;illud&lt;/td&gt;
&lt;td&gt;illōs&lt;/td&gt;
&lt;td&gt;illās&lt;/td&gt;
&lt;td&gt;illa&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gen&lt;/td&gt;
&lt;td&gt;illīus&lt;/td&gt;
&lt;td&gt;illīus&lt;/td&gt;
&lt;td&gt;illīus&lt;/td&gt;
&lt;td&gt;illōrum&lt;/td&gt;
&lt;td&gt;illārum&lt;/td&gt;
&lt;td&gt;illōrum&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dat&lt;/td&gt;
&lt;td&gt;illī&lt;/td&gt;
&lt;td&gt;illī&lt;/td&gt;
&lt;td&gt;illī&lt;/td&gt;
&lt;td&gt;illīs&lt;/td&gt;
&lt;td&gt;illīs&lt;/td&gt;
&lt;td&gt;hīs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Abl&lt;/td&gt;
&lt;td&gt;illō&lt;/td&gt;
&lt;td&gt;illā&lt;/td&gt;
&lt;td&gt;illō&lt;/td&gt;
&lt;td&gt;illīs&lt;/td&gt;
&lt;td&gt;illīs&lt;/td&gt;
&lt;td&gt;hīs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="ego-tū-nōs-vōs---i-you--we-you"&gt;&lt;em&gt;ego, tū, nōs, vōs&lt;/em&gt; - I, You / We, You&lt;/h3&gt;
&lt;p&gt;No distinguish between masculine and femnine.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;1s&lt;/th&gt;
&lt;th&gt;2s&lt;/th&gt;
&lt;th&gt;1p&lt;/th&gt;
&lt;th&gt;2p&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Nom&lt;/td&gt;
&lt;td&gt;ego&lt;/td&gt;
&lt;td&gt;tū&lt;/td&gt;
&lt;td&gt;nōs&lt;/td&gt;
&lt;td&gt;vōs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Voc&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Acc&lt;/td&gt;
&lt;td&gt;mē&lt;/td&gt;
&lt;td&gt;tē&lt;/td&gt;
&lt;td&gt;nōs&lt;/td&gt;
&lt;td&gt;vōs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gen&lt;/td&gt;
&lt;td&gt;meī&lt;/td&gt;
&lt;td&gt;tuī&lt;/td&gt;
&lt;td&gt;nōstrī&lt;/td&gt;
&lt;td&gt;vōstrī&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dat&lt;/td&gt;
&lt;td&gt;mīhī&lt;/td&gt;
&lt;td&gt;tībī&lt;/td&gt;
&lt;td&gt;nōbīs&lt;/td&gt;
&lt;td&gt;vōbīs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Abl&lt;/td&gt;
&lt;td&gt;mē&lt;/td&gt;
&lt;td&gt;tē&lt;/td&gt;
&lt;td&gt;nōbīs&lt;/td&gt;
&lt;td&gt;vōbīs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="is-ea-id-ei-eae-ea---he-she-it--they"&gt;&lt;em&gt;is, ea, id, ei, eae, ea&lt;/em&gt; - He, She, It / They&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Mas.sg.&lt;/th&gt;
&lt;th&gt;Fem.sg.&lt;/th&gt;
&lt;th&gt;Neu.sg.&lt;/th&gt;
&lt;th&gt;Mas.pl.&lt;/th&gt;
&lt;th&gt;Fem.pl.&lt;/th&gt;
&lt;th&gt;Neu.pl.&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Nom&lt;/td&gt;
&lt;td&gt;is&lt;/td&gt;
&lt;td&gt;ea&lt;/td&gt;
&lt;td&gt;id&lt;/td&gt;
&lt;td&gt;eī&lt;/td&gt;
&lt;td&gt;eae&lt;/td&gt;
&lt;td&gt;ea&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Voc&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Acc&lt;/td&gt;
&lt;td&gt;eum&lt;/td&gt;
&lt;td&gt;eam&lt;/td&gt;
&lt;td&gt;id&lt;/td&gt;
&lt;td&gt;eōs&lt;/td&gt;
&lt;td&gt;eās&lt;/td&gt;
&lt;td&gt;ea&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gen&lt;/td&gt;
&lt;td&gt;ēius&lt;/td&gt;
&lt;td&gt;ēius&lt;/td&gt;
&lt;td&gt;ēius&lt;/td&gt;
&lt;td&gt;eōrum&lt;/td&gt;
&lt;td&gt;eārum&lt;/td&gt;
&lt;td&gt;eōrum&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dat&lt;/td&gt;
&lt;td&gt;eī&lt;/td&gt;
&lt;td&gt;eī&lt;/td&gt;
&lt;td&gt;eī&lt;/td&gt;
&lt;td&gt;eīs&lt;/td&gt;
&lt;td&gt;eīs&lt;/td&gt;
&lt;td&gt;eīs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Abl&lt;/td&gt;
&lt;td&gt;eō&lt;/td&gt;
&lt;td&gt;ea&lt;/td&gt;
&lt;td&gt;eo&lt;/td&gt;
&lt;td&gt;eīs&lt;/td&gt;
&lt;td&gt;eīs&lt;/td&gt;
&lt;td&gt;eīs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="compound"&gt;Compound&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;abeō&lt;/strong&gt;, conjugate like &lt;em&gt;eō&lt;/em&gt; - go away&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;exeō&lt;/strong&gt;, conjugate like &lt;em&gt;eō&lt;/em&gt; - go out&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;absum&lt;/strong&gt;, conjugate like &lt;em&gt;sum&lt;/em&gt; - absent&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;adsum&lt;/strong&gt;, conjugate like &lt;em&gt;sum&lt;/em&gt; - present&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>Baremetal Host Audit Report</title><link>https://vox.app.home/posts/private/intranet/srv_host_security_audit/</link><pubDate>Mon, 31 Aug 2026 13:00:00 +0000</pubDate><guid>https://vox.app.home/posts/private/intranet/srv_host_security_audit/</guid><description>&lt;h1 id="host-security-audit--srv-machines"&gt;Host Security Audit — &lt;code&gt;srv*&lt;/code&gt; Machines&lt;/h1&gt;
&lt;p&gt;Attack-surface and firewall review of the six &lt;code&gt;srv*&lt;/code&gt; hosts, derived entirely from
the on-host collector reports in &lt;code&gt;host-env-scan/&lt;/code&gt;.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Scope&lt;/td&gt;
&lt;td&gt;&lt;code&gt;srv01hv&lt;/code&gt;, &lt;code&gt;srv02gate&lt;/code&gt;, &lt;code&gt;srv03mm&lt;/code&gt;, &lt;code&gt;srv04fs&lt;/code&gt;, &lt;code&gt;srv05access&lt;/code&gt;, &lt;code&gt;srv06hv&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sources&lt;/td&gt;
&lt;td&gt;&lt;code&gt;host-env-scan/hostenv_srv*.md&lt;/code&gt; — sections 2–6 plus the raw &lt;code&gt;fw.*&lt;/code&gt;, &lt;code&gt;net.sysctl&lt;/code&gt; and &lt;code&gt;svc.*&lt;/code&gt; appendix entries&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Corroborating&lt;/td&gt;
&lt;td&gt;&lt;code&gt;audit-report/NETWORK_TOPOLOGY.md&lt;/code&gt; (findings &lt;code&gt;T-01&lt;/code&gt;…&lt;code&gt;T-11&lt;/code&gt;), &lt;code&gt;Designated VLANs.md&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Method&lt;/td&gt;
&lt;td&gt;Desk analysis of existing read-only collection. &lt;strong&gt;No scanning, no probing, no connection attempts, no configuration changes were performed for this document.&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Collection window (UTC)&lt;/td&gt;
&lt;td&gt;2026-08-25 23:05 → 2026-08-26 12:35&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Finding prefix&lt;/td&gt;
&lt;td&gt;&lt;code&gt;S-xx&lt;/code&gt; (chosen to avoid collision with &lt;code&gt;F-xx&lt;/code&gt; in &lt;code&gt;NETWORK_AUDIT_REPORT.md&lt;/code&gt; and &lt;code&gt;T-xx&lt;/code&gt; in &lt;code&gt;NETWORK_TOPOLOGY.md&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Reading rule used throughout.&lt;/strong&gt; Section 5 (&amp;ldquo;Exposure Analysis&amp;rdquo;) of the collector
reports is &lt;em&gt;not&lt;/em&gt; taken at face value. Every verdict in this document is re-derived
from the raw ruleset in the appendix — &lt;code&gt;fw.nft&lt;/code&gt; for the firewalld hosts,
&lt;code&gt;fw.iptables&lt;/code&gt; for the Proxmox hosts — because the collector&amp;rsquo;s zone parser drops
the default zone and therefore mis-reports reachability on two of the six hosts
(finding &lt;code&gt;S-15&lt;/code&gt;). Where the raw ruleset was not collected the verdict is stated as
an assumption, not a fact.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="1-host-inventory"&gt;1. Host inventory&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Host&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;th&gt;OS / kernel&lt;/th&gt;
&lt;th&gt;Uptime&lt;/th&gt;
&lt;th&gt;VLANs terminated&lt;/th&gt;
&lt;th&gt;Host firewall&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;srv01hv&lt;/td&gt;
&lt;td&gt;Proxmox hypervisor (MS-A2)&lt;/td&gt;
&lt;td&gt;Debian 13.0 / 6.14.8-2-pve&lt;/td&gt;
&lt;td&gt;119d&lt;/td&gt;
&lt;td&gt;10, 200, 204, 214, 300, 400, 1024&lt;/td&gt;
&lt;td&gt;PVE &lt;code&gt;iptables&lt;/code&gt; (default DROP)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv02gate&lt;/td&gt;
&lt;td&gt;DNS / DHCP / RADIUS / reverse proxy / UniFi (RPi)&lt;/td&gt;
&lt;td&gt;Debian 13.2 / 6.12.47+rpt-rpi-v8&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;247d&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1, 10, 50, 200, 300, 1024&lt;/td&gt;
&lt;td&gt;firewalld (nftables)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv03mm&lt;/td&gt;
&lt;td&gt;Media + backup mirror (UGREEN DXP2800)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Debian 12.15&lt;/strong&gt; / 6.1.0-52&lt;/td&gt;
&lt;td&gt;2h&lt;/td&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;none&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv04fs&lt;/td&gt;
&lt;td&gt;Primary file server (PowerEdge T360)&lt;/td&gt;
&lt;td&gt;Debian 13.4 / 6.12.86&lt;/td&gt;
&lt;td&gt;102d&lt;/td&gt;
&lt;td&gt;200, 400&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;none&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv05access&lt;/td&gt;
&lt;td&gt;Choke / access host, monitoring (RPi 5)&lt;/td&gt;
&lt;td&gt;Debian 13.6 / 6.12.47+rpt-rpi-2712&lt;/td&gt;
&lt;td&gt;23d&lt;/td&gt;
&lt;td&gt;10, 200, 1024, 2871&lt;/td&gt;
&lt;td&gt;firewalld (nftables)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv06hv&lt;/td&gt;
&lt;td&gt;Proxmox hypervisor (R740xd)&lt;/td&gt;
&lt;td&gt;Debian 13.3 / 6.17.9-1-pve&lt;/td&gt;
&lt;td&gt;38d&lt;/td&gt;
&lt;td&gt;1(nested), 200, 204, 214, 400, 1024&lt;/td&gt;
&lt;td&gt;PVE &lt;code&gt;iptables&lt;/code&gt; (default DROP)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;VLAN roles per &lt;code&gt;Designated VLANs.md&lt;/code&gt;: 200 main internal, 2871 management
(isolated), 10 IoT, 1024 DMZ, 300 secure enclave, 50 guest, 400 network storage,
204 VM interconnect, 214 HV interconnect. VLAN 1 is live but undesignated
(&lt;code&gt;T-10&lt;/code&gt;).&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="2-attack-surface-what-is-actually-reachable-per-vlan"&gt;2. Attack surface: what is actually reachable, per VLAN&lt;/h2&gt;
&lt;p&gt;Ports below are &lt;strong&gt;inbound-reachable&lt;/strong&gt; after applying the host&amp;rsquo;s real ruleset.
&lt;code&gt;—&lt;/code&gt; means the ruleset drops or rejects everything on that interface.&lt;/p&gt;
&lt;h3 id="21-srv01hv--pve-firewall-verified-from-fwiptables"&gt;2.1 srv01hv — PVE firewall, verified from &lt;code&gt;fw.iptables&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;PVEFW-HOST-IN&lt;/code&gt; ends in &lt;code&gt;-j PVEFW-Drop&lt;/code&gt; / &lt;code&gt;-j DROP&lt;/code&gt;, so anything not matched is
denied. Interface → security group mapping:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Interface&lt;/th&gt;
&lt;th&gt;VLAN&lt;/th&gt;
&lt;th&gt;Address&lt;/th&gt;
&lt;th&gt;Group&lt;/th&gt;
&lt;th&gt;Reachable&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;vmbr1plc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;200 main&lt;/td&gt;
&lt;td&gt;10.1.1.11&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GROUP-management-IN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;22/tcp, 53/tcp+udp, 80/tcp, 443/tcp, 67-68/udp&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;hvintra&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;214 HV interconnect&lt;/td&gt;
&lt;td&gt;10.129.0.2&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GROUP-pve-basic-IN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;22/tcp, 53/tcp+udp, 111/tcp+udp, 443/tcp, 67-68/udp&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;vmbr0vm&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;204 VM interconnect&lt;/td&gt;
&lt;td&gt;10.128.128.20&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GROUP-pve-basic-IN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;as above&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;vmbr4nas&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;400 storage&lt;/td&gt;
&lt;td&gt;10.255.255.7&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GROUP-nas-IN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;22/tcp, 53/tcp+udp, 111/tcp+udp, 2049/tcp+udp, 135+139+445/tcp, 135+137-139+445/udp&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;vmbr2iot&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;10 IoT&lt;/td&gt;
&lt;td&gt;172.17.1.6&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GROUP-dmz-external-IN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;— (explicit DROP)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;vmbr10ext&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1024 DMZ&lt;/td&gt;
&lt;td&gt;172.16.1.6&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GROUP-dmz-external-IN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;— (explicit DROP)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;vmbr3sec&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;300 enclave&lt;/td&gt;
&lt;td&gt;10.10.1.2&lt;/td&gt;
&lt;td&gt;&lt;em&gt;no interface rule&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;only 22, 3128, 8006, 5900-5999, 60000-60050 from sources in ipset &lt;code&gt;PVEFW-0-management-v4/v6&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;enp3s0&lt;/code&gt;, &lt;code&gt;eth0p0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;native/untagged&lt;/td&gt;
&lt;td&gt;link-local&lt;/td&gt;
&lt;td&gt;&lt;em&gt;no interface rule&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;as &lt;code&gt;vmbr3sec&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;code&gt;5405/udp&lt;/code&gt; (corosync) is source-pinned to &lt;code&gt;10.129.0.1&lt;/code&gt; (srv06hv). &lt;code&gt;9100/tcp&lt;/code&gt;
(node_exporter), &lt;code&gt;8006/tcp&lt;/code&gt; and &lt;code&gt;3128/tcp&lt;/code&gt; are &lt;strong&gt;not&lt;/strong&gt; reachable from any VLAN
except via the management ipset. This host is in the best shape of the six.&lt;/p&gt;
&lt;h3 id="22-srv06hv--same-cluster-ruleset"&gt;2.2 srv06hv — same cluster ruleset&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Interface&lt;/th&gt;
&lt;th&gt;VLAN&lt;/th&gt;
&lt;th&gt;Address&lt;/th&gt;
&lt;th&gt;Group&lt;/th&gt;
&lt;th&gt;Reachable&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;vmbr1plc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;200 main&lt;/td&gt;
&lt;td&gt;10.1.1.15&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GROUP-management-IN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;22/tcp, 53/tcp+udp, 80/tcp, 443/tcp, 67-68/udp&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;vmbr0vm&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;204&lt;/td&gt;
&lt;td&gt;10.128.128.2&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GROUP-pve-basic-IN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;22/tcp, 53/tcp+udp, 111/tcp+udp, 443/tcp&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;hvintra&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;214&lt;/td&gt;
&lt;td&gt;10.129.0.1&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GROUP-pve-basic-IN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;as above&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;vmbr2nas&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;400 storage&lt;/td&gt;
&lt;td&gt;10.255.255.1&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GROUP-nas-IN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;22, 53, 111, 2049, SMB set (as srv01hv)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;vmbr10ext&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1024 DMZ&lt;/td&gt;
&lt;td&gt;172.16.1.3&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GROUP-dmz-external-IN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;docker&lt;/code&gt;, &lt;code&gt;hvintrav1&lt;/code&gt;, &lt;code&gt;ens2f0.*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1 nested in 214&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;em&gt;no interface rule&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;management ipset only&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;code&gt;5380/tcp&lt;/code&gt; (Technitium DNS admin console) and &lt;code&gt;9100/tcp&lt;/code&gt; are bound to all
interfaces but permitted nowhere — blocked. Good.&lt;/p&gt;
&lt;h3 id="23-srv02gate--firewalld-verified-from-fwnft-filter_in_public_allow"&gt;2.3 srv02gate — firewalld, verified from &lt;code&gt;fw.nft&lt;/code&gt; &lt;code&gt;filter_IN_public_allow&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;public&lt;/code&gt; zone is bound to &lt;strong&gt;six&lt;/strong&gt; interfaces: &lt;code&gt;eth0&lt;/code&gt; (native), &lt;code&gt;eth0.1&lt;/code&gt;
(VLAN 1), &lt;code&gt;eth0.10&lt;/code&gt; (IoT), &lt;code&gt;eth0.50&lt;/code&gt; (&lt;strong&gt;guest&lt;/strong&gt;), &lt;code&gt;eth0.200&lt;/code&gt; (main),
&lt;code&gt;eth0.300&lt;/code&gt; (&lt;strong&gt;secure enclave&lt;/strong&gt;). Every one of the following is reachable from
all six, including the guest and IoT networks:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;tcp 22 53 80 443 1812 1813 5380 5671 6789 8080 8443 8444 8843
9100 11443 27117 8880-8882
udp 22 53 67 546(link-local) 1900 3478 5514 10001
+ ICMP and ICMPv6 accepted unconditionally
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;eth0.1024&lt;/code&gt; (DMZ) is the only interface in a restrictive zone (&lt;code&gt;block&lt;/code&gt;,
target &lt;code&gt;%%REJECT%%&lt;/code&gt;) and is limited to &lt;code&gt;53/tcp&lt;/code&gt;, &lt;code&gt;53/udp&lt;/code&gt;, &lt;code&gt;67/udp&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Cross-referencing against what is actually listening:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Reachable and listening&lt;/th&gt;
&lt;th&gt;Service&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;22/tcp&lt;/td&gt;
&lt;td&gt;sshd&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;53/tcp+udp, 67/udp, 5380/tcp&lt;/td&gt;
&lt;td&gt;Technitium DNS + DHCP + &lt;strong&gt;admin web console&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;80/tcp, 443/tcp&lt;/td&gt;
&lt;td&gt;nginx (reverse proxy, 4 vhosts)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1812/1813 udp&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;FreeRADIUS&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9100/tcp&lt;/td&gt;
&lt;td&gt;node_exporter&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5671, 6789, 8080, 8443, 8444, 8880-8882, 11443, 28082(no), 3478/udp, 5514/udp, 10003/udp(no)&lt;/td&gt;
&lt;td&gt;UniFi Network Application in rootless podman (&lt;code&gt;pasta&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Allowed but nothing listening&lt;/th&gt;
&lt;th&gt;Note&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;8843/tcp, 27117/tcp, 1900/udp, 22/udp&lt;/td&gt;
&lt;td&gt;Dead allowances. 27117 is UniFi&amp;rsquo;s MongoDB — a rule that will silently expose the controller database the moment that container binds it.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="24-srv05access--firewalld-zones-verified-from-fwactive_zones--fwzones_permanent"&gt;2.4 srv05access — firewalld, zones verified from &lt;code&gt;fw.active_zones&lt;/code&gt; + &lt;code&gt;fw.zones_permanent&lt;/code&gt;&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Interface&lt;/th&gt;
&lt;th&gt;VLAN&lt;/th&gt;
&lt;th&gt;Zone&lt;/th&gt;
&lt;th&gt;Reachable&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;eth0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;native/untagged&lt;/td&gt;
&lt;td&gt;&lt;code&gt;public&lt;/code&gt; (default)&lt;/td&gt;
&lt;td&gt;22/tcp, 22/udp, 80/tcp, 443/tcp, 546/udp&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;eth0.200&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;200 main&lt;/td&gt;
&lt;td&gt;&lt;code&gt;restrict-regular&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;22/tcp, 80/tcp, 443/tcp, &lt;strong&gt;9090/tcp&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;eth0.10&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;10 IoT&lt;/td&gt;
&lt;td&gt;&lt;code&gt;restrict-ssh-only&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;22/tcp&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;eth0.2871&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;2871 management&lt;/td&gt;
&lt;td&gt;&lt;code&gt;restrict-ssh-only&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;22/tcp&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;eth0.1024&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1024 DMZ&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dmz&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;22/tcp&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Correctly blocked on every interface: &lt;code&gt;111&lt;/code&gt; (rpcbind), &lt;code&gt;3493&lt;/code&gt; (NUT &lt;code&gt;upsd&lt;/code&gt;),
&lt;code&gt;9100&lt;/code&gt; (node_exporter), &lt;code&gt;5353&lt;/code&gt; + ephemeral (avahi). This is the only host in the
set with per-VLAN zone differentiation, and it is broadly sound — the residual
issues are the DMZ/IoT-facing SSH and the unauthenticated Prometheus.&lt;/p&gt;
&lt;h3 id="25-srv03mm-and-srv04fs--no-host-firewall"&gt;2.5 srv03mm and srv04fs — no host firewall&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;firewalld available: no&lt;/code&gt;, and the collector version used (1.0.0) captured no
&lt;code&gt;nft&lt;/code&gt;/&lt;code&gt;iptables&lt;/code&gt; output at all, so no ruleset exists to evaluate. The working
assumption — consistent with a stock Debian install and with the reports'
&lt;code&gt;unknown&lt;/code&gt; verdicts — is that &lt;strong&gt;every listening socket is reachable from every
VLAN the host terminates.&lt;/strong&gt; On that assumption:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;srv03mm — VLAN 200, 10.1.1.12&lt;/th&gt;
&lt;th&gt;Service&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;22/tcp&lt;/td&gt;
&lt;td&gt;sshd&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;111/tcp+udp&lt;/td&gt;
&lt;td&gt;rpcbind&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;139/tcp, 445/tcp&lt;/td&gt;
&lt;td&gt;Samba &lt;code&gt;smbd&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2049/tcp&lt;/td&gt;
&lt;td&gt;kernel NFS server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;39101, 45867, 48823, 49651, 50083, 53993 /tcp + 6 udp&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rpc.mountd&lt;/code&gt; (ephemeral)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;42547, 57497 /tcp + 43339, 48722 /udp&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rpc.statd&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4330/tcp&lt;/td&gt;
&lt;td&gt;PCP &lt;code&gt;pmlogger&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;44321/tcp&lt;/td&gt;
&lt;td&gt;PCP &lt;code&gt;pmcd&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;44322, 44323 /tcp&lt;/td&gt;
&lt;td&gt;PCP &lt;code&gt;pmproxy&lt;/code&gt; (HTTP/REST metrics API)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8096/tcp, 7359/udp&lt;/td&gt;
&lt;td&gt;Jellyfin (plaintext HTTP)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9100/tcp&lt;/td&gt;
&lt;td&gt;node_exporter&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;srv04fs — VLAN 200 (10.1.1.13) &lt;strong&gt;and&lt;/strong&gt; VLAN 400 (10.255.255.9)&lt;/th&gt;
&lt;th&gt;Service&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;22/tcp&lt;/td&gt;
&lt;td&gt;sshd&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;69/udp&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;TFTP&lt;/strong&gt; (&lt;code&gt;tftpd-hpa&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;111/tcp+udp&lt;/td&gt;
&lt;td&gt;rpcbind&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;137/udp, 138/udp&lt;/td&gt;
&lt;td&gt;NetBIOS (&lt;code&gt;nmbd&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;139/tcp, 445/tcp&lt;/td&gt;
&lt;td&gt;Samba &lt;code&gt;smbd&lt;/code&gt; + &lt;code&gt;winbind&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;990/tcp&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;vsftpd&lt;/strong&gt; (implicit FTPS)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2049/tcp&lt;/td&gt;
&lt;td&gt;kernel NFS server (5 ZFS backup datasets, &lt;code&gt;/tank/lockbox&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;33709, 34341, 34733, 48295, 50373, 50689 /tcp + 6 udp&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rpc.mountd&lt;/code&gt; (ephemeral)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;41299, 52793 /tcp + 35500, 37950 /udp&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rpc.statd&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9100/tcp&lt;/td&gt;
&lt;td&gt;node_exporter&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="3-findings"&gt;3. Findings&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ID&lt;/th&gt;
&lt;th&gt;Severity&lt;/th&gt;
&lt;th&gt;Summary&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;S-01&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;High&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;srv03mm and srv04fs run no host firewall; the entire storage/backup surface is open to VLAN 200 and VLAN 400&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S-02&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;High&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;srv02gate exposes 27 port ranges — including SSH, the DNS admin console, RADIUS and the UniFi controller — to the guest, IoT and secure-enclave VLANs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S-03&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;High&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;srv02gate is a single unpatched host holding the DNS, DHCP, RADIUS and reverse-proxy planes, L2-attached to six VLANs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S-04&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;srv05access accepts SSH from the DMZ, IoT and management VLANs and bridges four VLANs, making it the estate&amp;rsquo;s most attractive pivot&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S-05&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Unauthenticated Prometheus (9090) reachable from VLAN 200; node_exporter (9100) reachable from guest/IoT on srv02gate and unfiltered on srv03mm/srv04fs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S-06&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;All six hosts accept ICMP redirects, send redirects, do not log martians, and have reverse-path filtering off (or loose)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S-07&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Proxmox cluster firewall contains rules for interfaces that do not exist on the node, and &lt;code&gt;GROUP-nas-IN&lt;/code&gt; opens SMB/NFS on hosts that serve neither&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S-08&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Four guest/container interfaces bypass the Proxmox per-VM firewall bridge, one of them on production VLAN 200&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S-09&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;The &lt;code&gt;PVEFW-0-management-v4/v6&lt;/code&gt; ipset gates the most privileged access on both hypervisors (8006, VNC, SPICE, SSH, migration) and its contents were never collected&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S-10&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Unauthenticated and legacy file services on srv04fs: TFTP, NetBIOS, FTPS, NFS with &lt;code&gt;AUTH_SYS&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S-11&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Configuration-integrity defects that will alter network/firewall posture on the next reboot&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S-12&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Hypervisors run nginx, and srv06hv also Technitium DNS + admin console, alongside &lt;code&gt;pveproxy&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S-13&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Xray tunnelling daemons on both cross-VLAN hosts (srv02gate, srv05access)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S-14&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Patch cadence: 247d / 119d / 102d uptime; srv03mm still on Debian 12&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S-15&lt;/td&gt;
&lt;td&gt;Low (tooling)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;collect_host_env.py&lt;/code&gt; drops the default zone from section 4.1, so section 5 reports 36 srv02gate ports as &lt;code&gt;filtered&lt;/code&gt; when they are reachable&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h3 id="s-01--no-host-firewall-on-srv03mm-and-srv04fs--high"&gt;S-01 — No host firewall on srv03mm and srv04fs — High&lt;/h3&gt;
&lt;p&gt;Both reports state &lt;code&gt;firewalld available: no&lt;/code&gt; / &lt;code&gt;firewalld not installed&lt;/code&gt;, and
neither has any &lt;code&gt;fw.*&lt;/code&gt; appendix entry, so no packet filter of any kind is
evidenced. srv04fs is the primary file server: it holds &lt;code&gt;tank/backups/pbs&lt;/code&gt;,
&lt;code&gt;tank/backups/baremetals&lt;/code&gt;, &lt;code&gt;tank/backups/lxskypc&lt;/code&gt;, &lt;code&gt;tank/archive&lt;/code&gt; and
&lt;code&gt;tank/lockbox/lxsky&lt;/code&gt;, and exports them over NFS and SMB. srv03mm holds the
&lt;code&gt;backup-mirror&lt;/code&gt; copy of the same data.&lt;/p&gt;
&lt;p&gt;Consequences, on VLAN 200 — which every general-purpose host, both hypervisors
and every VM on &lt;code&gt;vmbr1plc&lt;/code&gt; can reach:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;rpcbind&lt;/code&gt; (111) is queryable, enumerating NFS, mountd and statd including their
randomised high ports. Combined with an unrestricted &lt;code&gt;/etc/exports&lt;/code&gt; this is a
direct route to the backup datasets; NFSv3/AUTH_SYS trusts whatever UID the
client claims.&lt;/li&gt;
&lt;li&gt;SMB (139/445) is exposed on both hosts, with &lt;code&gt;nmbd&lt;/code&gt; NetBIOS name service on
srv04fs. &lt;code&gt;smb.conf&lt;/code&gt; was not collected, so share ACLs and the minimum SMB
protocol version are unverified.&lt;/li&gt;
&lt;li&gt;srv04fs additionally exposes &lt;strong&gt;TFTP&lt;/strong&gt; (69/udp) and &lt;strong&gt;vsftpd&lt;/strong&gt; (990/tcp).&lt;/li&gt;
&lt;li&gt;srv03mm exposes the full PCP stack (&lt;code&gt;pmcd&lt;/code&gt; 44321, &lt;code&gt;pmproxy&lt;/code&gt; 44322/44323,
&lt;code&gt;pmlogger&lt;/code&gt; 4330). &lt;code&gt;pmproxy&lt;/code&gt; is an HTTP API over the host&amp;rsquo;s performance metrics;
&lt;code&gt;pmcd&lt;/code&gt; serves metric namespaces to any client its access controls admit.&lt;/li&gt;
&lt;li&gt;Jellyfin (8096) is plaintext HTTP with a login form.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;srv04fs is worse than srv03mm because it is dual-homed: the &lt;em&gt;same&lt;/em&gt; unfiltered
socket set is presented on VLAN 400 (10.255.255.9), the storage VLAN, which is
also terminated by both hypervisors and by &lt;code&gt;tap&lt;/code&gt; interfaces belonging to guest
VMs (see &lt;code&gt;S-08&lt;/code&gt;). A compromised VM on the storage VLAN reaches the backup server
with no host-level filter in front of it.&lt;/p&gt;
&lt;p&gt;The evidence gap here is real and should be closed before the finding is treated
as settled — see &lt;code&gt;G-01&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="s-02--srv02gates-public-zone-spans-six-vlans-including-guest-and-iot--high"&gt;S-02 — srv02gate&amp;rsquo;s &lt;code&gt;public&lt;/code&gt; zone spans six VLANs including guest and IoT — High&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;firewall-cmd --get-active-zones&lt;/code&gt; shows:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;block
interfaces: eth0.1024
public (default)
interfaces: eth0.50 eth0.300 eth0.200 eth0.10 eth0.1 eth0
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and &lt;code&gt;nft list ruleset&lt;/code&gt; confirms &lt;code&gt;filter_INPUT_POLICIES&lt;/code&gt; jumps each of those six
interfaces to &lt;code&gt;filter_IN_public&lt;/code&gt;, whose &lt;code&gt;_allow&lt;/code&gt; chain holds 27 accept rules
(section 2.3 above). The DMZ is the only segment that was actually restricted.&lt;/p&gt;
&lt;p&gt;The design intent is visible and inverted: someone carefully placed the DMZ into
&lt;code&gt;block&lt;/code&gt;, then left the guest network, the IoT network and the &amp;ldquo;secure enclave&amp;rdquo; in
the same permissive zone as the trusted server VLAN. Concretely, a device on the
guest Wi-Fi (VLAN 50, 192.168.1.0/24) can reach:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;5380/tcp&lt;/code&gt;&lt;/strong&gt; — the Technitium DNS admin console. Full control of the
estate&amp;rsquo;s resolver: rewrite any A record, point &lt;code&gt;nas.home&lt;/code&gt; or &lt;code&gt;srv04fs.nas.home&lt;/code&gt;
at an attacker host, disable DNSSEC, read every query log.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;1812&lt;/code&gt;/&lt;code&gt;1813&lt;/code&gt; udp&lt;/strong&gt; — FreeRADIUS. Offline dictionary attack against the
shared secret and, depending on EAP configuration, against user credentials;
this is the authentication plane for the wireless/wired 802.1X estate.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;8080&lt;/code&gt;, &lt;code&gt;8443&lt;/code&gt;, &lt;code&gt;8843&lt;/code&gt;, &lt;code&gt;6789&lt;/code&gt;, &lt;code&gt;11443&lt;/code&gt;, &lt;code&gt;8880-8882&lt;/code&gt;, &lt;code&gt;3478/udp&lt;/code&gt;,
&lt;code&gt;5514/udp&lt;/code&gt;&lt;/strong&gt; — the UniFi controller, i.e. the switch and AP management plane,
including the device-inform endpoint and the syslog sink.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;27117/tcp&lt;/code&gt;&lt;/strong&gt; — permitted for UniFi&amp;rsquo;s MongoDB. Nothing is bound to it today,
which is the only reason it is not an unauthenticated database exposed to the
guest network.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;22/tcp&lt;/code&gt;&lt;/strong&gt; — sshd, from guest and IoT.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;9100/tcp&lt;/code&gt;&lt;/strong&gt; — node_exporter (see &lt;code&gt;S-05&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;22/udp&lt;/code&gt; and &lt;code&gt;1900/udp&lt;/code&gt; are also permitted and serve no listening service.&lt;/p&gt;
&lt;h3 id="s-03--single-host-concentration-of-dns-dhcp-radius-and-ingress--high"&gt;S-03 — Single-host concentration of DNS, DHCP, RADIUS and ingress — High&lt;/h3&gt;
&lt;p&gt;srv02gate is a Raspberry Pi 4 (Cortex-A72, 7.6 GiB) terminating VLANs 1, 10, 50,
200, 300 and 1024 on one 1G link, and it is simultaneously:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the DHCP server for VLANs 10, 50, 200, 300 and 1024 (&lt;code&gt;67/udp&lt;/code&gt; bound to
&lt;code&gt;172.17.1.2&lt;/code&gt;, &lt;code&gt;192.168.1.2&lt;/code&gt;, &lt;code&gt;10.1.1.10&lt;/code&gt;, &lt;code&gt;10.10.1.1&lt;/code&gt;, &lt;code&gt;172.16.1.2&lt;/code&gt;),&lt;/li&gt;
&lt;li&gt;the DNS server for the estate (&lt;code&gt;10.1.1.10&lt;/code&gt; and &lt;code&gt;172.16.1.2&lt;/code&gt; appear in the
&lt;code&gt;resolv.conf&lt;/code&gt; of srv01hv, srv04fs, srv05access and srv06hv),&lt;/li&gt;
&lt;li&gt;the RADIUS server,&lt;/li&gt;
&lt;li&gt;the TLS reverse proxy (nginx, four &lt;code&gt;443&lt;/code&gt; vhosts),&lt;/li&gt;
&lt;li&gt;the network-equipment controller (UniFi).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Compromise of this host — reachable per &lt;code&gt;S-02&lt;/code&gt; from the least trusted segments —
yields addressing, name resolution, network-device management and network
authentication in one step. &lt;code&gt;net.ipv4.ip_forward&lt;/code&gt; is &lt;code&gt;0&lt;/code&gt;, so it is not the router
(the TL-SE5226 is, per &lt;code&gt;T-06&lt;/code&gt;), but it does not need to route to be catastrophic.&lt;/p&gt;
&lt;p&gt;Aggravating: uptime is &lt;strong&gt;247 days&lt;/strong&gt; on kernel &lt;code&gt;6.12.47+rpt-rpi-v8&lt;/code&gt;, so no kernel
update has been applied in roughly eight months. Two default routes are
configured (&lt;code&gt;10.1.1.1&lt;/code&gt; via &lt;code&gt;eth0.200&lt;/code&gt;, static; &lt;code&gt;10.0.2.1&lt;/code&gt; via &lt;code&gt;eth0.1&lt;/code&gt;, DHCP),
with &lt;code&gt;rp_filter=0&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="s-04--srv05access-is-the-estates-best-pivot-and-accepts-ssh-from-dmz-and-iot--medium"&gt;S-04 — srv05access is the estate&amp;rsquo;s best pivot, and accepts SSH from DMZ and IoT — Medium&lt;/h3&gt;
&lt;p&gt;srv05access is the deliberate multihomed choke host. Its zoning is the most
disciplined of the six, but the residual surface is exactly the dangerous part:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;dmz&lt;/code&gt; on &lt;code&gt;eth0.1024&lt;/code&gt; permits &lt;code&gt;ssh&lt;/code&gt;. A compromised DMZ host gets an SSH
brute-force / credential-replay target that sits on VLAN 200 &lt;em&gt;and&lt;/em&gt; on the
isolated management VLAN 2871.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;restrict-ssh-only&lt;/code&gt; on &lt;code&gt;eth0.10&lt;/code&gt; gives every IoT device the same target.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;public&lt;/code&gt; on &lt;code&gt;eth0&lt;/code&gt; (the untagged trunk parent, native VLAN 1) permits
&lt;code&gt;22/tcp&lt;/code&gt;, &lt;code&gt;22/udp&lt;/code&gt;, &lt;code&gt;80&lt;/code&gt;, &lt;code&gt;443&lt;/code&gt;. VLAN 1 is undesignated (&lt;code&gt;T-10&lt;/code&gt;) and is the
native VLAN on every observed access port, which makes this the least
controlled of its five attachment points.&lt;/li&gt;
&lt;li&gt;Two default routes (&lt;code&gt;10.1.1.3&lt;/code&gt; via &lt;code&gt;eth0.200&lt;/code&gt;, &lt;code&gt;10.0.1.1&lt;/code&gt; via &lt;code&gt;eth0.2871&lt;/code&gt;) with
&lt;code&gt;rp_filter=0&lt;/code&gt;: egress selection is not deterministic and spoofed sources are
not rejected.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sshd_config&lt;/code&gt; was not collected, so it is unknown whether password
authentication or root login are permitted — this materially changes the
severity.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The management VLAN 2871 terminates on this host &lt;em&gt;only&lt;/em&gt; (&lt;code&gt;T-04&lt;/code&gt;), so srv05access
is the sole bridge between &amp;ldquo;isolated management&amp;rdquo; and everything else.&lt;/p&gt;
&lt;h3 id="s-05--unauthenticated-monitoring-surfaces--medium"&gt;S-05 — Unauthenticated monitoring surfaces — Medium&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Prometheus 9090 on srv05access&lt;/strong&gt; is explicitly permitted in
&lt;code&gt;restrict-regular&lt;/code&gt;, i.e. reachable from all of VLAN 200. Prometheus ships with
no authentication. Its &lt;code&gt;/targets&lt;/code&gt;, &lt;code&gt;/config&lt;/code&gt; and &lt;code&gt;/service-discovery&lt;/code&gt;
endpoints hand an attacker a complete inventory of hosts, scrape endpoints and
any credentials embedded in scrape configs; &lt;code&gt;/api/v1/query&lt;/code&gt; exposes the metric
history.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;node_exporter 9100&lt;/strong&gt; is bound to all interfaces on all six hosts. It is
reachable from guest and IoT on srv02gate (permitted by the
&lt;code&gt;prometheus-node-exporter&lt;/code&gt; service in &lt;code&gt;public&lt;/code&gt;), and unfiltered on srv03mm and
srv04fs. node_exporter discloses kernel and distribution version, every
filesystem and mount point, NIC inventory, uptime and systemd unit states — a
precise, unauthenticated fingerprint for choosing an exploit.&lt;/li&gt;
&lt;li&gt;srv03mm&amp;rsquo;s PCP &lt;code&gt;pmproxy&lt;/code&gt; (44322/44323) and &lt;code&gt;pmcd&lt;/code&gt; (44321) are the same class of
exposure with a wider metric namespace.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Correctly handled by contrast: 9100 is blocked on both hypervisors and on
srv05access itself.&lt;/p&gt;
&lt;h3 id="s-06--kernel-network-hardening-is-off-estate-wide--medium"&gt;S-06 — Kernel network hardening is off estate-wide — Medium&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Host&lt;/th&gt;
&lt;th&gt;&lt;code&gt;accept_redirects&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;send_redirects&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;rp_filter&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;log_martians&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;srv01hv&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;2 (loose)&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv02gate&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv03mm&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv04fs&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv05access&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv06hv&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;2 (loose)&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;code&gt;accept_source_route&lt;/code&gt; is correctly &lt;code&gt;0&lt;/code&gt; everywhere, and &lt;code&gt;ip_forward&lt;/code&gt; /
&lt;code&gt;ipv6.conf.all.forwarding&lt;/code&gt; are &lt;code&gt;0&lt;/code&gt; everywhere (so none of these hosts routes
between the VLANs it terminates — an important, deliberate control worth
preserving).&lt;/p&gt;
&lt;p&gt;The remaining settings matter most on precisely the hosts that straddle VLANs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;accept_redirects=1&lt;/code&gt; lets any on-link host inject a route into the kernel&amp;rsquo;s
cache with an ICMP redirect. On srv02gate that means an IoT or guest device can
redirect the DNS/RADIUS server&amp;rsquo;s traffic for a given destination through
itself. On srv05access, a DMZ host can do the same.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rp_filter=0&lt;/code&gt; on the four non-Proxmox hosts means a packet with a spoofed
source is accepted on any interface. On srv04fs, a host on VLAN 200 can send
frames claiming a VLAN 400 source and vice versa, defeating any future
source-based rule. This is the single change that most cheaply improves the
posture, but see the caveat in section 6 — strict mode will break srv02gate and
srv05access while they each carry two default routes.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;log_martians=0&lt;/code&gt; on all six means none of the above leaves a trace.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="s-07--proxmox-cluster-ruleset-contains-stale-interface-rules-and-over-broad-groups--medium"&gt;S-07 — Proxmox cluster ruleset contains stale interface rules and over-broad groups — Medium&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;PVEFW-HOST-IN&lt;/code&gt; is byte-identical on both nodes (it is generated from the shared
&lt;code&gt;/etc/pve&lt;/code&gt;), and references four bridges of which each node only has some:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Rule&lt;/th&gt;
&lt;th&gt;srv01hv&lt;/th&gt;
&lt;th&gt;srv06hv&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-i vmbr2nas -j GROUP-nas-IN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;does not exist&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;exists (VLAN 400)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-i vmbr4nas -j GROUP-nas-IN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;exists (VLAN 400)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;does not exist&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-i vmbr2iot -j GROUP-dmz-external-IN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;exists (VLAN 10)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;does not exist&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-i vmbr10ext -j GROUP-dmz-external-IN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;exists (VLAN 1024)&lt;/td&gt;
&lt;td&gt;exists (VLAN 1024)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Dead rules are not themselves a hole, but they mean the intended posture cannot
be read off the ruleset, and a future bridge rename silently re-activates them.
More importantly srv06hv has &lt;strong&gt;no&lt;/strong&gt; IoT bridge rule at all — if VLAN 10 is ever
added to that node it lands in the default path rather than in
&lt;code&gt;GROUP-dmz-external-IN&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;GROUP-nas-IN&lt;/code&gt; permits &lt;code&gt;111&lt;/code&gt;, &lt;code&gt;2049&lt;/code&gt;, &lt;code&gt;135&lt;/code&gt;, &lt;code&gt;137-139&lt;/code&gt;, &lt;code&gt;445&lt;/code&gt; on the storage
VLAN. Neither hypervisor runs an SMB or NFS &lt;em&gt;server&lt;/em&gt; — they are NFS/CIFS
&lt;em&gt;clients&lt;/em&gt; of &lt;code&gt;nas.home&lt;/code&gt;. Every SMB entry and the 2049 entry are unnecessary
grants. &lt;code&gt;GROUP-management-IN&lt;/code&gt; permits &lt;code&gt;80&lt;/code&gt; and &lt;code&gt;443&lt;/code&gt; on VLAN 200, which exists
only to serve the &lt;code&gt;nginx&lt;/code&gt; instance discussed in &lt;code&gt;S-12&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;GROUP-pve-basic-IN&lt;/code&gt; and &lt;code&gt;GROUP-nas-IN&lt;/code&gt; permit &lt;code&gt;111&lt;/code&gt; but not the ephemeral
&lt;code&gt;rpc.statd&lt;/code&gt; ports, so NFS lock recovery from the storage VLAN is filtered — an
operational inconsistency that suggests the groups were not derived from the
actual service set.&lt;/p&gt;
&lt;h3 id="s-08--guest-and-container-interfaces-bypassing-the-pve-bridge-firewall--medium"&gt;S-08 — Guest and container interfaces bypassing the PVE bridge firewall — Medium&lt;/h3&gt;
&lt;p&gt;Proxmox filters guest traffic only when the tap is placed behind a per-VM
&lt;code&gt;fwbr*&lt;/code&gt; bridge, because &lt;code&gt;PVEFW-FORWARD&lt;/code&gt; matches &lt;code&gt;--physdev-in fwln+&lt;/code&gt;. The
following are attached directly to a production bridge:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Host&lt;/th&gt;
&lt;th&gt;Interface&lt;/th&gt;
&lt;th&gt;Bridge&lt;/th&gt;
&lt;th&gt;VLAN&lt;/th&gt;
&lt;th&gt;Consequence&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;srv01hv&lt;/td&gt;
&lt;td&gt;&lt;code&gt;tap106i2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vmbr4nas&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;400 storage&lt;/td&gt;
&lt;td&gt;VM 106 NIC unfiltered on the storage VLAN&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv06hv&lt;/td&gt;
&lt;td&gt;&lt;code&gt;tap104i2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vmbr2nas&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;400 storage&lt;/td&gt;
&lt;td&gt;VM 104 NIC unfiltered on the storage VLAN&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv06hv&lt;/td&gt;
&lt;td&gt;&lt;code&gt;tap110i1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vmbr1plc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;200 main internal&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;VM 110 NIC unfiltered on the production VLAN&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv06hv&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ln_docker&lt;/code&gt; / &lt;code&gt;pr_docker&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;docker&lt;/code&gt; ↔ &lt;code&gt;hvintrav1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1 nested in 214&lt;/td&gt;
&lt;td&gt;veth pair named outside the &lt;code&gt;fwln+&lt;/code&gt; pattern, so &lt;code&gt;PVEFW-FWBR-IN&lt;/code&gt; never inspects it&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The last one deserves emphasis. &lt;code&gt;/etc/network/interfaces.d/sdn&lt;/code&gt; on srv06hv
builds:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;docker bridge_ports ln_docker
hvintrav1 bridge_ports ens2f0.214.1 pr_docker
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;ens2f0.214.1&lt;/code&gt; is VLAN 1 tagged &lt;em&gt;inside&lt;/em&gt; VLAN 214 — the QinQ construct flagged as
&lt;code&gt;T-10&lt;/code&gt;. Anything on the &lt;code&gt;docker&lt;/code&gt; bridge therefore has unfiltered layer-2 access
to a double-tagged VLAN riding the hypervisor interconnect trunk. Because the
veths are not named &lt;code&gt;fwln*&lt;/code&gt;, no Proxmox rule applies to that path at any point.
&lt;code&gt;iptables-save&lt;/code&gt; contains no &lt;code&gt;DOCKER&lt;/code&gt; chains and no &lt;code&gt;nat&lt;/code&gt; table, so no
alternative filter is in place either.&lt;/p&gt;
&lt;p&gt;This corroborates and extends &lt;code&gt;T-09&lt;/code&gt;, which counted three such interfaces.&lt;/p&gt;
&lt;h3 id="s-09--the-most-privileged-access-path-on-both-hypervisors-is-unverified--medium"&gt;S-09 — The most privileged access path on both hypervisors is unverified — Medium&lt;/h3&gt;
&lt;p&gt;Both nodes end &lt;code&gt;PVEFW-HOST-IN&lt;/code&gt; with:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;-p tcp -m set --match-set PVEFW-0-management-v4 src -m tcp --dport 8006 -j RETURN
-p tcp -m set --match-set PVEFW-0-management-v4 src -m tcp --dport 5900:5999 -j RETURN
-p tcp -m set --match-set PVEFW-0-management-v4 src -m tcp --dport 3128 -j RETURN
-p tcp -m set --match-set PVEFW-0-management-v4 src -m tcp --dport 22 -j RETURN
-p tcp -m set --match-set PVEFW-0-management-v4 src -m tcp --dport 60000:60050 -j RETURN
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;These are &lt;strong&gt;interface-independent&lt;/strong&gt;: they apply to every VLAN including the DMZ
and IoT bridges, whose &lt;code&gt;GROUP-dmz-external-IN&lt;/code&gt; DROP is reached earlier only for
traffic that the group&amp;rsquo;s own rules do not mark. The set therefore defines who can
reach the Proxmox web UI (8006), the VNC console range (5900-5999), the SPICE
proxy (3128), SSH and the live-migration range on both hypervisors.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ipset list&lt;/code&gt; / &lt;code&gt;ipset save&lt;/code&gt; is not among the collector&amp;rsquo;s commands, so the set
contents are unknown. The single most privileged access control in the estate is
undocumented. If the set contains a broad CIDR such as &lt;code&gt;10.1.0.0/20&lt;/code&gt;, the
hypervisor web UI is exposed to the whole of VLAN 200.&lt;/p&gt;
&lt;h3 id="s-10--unauthenticated-and-legacy-file-services-on-srv04fs--medium"&gt;S-10 — Unauthenticated and legacy file services on srv04fs — Medium&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;TFTP (&lt;code&gt;69/udp&lt;/code&gt;, &lt;code&gt;tftpd-hpa&lt;/code&gt;)&lt;/strong&gt; has no authentication by design. &lt;code&gt;/etc/default/tftpd-hpa&lt;/code&gt;
was not collected, so the root directory and whether &lt;code&gt;--create&lt;/code&gt;/&lt;code&gt;-c&lt;/code&gt; (write
access) is enabled are unknown. If writable, any host on VLAN 200 or 400 can
place files in the TFTP root; if that root is also served over another
protocol, this is a file-write primitive. TFTP on a backup server, exposed
unfiltered, warrants immediate confirmation.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;nmbd&lt;/code&gt; (137/138 udp)&lt;/strong&gt; is NetBIOS name service — the SMBv1-era discovery
protocol. It is broadcasting on &lt;code&gt;10.1.15.255&lt;/code&gt; and &lt;code&gt;10.255.255.255&lt;/code&gt;. Its
presence indicates the Samba install has not been modernised; the minimum
protocol version in &lt;code&gt;smb.conf&lt;/code&gt; should be confirmed as &lt;code&gt;SMB3&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;vsftpd on &lt;code&gt;990/tcp&lt;/code&gt;&lt;/strong&gt; is implicit FTPS. Only 990 is listening (not 21), so
cleartext FTP is not offered, but implicit FTPS is deprecated and vsftpd&amp;rsquo;s
configuration (anonymous access, chroot, allowed users) was not collected.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NFS with &lt;code&gt;AUTH_SYS&lt;/code&gt;.&lt;/strong&gt; &lt;code&gt;nfs-idmapd&lt;/code&gt; runs but no &lt;code&gt;rpc.gssd&lt;/code&gt; — so there is no
Kerberos, and client-supplied UIDs are trusted. Access control rests entirely
on &lt;code&gt;/etc/exports&lt;/code&gt;, which was not collected. srv03mm is in the same position.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="s-11--configuration-integrity-defects--low"&gt;S-11 — Configuration-integrity defects — Low&lt;/h3&gt;
&lt;p&gt;None of these are exploitable as they stand, but each means the audited runtime
state and the on-disk state disagree, so the next reboot produces an unaudited
posture.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;srv06hv &lt;code&gt;/etc/network/interfaces&lt;/code&gt;&lt;/strong&gt; declares &lt;code&gt;esn2f0.400&lt;/code&gt; and
&lt;code&gt;esn2f0.1024&lt;/code&gt; — &lt;code&gt;ens&lt;/code&gt; transposed to &lt;code&gt;esn&lt;/code&gt;. The bridges &lt;code&gt;vmbr2nas&lt;/code&gt; and
&lt;code&gt;vmbr10ext&lt;/code&gt; list &lt;code&gt;ens2f0.400&lt;/code&gt; / &lt;code&gt;ens2f0.1024&lt;/code&gt; as &lt;code&gt;bridge-ports&lt;/code&gt;, which are
never declared. The storage and DMZ bridges depend on interfaces that the
config file does not create. It also declares &lt;code&gt;nic1&lt;/code&gt; / &lt;code&gt;nic1.200&lt;/code&gt; for a NIC
that is down.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;srv01hv &lt;code&gt;vmbr3sec&lt;/code&gt;&lt;/strong&gt; is declared &lt;code&gt;inet dhcp&lt;/code&gt; &lt;em&gt;and&lt;/em&gt; carries a static
&lt;code&gt;address 10.128.255.1/24&lt;/code&gt;; the runtime address is &lt;code&gt;10.10.1.2/20&lt;/code&gt;. Three
different intents in one stanza for the secure-enclave bridge.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;srv02gate and srv05access&lt;/strong&gt; both report &amp;ldquo;runtime and permanent firewalld
configuration differ (&lt;code&gt;public/interfaces&lt;/code&gt;)&amp;rdquo;. On srv05access the permanent
&lt;code&gt;public&lt;/code&gt; zone has no interfaces while &lt;code&gt;eth0&lt;/code&gt; is assigned at runtime; on
srv02gate the permanent zone lists the six. Either way the firewall&amp;rsquo;s
interface bindings are not fully reproducible from disk.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;srv03mm &lt;code&gt;/etc/network/interfaces&lt;/code&gt;&lt;/strong&gt; configures IPv6 autoconf on &lt;code&gt;enp1s0&lt;/code&gt;,
which does not exist (the NIC is &lt;code&gt;enp2s0&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;srv02gate hostname&lt;/strong&gt; is &lt;code&gt;srv02gagte&lt;/code&gt; and its FQDN is unqualified — this
propagates into logs, certificates and any host-based authorisation.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;srv05access &lt;code&gt;wlan0&lt;/code&gt;&lt;/strong&gt; and both hypervisors&amp;rsquo; &lt;code&gt;fwbr*&lt;/code&gt; bridges are present at
runtime but absent from disk (expected for &lt;code&gt;fwbr*&lt;/code&gt;, which PVE creates on VM
start; not expected for &lt;code&gt;wlan0&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="s-12--extra-network-daemons-on-the-hypervisors--low"&gt;S-12 — Extra network daemons on the hypervisors — Low&lt;/h3&gt;
&lt;p&gt;Both hypervisors run &lt;code&gt;nginx&lt;/code&gt; on &lt;code&gt;80&lt;/code&gt; and &lt;code&gt;443&lt;/code&gt;, reachable from VLAN 200 via
&lt;code&gt;GROUP-management-IN&lt;/code&gt;, in addition to &lt;code&gt;pveproxy&lt;/code&gt; (8006) and &lt;code&gt;spiceproxy&lt;/code&gt; (3128).
srv06hv additionally runs Technitium DNS (&lt;code&gt;53&lt;/code&gt;, plus the &lt;code&gt;5380&lt;/code&gt; admin console
bound to all interfaces) and DHCP (&lt;code&gt;67/udp&lt;/code&gt; on four bridge addresses).&lt;/p&gt;
&lt;p&gt;The hypervisors are the highest-value hosts in the estate: a root compromise
yields every VM. Running a web server and a DNS/DHCP service in the same
namespace adds two remote-code-execution surfaces to that host for no
virtualisation benefit. &lt;code&gt;5380&lt;/code&gt; is currently blocked by the PVE ruleset, which is
the only thing standing between VLAN 200 and a second DNS admin console.&lt;/p&gt;
&lt;h3 id="s-13--tunnelling-software-on-both-cross-vlan-hosts--low"&gt;S-13 — Tunnelling software on both cross-VLAN hosts — Low&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;srv05access: &lt;code&gt;xray-jumper.service&lt;/code&gt; listening on &lt;code&gt;127.0.0.1:10086&lt;/code&gt; (tcp+udp).&lt;/li&gt;
&lt;li&gt;srv02gate: &lt;code&gt;xray.service&lt;/code&gt; on &lt;code&gt;127.0.0.1:18443&lt;/code&gt;, fronted by an nginx listener on
&lt;code&gt;127.0.0.1:8443&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Both are loopback-bound, so neither is an inbound exposure, and both are
presumably intentional. They are recorded because they sit on the two hosts that
touch every VLAN, and because a proxy that terminates on localhost behind a
public-facing nginx vhost is a policy-bypass channel: it can carry arbitrary
traffic in and out of the estate without traversing any of the zone rules
analysed above. Their configuration files were not collected.&lt;/p&gt;
&lt;h3 id="s-14--patch-cadence-and-os-drift--low"&gt;S-14 — Patch cadence and OS drift — Low&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Host&lt;/th&gt;
&lt;th&gt;Uptime&lt;/th&gt;
&lt;th&gt;Kernel&lt;/th&gt;
&lt;th&gt;Note&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;srv02gate&lt;/td&gt;
&lt;td&gt;247d&lt;/td&gt;
&lt;td&gt;6.12.47+rpt-rpi-v8&lt;/td&gt;
&lt;td&gt;~8 months without a kernel update, on the most exposed host&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv01hv&lt;/td&gt;
&lt;td&gt;119d&lt;/td&gt;
&lt;td&gt;6.14.8-2-pve&lt;/td&gt;
&lt;td&gt;Debian 13.0 while srv06hv is 13.3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv04fs&lt;/td&gt;
&lt;td&gt;102d&lt;/td&gt;
&lt;td&gt;6.12.86+deb13&lt;/td&gt;
&lt;td&gt;primary file server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv06hv&lt;/td&gt;
&lt;td&gt;38d&lt;/td&gt;
&lt;td&gt;6.17.9-1-pve&lt;/td&gt;
&lt;td&gt;current&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv05access&lt;/td&gt;
&lt;td&gt;23d&lt;/td&gt;
&lt;td&gt;6.12.47+rpt-rpi-2712&lt;/td&gt;
&lt;td&gt;Debian 13.6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv03mm&lt;/td&gt;
&lt;td&gt;2h&lt;/td&gt;
&lt;td&gt;6.1.0-52&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Debian 12 (bookworm)&lt;/strong&gt; — one major release behind the rest&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="s-15--collector-drops-the-default-zone-producing-false-filtered-verdicts--low-tooling"&gt;S-15 — Collector drops the default zone, producing false &lt;code&gt;filtered&lt;/code&gt; verdicts — Low (tooling)&lt;/h3&gt;
&lt;p&gt;This is a defect in &lt;code&gt;scripts/collect_host_env.py&lt;/code&gt; that affects the correctness of
the deliverable, not a property of the network.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;firewall-cmd --get-active-zones&lt;/code&gt; emits the default zone with an annotation:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public (default)
interfaces: eth0.50 eth0.300 eth0.200 eth0.10 eth0.1 eth0
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and &lt;code&gt;--list-all-zones&lt;/code&gt; heads it &lt;code&gt;public (default, active)&lt;/code&gt;. The parser does not
strip the parenthesised annotation, so:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;section 4.1 &amp;ldquo;Active Zones&amp;rdquo; omits &lt;code&gt;public&lt;/code&gt; entirely on &lt;strong&gt;both&lt;/strong&gt; firewalld hosts;&lt;/li&gt;
&lt;li&gt;section 4.2 therefore omits its effective ports;&lt;/li&gt;
&lt;li&gt;section 5 renders &lt;code&gt;public (default): zone not found&lt;/code&gt; and falls through to a
&lt;code&gt;filtered&lt;/code&gt; verdict;&lt;/li&gt;
&lt;li&gt;the header summary undercounts: srv02gate reports &amp;ldquo;firewalld zones (active) 1&amp;rdquo;
against an actual 2, srv05access &amp;ldquo;3&amp;rdquo; against an actual 4.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Impact on srv02gate: the report claims &lt;strong&gt;3 reachable ports&lt;/strong&gt; and 36 filtered. The
nft ruleset shows 27 accept rules applying to six interfaces; at least 22
listening ports are reachable. The report understates that host&amp;rsquo;s attack surface
by an order of magnitude. Impact on srv05access is smaller (the untagged &lt;code&gt;eth0&lt;/code&gt;
path is missed) because its three custom zones were parsed correctly.&lt;/p&gt;
&lt;p&gt;Suggested fix in the zone-name parser: split on whitespace and discard any
trailing &lt;code&gt;(...)&lt;/code&gt; token, in both the &lt;code&gt;--get-active-zones&lt;/code&gt; and &lt;code&gt;--list-all-zones&lt;/code&gt;
handlers, and treat the default zone as the fallback for any interface not
otherwise assigned. Regression fixture: the &lt;code&gt;fw.active_zones&lt;/code&gt; and
&lt;code&gt;fw.zones_runtime&lt;/code&gt; appendix blocks from
&lt;code&gt;hostenv_srv02gate_20260826T123456Z.md&lt;/code&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="4-firewall-configuration-issues-by-host"&gt;4. Firewall configuration issues, by host&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Host&lt;/th&gt;
&lt;th&gt;Issue&lt;/th&gt;
&lt;th&gt;Findings&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;srv03mm&lt;/td&gt;
&lt;td&gt;No packet filter. Every service on VLAN 200.&lt;/td&gt;
&lt;td&gt;S-01&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv04fs&lt;/td&gt;
&lt;td&gt;No packet filter. Every service on VLAN 200 &lt;strong&gt;and&lt;/strong&gt; VLAN 400.&lt;/td&gt;
&lt;td&gt;S-01, S-10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv02gate&lt;/td&gt;
&lt;td&gt;Six VLANs of differing trust share one permissive zone; 27 allowances of which 4 serve nothing; DMZ correctly restricted, guest/IoT/enclave not; runtime ≠ permanent.&lt;/td&gt;
&lt;td&gt;S-02, S-11&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv05access&lt;/td&gt;
&lt;td&gt;Sound per-VLAN zoning. SSH offered to DMZ and IoT; unauthenticated 9090 to all of VLAN 200; &lt;code&gt;22/udp&lt;/code&gt; allowed for no reason; untagged &lt;code&gt;eth0&lt;/code&gt; in the permissive default zone; runtime ≠ permanent.&lt;/td&gt;
&lt;td&gt;S-04, S-05, S-11&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv01hv&lt;/td&gt;
&lt;td&gt;Correct default-deny. Stale &lt;code&gt;vmbr2nas&lt;/code&gt; rule; SMB/NFS grants on the storage VLAN for services not run; enclave and native VLAN governed only by an unverified ipset; nginx grant on VLAN 200.&lt;/td&gt;
&lt;td&gt;S-07, S-09, S-12&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv06hv&lt;/td&gt;
&lt;td&gt;Correct default-deny. Stale &lt;code&gt;vmbr4nas&lt;/code&gt; and &lt;code&gt;vmbr2iot&lt;/code&gt; rules; no IoT rule at all; same SMB/NFS over-grant; unverified ipset; &lt;code&gt;docker&lt;/code&gt;/&lt;code&gt;hvintrav1&lt;/code&gt; path outside the &lt;code&gt;fwln+&lt;/code&gt; filter; DNS/DHCP/nginx on a hypervisor.&lt;/td&gt;
&lt;td&gt;S-07, S-08, S-09, S-12&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;all&lt;/td&gt;
&lt;td&gt;ICMP redirects accepted and sent, no martian logging, rp_filter off or loose.&lt;/td&gt;
&lt;td&gt;S-06&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Two structural observations across the set:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Three different firewall technologies&lt;/strong&gt; are in use (firewalld/nftables,
PVE/iptables-legacy, and nothing), each with its own default and its own
failure mode. There is no single place to answer &amp;ldquo;who can reach port X&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Two hosts do all the cross-VLAN work&lt;/strong&gt; (srv02gate with six VLANs,
srv05access with four) and both have &lt;code&gt;rp_filter=0&lt;/code&gt; and two default routes.
That combination makes source-based rules unenforceable on exactly the hosts
that most need them.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="5-recommended-actions"&gt;5. Recommended actions&lt;/h2&gt;
&lt;p&gt;Priority is by risk-reduction per unit of effort. Nothing below has been applied;
this engagement is read-only.&lt;/p&gt;
&lt;h3 id="p1--do-first"&gt;P1 — do first&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Fence srv04fs and srv03mm&lt;/strong&gt; (&lt;code&gt;S-01&lt;/code&gt;). Install and enable firewalld on both,
with a default-deny posture, and split VLAN 200 from VLAN 400 on srv04fs.
Concrete configuration in section 6.1. Before that, pin the NFS ephemeral
ports (section 6.1) so the rules can be written at all.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Confirm the TFTP configuration on srv04fs&lt;/strong&gt; (&lt;code&gt;S-10&lt;/code&gt;): read
&lt;code&gt;/etc/default/tftpd-hpa&lt;/code&gt; for the root directory and the &lt;code&gt;-c&lt;/code&gt;/&lt;code&gt;--create&lt;/code&gt; flag.
If write access is enabled, disable it or stop the service pending review.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Split srv02gate&amp;rsquo;s &lt;code&gt;public&lt;/code&gt; zone&lt;/strong&gt; (&lt;code&gt;S-02&lt;/code&gt;). Guest (50), IoT (10) and enclave
(300) must not share a zone with VLAN 200. Concrete configuration in section
6.2. Highest-value single change: move &lt;code&gt;5380/tcp&lt;/code&gt; (DNS admin) and
&lt;code&gt;1812&lt;/code&gt;/&lt;code&gt;1813&lt;/code&gt; (RADIUS) off the guest and IoT interfaces.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Retrieve and review the &lt;code&gt;PVEFW-0-management&lt;/code&gt; ipset&lt;/strong&gt; on both hypervisors
(&lt;code&gt;S-09&lt;/code&gt;): &lt;code&gt;ipset list PVEFW-0-management-v4&lt;/code&gt;. Constrain it to VLAN 2871 and/or
named admin hosts. Add &lt;code&gt;ipset save&lt;/code&gt; to the collector so it is captured in
future runs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Verify &lt;code&gt;/etc/exports&lt;/code&gt;, &lt;code&gt;smb.conf&lt;/code&gt; and &lt;code&gt;sshd_config&lt;/code&gt;&lt;/strong&gt; on srv03mm, srv04fs
and srv05access (&lt;code&gt;S-01&lt;/code&gt;, &lt;code&gt;S-04&lt;/code&gt;, &lt;code&gt;S-10&lt;/code&gt;). These four files determine whether
the exposures above are exploitable, and none was collected.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="p2--next"&gt;P2 — next&lt;/h3&gt;
&lt;ol start="6"&gt;
&lt;li&gt;&lt;strong&gt;Remove SSH from the DMZ and IoT zones on srv05access&lt;/strong&gt; (&lt;code&gt;S-04&lt;/code&gt;), or restrict
it by source to a named jump host. Move &lt;code&gt;eth0&lt;/code&gt; (untagged) out of &lt;code&gt;public&lt;/code&gt; into
&lt;code&gt;drop&lt;/code&gt;. Section 6.3.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Put an authenticating proxy in front of Prometheus, or restrict 9090 by
source&lt;/strong&gt; (&lt;code&gt;S-05&lt;/code&gt;). Bind &lt;code&gt;node_exporter&lt;/code&gt; to a single management address on all
six hosts (&lt;code&gt;--web.listen-address=10.x.x.x:9100&lt;/code&gt;) rather than &lt;code&gt;*&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Apply the sysctl hardening&lt;/strong&gt; in section 6.5 (&lt;code&gt;S-06&lt;/code&gt;), starting with
&lt;code&gt;accept_redirects=0&lt;/code&gt; and &lt;code&gt;log_martians=1&lt;/code&gt;, which are safe everywhere. Defer
&lt;code&gt;rp_filter=1&lt;/code&gt; on srv02gate and srv05access until their duplicate default
routes are resolved.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Prune the Proxmox security groups&lt;/strong&gt; (&lt;code&gt;S-07&lt;/code&gt;): drop the SMB and 2049 entries
from &lt;code&gt;GROUP-nas-IN&lt;/code&gt;, remove the stale interface rules, and add an explicit IoT
rule to srv06hv&amp;rsquo;s node config. Section 6.4.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enable the per-VM firewall on &lt;code&gt;tap106i2&lt;/code&gt;, &lt;code&gt;tap104i2&lt;/code&gt; and &lt;code&gt;tap110i1&lt;/code&gt;&lt;/strong&gt;
(&lt;code&gt;S-08&lt;/code&gt;) — set &lt;code&gt;firewall=1&lt;/code&gt; on those NICs in the guest configs so Proxmox
inserts the &lt;code&gt;fwbr&lt;/code&gt; bridge. &lt;code&gt;tap110i1&lt;/code&gt; on production VLAN 200 first.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Patch and reboot srv02gate, srv01hv and srv04fs&lt;/strong&gt; (&lt;code&gt;S-14&lt;/code&gt;); schedule
srv03mm&amp;rsquo;s Debian 12 → 13 upgrade.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="p3--hygiene-and-hardening"&gt;P3 — hygiene and hardening&lt;/h3&gt;
&lt;ol start="12"&gt;
&lt;li&gt;&lt;strong&gt;Rework the srv06hv docker path&lt;/strong&gt; (&lt;code&gt;S-08&lt;/code&gt;): either rename the veth pair to
match &lt;code&gt;fwln+&lt;/code&gt; so PVE filters it, or detach the &lt;code&gt;docker&lt;/code&gt; bridge from
&lt;code&gt;hvintrav1&lt;/code&gt; and stop nesting VLAN 1 inside VLAN 214.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fix the on-disk configuration defects&lt;/strong&gt; in &lt;code&gt;S-11&lt;/code&gt; — the srv06hv &lt;code&gt;esn2f0.*&lt;/code&gt;
typos are the urgent one, because the storage and DMZ bridges will not come
up correctly from a cold boot.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Run &lt;code&gt;firewall-cmd --runtime-to-permanent&lt;/code&gt;&lt;/strong&gt; (after review) on srv02gate and
srv05access so the audited state survives a reload.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Move nginx off both hypervisors&lt;/strong&gt;, or bind it to &lt;code&gt;127.0.0.1&lt;/code&gt; and drop the
&lt;code&gt;80&lt;/code&gt;/&lt;code&gt;443&lt;/code&gt; grants from &lt;code&gt;GROUP-management-IN&lt;/code&gt; (&lt;code&gt;S-12&lt;/code&gt;). Consider moving
srv06hv&amp;rsquo;s DNS/DHCP role into a VM.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bind loopback-only services explicitly&lt;/strong&gt; rather than relying on the
firewall: &lt;code&gt;rpcbind&lt;/code&gt;, &lt;code&gt;avahi-daemon&lt;/code&gt; and &lt;code&gt;upsd&lt;/code&gt; on srv05access are all
&lt;code&gt;0.0.0.0&lt;/code&gt; and blocked only by firewalld. If firewalld ever fails to start,
they are exposed. &lt;code&gt;rpcbind&lt;/code&gt; can be disabled entirely on hosts that are not
NFS clients or servers.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Document the Xray tunnels&lt;/strong&gt; (&lt;code&gt;S-13&lt;/code&gt;) or remove them.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fix the collector&amp;rsquo;s zone parser&lt;/strong&gt; (&lt;code&gt;S-15&lt;/code&gt;) and re-collect srv03mm and
srv04fs with version 1.1.0 (&lt;code&gt;G-01&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="6-recommended-firewall-configuration"&gt;6. Recommended firewall configuration&lt;/h2&gt;
&lt;p&gt;Reference configurations, not applied. Each assumes the VLAN roles in
&lt;code&gt;Designated VLANs.md&lt;/code&gt;. Substitute your own management CIDR for
&lt;code&gt;&amp;lt;MGMT&amp;gt;&lt;/code&gt; = &lt;code&gt;10.0.1.0/24&lt;/code&gt; (VLAN 2871) and monitoring host
&lt;code&gt;&amp;lt;MON&amp;gt;&lt;/code&gt; = &lt;code&gt;10.1.1.14&lt;/code&gt; (srv05access, the Prometheus server).&lt;/p&gt;
&lt;h3 id="61-srv04fs-and-srv03mm--from-nothing-to-default-deny"&gt;6.1 srv04fs and srv03mm — from nothing to default-deny&lt;/h3&gt;
&lt;p&gt;First make NFS&amp;rsquo;s ports predictable, otherwise no static rule can cover
&lt;code&gt;mountd&lt;/code&gt;/&lt;code&gt;statd&lt;/code&gt;:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# /etc/nfs.conf
[mountd]
port = 20048
[statd]
port = 32765
outgoing-port = 32766
[lockd]
port = 32803
udp-port = 32803
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then, on &lt;strong&gt;srv04fs&lt;/strong&gt; — the point is that VLAN 200 and VLAN 400 get different
policies, which is impossible today:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# storage VLAN 400: file services live here&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --new-zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;storage
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;storage --add-service&lt;span style="color:#f92672"&gt;=&lt;/span&gt;ssh
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;storage --add-service&lt;span style="color:#f92672"&gt;=&lt;/span&gt;nfs
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;storage --add-port&lt;span style="color:#f92672"&gt;=&lt;/span&gt;20048/tcp --add-port&lt;span style="color:#f92672"&gt;=&lt;/span&gt;20048/udp
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;storage --add-port&lt;span style="color:#f92672"&gt;=&lt;/span&gt;32765/tcp --add-port&lt;span style="color:#f92672"&gt;=&lt;/span&gt;32765/udp
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;storage --add-port&lt;span style="color:#f92672"&gt;=&lt;/span&gt;32803/tcp --add-port&lt;span style="color:#f92672"&gt;=&lt;/span&gt;32803/udp
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;storage --add-service&lt;span style="color:#f92672"&gt;=&lt;/span&gt;samba
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;storage --add-rich-rule&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;rule family=ipv4 source address=&amp;lt;MON&amp;gt; port port=9100 protocol=tcp accept&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;storage --change-interface&lt;span style="color:#f92672"&gt;=&lt;/span&gt;ens4f0.400
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# main VLAN 200: administration and SMB clients only, no NFS, no TFTP, no FTP&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --new-zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;srv-main
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;srv-main --add-service&lt;span style="color:#f92672"&gt;=&lt;/span&gt;ssh
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;srv-main --add-service&lt;span style="color:#f92672"&gt;=&lt;/span&gt;samba
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;srv-main --add-rich-rule&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;rule family=ipv4 source address=&amp;lt;MON&amp;gt; port port=9100 protocol=tcp accept&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;srv-main --change-interface&lt;span style="color:#f92672"&gt;=&lt;/span&gt;ens4f0.200
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# the untagged trunk parent gets nothing&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;drop --change-interface&lt;span style="color:#f92672"&gt;=&lt;/span&gt;ens4f0
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --set-default-zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;drop
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --reload
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;TFTP and vsftpd are deliberately absent. If TFTP is genuinely required (network
boot), give it its own zone bound to the one VLAN that needs it and confirm the
service is read-only:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;storage --add-service&lt;span style="color:#f92672"&gt;=&lt;/span&gt;tftp &lt;span style="color:#75715e"&gt;# only if required&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;On &lt;strong&gt;srv03mm&lt;/strong&gt; the same shape, with one VLAN:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --new-zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;srv-main
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;srv-main --add-service&lt;span style="color:#f92672"&gt;=&lt;/span&gt;ssh
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;srv-main --add-service&lt;span style="color:#f92672"&gt;=&lt;/span&gt;samba
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;srv-main --add-port&lt;span style="color:#f92672"&gt;=&lt;/span&gt;8096/tcp &lt;span style="color:#75715e"&gt;# Jellyfin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;srv-main --add-rich-rule&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;rule family=ipv4 source address=10.1.1.13 port port=2049 protocol=tcp accept&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;srv-main --add-rich-rule&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;rule family=ipv4 source address=&amp;lt;MON&amp;gt; port port=9100 protocol=tcp accept&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;srv-main --add-rich-rule&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;rule family=ipv4 source address=&amp;lt;MON&amp;gt; port port=44322 protocol=tcp accept&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;srv-main --change-interface&lt;span style="color:#f92672"&gt;=&lt;/span&gt;enp2s0.200
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;drop --change-interface&lt;span style="color:#f92672"&gt;=&lt;/span&gt;enp2s0
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --set-default-zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;drop
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --reload
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;NFS on srv03mm exists to serve &lt;code&gt;tank/backup-mirror&lt;/code&gt; to srv04fs only, hence the
single-source rich rule rather than &lt;code&gt;--add-service=nfs&lt;/code&gt;. PCP is restricted to the
monitoring host. &lt;code&gt;rpcbind&lt;/code&gt; should be masked if the NFS server is moved to NFSv4-only.&lt;/p&gt;
&lt;h3 id="62-srv02gate--split-public-by-trust-level"&gt;6.2 srv02gate — split &lt;code&gt;public&lt;/code&gt; by trust level&lt;/h3&gt;
&lt;p&gt;The goal: DNS and DHCP everywhere (that is the host&amp;rsquo;s job), everything else only
where it belongs.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 1. A zone for the least-trusted segments: resolver and addressing only.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --new-zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;untrusted
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;untrusted --set-target&lt;span style="color:#f92672"&gt;=&lt;/span&gt;DROP
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;untrusted --add-service&lt;span style="color:#f92672"&gt;=&lt;/span&gt;dns
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;untrusted --add-service&lt;span style="color:#f92672"&gt;=&lt;/span&gt;dhcp
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;untrusted --change-interface&lt;span style="color:#f92672"&gt;=&lt;/span&gt;eth0.50 &lt;span style="color:#75715e"&gt;# guest&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;untrusted --change-interface&lt;span style="color:#f92672"&gt;=&lt;/span&gt;eth0.10 &lt;span style="color:#75715e"&gt;# IoT&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;untrusted --change-interface&lt;span style="color:#f92672"&gt;=&lt;/span&gt;eth0.300 &lt;span style="color:#75715e"&gt;# enclave&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 2. The DMZ keeps its current, correct policy.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# (block/eth0.1024 with dns+dhcp — unchanged)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 3. VLAN 200: administration and the published web services.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --new-zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;infra
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;infra --add-service&lt;span style="color:#f92672"&gt;=&lt;/span&gt;dns
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;infra --add-service&lt;span style="color:#f92672"&gt;=&lt;/span&gt;dhcp
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;infra --add-service&lt;span style="color:#f92672"&gt;=&lt;/span&gt;http
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;infra --add-service&lt;span style="color:#f92672"&gt;=&lt;/span&gt;https
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;infra --add-rich-rule&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;rule family=ipv4 source address=&amp;lt;MGMT&amp;gt; service name=ssh accept&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;infra --add-rich-rule&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;rule family=ipv4 source address=&amp;lt;MGMT&amp;gt; port port=5380 protocol=tcp accept&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;infra --add-rich-rule&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;rule family=ipv4 source address=&amp;lt;MON&amp;gt; port port=9100 protocol=tcp accept&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;infra --change-interface&lt;span style="color:#f92672"&gt;=&lt;/span&gt;eth0.200
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 4. VLAN 1 / native: the network-equipment management plane.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Restrict RADIUS and the UniFi ports to the switch/AP subnet only.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --new-zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;netmgmt
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;netmgmt --set-target&lt;span style="color:#f92672"&gt;=&lt;/span&gt;DROP
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;netmgmt --add-service&lt;span style="color:#f92672"&gt;=&lt;/span&gt;dns
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;netmgmt --add-service&lt;span style="color:#f92672"&gt;=&lt;/span&gt;dhcp
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;netmgmt --add-rich-rule&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;rule family=ipv4 source address=10.0.2.0/24 service name=radius accept&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;netmgmt --add-rich-rule&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;rule family=ipv4 source address=10.0.2.0/24 port port=8080 protocol=tcp accept&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;netmgmt --add-rich-rule&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;rule family=ipv4 source address=10.0.2.0/24 port port=3478 protocol=udp accept&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;netmgmt --add-rich-rule&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;rule family=ipv4 source address=10.0.2.0/24 port port=5514 protocol=udp accept&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;netmgmt --add-rich-rule&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;rule family=ipv4 source address=&amp;lt;MGMT&amp;gt; port port=8443 protocol=tcp accept&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;netmgmt --change-interface&lt;span style="color:#f92672"&gt;=&lt;/span&gt;eth0.1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;drop --change-interface&lt;span style="color:#f92672"&gt;=&lt;/span&gt;eth0
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 5. Retire the blanket allowances entirely.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;public --remove-port&lt;span style="color:#f92672"&gt;=&lt;/span&gt;22/udp
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;public --remove-port&lt;span style="color:#f92672"&gt;=&lt;/span&gt;1900/udp
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;public --remove-port&lt;span style="color:#f92672"&gt;=&lt;/span&gt;8843/tcp
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;public --remove-port&lt;span style="color:#f92672"&gt;=&lt;/span&gt;27117/tcp
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;public --remove-port&lt;span style="color:#f92672"&gt;=&lt;/span&gt;5671/tcp
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;public --remove-port&lt;span style="color:#f92672"&gt;=&lt;/span&gt;6789/tcp
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;public --remove-port&lt;span style="color:#f92672"&gt;=&lt;/span&gt;8880-8882/tcp
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;public --remove-port&lt;span style="color:#f92672"&gt;=&lt;/span&gt;11443/tcp
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;public --remove-port&lt;span style="color:#f92672"&gt;=&lt;/span&gt;5380/tcp
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;public --remove-service&lt;span style="color:#f92672"&gt;=&lt;/span&gt;radius
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;public --remove-service&lt;span style="color:#f92672"&gt;=&lt;/span&gt;prometheus-node-exporter
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;public --remove-service&lt;span style="color:#f92672"&gt;=&lt;/span&gt;ssh
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --set-default-zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;drop
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --reload
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note the substantive decisions embedded above: the UniFi controller&amp;rsquo;s
device-facing ports are opened only towards the subnet where switches and APs
live (&lt;code&gt;10.0.2.0/24&lt;/code&gt;, VLAN 1); its admin UI (&lt;code&gt;8443&lt;/code&gt;) and the DNS admin console
(&lt;code&gt;5380&lt;/code&gt;) only towards the management network; RADIUS only towards the
authenticators, never towards clients. &lt;code&gt;27117&lt;/code&gt; (MongoDB) is removed outright.
&lt;code&gt;8880-8882&lt;/code&gt; (UniFi guest portal HTTP/HTTPS redirect) is the one case where a
guest-facing allowance may be genuinely required — if so, add it back to
&lt;code&gt;untrusted&lt;/code&gt; explicitly rather than leaving the whole zone open.&lt;/p&gt;
&lt;p&gt;Verify afterwards with the same evidence path used in this audit:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;nft list chain inet firewalld filter_IN_untrusted_allow
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --get-active-zones
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="63-srv05access--tighten-the-choke-host"&gt;6.3 srv05access — tighten the choke host&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# DMZ and IoT get no SSH; if a break-glass path is needed, pin it by source.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;dmz --remove-service&lt;span style="color:#f92672"&gt;=&lt;/span&gt;ssh
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;restrict-ssh-only --remove-service&lt;span style="color:#f92672"&gt;=&lt;/span&gt;ssh
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;restrict-ssh-only --add-rich-rule&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;rule family=ipv4 source address=&amp;lt;MGMT&amp;gt; service name=ssh accept&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Prometheus by source, not by VLAN.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;restrict-regular --remove-service&lt;span style="color:#f92672"&gt;=&lt;/span&gt;prometheus
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;restrict-regular --add-rich-rule&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;rule family=ipv4 source address=&amp;lt;MGMT&amp;gt; port port=9090 protocol=tcp accept&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# SSH on VLAN 200 by source as well.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;restrict-regular --remove-service&lt;span style="color:#f92672"&gt;=&lt;/span&gt;ssh
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;restrict-regular --add-rich-rule&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;rule family=ipv4 source address=&amp;lt;MGMT&amp;gt; service name=ssh accept&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# The untagged trunk parent should carry no host services.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;drop --change-interface&lt;span style="color:#f92672"&gt;=&lt;/span&gt;eth0
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;public --remove-port&lt;span style="color:#f92672"&gt;=&lt;/span&gt;22/udp
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --permanent --set-default-zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;drop
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;firewall-cmd --reload
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then bind the services that are currently protected only by the firewall:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# rpcbind: disable if not required, else
systemctl mask rpcbind.socket rpcbind.service
# avahi-daemon
/etc/avahi/avahi-daemon.conf: allow-interfaces=eth0.200
# NUT upsd
/etc/nut/upsd.conf: LISTEN 127.0.0.1 3493
# node_exporter
ExecStart=... --web.listen-address=10.1.1.14:9100
# Prometheus
ExecStart=... --web.listen-address=127.0.0.1:9090 # front with authenticating proxy
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="64-srv01hv-and-srv06hv--proxmox-security-groups"&gt;6.4 srv01hv and srv06hv — Proxmox security groups&lt;/h3&gt;
&lt;p&gt;Datacenter → Firewall → Security Group. Replace &lt;code&gt;GROUP-nas-IN&lt;/code&gt; with a version
matching what the hypervisors actually do on VLAN 400 (they are NFS/CIFS
&lt;em&gt;clients&lt;/em&gt;):&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# GROUP-nas-IN — hypervisor is a client, not a server
IN ACCEPT -source 10.255.255.0/24 -p tcp -dport 22 # admin
IN ACCEPT -p udp -dport 67:68 # DHCP
# remove: 111, 2049, 135, 137-139, 445
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;GROUP-management-IN&lt;/code&gt; — drop the web server grants once nginx is bound to
loopback (&lt;code&gt;S-12&lt;/code&gt;):&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;IN ACCEPT -p udp -dport 67:68
IN ACCEPT -p tcp -dport 53
IN ACCEPT -p udp -dport 53
IN ACCEPT -source &amp;lt;MGMT&amp;gt; -p tcp -dport 22
# remove: 80/tcp, 443/tcp, unrestricted 22/tcp
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Per-node Firewall → set the interface→group bindings to the bridges that exist on
that node, and add the missing IoT binding on srv06hv:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Node&lt;/th&gt;
&lt;th&gt;Binding&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;srv01hv&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vmbr4nas&lt;/code&gt;→nas, &lt;code&gt;vmbr2iot&lt;/code&gt;→dmz-external, &lt;code&gt;vmbr10ext&lt;/code&gt;→dmz-external, &lt;code&gt;vmbr1plc&lt;/code&gt;→management, &lt;code&gt;vmbr0vm&lt;/code&gt;+&lt;code&gt;hvintra&lt;/code&gt;→pve-basic, &lt;code&gt;vmbr3sec&lt;/code&gt;→&lt;strong&gt;new&lt;/strong&gt; &lt;code&gt;GROUP-enclave-IN&lt;/code&gt; (currently default-deny by accident)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv06hv&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vmbr2nas&lt;/code&gt;→nas, &lt;code&gt;vmbr10ext&lt;/code&gt;→dmz-external, &lt;code&gt;vmbr1plc&lt;/code&gt;→management, &lt;code&gt;vmbr0vm&lt;/code&gt;+&lt;code&gt;hvintra&lt;/code&gt;→pve-basic, &lt;code&gt;docker&lt;/code&gt;/&lt;code&gt;hvintrav1&lt;/code&gt;→&lt;strong&gt;explicit DROP&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Datacenter → Firewall → Alias/IPSet &lt;code&gt;management&lt;/code&gt;: restrict to the VLAN 2871
range and/or named admin hosts, and confirm with &lt;code&gt;ipset list PVEFW-0-management-v4&lt;/code&gt; that it does not contain a production CIDR.&lt;/p&gt;
&lt;p&gt;Per-VM: set &lt;code&gt;firewall=1&lt;/code&gt; on &lt;code&gt;net&lt;/code&gt; entries &lt;code&gt;106:net2&lt;/code&gt; (srv01hv), &lt;code&gt;104:net2&lt;/code&gt; and
&lt;code&gt;110:net1&lt;/code&gt; (srv06hv) so their taps move behind &lt;code&gt;fwbr*&lt;/code&gt; bridges.&lt;/p&gt;
&lt;h3 id="65-estate-wide-sysctl-baseline"&gt;6.5 Estate-wide sysctl baseline&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;/etc/sysctl.d/60-net-harden.conf&lt;/code&gt; on all six hosts:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# Reject route injection
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.default.secure_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.default.accept_redirects = 0
# Do not emit redirects (none of these hosts routes: ip_forward=0)
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
# Source-address validation
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# Visibility
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.default.log_martians = 1
# Already correct everywhere — pin it
net.ipv4.conf.all.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Caveat on &lt;code&gt;rp_filter&lt;/code&gt;.&lt;/strong&gt; Strict mode (&lt;code&gt;1&lt;/code&gt;) will drop legitimate traffic on
srv02gate and srv05access while each carries two default routes, and may affect
the hypervisors&amp;rsquo; multi-bridge paths. Sequence: apply &lt;code&gt;accept_redirects&lt;/code&gt;,
&lt;code&gt;send_redirects&lt;/code&gt; and &lt;code&gt;log_martians&lt;/code&gt; first (safe on all six); then resolve the
duplicate default routes on srv02gate and srv05access; then move those two and
the hypervisors from &lt;code&gt;rp_filter=2&lt;/code&gt; to &lt;code&gt;1&lt;/code&gt;, verifying with &lt;code&gt;log_martians&lt;/code&gt; output
before and after. Do not set &lt;code&gt;net.ipv4.ip_forward=1&lt;/code&gt; on any of these hosts — the
current &lt;code&gt;0&lt;/code&gt; is a meaningful control given how many VLANs they each terminate.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="7-evidence-gaps"&gt;7. Evidence gaps&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ID&lt;/th&gt;
&lt;th&gt;Gap&lt;/th&gt;
&lt;th&gt;Effect&lt;/th&gt;
&lt;th&gt;Close by&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;G-01&lt;/td&gt;
&lt;td&gt;srv03mm and srv04fs were collected with &lt;code&gt;collect_host_env.py&lt;/code&gt; &lt;strong&gt;1.0.0&lt;/strong&gt;, which captured no &lt;code&gt;nft&lt;/code&gt;/&lt;code&gt;iptables&lt;/code&gt; output; their firewall state is inferred, not observed&lt;/td&gt;
&lt;td&gt;&lt;code&gt;S-01&lt;/code&gt; rests on an assumption. If a hand-written ruleset exists, the severity drops sharply&lt;/td&gt;
&lt;td&gt;Re-run with 1.1.0: &lt;code&gt;./collect_host_env.py srv03mm srv04fs&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;G-02&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PVEFW-0-management-v4/-v6&lt;/code&gt; ipset contents never collected&lt;/td&gt;
&lt;td&gt;The most privileged access control on both hypervisors is unverified (&lt;code&gt;S-09&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ipset list PVEFW-0-management-v4&lt;/code&gt;; add &lt;code&gt;ipset save&lt;/code&gt; to the collector&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;G-03&lt;/td&gt;
&lt;td&gt;srv05access&amp;rsquo;s &lt;code&gt;fw.nft&lt;/code&gt; appendix is truncated (&amp;ldquo;857 more lines&amp;rdquo;)&lt;/td&gt;
&lt;td&gt;Its custom zone chains could not be verified against the zone tables; verdicts for that host rest on &lt;code&gt;firewall-cmd&lt;/code&gt; output alone&lt;/td&gt;
&lt;td&gt;Re-collect, or raise the appendix truncation limit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;G-04&lt;/td&gt;
&lt;td&gt;Service configuration files not collected: &lt;code&gt;/etc/exports&lt;/code&gt;, &lt;code&gt;smb.conf&lt;/code&gt;, &lt;code&gt;sshd_config&lt;/code&gt;, &lt;code&gt;/etc/default/tftpd-hpa&lt;/code&gt;, &lt;code&gt;vsftpd.conf&lt;/code&gt;, &lt;code&gt;prometheus.yml&lt;/code&gt;, Xray configs&lt;/td&gt;
&lt;td&gt;Determines whether &lt;code&gt;S-01&lt;/code&gt;, &lt;code&gt;S-04&lt;/code&gt;, &lt;code&gt;S-05&lt;/code&gt;, &lt;code&gt;S-10&lt;/code&gt; and &lt;code&gt;S-13&lt;/code&gt; are exploitable or merely present&lt;/td&gt;
&lt;td&gt;Add a read-only &lt;code&gt;cfg.*&lt;/code&gt; collector group&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;G-05&lt;/td&gt;
&lt;td&gt;No process-level TLS/credential inspection; no view of the nginx vhost configuration on srv02gate, srv01hv, srv06hv&lt;/td&gt;
&lt;td&gt;The published web surface (four &lt;code&gt;443&lt;/code&gt; vhosts on srv02gate) is unmapped&lt;/td&gt;
&lt;td&gt;Out of scope for host-env collection; needs a separate config review&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;G-06&lt;/td&gt;
&lt;td&gt;srv02gate&amp;rsquo;s podman containers were enumerated by published port only (&lt;code&gt;pasta&lt;/code&gt;, &lt;code&gt;podman-250104.scope&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Container images, versions and internal exposure unknown&lt;/td&gt;
&lt;td&gt;&lt;code&gt;podman ps --format json&lt;/code&gt;, &lt;code&gt;podman image ls&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;code&gt;S-15&lt;/code&gt; is a defect rather than a gap, but it has the same effect on the
deliverable: any conclusion previously drawn from section 5 of the two firewalld
reports should be re-derived from &lt;code&gt;fw.nft&lt;/code&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="8-method-note"&gt;8. Method note&lt;/h2&gt;
&lt;p&gt;Derivation for each verdict in section 2:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;firewalld hosts&lt;/strong&gt; — &lt;code&gt;fw.active_zones&lt;/code&gt; for interface→zone binding, then the
matching &lt;code&gt;filter_IN_&amp;lt;zone&amp;gt;_allow&lt;/code&gt; chain in &lt;code&gt;fw.nft&lt;/code&gt; for the accepted port set,
cross-checked against &lt;code&gt;fw.zones_runtime&lt;/code&gt; and &lt;code&gt;fw.zones_permanent&lt;/code&gt;. The
&lt;code&gt;filter_INPUT&lt;/code&gt; chain was confirmed to end in &lt;code&gt;reject with icmpx admin-prohibited&lt;/code&gt; on both hosts, so unmatched traffic is denied.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Proxmox hosts&lt;/strong&gt; — &lt;code&gt;fw.iptables&lt;/code&gt; &lt;code&gt;PVEFW-HOST-IN&lt;/code&gt;, walked top to bottom:
interface rules jump to a &lt;code&gt;GROUP-*-IN&lt;/code&gt; chain, which sets the accept mark via
&lt;code&gt;PVEFW-SET-ACCEPT-MARK&lt;/code&gt;; a following &lt;code&gt;-m mark --mark 0x80000000 -j RETURN&lt;/code&gt;
releases marked packets. Interfaces with no rule fall through to the
&lt;code&gt;PVEFW-0-management&lt;/code&gt; ipset rules and then &lt;code&gt;PVEFW-Drop&lt;/code&gt;/&lt;code&gt;DROP&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;srv03mm, srv04fs&lt;/strong&gt; — no ruleset exists in the collection; stated as an
assumption (&lt;code&gt;G-01&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Listening sockets&lt;/strong&gt; — section 3 of each report, which derives from
&lt;code&gt;svc.ss&lt;/code&gt; (&lt;code&gt;ss -tulpnH&lt;/code&gt;) plus &lt;code&gt;svc.pidinfo&lt;/code&gt;/&lt;code&gt;svc.dpkg&lt;/code&gt; for process attribution.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;VLAN and interface facts&lt;/strong&gt; — sections 2.1–2.6, corroborated against
&lt;code&gt;audit-report/NETWORK_TOPOLOGY.md&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;No host was contacted and no packet was sent in the production of this document.&lt;/p&gt;</description></item><item><title>Network Topology Report</title><link>https://vox.app.home/posts/private/intranet/network_topology/</link><pubDate>Mon, 31 Aug 2026 13:00:00 +0000</pubDate><guid>https://vox.app.home/posts/private/intranet/network_topology/</guid><description>&lt;h1 id="network-topology--srv-hosts"&gt;Network Topology — &lt;code&gt;srv*&lt;/code&gt; Hosts&lt;/h1&gt;
&lt;p&gt;Reconstructed switch/port/VLAN topology for the six &lt;code&gt;srv*&lt;/code&gt; machines.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Scope&lt;/td&gt;
&lt;td&gt;&lt;code&gt;srv01hv&lt;/code&gt;, &lt;code&gt;srv02gate&lt;/code&gt;, &lt;code&gt;srv03mm&lt;/code&gt;, &lt;code&gt;srv04fs&lt;/code&gt;, &lt;code&gt;srv05access&lt;/code&gt;, &lt;code&gt;srv06hv&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sources&lt;/td&gt;
&lt;td&gt;&lt;code&gt;host-env-scan/hostenv_srv*.md&lt;/code&gt; — sections 2.1–2.6 and the raw &lt;code&gt;net.lldp&lt;/code&gt; (&lt;code&gt;lldpctl -f json&lt;/code&gt;) appendix entries; &lt;code&gt;Designated VLANs.md&lt;/code&gt; for VLAN roles and designated ranges&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Method&lt;/td&gt;
&lt;td&gt;On-host inspection only (read-only). No switch was logged into, no scanning was performed for this document.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Collection window (UTC)&lt;/td&gt;
&lt;td&gt;2026-08-25 23:05 → 2026-08-26 12:35&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Revision&lt;/td&gt;
&lt;td&gt;2 — re-collected srv01hv and srv02gate folded in; VLAN roles reconciled against &lt;code&gt;Designated VLANs.md&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Source report files:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Host&lt;/th&gt;
&lt;th&gt;Report&lt;/th&gt;
&lt;th&gt;Collected (UTC)&lt;/th&gt;
&lt;th&gt;Privilege&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;srv01hv&lt;/td&gt;
&lt;td&gt;&lt;code&gt;hostenv_srv01hv_20260826T123515Z.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;2026-08-26 12:35&lt;/td&gt;
&lt;td&gt;connected as root&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv02gate&lt;/td&gt;
&lt;td&gt;&lt;code&gt;hostenv_srv02gate_20260826T123456Z.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;2026-08-26 12:34&lt;/td&gt;
&lt;td&gt;passwordless sudo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv03mm&lt;/td&gt;
&lt;td&gt;&lt;code&gt;hostenv_srv03mm_20260825T230531Z.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;2026-08-25 23:05&lt;/td&gt;
&lt;td&gt;sudo via password&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv04fs&lt;/td&gt;
&lt;td&gt;&lt;code&gt;hostenv_srv04fs_20260825T230503Z.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;2026-08-25 23:05&lt;/td&gt;
&lt;td&gt;sudo via password&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv05access&lt;/td&gt;
&lt;td&gt;&lt;code&gt;hostenv_srv05access_20260825T231718Z.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;2026-08-25 23:17&lt;/td&gt;
&lt;td&gt;sudo via password&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv06hv&lt;/td&gt;
&lt;td&gt;&lt;code&gt;hostenv_srv06hv_20260826T121246Z.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;2026-08-26 12:12&lt;/td&gt;
&lt;td&gt;sudo via password&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;What the re-collection changed.&lt;/strong&gt; srv02gate&amp;rsquo;s LLDP table is now populated,
which resolves the largest gap in revision 1 (finding T-02) and places the last
unattached host on a known switch port. srv01hv was re-run as root and its
&lt;code&gt;net.lldp&lt;/code&gt; appendix is no longer truncated (finding T-08), but its 10G &lt;code&gt;eth0p0&lt;/code&gt;
link still reports &lt;strong&gt;no&lt;/strong&gt; LLDP neighbour — so T-01 stays open, and the absence is
now attributable to the peer rather than to insufficient privilege. Interface,
VLAN and address data for both hosts are otherwise byte-identical to revision 1;
no address or VLAN changed.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="1-switches"&gt;1. Switches&lt;/h2&gt;
&lt;p&gt;Identified purely from LLDP chassis TLVs received by the hosts.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Switch&lt;/th&gt;
&lt;th&gt;Model / descr&lt;/th&gt;
&lt;th&gt;Chassis MAC&lt;/th&gt;
&lt;th&gt;Management IP&lt;/th&gt;
&lt;th&gt;Capabilities&lt;/th&gt;
&lt;th&gt;Observed from&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;TL-SE5226&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;TP-Link, &lt;code&gt;24*2.5GE+2SFP+ L3 Managed Switch&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;24:5a:5f:9b:fd:01&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.1.1.3&lt;/code&gt; (mgmt-iface VLAN &lt;code&gt;200&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Bridge + &lt;strong&gt;Router&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;srv01hv, &lt;strong&gt;srv02gate&lt;/strong&gt;, srv03mm, srv05access&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;USW-Aggregation&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Ubiquiti, &lt;code&gt;UBNT-USL8A&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0c:ea:14:bf:29:3f&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.0.2.6&lt;/code&gt;, &lt;code&gt;fe80::eea:14ff:febf:293f&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Bridge only&lt;/td&gt;
&lt;td&gt;srv04fs, srv06hv&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Four TL-SE5226 access ports are now accounted for (&lt;code&gt;TG1/0/4&lt;/code&gt;, &lt;code&gt;TG1/0/6&lt;/code&gt;,
&lt;code&gt;TG1/0/18&lt;/code&gt;, &lt;code&gt;TG1/0/20&lt;/code&gt;) and two USW-Aggregation SFP+ ports (&lt;code&gt;Port 4&lt;/code&gt;, &lt;code&gt;Port 6&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;&lt;code&gt;10.1.1.3&lt;/code&gt; is simultaneously the TL-SE5226&amp;rsquo;s management address and the VLAN 200
default gateway of srv01hv, srv03mm, srv04fs, srv05access and srv06hv — the
TL-SE5226 is therefore the L3 edge for VLAN 200.&lt;/p&gt;
&lt;p&gt;An &lt;strong&gt;inter-switch trunk must exist&lt;/strong&gt;, on three independent grounds:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;srv04fs and srv06hv attach to the L2-only USW-Aggregation yet route VLAN 200
through &lt;code&gt;10.1.1.3&lt;/code&gt; on the TL-SE5226.&lt;/li&gt;
&lt;li&gt;VLAN 1024 (DMZ) is live on hosts attached to both switches.&lt;/li&gt;
&lt;li&gt;The USW-Aggregation&amp;rsquo;s own management address &lt;code&gt;10.0.2.6&lt;/code&gt; sits in VLAN 1
&lt;code&gt;10.0.2.0/24&lt;/code&gt;, the same subnet as srv02gate&amp;rsquo;s &lt;code&gt;eth0.1&lt;/code&gt; &lt;code&gt;10.0.2.3&lt;/code&gt; — and
srv02gate is now confirmed to hang off the TL-SE5226 (&lt;code&gt;TG1/0/18&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The trunk link itself was still not directly observed; no host sits on it.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="2-host--switch--port--vlan"&gt;2. Host → switch → port → VLAN&lt;/h2&gt;
&lt;p&gt;Uplinks with a live carrier, and the VLANs each one trunks.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Host&lt;/th&gt;
&lt;th&gt;Hardware / OS&lt;/th&gt;
&lt;th&gt;Uplink NIC (driver, Mb/s)&lt;/th&gt;
&lt;th&gt;MAC&lt;/th&gt;
&lt;th&gt;Switch&lt;/th&gt;
&lt;th&gt;Port&lt;/th&gt;
&lt;th&gt;Port description&lt;/th&gt;
&lt;th&gt;VLANs advertised by port&lt;/th&gt;
&lt;th&gt;VLANs configured on host&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;srv01hv&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Minisforum MS-A2, Debian 13 / PVE 6.14.8&lt;/td&gt;
&lt;td&gt;&lt;code&gt;enp3s0&lt;/code&gt; (r8169, 2500)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;38:05:25:33:67:cf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;TL-SE5226&lt;/td&gt;
&lt;td&gt;&lt;code&gt;TG1/0/4&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;TG1/0/4 Interface&lt;/td&gt;
&lt;td&gt;10 (System-VLAN), 1 (pvid)&lt;/td&gt;
&lt;td&gt;10, 200, 300&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;srv01hv&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&amp;quot;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;eth0p0&lt;/code&gt; (i40e, 10000)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;38:05:25:33:67:d2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;no LLDP neighbour&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;204, 214, 400, 1024&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;srv02gate&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Raspberry Pi (&lt;code&gt;rpi-v8&lt;/code&gt;), Debian 13&lt;/td&gt;
&lt;td&gt;&lt;code&gt;eth0&lt;/code&gt; (bcmgenet, 1000)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;d8:3a:dd:99:8b:43&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;TL-SE5226&lt;/td&gt;
&lt;td&gt;&lt;code&gt;TG1/0/18&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;TG1/0/18 Interface&lt;/td&gt;
&lt;td&gt;1 (pvid, System-VLAN)&lt;/td&gt;
&lt;td&gt;1, 10, 50, 200, 300, 1024&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;srv03mm&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;UGREEN DXP2800, Debian 12&lt;/td&gt;
&lt;td&gt;&lt;code&gt;enp2s0&lt;/code&gt; (igc, 2500)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;6c:1f:f7:56:8e:da&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;TL-SE5226&lt;/td&gt;
&lt;td&gt;&lt;code&gt;TG1/0/6&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;TG1/0/6 Interface&lt;/td&gt;
&lt;td&gt;200 (System-VLAN), 1 (pvid)&lt;/td&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;srv04fs&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Dell PowerEdge T360, Debian 13&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ens4f0&lt;/code&gt; (bnx2x, 10000)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;98:b7:85:21:4a:69&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;USW-Aggregation&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Port 4&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SFP_ 4&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1 (pvid)&lt;/td&gt;
&lt;td&gt;200, 400&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;srv05access&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Raspberry Pi 5 (&lt;code&gt;rpi-2712&lt;/code&gt;), Debian 13&lt;/td&gt;
&lt;td&gt;&lt;code&gt;eth0&lt;/code&gt; (macb, 1000)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;d8:3a:dd:c5:13:da&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;TL-SE5226&lt;/td&gt;
&lt;td&gt;&lt;code&gt;TG1/0/20&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;TG1/0/20 Interface&lt;/td&gt;
&lt;td&gt;10 (System-VLAN), 1 (pvid)&lt;/td&gt;
&lt;td&gt;10, 200, 1024, &lt;strong&gt;2871&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;srv06hv&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Dell PowerEdge R740xd, Debian 13 / PVE 6.17.9&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ens2f0&lt;/code&gt; (qede, 10000)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;f4:c7:aa:57:15:98&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;USW-Aggregation&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Port 6&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SFP_ 6&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1 (pvid)&lt;/td&gt;
&lt;td&gt;200, 204, 214, 214.1, 400, 1024&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;srv05access negotiated &lt;code&gt;1000BaseTFD&lt;/code&gt; on &lt;code&gt;TG1/0/20&lt;/code&gt;; all TL-SE5226 ports report
&lt;code&gt;mfs 9216&lt;/code&gt;. &lt;code&gt;eth0p0&lt;/code&gt; on srv01hv is the only live uplink in the estate whose
switch and port remain unidentified (T-01).&lt;/p&gt;
&lt;h3 id="interfaces-with-no-switch-attachment-carrier-down"&gt;Interfaces with no switch attachment (carrier down)&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Host&lt;/th&gt;
&lt;th&gt;Interfaces&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;srv01hv&lt;/td&gt;
&lt;td&gt;&lt;code&gt;enp4s0&lt;/code&gt; (igc), &lt;code&gt;enp5s0f0np0&lt;/code&gt; (i40e), &lt;code&gt;wlp6s0&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv02gate&lt;/td&gt;
&lt;td&gt;&lt;code&gt;wlan0&lt;/code&gt; (brcmfmac)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv04fs&lt;/td&gt;
&lt;td&gt;&lt;code&gt;eno8303&lt;/code&gt;, &lt;code&gt;eno8403&lt;/code&gt; (tg3), &lt;code&gt;ens4f1&lt;/code&gt; (bnx2x)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv05access&lt;/td&gt;
&lt;td&gt;&lt;code&gt;wlan0&lt;/code&gt; (brcmfmac)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv06hv&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ens2f1&lt;/code&gt;, &lt;code&gt;ens2f2&lt;/code&gt;, &lt;code&gt;ens2f3&lt;/code&gt; (qede), &lt;code&gt;nic0&lt;/code&gt;–&lt;code&gt;nic3&lt;/code&gt; (igb)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="3-per-host-vlan--interface--address-mapping"&gt;3. Per-host VLAN → interface → address mapping&lt;/h2&gt;
&lt;h3 id="srv01hv-proxmox-dual-homed-25g--10g"&gt;srv01hv (Proxmox, dual-homed 2.5G + 10G)&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;VLAN&lt;/th&gt;
&lt;th&gt;VLAN iface&lt;/th&gt;
&lt;th&gt;Parent&lt;/th&gt;
&lt;th&gt;Bridge&lt;/th&gt;
&lt;th&gt;Address&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;&lt;code&gt;enp3s0.10&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;enp3s0&lt;/code&gt; (TL-SE5226 TG1/0/4)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vmbr2iot&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;172.17.1.6/16&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;&lt;code&gt;enp3s0.200&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;enp3s0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vmbr1plc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.1.1.11/20&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;300&lt;/td&gt;
&lt;td&gt;&lt;code&gt;enp3s0.300&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;enp3s0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vmbr3sec&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.10.1.2/20&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;204&lt;/td&gt;
&lt;td&gt;&lt;code&gt;eth0p0.204&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;eth0p0&lt;/code&gt; (switch unknown)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vmbr0vm&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.128.128.20/24&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;214&lt;/td&gt;
&lt;td&gt;&lt;code&gt;eth0p0.214&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;eth0p0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;hvintra&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.129.0.2/24&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;400&lt;/td&gt;
&lt;td&gt;&lt;code&gt;eth0p0.400&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;eth0p0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vmbr4nas&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.255.255.7/24&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1024&lt;/td&gt;
&lt;td&gt;&lt;code&gt;eth0p0.1024&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;eth0p0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vmbr10ext&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;172.16.1.6/16&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Default route: &lt;code&gt;10.1.1.3&lt;/code&gt; via &lt;code&gt;vmbr1plc&lt;/code&gt;. Guest fan-out via Proxmox
&lt;code&gt;fwbr&amp;lt;vmid&amp;gt;i&amp;lt;n&amp;gt;&lt;/code&gt; / &lt;code&gt;fwln&lt;/code&gt; / &lt;code&gt;fwpr&lt;/code&gt; veth pairs and &lt;code&gt;tap&amp;lt;vmid&amp;gt;i&amp;lt;n&amp;gt;&lt;/code&gt; into
&lt;code&gt;vmbr0vm&lt;/code&gt;, &lt;code&gt;vmbr1plc&lt;/code&gt;, &lt;code&gt;vmbr2iot&lt;/code&gt;, &lt;code&gt;vmbr4nas&lt;/code&gt; (VMs 105, 106, 107).&lt;/p&gt;
&lt;h3 id="srv06hv-proxmox-single-10g-uplink"&gt;srv06hv (Proxmox, single 10G uplink)&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;VLAN&lt;/th&gt;
&lt;th&gt;VLAN iface&lt;/th&gt;
&lt;th&gt;Bridge&lt;/th&gt;
&lt;th&gt;Address&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ens2f0.200&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vmbr1plc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.1.1.15/20&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;204&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ens2f0.204&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vmbr0vm&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.128.128.2/24&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;214&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ens2f0.214&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;hvintra&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.129.0.1/24&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1 (over 214)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ens2f0.214.1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;hvintrav1&lt;/code&gt; → &lt;code&gt;docker&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;none&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;400&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ens2f0.400&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vmbr2nas&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.255.255.1/24&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1024&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ens2f0.1024&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vmbr10ext&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;172.16.1.3/16&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Default route: &lt;code&gt;10.1.1.3&lt;/code&gt; via &lt;code&gt;vmbr1plc&lt;/code&gt;. Guest fan-out for VMs 100, 101, 102,
103, 104, 110, 112 plus a &lt;code&gt;ln_docker&lt;/code&gt;/&lt;code&gt;pr_docker&lt;/code&gt; veth pair into &lt;code&gt;hvintrav1&lt;/code&gt;.
&lt;code&gt;ens2f0.214.1&lt;/code&gt; is a &lt;strong&gt;double-tagged (802.1Q-in-Q) stack&lt;/strong&gt;: VLAN 1 nested inside
VLAN 214. srv06hv carries &lt;strong&gt;no VLAN 10 (IoT)&lt;/strong&gt; interface.&lt;/p&gt;
&lt;h3 id="srv02gate-router-ish-pi-6-vlans-on-one-1g-link"&gt;srv02gate (router-ish Pi, 6 VLANs on one 1G link)&lt;/h3&gt;
&lt;p&gt;Uplink: &lt;code&gt;eth0&lt;/code&gt; → TL-SE5226 &lt;code&gt;TG1/0/18&lt;/code&gt;.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;VLAN&lt;/th&gt;
&lt;th&gt;VLAN iface&lt;/th&gt;
&lt;th&gt;Address&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;code&gt;eth0.1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.0.2.3/24&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;DHCP, gw &lt;code&gt;10.0.2.1&lt;/code&gt;; same subnet as USW mgmt &lt;code&gt;10.0.2.6&lt;/code&gt;; &lt;strong&gt;not in &lt;code&gt;Designated VLANs.md&lt;/code&gt;&lt;/strong&gt; (T-10)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;&lt;code&gt;eth0.10&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;172.17.1.2/16&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;IoT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;td&gt;&lt;code&gt;eth0.50&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;192.168.1.2/24&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Guest; designated, not in audit scope&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;&lt;code&gt;eth0.200&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.1.1.10/20&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;also the DNS server used by srv03mm&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;300&lt;/td&gt;
&lt;td&gt;&lt;code&gt;eth0.300&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.10.1.1/20&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Secure Enclave; designated, not in audit scope&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1024&lt;/td&gt;
&lt;td&gt;&lt;code&gt;eth0.1024&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;172.16.1.2/16&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;DMZ&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;This is the widest VLAN reach of any &lt;code&gt;srv*&lt;/code&gt; host — six VLANs spanning Guest,
IoT, DMZ, Secure Enclave and main internal — on a single 1G access port.&lt;/p&gt;
&lt;p&gt;Two default routes: &lt;code&gt;10.1.1.1&lt;/code&gt; via &lt;code&gt;eth0.200&lt;/code&gt; (static) and &lt;code&gt;10.0.2.1&lt;/code&gt; via
&lt;code&gt;eth0.1&lt;/code&gt; (DHCP). Physical &lt;code&gt;eth0&lt;/code&gt; also holds a link-local &lt;code&gt;169.254.252.56/16&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="srv03mm"&gt;srv03mm&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;VLAN&lt;/th&gt;
&lt;th&gt;VLAN iface&lt;/th&gt;
&lt;th&gt;Address&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;&lt;code&gt;enp2s0.200&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.1.1.12/20&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Default route &lt;code&gt;10.1.1.3&lt;/code&gt;; nameserver &lt;code&gt;10.1.1.10&lt;/code&gt; (srv02gate).&lt;/p&gt;
&lt;h3 id="srv04fs"&gt;srv04fs&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;VLAN&lt;/th&gt;
&lt;th&gt;VLAN iface&lt;/th&gt;
&lt;th&gt;Address&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ens4f0.200&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.1.1.13/20&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;400&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ens4f0.400&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.255.255.9/24&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Both addresses via DHCP; default route &lt;code&gt;10.1.1.3&lt;/code&gt; via &lt;code&gt;ens4f0.200&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="srv05access-choke--multihomed-audit-host"&gt;srv05access (choke / multihomed audit host)&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;VLAN&lt;/th&gt;
&lt;th&gt;VLAN iface&lt;/th&gt;
&lt;th&gt;Address&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;&lt;code&gt;eth0.10&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;172.17.1.3/16&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;&lt;code&gt;eth0.200&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.1.1.14/20&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1024&lt;/td&gt;
&lt;td&gt;&lt;code&gt;eth0.1024&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;172.16.1.5/16&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2871&lt;/td&gt;
&lt;td&gt;&lt;code&gt;eth0.2871&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.0.1.15/24&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Two default routes: &lt;code&gt;10.1.1.3&lt;/code&gt; via &lt;code&gt;eth0.200&lt;/code&gt; and &lt;code&gt;10.0.1.1&lt;/code&gt; via &lt;code&gt;eth0.2871&lt;/code&gt;.
Physical &lt;code&gt;eth0&lt;/code&gt; also holds &lt;code&gt;169.254.226.139/16&lt;/code&gt;. This is the only &lt;code&gt;srv*&lt;/code&gt; host
present in VLAN 2871, and the only one reaching all four audited VLANs.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="4-vlan-inventory"&gt;4. VLAN inventory&lt;/h2&gt;
&lt;p&gt;Roles and designated ranges are taken from &lt;code&gt;Designated VLANs.md&lt;/code&gt;. &amp;ldquo;Audit scope&amp;rdquo;
is the four VLANs authorized in &lt;code&gt;TASK.md&lt;/code&gt; / &lt;code&gt;AGENTS.md&lt;/code&gt; — the designation file is
a network-design document, &lt;strong&gt;not&lt;/strong&gt; an extension of scan authorization.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;VLAN&lt;/th&gt;
&lt;th&gt;Designated role&lt;/th&gt;
&lt;th&gt;Designated range&lt;/th&gt;
&lt;th&gt;Observed subnet&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;th&gt;&lt;code&gt;srv*&lt;/code&gt; addresses&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;em&gt;not designated&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.0.2.0/24&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;undesignated, in production&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;srv02gate &lt;code&gt;10.0.2.3&lt;/code&gt;; USW-Aggregation mgmt &lt;code&gt;10.0.2.6&lt;/code&gt;; gw &lt;code&gt;10.0.2.1&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;IoT&lt;/td&gt;
&lt;td&gt;&lt;code&gt;172.17.1.0/16&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;172.17.0.0/16&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;in audit scope&lt;/td&gt;
&lt;td&gt;srv02gate &lt;code&gt;.1.2&lt;/code&gt;, srv05access &lt;code&gt;.1.3&lt;/code&gt;, srv01hv &lt;code&gt;.1.6&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;td&gt;Guest&lt;/td&gt;
&lt;td&gt;&lt;code&gt;192.168.1.1/24&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;192.168.1.0/24&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;designated, not in scope&lt;/td&gt;
&lt;td&gt;srv02gate &lt;code&gt;192.168.1.2&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;Main internal&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.1.1.0/20&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.1.0.0/20&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;in audit scope&lt;/td&gt;
&lt;td&gt;gate &lt;code&gt;.10&lt;/code&gt;, srv01hv &lt;code&gt;.11&lt;/code&gt;, srv03mm &lt;code&gt;.12&lt;/code&gt;, srv04fs &lt;code&gt;.13&lt;/code&gt;, srv05access &lt;code&gt;.14&lt;/code&gt;, srv06hv &lt;code&gt;.15&lt;/code&gt;; gw &lt;code&gt;10.1.1.3&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;204&lt;/td&gt;
&lt;td&gt;VMs Interconnect&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.128.128.0/24&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.128.128.0/24&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;designated, not in scope&lt;/td&gt;
&lt;td&gt;srv01hv &lt;code&gt;.20&lt;/code&gt;, srv06hv &lt;code&gt;.2&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;214&lt;/td&gt;
&lt;td&gt;HVs Interconnect&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.129.0.0/24&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.129.0.0/24&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;designated, not in scope&lt;/td&gt;
&lt;td&gt;srv01hv &lt;code&gt;10.129.0.2&lt;/code&gt;, srv06hv &lt;code&gt;10.129.0.1&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;214.1&lt;/td&gt;
&lt;td&gt;&lt;em&gt;not designated&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;none&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;undesignated&lt;/strong&gt;, double tag inside 214&lt;/td&gt;
&lt;td&gt;srv06hv &lt;code&gt;hvintrav1&lt;/code&gt; (no IP), feeds &lt;code&gt;docker&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;300&lt;/td&gt;
&lt;td&gt;Secure Enclave&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.10.1.0/20&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.10.0.0/20&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;designated, not in scope&lt;/td&gt;
&lt;td&gt;srv02gate &lt;code&gt;10.10.1.1&lt;/code&gt;, srv01hv &lt;code&gt;10.10.1.2&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;400&lt;/td&gt;
&lt;td&gt;Network Storage&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.255.255.0/24&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.255.255.0/24&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;designated, not in scope&lt;/td&gt;
&lt;td&gt;srv06hv &lt;code&gt;.1&lt;/code&gt;, srv01hv &lt;code&gt;.7&lt;/code&gt;, srv04fs &lt;code&gt;.9&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1024&lt;/td&gt;
&lt;td&gt;DMZ&lt;/td&gt;
&lt;td&gt;&lt;code&gt;172.16.1.0/24&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;172.16.0.0/16&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;in audit scope&lt;/td&gt;
&lt;td&gt;gate &lt;code&gt;.1.2&lt;/code&gt;, srv06hv &lt;code&gt;.1.3&lt;/code&gt;, srv05access &lt;code&gt;.1.5&lt;/code&gt;, srv01hv &lt;code&gt;.1.6&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2871&lt;/td&gt;
&lt;td&gt;Management (isolated)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.0.1.1/24&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.0.1.0/24&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;in audit scope&lt;/td&gt;
&lt;td&gt;srv05access &lt;code&gt;10.0.1.15&lt;/code&gt; only; gw &lt;code&gt;10.0.1.1&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Every observed host address falls inside its designated range.&lt;/strong&gt; No host is
addressed outside the design, and no designated VLAN carries an address from the
wrong block.&lt;/p&gt;
&lt;p&gt;All nine distinct designated VLANs (10, 50, 200, 204, 214, 300, 400, 1024, 2871)
are present on at least one &lt;code&gt;srv*&lt;/code&gt; host; none is unused. Conversely two live
VLANs — 1 and the 214.1 double tag — are absent from the designation file
(T-10).&lt;/p&gt;
&lt;p&gt;Notation: the designated ranges use host-style bases (&lt;code&gt;10.1.1.0/20&lt;/code&gt;,
&lt;code&gt;172.17.1.0/16&lt;/code&gt;, &lt;code&gt;192.168.1.1/24&lt;/code&gt;, &lt;code&gt;10.0.1.1/24&lt;/code&gt;) rather than normalized network
addresses, matching the existing &lt;code&gt;TASK.md&lt;/code&gt; convention. Per &lt;code&gt;AGENTS.md&lt;/code&gt; this is
deliberate and is not to be &amp;ldquo;corrected&amp;rdquo;; the &amp;ldquo;Observed subnet&amp;rdquo; column above
carries the normalized form for comparison. The DMZ discrepancy is the same one
already documented in &lt;code&gt;AGENTS.md&lt;/code&gt;: designated &lt;code&gt;172.16.1.0/24&lt;/code&gt;, but every host
interface is configured &lt;code&gt;/16&lt;/code&gt;. All observed DMZ addresses nonetheless fall within
&lt;code&gt;172.16.1.0/24&lt;/code&gt;, so the intent holds even though the masks are wider.&lt;/p&gt;
&lt;p&gt;VLANs 1, 50, 204, 214, 214.1, 300 and 400 fall outside the four authorized scan
ranges. They appear here only because they were read from on-host configuration;
nothing was scanned in them.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="5-topology-diagrams"&gt;5. Topology diagrams&lt;/h2&gt;
&lt;h3 id="51-physical-link-layer--switch-port-trunked-vlans"&gt;5.1 Physical link layer — switch, port, trunked VLANs&lt;/h3&gt;
&lt;div class="mermaid"&gt;flowchart TB
SW1["TL-SE5226&lt;br/&gt;TP-Link L3 managed switch&lt;br/&gt;24x2.5GE + 2 SFP+&lt;br/&gt;chassis 24:5a:5f:9b:fd:01&lt;br/&gt;mgmt 10.1.1.3 on VLAN 200&lt;br/&gt;caps Bridge + Router"]
SW2["USW-Aggregation&lt;br/&gt;Ubiquiti UBNT-USL8A&lt;br/&gt;chassis 0c:ea:14:bf:29:3f&lt;br/&gt;mgmt 10.0.2.6 on VLAN 1&lt;br/&gt;caps Bridge only"]
SWX["switch UNKNOWN&lt;br/&gt;no LLDP neighbour on link&lt;br/&gt;finding T-01"]
H1A["srv01hv : enp3s0&lt;br/&gt;r8169, 2500 Mb/s&lt;br/&gt;38:05:25:33:67:cf"]
H1B["srv01hv : eth0p0&lt;br/&gt;i40e, 10000 Mb/s&lt;br/&gt;38:05:25:33:67:d2"]
MM["srv03mm : enp2s0&lt;br/&gt;igc, 2500 Mb/s&lt;br/&gt;6c:1f:f7:56:8e:da"]
AC["srv05access : eth0&lt;br/&gt;macb, 1000 Mb/s&lt;br/&gt;d8:3a:dd:c5:13:da&lt;br/&gt;CHOKE HOST"]
FS["srv04fs : ens4f0&lt;br/&gt;bnx2x, 10000 Mb/s&lt;br/&gt;98:b7:85:21:4a:69"]
H6["srv06hv : ens2f0&lt;br/&gt;qede, 10000 Mb/s&lt;br/&gt;f4:c7:aa:57:15:98"]
GW["srv02gate : eth0&lt;br/&gt;bcmgenet, 1000 Mb/s&lt;br/&gt;d8:3a:dd:99:8b:43"]
SW1 -.-|"inter-switch trunk&lt;br/&gt;required by routing, never observed"| SW2
SW1 ---|"TG1/0/4&lt;br/&gt;tagged 10, 200, 300"| H1A
SW1 ---|"TG1/0/6&lt;br/&gt;tagged 200"| MM
SW1 ---|"TG1/0/18&lt;br/&gt;tagged 1, 10, 50, 200, 300, 1024"| GW
SW1 ---|"TG1/0/20&lt;br/&gt;tagged 10, 200, 1024, 2871"| AC
SW2 ---|"Port 4 / SFP_ 4&lt;br/&gt;tagged 200, 400"| FS
SW2 ---|"Port 6 / SFP_ 6&lt;br/&gt;tagged 200, 204, 214, 400, 1024"| H6
SWX ---|"port unknown&lt;br/&gt;tagged 204, 214, 400, 1024"| H1B
SWX -.-|"likely the same chassis as SW2&lt;br/&gt;8x SFP+ aggregation, 10G peers&lt;br/&gt;inference only"| SW2
classDef sw fill:#0f2f46,stroke:#061722,color:#ffffff
classDef unk fill:#4a1f1f,stroke:#220c0c,color:#ffffff,stroke-dasharray:5 4
classDef nic fill:#14331d,stroke:#07180d,color:#ffffff
classDef choke fill:#5a4310,stroke:#2b2007,color:#ffffff
class SW1,SW2 sw
class SWX unk
class H1A,H1B,MM,FS,H6,GW nic
class AC choke
&lt;/div&gt;
&lt;p&gt;Advertised-VLAN caveat: the &amp;ldquo;tagged&amp;rdquo; lists above come from each host&amp;rsquo;s own
802.1Q sub-interfaces, &lt;strong&gt;not&lt;/strong&gt; from the switches&amp;rsquo; LLDP VLAN TLVs. Neither switch
advertises its full trunk allow-list — see finding T-03.&lt;/p&gt;
&lt;h3 id="52-vlan-membership"&gt;5.2 VLAN membership&lt;/h3&gt;
&lt;div class="mermaid"&gt;flowchart LR
subgraph HOSTS["srv hosts"]
direction TB
GW["srv02gate"]
H1["srv01hv"]
MM["srv03mm"]
FS["srv04fs"]
AC["srv05access"]
H6["srv06hv"]
end
subgraph INSCOPE["Designated, in audit scope"]
direction TB
V10["VLAN 10 — IoT&lt;br/&gt;172.17.0.0/16"]
V200["VLAN 200 — Main internal&lt;br/&gt;10.1.0.0/20&lt;br/&gt;gw 10.1.1.3"]
V1024["VLAN 1024 — DMZ&lt;br/&gt;172.16.0.0/16"]
V2871["VLAN 2871 — Management, isolated&lt;br/&gt;10.0.1.0/24&lt;br/&gt;gw 10.0.1.1"]
end
subgraph OUTSCOPE["Designated, outside audit scope"]
direction TB
V50["VLAN 50 — Guest&lt;br/&gt;192.168.1.0/24"]
V204["VLAN 204 — VMs Interconnect&lt;br/&gt;10.128.128.0/24"]
V214["VLAN 214 — HVs Interconnect&lt;br/&gt;10.129.0.0/24"]
V300["VLAN 300 — Secure Enclave&lt;br/&gt;10.10.0.0/20"]
V400["VLAN 400 — Network Storage&lt;br/&gt;10.255.255.0/24"]
end
subgraph UNDESIG["Live but NOT in Designated VLANs.md — T-10"]
direction TB
V1["VLAN 1 — native, switch mgmt&lt;br/&gt;10.0.2.0/24&lt;br/&gt;gw 10.0.2.1"]
V2141["VLAN 1 nested in 214&lt;br/&gt;double tagged, no IP"]
end
GW ---|"10.0.2.3 dhcp"| V1
GW ---|"172.17.1.2"| V10
GW ---|"192.168.1.2"| V50
GW ---|"10.1.1.10"| V200
GW ---|"10.10.1.1"| V300
GW ---|"172.16.1.2"| V1024
H1 ---|"172.17.1.6"| V10
H1 ---|"10.1.1.11"| V200
H1 ---|"10.128.128.20"| V204
H1 ---|"10.129.0.2"| V214
H1 ---|"10.10.1.2"| V300
H1 ---|"10.255.255.7"| V400
H1 ---|"172.16.1.6"| V1024
MM ---|"10.1.1.12"| V200
FS ---|"10.1.1.13"| V200
FS ---|"10.255.255.9"| V400
AC ---|"172.17.1.3"| V10
AC ---|"10.1.1.14"| V200
AC ---|"172.16.1.5"| V1024
AC ---|"10.0.1.15"| V2871
H6 ---|"10.1.1.15"| V200
H6 ---|"10.128.128.2"| V204
H6 ---|"10.129.0.1"| V214
H6 ---|"no address"| V2141
H6 ---|"10.255.255.1"| V400
H6 ---|"172.16.1.3"| V1024
classDef host fill:#14331d,stroke:#07180d,color:#ffffff
classDef vin fill:#0f2f46,stroke:#061722,color:#ffffff
classDef vout fill:#3a3a3a,stroke:#1a1a1a,color:#ffffff,stroke-dasharray:4 3
classDef vund fill:#4a1f1f,stroke:#220c0c,color:#ffffff,stroke-dasharray:5 4
class GW,H1,MM,FS,AC,H6 host
class V10,V200,V1024,V2871 vin
class V50,V204,V214,V300,V400 vout
class V1,V2141 vund
&lt;/div&gt;
&lt;p&gt;srv05access is the only &lt;code&gt;srv*&lt;/code&gt; host in VLAN 2871, and the only one touching all
four audited VLANs. srv06hv has no VLAN 10 interface. VLAN 200 is the only VLAN
common to all six hosts. srv02gate is the only host in VLAN 1 and VLAN 50, and
carries six of the eleven VLANs by itself.&lt;/p&gt;
&lt;h3 id="53-hypervisor-bridge-fan-out"&gt;5.3 Hypervisor bridge fan-out&lt;/h3&gt;
&lt;p&gt;Guest attachment on the two Proxmox nodes. Solid edges pass through a per-VM
firewall bridge (&lt;code&gt;fwbr&amp;lt;vmid&amp;gt;i&amp;lt;n&amp;gt;&lt;/code&gt;); dashed edges are raw &lt;code&gt;tap&lt;/code&gt; devices attached
straight to the bridge, which bypass that filter — see finding T-09.&lt;/p&gt;
&lt;div class="mermaid"&gt;flowchart LR
subgraph SRV01["srv01hv"]
direction LR
N1A["enp3s0&lt;br/&gt;2500 Mb/s&lt;br/&gt;TL-SE5226 TG1/0/4"]
N1B["eth0p0&lt;br/&gt;10000 Mb/s&lt;br/&gt;switch unknown"]
B12["vmbr2iot&lt;br/&gt;vlan 10&lt;br/&gt;172.17.1.6/16"]
B11["vmbr1plc&lt;br/&gt;vlan 200&lt;br/&gt;10.1.1.11/20"]
B13["vmbr3sec&lt;br/&gt;vlan 300&lt;br/&gt;10.10.1.2/20"]
B10["vmbr0vm&lt;br/&gt;vlan 204&lt;br/&gt;10.128.128.20/24"]
B1H["hvintra&lt;br/&gt;vlan 214&lt;br/&gt;10.129.0.2/24"]
B14["vmbr4nas&lt;br/&gt;vlan 400&lt;br/&gt;10.255.255.7/24"]
B1E["vmbr10ext&lt;br/&gt;vlan 1024&lt;br/&gt;172.16.1.6/16"]
VM105["VM105"]
VM106["VM106"]
VM107["VM107"]
N1A --&gt; B12
N1A --&gt; B11
N1A --&gt; B13
N1B --&gt; B10
N1B --&gt; B1H
N1B --&gt; B14
N1B --&gt; B1E
B10 --&gt; VM105
B10 --&gt; VM106
B10 --&gt; VM107
B11 --&gt; VM105
B11 --&gt; VM106
B11 --&gt; VM107
B12 --&gt; VM107
B14 -.-&gt;|"tap106i2 raw"| VM106
end
subgraph SRV06["srv06hv"]
direction LR
N6["ens2f0&lt;br/&gt;10000 Mb/s&lt;br/&gt;USW-Aggregation Port 6"]
B61["vmbr1plc&lt;br/&gt;vlan 200&lt;br/&gt;10.1.1.15/20"]
B60["vmbr0vm&lt;br/&gt;vlan 204&lt;br/&gt;10.128.128.2/24"]
B6H["hvintra&lt;br/&gt;vlan 214&lt;br/&gt;10.129.0.1/24"]
B6H1["hvintrav1&lt;br/&gt;vlan 1 in 214&lt;br/&gt;no IP"]
B6D["docker bridge"]
B62["vmbr2nas&lt;br/&gt;vlan 400&lt;br/&gt;10.255.255.1/24"]
B6E["vmbr10ext&lt;br/&gt;vlan 1024&lt;br/&gt;172.16.1.3/16"]
G6["VM100 VM101 VM102&lt;br/&gt;VM103 VM104 VM112"]
VM110["VM110"]
VM102["VM102"]
VM104["VM104"]
N6 --&gt; B61
N6 --&gt; B60
N6 --&gt; B6H
N6 --&gt; B6H1
N6 --&gt; B62
N6 --&gt; B6E
B6H1 ---|"pr_docker / ln_docker veth"| B6D
B60 --&gt; G6
B60 --&gt; VM110
B61 --&gt; G6
B62 --&gt; VM102
B61 -.-&gt;|"tap110i1 raw"| VM110
B62 -.-&gt;|"tap104i2 raw"| VM104
end
classDef nic fill:#0f2f46,stroke:#061722,color:#ffffff
classDef br fill:#14331d,stroke:#07180d,color:#ffffff
classDef vm fill:#3a3a3a,stroke:#1a1a1a,color:#ffffff
class N1A,N1B,N6 nic
class B10,B11,B12,B13,B14,B1E,B1H,B60,B61,B62,B6E,B6H,B6H1,B6D br
class VM105,VM106,VM107,G6,VM110,VM102,VM104 vm
&lt;/div&gt;
&lt;p&gt;&lt;code&gt;vmbr3sec&lt;/code&gt;, &lt;code&gt;vmbr10ext&lt;/code&gt; and &lt;code&gt;hvintra&lt;/code&gt; carry no guest interfaces on either node —
they exist purely as host-side L3 attachments.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="6-gaps-and-anomalies"&gt;6. Gaps and anomalies&lt;/h2&gt;
&lt;p&gt;Status key: &lt;strong&gt;OPEN&lt;/strong&gt; — unresolved; &lt;strong&gt;RESOLVED&lt;/strong&gt; — closed by the revision 2
re-collection, retained for provenance.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ID&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;th&gt;Summary&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;T-01&lt;/td&gt;
&lt;td&gt;OPEN&lt;/td&gt;
&lt;td&gt;srv01hv &lt;code&gt;eth0p0&lt;/code&gt; switch/port still unidentified&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;T-02&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;RESOLVED&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;srv02gate LLDP now populated — TL-SE5226 &lt;code&gt;TG1/0/18&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;T-03&lt;/td&gt;
&lt;td&gt;OPEN&lt;/td&gt;
&lt;td&gt;switch &amp;ldquo;VLANs offered&amp;rdquo; unusable as a misconfiguration check&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;T-04&lt;/td&gt;
&lt;td&gt;OPEN&lt;/td&gt;
&lt;td&gt;switch management shares production VLANs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;T-05&lt;/td&gt;
&lt;td&gt;OPEN&lt;/td&gt;
&lt;td&gt;divergent VLAN 200 default gateways&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;T-06&lt;/td&gt;
&lt;td&gt;OPEN&lt;/td&gt;
&lt;td&gt;TL-SE5226 is the sole L3 boundary across internal/DMZ/mgmt&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;T-07&lt;/td&gt;
&lt;td&gt;OPEN&lt;/td&gt;
&lt;td&gt;collector renders unnamed LLDP chassis as literal &lt;code&gt;id&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;T-08&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;RESOLVED&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;srv01hv &lt;code&gt;net.lldp&lt;/code&gt; appendix no longer truncated&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;T-09&lt;/td&gt;
&lt;td&gt;OPEN&lt;/td&gt;
&lt;td&gt;three guest taps bypass the per-VM firewall bridge&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;T-10&lt;/td&gt;
&lt;td&gt;OPEN&lt;/td&gt;
&lt;td&gt;VLAN 1 live in production but absent from &lt;code&gt;Designated VLANs.md&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;T-11&lt;/td&gt;
&lt;td&gt;OPEN&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Designated VLANs.md&lt;/code&gt; lists VLAN 400 twice&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="t-01--srv01hv-eth0p0-upstream-switchport-unresolved--open"&gt;T-01 — srv01hv &lt;code&gt;eth0p0&lt;/code&gt; upstream switch/port unresolved — OPEN&lt;/h3&gt;
&lt;p&gt;The 10G &lt;code&gt;eth0p0&lt;/code&gt; link received no LLDP neighbour, so its switch and port are
unknown. It trunks VLANs 204, 214, 400 and 1024; VLAN 400 (&lt;code&gt;10.255.255.7&lt;/code&gt;) and
1024 also live on USW-Aggregation-attached hosts (srv04fs &lt;code&gt;10.255.255.9&lt;/code&gt;,
srv06hv &lt;code&gt;10.255.255.1&lt;/code&gt;), and its VLAN 214 peer &lt;code&gt;10.129.0.1&lt;/code&gt; is srv06hv on Port 6.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Revision 2 strengthens the diagnosis without closing the finding.&lt;/strong&gt; srv01hv was
re-collected while logged in as root, so &lt;code&gt;lldpctl&lt;/code&gt; ran fully privileged and its
appendix output is complete (25 KB of JSON, no truncation) — yet &lt;code&gt;eth0p0&lt;/code&gt; still
does not appear among the LLDP interfaces, while &lt;code&gt;enp3s0&lt;/code&gt; on the same host does.
The silence is therefore a property of the peer or of that link, not a collection
artifact. This eliminates the &amp;ldquo;insufficient privilege&amp;rdquo; explanation that T-02
turned out to be.&lt;/p&gt;
&lt;p&gt;Attachment to the USW-Aggregation remains the most probable answer: it is a
&lt;code&gt;UBNT-USL8A&lt;/code&gt;, an 8-port SFP+ aggregation switch, and both of its known ports face
10G hosts, whereas the TL-SE5226 is a 2.5GE switch with only two SFP+ uplinks.
That is still an inference from port-count and subnet adjacency, &lt;strong&gt;not&lt;/strong&gt; observed
LLDP, and the port number is unknown. Resolving it needs a switch-side MAC or
LLDP table lookup for &lt;code&gt;38:05:25:33:67:d2&lt;/code&gt;, which is outside read-only host
inspection.&lt;/p&gt;
&lt;h3 id="t-02--srv02gate-returned-an-empty-lldp-table--resolved"&gt;T-02 — srv02gate returned an empty LLDP table — RESOLVED&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Revision 1:&lt;/em&gt; &lt;code&gt;lldpd.service&lt;/code&gt; was active and &lt;code&gt;lldpctl -f json&lt;/code&gt; exited 0, but
returned &lt;code&gt;{&amp;quot;lldp&amp;quot;: {}}&lt;/code&gt;, so the report had no section 2.5 at all. The appendix
showed the command had run &lt;strong&gt;unprivileged&lt;/strong&gt; despite the host having passwordless
sudo — the &lt;code&gt;r.available&lt;/code&gt; vs &lt;code&gt;r.binaries&lt;/code&gt; pitfall documented in &lt;code&gt;AGENTS.md&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Revision 2:&lt;/em&gt; the re-collection returns a populated neighbour table:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Interface&lt;/th&gt;
&lt;th&gt;Switch&lt;/th&gt;
&lt;th&gt;Port&lt;/th&gt;
&lt;th&gt;Port description&lt;/th&gt;
&lt;th&gt;VLANs offered&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;eth0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;TL-SE5226 (&lt;code&gt;24*2.5GE+2SFP+ L3 Managed Switch&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;TG1/0/18&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;TG1/0/18 Interface&lt;/td&gt;
&lt;td&gt;1 (pvid, System-VLAN)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;srv02gate therefore sits on the &lt;strong&gt;TL-SE5226&lt;/strong&gt;, not the USW-Aggregation — the same
switch as srv01hv&amp;rsquo;s 2.5G leg, srv03mm and srv05access. This closes the last
unattached uplink apart from T-01 and supplies the third independent argument for
the inter-switch trunk in section 1. Note the chassis TLV carried no &lt;code&gt;mgmt-ip&lt;/code&gt;
this time, so the switch&amp;rsquo;s management address is corroborated only by srv03mm&amp;rsquo;s
observation (&lt;code&gt;10.1.1.3&lt;/code&gt;, mgmt-iface VLAN 200).&lt;/p&gt;
&lt;h3 id="t-03--vlans-offered-is-not-a-usable-misconfiguration-check-on-this-fabric--open"&gt;T-03 — &amp;ldquo;VLANs offered&amp;rdquo; is not a usable misconfiguration check on this fabric — OPEN&lt;/h3&gt;
&lt;p&gt;Section 2.5&amp;rsquo;s guidance (&amp;ldquo;a VLAN configured here but not offered by the switch is
a misconfiguration&amp;rdquo;) does not hold against these two switch models:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;USW-Aggregation advertises only the PVID (VLAN 1) on both ports, while srv04fs
and srv06hv carry tagged 200/400/1024 over them successfully.&lt;/li&gt;
&lt;li&gt;TL-SE5226 advertises only VLANs flagged &lt;code&gt;System-VLAN&lt;/code&gt; plus the PVID — port
&lt;code&gt;TG1/0/4&lt;/code&gt; shows VLAN 10 while srv01hv also runs 200 and 300 over it, and
&lt;code&gt;TG1/0/20&lt;/code&gt; shows VLAN 10 while srv05access also runs 200, 1024 and 2871.&lt;/li&gt;
&lt;li&gt;Revision 2 adds the strongest case: &lt;code&gt;TG1/0/18&lt;/code&gt; advertises &lt;strong&gt;VLAN 1 only&lt;/strong&gt;,
while srv02gate runs six tagged VLANs over it (1, 10, 50, 200, 300, 1024),
spanning Guest, IoT, DMZ and Secure Enclave. Taken literally the section 2.5
rule would flag five misconfigurations on that one port.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The apparent mismatches in section 2 are advertisement limitations, not proven
misconfigurations. Confirmation would need the switch-side trunk configuration.&lt;/p&gt;
&lt;h3 id="t-04--switch-management-shares-production-vlans-not-vlan-2871--open"&gt;T-04 — Switch management shares production VLANs, not VLAN 2871 — OPEN&lt;/h3&gt;
&lt;p&gt;The &amp;ldquo;isolated management&amp;rdquo; VLAN 2871 terminates on exactly one host
(srv05access &lt;code&gt;10.0.1.15&lt;/code&gt;). Neither switch is managed from it: TL-SE5226 is
managed at &lt;code&gt;10.1.1.3&lt;/code&gt; on VLAN 200 — the same VLAN as all general server traffic —
and USW-Aggregation at &lt;code&gt;10.0.2.6&lt;/code&gt; on VLAN 1.&lt;/p&gt;
&lt;p&gt;Revision 2 makes this worse rather than better. VLAN 1 is now confirmed to reach
the TL-SE5226 as a tagged VLAN on &lt;code&gt;TG1/0/18&lt;/code&gt;, where srv02gate holds &lt;code&gt;10.0.2.3&lt;/code&gt; in
the same &lt;code&gt;/24&lt;/code&gt; as the USW&amp;rsquo;s management address and takes a DHCP default route via
&lt;code&gt;10.0.2.1&lt;/code&gt;. So the switch management plane sits in a VLAN that (a) is not in
&lt;code&gt;Designated VLANs.md&lt;/code&gt; at all (T-10), (b) is the untagged/native VLAN on every
observed access port, and (c) is directly addressable from a production host.
Management traffic is not separated from the data plane, contrary to the intent
implied by VLAN 2871&amp;rsquo;s existence.&lt;/p&gt;
&lt;h3 id="t-05--divergent-vlan-200-default-gateways--open"&gt;T-05 — Divergent VLAN 200 default gateways — OPEN&lt;/h3&gt;
&lt;p&gt;srv02gate&amp;rsquo;s default route on VLAN 200 is &lt;code&gt;10.1.1.1&lt;/code&gt; (static), while srv01hv,
srv03mm, srv04fs, srv05access and srv06hv all use &lt;code&gt;10.1.1.3&lt;/code&gt; (the TL-SE5226).
Two distinct L3 next-hops are in use on the same VLAN; &lt;code&gt;10.1.1.1&lt;/code&gt; was not
identified from host data.&lt;/p&gt;
&lt;h3 id="t-06--tl-se5226-is-the-sole-l3-boundary-across-internal-dmz-and-management--open"&gt;T-06 — TL-SE5226 is the sole L3 boundary across internal, DMZ and management — OPEN&lt;/h3&gt;
&lt;p&gt;The TL-SE5226 advertises the Router capability and is the VLAN 200 gateway. With
srv02gate now placed on it, the same chassis is confirmed to trunk seven distinct
VLANs to attached hosts: 1 (native/mgmt), 10 (IoT), 50 (Guest), 200 (Main
internal), 300 (Secure Enclave), 1024 (DMZ) and 2871 (Management). Five of the
nine designated VLANs — including both segments whose names assert isolation,
Secure Enclave and Management — converge on one appliance that is also the L3
router between them. The segmentation boundary for most of the estate is a single
device, and its own management address sits inside one of the VLANs it separates
(T-04).&lt;/p&gt;
&lt;h3 id="t-07--collector-renders-unnamed-lldp-chassis-as-literal-id-collect_host_envpy--open"&gt;T-07 — Collector renders unnamed LLDP chassis as literal &lt;code&gt;id&lt;/code&gt; (&lt;code&gt;collect_host_env.py&lt;/code&gt;) — OPEN&lt;/h3&gt;
&lt;p&gt;srv01hv&amp;rsquo;s LLDP table renders &lt;code&gt;tap105i0&lt;/code&gt; / &lt;code&gt;tap105i1&lt;/code&gt; with the Switch column set
to the literal string &lt;code&gt;id&lt;/code&gt;. The raw JSON for those neighbours is
&lt;code&gt;chassis: {&amp;quot;id&amp;quot;: {&amp;quot;type&amp;quot;: &amp;quot;local&amp;quot;, &amp;quot;value&amp;quot;: &amp;quot;VM006-WIN&amp;quot;}}&lt;/code&gt; — a chassis object
with no name key — so the renderer takes the first key (&lt;code&gt;id&lt;/code&gt;) as the neighbour
name and loses &lt;code&gt;VM006-WIN&lt;/code&gt;. Any LLDP-speaking guest that advertises a
local-type chassis ID is misrendered this way. Fix: when the chassis object has
no name key, fall back to &lt;code&gt;chassis.id.value&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Still present in the revision 2 srv01hv report (section 2.5, rows for
&lt;code&gt;tap105i0&lt;/code&gt;/&lt;code&gt;tap105i1&lt;/code&gt;), and running as root did not change it — confirming it is
a parser defect rather than a privilege artifact.&lt;/p&gt;
&lt;h3 id="t-08--srv01hv-lldp-raw-output-truncated-in-the-appendix--resolved"&gt;T-08 — srv01hv LLDP raw output truncated in the appendix — RESOLVED&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Revision 1:&lt;/em&gt; the &lt;code&gt;net.lldp&lt;/code&gt; appendix block for srv01hv ended with
&lt;code&gt;... [truncated, 714 more lines]&lt;/code&gt;, so the appendix could not be used to re-derive
the topology independently of the rendered table.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Revision 2:&lt;/em&gt; the block is complete — roughly 25 KB of JSON covering all 17
neighbour entries, and the only remaining occurrence of the word &amp;ldquo;truncated&amp;rdquo; in
the file is the boilerplate sentence in the appendix preamble. The srv02gate
report is likewise untruncated. Both reports can now be re-derived from raw
output alone. srv06hv (still revision 1, collected 12:12) has not been re-run and
its larger blocks were not re-checked.&lt;/p&gt;
&lt;h3 id="t-09--three-guest-interfaces-bypass-the-per-vm-firewall-bridge--open"&gt;T-09 — Three guest interfaces bypass the per-VM firewall bridge — OPEN&lt;/h3&gt;
&lt;p&gt;Surfaced while drawing diagram 5.3. Proxmox normally inserts a per-VM filter
bridge (&lt;code&gt;fwbr&amp;lt;vmid&amp;gt;i&amp;lt;n&amp;gt;&lt;/code&gt; with an &lt;code&gt;fwln&lt;/code&gt;/&lt;code&gt;fwpr&lt;/code&gt; veth pair) between a guest tap
and the target &lt;code&gt;vmbr&lt;/code&gt;. Three taps are instead enslaved directly to a bridge,
so no per-VM firewall is applied to them:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Host&lt;/th&gt;
&lt;th&gt;Tap&lt;/th&gt;
&lt;th&gt;Bridge&lt;/th&gt;
&lt;th&gt;VLAN&lt;/th&gt;
&lt;th&gt;Segment&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;srv01hv&lt;/td&gt;
&lt;td&gt;&lt;code&gt;tap106i2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vmbr4nas&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;400&lt;/td&gt;
&lt;td&gt;storage &lt;code&gt;10.255.255.0/24&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv06hv&lt;/td&gt;
&lt;td&gt;&lt;code&gt;tap110i1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vmbr1plc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;main internal &lt;code&gt;10.1.0.0/20&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv06hv&lt;/td&gt;
&lt;td&gt;&lt;code&gt;tap104i2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vmbr2nas&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;400&lt;/td&gt;
&lt;td&gt;storage &lt;code&gt;10.255.255.0/24&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The same VMs&amp;rsquo; other interfaces &lt;em&gt;are&lt;/em&gt; filtered (&lt;code&gt;fwbr106i0/i1&lt;/code&gt;, &lt;code&gt;fwbr110i0&lt;/code&gt;,
&lt;code&gt;fwbr104i0/i1&lt;/code&gt; all exist), so this is per-interface, not a host-wide setting —
consistent with the firewall checkbox being left off on those specific NICs.
&lt;code&gt;tap110i1&lt;/code&gt; is the notable one: it places VM110 unfiltered on VLAN 200, the main
internal network. Verify against &lt;code&gt;results/&lt;/code&gt; external scans for the affected
guest addresses before treating this as exploitable.&lt;/p&gt;
&lt;h3 id="t-10--vlan-1-and-the-2141-double-tag-are-live-but-not-designated--open"&gt;T-10 — VLAN 1 and the 214.1 double tag are live but not designated — OPEN&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;Designated VLANs.md&lt;/code&gt; lists nine VLANs (10, 50, 200, 204, 214, 300, 400, 1024,
2871). Two VLANs carrying real traffic are absent from it:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;VLAN&lt;/th&gt;
&lt;th&gt;Where&lt;/th&gt;
&lt;th&gt;Evidence&lt;/th&gt;
&lt;th&gt;Why it matters&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;srv02gate &lt;code&gt;eth0.1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.0.2.3/24&lt;/code&gt;, DHCP, default route via &lt;code&gt;10.0.2.1&lt;/code&gt;; USW-Aggregation managed at &lt;code&gt;10.0.2.6&lt;/code&gt;; PVID on all four observed access ports&lt;/td&gt;
&lt;td&gt;Undocumented subnet that carries switch management and a working default route off-box&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1 nested in 214&lt;/td&gt;
&lt;td&gt;srv06hv &lt;code&gt;ens2f0.214.1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;802.1Q double tag, bridged to &lt;code&gt;hvintrav1&lt;/code&gt; → &lt;code&gt;docker&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Undocumented QinQ path from container workloads onto the HV interconnect&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;VLAN 1 is not a stray: it has a DHCP server, a gateway, a switch management
address and it is the native VLAN on every access port observed. It is
load-bearing infrastructure that the design document does not acknowledge, which
means no one has assigned it an intended security posture. The 214.1 stack is
narrower but more surprising — it nests the native VLAN inside the hypervisor
interconnect to reach a Docker bridge.&lt;/p&gt;
&lt;p&gt;Neither is in the authorized scan scope, so no active verification was performed.
Recommend either adding both to &lt;code&gt;Designated VLANs.md&lt;/code&gt; with an explicit role, or
confirming they should not exist.&lt;/p&gt;
&lt;h3 id="t-11--designated-vlansmd-lists-vlan-400-twice--open"&gt;T-11 — &lt;code&gt;Designated VLANs.md&lt;/code&gt; lists VLAN 400 twice — OPEN&lt;/h3&gt;
&lt;p&gt;Lines 9 and 10 of the file are byte-identical:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;| 400 | Network Storage | `10.255.255.0/24` |
| 400 | Network Storage | `10.255.255.0/24` |
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Harmless as data — both rows agree, so no VLAN is ambiguously defined — but the
file reads as ten designated VLANs when there are nine. Anything that counts rows
rather than distinct VLAN IDs will be off by one. Worth deduplicating in the
source; this report counts nine.&lt;/p&gt;</description></item><item><title>VM Host Audit Report</title><link>https://vox.app.home/posts/private/intranet/vm_network_topology/</link><pubDate>Mon, 31 Aug 2026 13:00:00 +0000</pubDate><guid>https://vox.app.home/posts/private/intranet/vm_network_topology/</guid><description>&lt;h1 id="network-topology--vm-guests"&gt;Network Topology — &lt;code&gt;vm*&lt;/code&gt; Guests&lt;/h1&gt;
&lt;p&gt;Reconstructed VLAN attachment and exposed-service map for the seven &lt;code&gt;vm*&lt;/code&gt; virtual
machines.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Scope&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vm001-devel&lt;/code&gt;, &lt;code&gt;vm002-docker&lt;/code&gt;, &lt;code&gt;vm004-es&lt;/code&gt;, &lt;code&gt;vm005-obj&lt;/code&gt;, &lt;code&gt;vm010-db&lt;/code&gt;, &lt;code&gt;vm011-jenkins&lt;/code&gt;, &lt;code&gt;vm012-clickhouse&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sources&lt;/td&gt;
&lt;td&gt;&lt;code&gt;host-env-scan/hostenv_vm*.md&lt;/code&gt; — sections 1–6 and the &lt;code&gt;net.*&lt;/code&gt; appendix entries&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Corroborating&lt;/td&gt;
&lt;td&gt;&lt;code&gt;host-env-scan/hostenv_srv01hv_*.md&lt;/code&gt; / &lt;code&gt;hostenv_srv06hv_*.md&lt;/code&gt; (bridge topology + &lt;code&gt;fw.iptables&lt;/code&gt;), &lt;code&gt;audit-report/NETWORK_TOPOLOGY.md&lt;/code&gt; (&lt;code&gt;T-01&lt;/code&gt;…&lt;code&gt;T-11&lt;/code&gt;), &lt;code&gt;audit-report/SRV_HOST_SECURITY_AUDIT.md&lt;/code&gt; (&lt;code&gt;S-01&lt;/code&gt;…&lt;code&gt;S-15&lt;/code&gt;), &lt;code&gt;Designated VLANs.md&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Method&lt;/td&gt;
&lt;td&gt;Desk analysis of existing read-only collection. &lt;strong&gt;No scanning, no probing, no connection attempts and no configuration changes were performed for this document.&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Collection window (UTC)&lt;/td&gt;
&lt;td&gt;2026-08-25 23:10:48 → 23:14:23 (guests); hypervisors re-collected 2026-08-26 12:12 / 12:35&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Finding prefix&lt;/td&gt;
&lt;td&gt;&lt;code&gt;V-xx&lt;/code&gt; (chosen to avoid collision with &lt;code&gt;F-xx&lt;/code&gt; in &lt;code&gt;NETWORK_AUDIT_REPORT.md&lt;/code&gt;, &lt;code&gt;T-xx&lt;/code&gt; in &lt;code&gt;NETWORK_TOPOLOGY.md&lt;/code&gt;, &lt;code&gt;S-xx&lt;/code&gt;/&lt;code&gt;G-xx&lt;/code&gt; in &lt;code&gt;SRV_HOST_SECURITY_AUDIT.md&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Source report files:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Host&lt;/th&gt;
&lt;th&gt;Report&lt;/th&gt;
&lt;th&gt;Collected (UTC)&lt;/th&gt;
&lt;th&gt;Privilege&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;vm002-docker&lt;/td&gt;
&lt;td&gt;&lt;code&gt;hostenv_vm002-docker_20260825T231048Z.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;23:10:52&lt;/td&gt;
&lt;td&gt;sudo via password&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vm001-devel&lt;/td&gt;
&lt;td&gt;&lt;code&gt;hostenv_vm001-devel_20260825T231259Z.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;23:13:02&lt;/td&gt;
&lt;td&gt;sudo via password&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vm004-es&lt;/td&gt;
&lt;td&gt;&lt;code&gt;hostenv_vm004-es_20260825T231403Z.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;23:14:14&lt;/td&gt;
&lt;td&gt;sudo via password&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vm005-obj&lt;/td&gt;
&lt;td&gt;&lt;code&gt;hostenv_vm005-obj_20260825T231403Z.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;23:14:16&lt;/td&gt;
&lt;td&gt;sudo via password&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vm010-db&lt;/td&gt;
&lt;td&gt;&lt;code&gt;hostenv_vm010-db_20260825T231403Z.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;23:14:19&lt;/td&gt;
&lt;td&gt;sudo via password&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vm011-jenkins&lt;/td&gt;
&lt;td&gt;&lt;code&gt;hostenv_vm011-jenkins_20260825T231403Z.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;23:14:21&lt;/td&gt;
&lt;td&gt;sudo via password&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vm012-clickhouse&lt;/td&gt;
&lt;td&gt;&lt;code&gt;hostenv_vm012-clickhouse_20260825T231403Z.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;23:14:23&lt;/td&gt;
&lt;td&gt;sudo via password&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;The external view could not be cross-referenced.&lt;/strong&gt; &lt;code&gt;results/&lt;/code&gt; and
&lt;code&gt;NETWORK_AUDIT_REPORT.md&lt;/code&gt; are root-owned and unreadable by the account running
this analysis, so the usual &lt;code&gt;AGENTS.md&lt;/code&gt; practice of reconciling the on-host view
against the nmap view was not possible here. Everything below is the on-host view
only. Where that view is insufficient to reach a conclusion, this document says so
rather than guessing.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="1-how-vlan-membership-was-derived"&gt;1. How VLAN membership was derived&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;No &lt;code&gt;vm*&lt;/code&gt; guest has a single VLAN interface.&lt;/strong&gt; All seven report &lt;code&gt;VLAN interfaces: 0&lt;/code&gt; in section 2.2. Every guest NIC is an untagged &lt;code&gt;virtio_net&lt;/code&gt; device; the 802.1Q
tag is applied on the hypervisor side, by the Proxmox bridge the guest&amp;rsquo;s &lt;code&gt;tap&lt;/code&gt; is
enslaved to. A guest therefore cannot report its own VLAN, and reading the guest
report alone tells you nothing about segmentation.&lt;/p&gt;
&lt;p&gt;VLAN membership below is established by two independent means, which agree
everywhere they overlap:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Subnet match.&lt;/strong&gt; Each guest address is matched against the subnets that the
&lt;code&gt;srv*&lt;/code&gt; hosts terminate on known VLAN interfaces (&lt;code&gt;NETWORK_TOPOLOGY.md&lt;/code&gt; §3–4).
&lt;code&gt;10.128.128.0/24&lt;/code&gt; exists only on &lt;code&gt;eth0p0.204&lt;/code&gt;/&lt;code&gt;ens2f0.204&lt;/code&gt;, &lt;code&gt;10.1.0.0/20&lt;/code&gt; only
on &lt;code&gt;*.200&lt;/code&gt;, &lt;code&gt;10.255.255.0/24&lt;/code&gt; only on &lt;code&gt;*.400&lt;/code&gt;. The mapping is unambiguous.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bridge match.&lt;/strong&gt; Each hypervisor&amp;rsquo;s &lt;code&gt;vmbr*&lt;/code&gt; carries exactly one VLAN
subinterface, so bridge identity fixes the VLAN: on srv01hv &lt;code&gt;vmbr0vm&lt;/code&gt;→204,
&lt;code&gt;vmbr1plc&lt;/code&gt;→200, &lt;code&gt;vmbr2iot&lt;/code&gt;→10, &lt;code&gt;vmbr4nas&lt;/code&gt;→400; on srv06hv &lt;code&gt;vmbr0vm&lt;/code&gt;→204,
&lt;code&gt;vmbr1plc&lt;/code&gt;→200, &lt;code&gt;vmbr2nas&lt;/code&gt;→400, &lt;code&gt;vmbr10ext&lt;/code&gt;→1024.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Consequence worth stating plainly: &lt;strong&gt;the guest&amp;rsquo;s own &lt;code&gt;ens18&lt;/code&gt;/&lt;code&gt;ens19&lt;/code&gt;/&lt;code&gt;ens20&lt;/code&gt;
numbering is the only handle an operator has on which segment a NIC lands in, and
that numbering is not self-describing.&lt;/strong&gt; &lt;code&gt;ens18&lt;/code&gt; is VLAN 204 on six of the seven
guests and VLAN 204-but-down on the seventh; &lt;code&gt;ens19&lt;/code&gt; is VLAN 200 on five guests,
VLAN 400 on one, and unconfigured on one. This is finding &lt;code&gt;V-07&lt;/code&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="2-guest-inventory"&gt;2. Guest inventory&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Host&lt;/th&gt;
&lt;th&gt;Role (inferred from listeners)&lt;/th&gt;
&lt;th&gt;OS / kernel&lt;/th&gt;
&lt;th&gt;vCPU / RAM&lt;/th&gt;
&lt;th&gt;NICs&lt;/th&gt;
&lt;th&gt;VLANs attached&lt;/th&gt;
&lt;th&gt;Host firewall&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;vm001-devel&lt;/td&gt;
&lt;td&gt;Development box, nginx TLS front end, Docker installed but idle&lt;/td&gt;
&lt;td&gt;Debian 13 / &lt;strong&gt;6.18.0-dirty&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;16 / 19.5 GiB&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;200, 204&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;none&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vm002-docker&lt;/td&gt;
&lt;td&gt;Docker &lt;strong&gt;Swarm&lt;/strong&gt; node, 25 containers, Traefik ingress&lt;/td&gt;
&lt;td&gt;Debian 13 / 6.12.74+deb13+1&lt;/td&gt;
&lt;td&gt;32 / 62.8 GiB&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;200, 204&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;none&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vm004-es&lt;/td&gt;
&lt;td&gt;Elasticsearch + Kibana behind nginx&lt;/td&gt;
&lt;td&gt;Debian 13 / 6.12.48&lt;/td&gt;
&lt;td&gt;8 / 31.3 GiB&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;200, 204&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;none&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vm005-obj&lt;/td&gt;
&lt;td&gt;Garage S3 object store behind OpenResty; NFS client&lt;/td&gt;
&lt;td&gt;Debian 13 / 6.12.48&lt;/td&gt;
&lt;td&gt;8 / 15.6 GiB&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;200, 204, &lt;strong&gt;400&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;none&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vm010-db&lt;/td&gt;
&lt;td&gt;MariaDB + Valkey&lt;/td&gt;
&lt;td&gt;Debian 13 / 6.12.95&lt;/td&gt;
&lt;td&gt;16 / 31.3 GiB&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;200, 204&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;none&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vm011-jenkins&lt;/td&gt;
&lt;td&gt;Jenkins behind nginx&lt;/td&gt;
&lt;td&gt;Debian 13 / 6.12.95&lt;/td&gt;
&lt;td&gt;8 / 15.6 GiB&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;200, 204&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;none&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vm012-clickhouse&lt;/td&gt;
&lt;td&gt;ClickHouse behind nginx, Vector metrics&lt;/td&gt;
&lt;td&gt;Debian 13 / 6.12.101&lt;/td&gt;
&lt;td&gt;8 / 7.8 GiB&lt;/td&gt;
&lt;td&gt;3 (2 down)&lt;/td&gt;
&lt;td&gt;200 &lt;em&gt;(204, 400 cabled but unconfigured)&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;none&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;All seven are Debian 13 (trixie) KVM guests on QEMU &lt;code&gt;Standard PC (i440FX + PIIX, 1996)&lt;/code&gt; with &lt;code&gt;virtio_net&lt;/code&gt; NICs in the &lt;code&gt;bc:24:11:*&lt;/code&gt; range — the Proxmox VE MAC
prefix. &lt;strong&gt;firewalld is not installed on any of the seven&lt;/strong&gt;; the collector reports
&lt;code&gt;firewalld zones (active) = 0&lt;/code&gt; and &lt;code&gt;Reachable through firewall = 0&lt;/code&gt; for all of
them, and every verdict in their section 5 is &lt;code&gt;unknown — firewall data unavailable&lt;/code&gt;. See &lt;code&gt;V-01&lt;/code&gt; for what that means once the hypervisor ruleset is taken
into account.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;vm001-devel&lt;/code&gt; runs a locally built kernel (&lt;code&gt;6.18.0-dirty&lt;/code&gt;) — the &lt;code&gt;-dirty&lt;/code&gt; suffix
means it was compiled from a modified, uncommitted tree. It is the only host in
the estate not on a distribution kernel.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="3-per-guest-vlan--interface--address-mapping"&gt;3. Per-guest VLAN → interface → address mapping&lt;/h2&gt;
&lt;p&gt;Gateway &lt;code&gt;10.1.1.3&lt;/code&gt; is the TL-SE5226 switch (&lt;code&gt;NETWORK_TOPOLOGY.md&lt;/code&gt; §1). &lt;code&gt;10.1.1.10&lt;/code&gt;
is srv02gate; &lt;code&gt;10.128.128.2&lt;/code&gt; and &lt;code&gt;10.255.255.1&lt;/code&gt; are both srv06hv, which runs a
&lt;code&gt;dotnet&lt;/code&gt;-based &lt;code&gt;dns.service&lt;/code&gt; bound to every one of its VLAN addresses.&lt;/p&gt;
&lt;h3 id="vm001-devel"&gt;vm001-devel&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;VLAN&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;th&gt;Interface&lt;/th&gt;
&lt;th&gt;MAC&lt;/th&gt;
&lt;th&gt;Address&lt;/th&gt;
&lt;th&gt;Assignment&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;204&lt;/td&gt;
&lt;td&gt;VMs Interconnect&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ens18&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bc:24:11:0a:f0:87&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.128.128.7/24&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;DHCP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;Main internal&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ens19&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bc:24:11:9d:6a:f6&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.1.2.83/20&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;DHCP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;em&gt;(Docker default bridge, DOWN)&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;docker0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;code&gt;172.17.0.1/16&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;static&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Default route &lt;code&gt;10.1.1.3&lt;/code&gt; via &lt;code&gt;ens19&lt;/code&gt;. Resolver is the local systemd-resolved stub
&lt;code&gt;127.0.0.53&lt;/code&gt;; search &lt;code&gt;home hv.home vm.home&lt;/code&gt;. &lt;code&gt;net.ipv4.ip_forward = 1&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="vm002-docker"&gt;vm002-docker&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;VLAN&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;th&gt;Interface&lt;/th&gt;
&lt;th&gt;MAC&lt;/th&gt;
&lt;th&gt;Address&lt;/th&gt;
&lt;th&gt;Assignment&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;204&lt;/td&gt;
&lt;td&gt;VMs Interconnect&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ens18&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bc:24:11:65:fe:9d&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.128.128.4/24&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;DHCP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;Main internal&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ens19&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bc:24:11:c3:8f:7d&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.1.2.73/20&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;DHCP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;Docker default bridge (DOWN)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;docker0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;code&gt;172.17.0.1/16&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;static&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;Docker user bridge&lt;/td&gt;
&lt;td&gt;&lt;code&gt;br-70f3ee0fb257&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;code&gt;172.18.0.1/16&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;static&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;Docker user bridge&lt;/td&gt;
&lt;td&gt;&lt;code&gt;br-9e2a20ddf105&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;code&gt;172.20.0.1/16&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;static&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;Swarm gateway bridge&lt;/td&gt;
&lt;td&gt;&lt;code&gt;docker_gwbridge&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;code&gt;172.22.0.1/16&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;static&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Plus 40 &lt;code&gt;veth&lt;/code&gt; interfaces. Default route &lt;code&gt;10.1.1.3&lt;/code&gt; via &lt;code&gt;ens19&lt;/code&gt;; nameservers
&lt;code&gt;10.1.1.10&lt;/code&gt; (srv02gate) and &lt;code&gt;10.128.128.2&lt;/code&gt; (srv06hv). &lt;code&gt;net.ipv4.ip_forward = 1&lt;/code&gt;.
&lt;code&gt;docker_gwbridge&lt;/code&gt; is flagged by the collector as having no on-disk configuration —
correct, and expected for a runtime-managed bridge.&lt;/p&gt;
&lt;h3 id="vm004-es"&gt;vm004-es&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;VLAN&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;th&gt;Interface&lt;/th&gt;
&lt;th&gt;MAC&lt;/th&gt;
&lt;th&gt;Address&lt;/th&gt;
&lt;th&gt;Assignment&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;204&lt;/td&gt;
&lt;td&gt;VMs Interconnect&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ens18&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bc:24:11:bb:51:3c&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.128.128.16/24&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;DHCP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;Main internal&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ens19&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bc:24:11:4f:71:23&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.1.2.70/20&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;DHCP&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Default route &lt;code&gt;10.1.1.3&lt;/code&gt; via &lt;code&gt;ens19&lt;/code&gt;; nameservers &lt;code&gt;10.1.1.10&lt;/code&gt;, &lt;code&gt;10.128.128.2&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="vm005-obj--the-only-three-vlan-guest"&gt;vm005-obj — the only three-VLAN guest&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;VLAN&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;th&gt;Interface&lt;/th&gt;
&lt;th&gt;MAC&lt;/th&gt;
&lt;th&gt;Address&lt;/th&gt;
&lt;th&gt;Assignment&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;204&lt;/td&gt;
&lt;td&gt;VMs Interconnect&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ens18&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bc:24:11:11:e5:b4&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.128.128.13/24&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;DHCP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;Main internal&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ens19&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bc:24:11:f4:d4:4a&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.1.2.31/20&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;DHCP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;400&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Network Storage&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ens20&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bc:24:11:8f:2f:32&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.255.255.8/24&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;DHCP&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Default route &lt;code&gt;10.1.1.3&lt;/code&gt; via &lt;code&gt;ens19&lt;/code&gt;; connected route &lt;code&gt;10.255.255.0/24&lt;/code&gt; via
&lt;code&gt;ens20&lt;/code&gt;. Nameservers in order &lt;code&gt;10.255.255.1&lt;/code&gt; (srv06hv on VLAN 400),
&lt;code&gt;10.128.128.2&lt;/code&gt; (srv06hv on VLAN 204), &lt;code&gt;10.1.1.10&lt;/code&gt; (srv02gate on VLAN 200); domain
&lt;code&gt;nas.home&lt;/code&gt;. This is the only &lt;code&gt;vm*&lt;/code&gt; host that reaches the storage VLAN directly,
and it is the only one that mounts &lt;code&gt;srv04fs.nas.home:/share-mnts/objects&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="vm010-db"&gt;vm010-db&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;VLAN&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;th&gt;Interface&lt;/th&gt;
&lt;th&gt;MAC&lt;/th&gt;
&lt;th&gt;Address&lt;/th&gt;
&lt;th&gt;Assignment&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;204&lt;/td&gt;
&lt;td&gt;VMs Interconnect&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ens18&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bc:24:11:ac:90:e5&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.128.128.17/24&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;DHCP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;Main internal&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ens19&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bc:24:11:1f:36:b8&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.1.2.71/20&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;DHCP&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Default route &lt;code&gt;10.1.1.3&lt;/code&gt; via &lt;code&gt;ens19&lt;/code&gt;; nameservers &lt;code&gt;10.128.128.2&lt;/code&gt;, &lt;code&gt;10.1.1.10&lt;/code&gt;.
Uptime 38 d and &lt;strong&gt;NTP not synchronised&lt;/strong&gt; — the only guest reporting clock drift,
which matters for a database host and for log correlation.&lt;/p&gt;
&lt;h3 id="vm011-jenkins"&gt;vm011-jenkins&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;VLAN&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;th&gt;Interface&lt;/th&gt;
&lt;th&gt;MAC&lt;/th&gt;
&lt;th&gt;Address&lt;/th&gt;
&lt;th&gt;Assignment&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;204&lt;/td&gt;
&lt;td&gt;VMs Interconnect&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ens18&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bc:24:11:4f:0d:8f&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.128.128.15/24&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;DHCP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;Main internal&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ens19&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bc:24:11:cf:5a:59&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.1.2.68/20&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;DHCP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;em&gt;(Docker default bridge, DOWN)&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;docker0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;code&gt;172.17.0.1/16&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;static&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Default route &lt;code&gt;10.1.1.3&lt;/code&gt; via &lt;code&gt;ens19&lt;/code&gt;. Resolver is the systemd-resolved stub.
&lt;code&gt;net.ipv4.ip_forward = 1&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="vm012-clickhouse--two-nics-cabled-but-never-configured"&gt;vm012-clickhouse — two NICs cabled but never configured&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;VLAN&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;th&gt;Interface&lt;/th&gt;
&lt;th&gt;MAC&lt;/th&gt;
&lt;th&gt;Address&lt;/th&gt;
&lt;th&gt;State&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;204 &lt;em&gt;(inferred)&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;VMs Interconnect&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ens18&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bc:24:11:75:87:8b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;none&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;DOWN&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;400 &lt;em&gt;(inferred)&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;Network Storage&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ens19&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bc:24:11:03:42:ab&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;none&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;DOWN&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;Main internal&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ens20&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bc:24:11:e9:84:e3&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.1.2.78/20&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;UP, DHCP&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Default route &lt;code&gt;10.1.1.3&lt;/code&gt; via &lt;code&gt;ens20&lt;/code&gt;; single nameserver &lt;code&gt;10.1.1.10&lt;/code&gt; (srv02gate);
domain &lt;code&gt;home&lt;/code&gt;, &lt;strong&gt;no search list&lt;/strong&gt;. Only &lt;code&gt;ens20&lt;/code&gt; appears in
&lt;code&gt;/etc/network/interfaces.d/&lt;/code&gt;; the collector correctly flags &lt;code&gt;ens18&lt;/code&gt;/&lt;code&gt;ens19&lt;/code&gt; as
runtime-present but unconfigured. Their VLANs are inferred from the hypervisor
placement deduced in §4, not observed — see &lt;code&gt;V-08&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This is also the only guest whose FQDN is unqualified (&lt;code&gt;vm012-clickhouse&lt;/code&gt;, not
&lt;code&gt;vm012-clickhouse.vm.home&lt;/code&gt;), consistent with its truncated resolver
configuration.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="4-which-hypervisor-hosts-which-guest"&gt;4. Which hypervisor hosts which guest&lt;/h2&gt;
&lt;p&gt;No direct evidence links a &lt;code&gt;vm*&lt;/code&gt; guest to a hypervisor: the guest MACs
(&lt;code&gt;bc:24:11:0a:f0:87&lt;/code&gt; etc.) appear in &lt;strong&gt;neither&lt;/strong&gt; &lt;code&gt;hostenv_srv01hv_*.md&lt;/code&gt; nor
&lt;code&gt;hostenv_srv06hv_*.md&lt;/code&gt;. The only guest MACs the hypervisors observe are
&lt;code&gt;bc:24:11:96:d2:e9&lt;/code&gt; / &lt;code&gt;bc:24:11:9b:57:1a&lt;/code&gt; on srv01hv&amp;rsquo;s &lt;code&gt;tap105i0&lt;/code&gt;/&lt;code&gt;tap105i1&lt;/code&gt;,
learned via LLDP from a guest that advertises itself as &lt;code&gt;VM006-WIN&lt;/code&gt; — a Windows
machine, not one of ours. The collector runs no &lt;code&gt;ip neigh&lt;/code&gt;, no &lt;code&gt;bridge fdb&lt;/code&gt; and no
&lt;code&gt;qm list&lt;/code&gt;, so there is no lookup table to consult.&lt;/p&gt;
&lt;p&gt;Placement below is therefore &lt;strong&gt;deduced&lt;/strong&gt;, from three constraints.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Constraint 1 — guest CPU model identifies the host CPU when &lt;code&gt;cpu: host&lt;/code&gt; is set.&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Hypervisor&lt;/th&gt;
&lt;th&gt;Host CPU&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;srv01hv (Minisforum MS-A2)&lt;/td&gt;
&lt;td&gt;AMD Ryzen 9 7940HX&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv06hv (Dell PowerEdge R740xd)&lt;/td&gt;
&lt;td&gt;Intel Xeon Gold 6138&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Three guests report &lt;code&gt;Intel(R) Xeon(R) Gold 6138 CPU @ 2.00GHz&lt;/code&gt; — vm001-devel,
vm002-docker and vm012-clickhouse — so those three are &lt;strong&gt;on srv06hv&lt;/strong&gt;. The other
four report &lt;code&gt;QEMU Virtual CPU version 2.5+&lt;/code&gt;, the default &lt;code&gt;kvm64&lt;/code&gt; model, which
masks the host and yields nothing. &lt;strong&gt;No guest reports an AMD Ryzen.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Constraint 2 — NIC count and per-index VLAN must match the hypervisor&amp;rsquo;s tap →
bridge wiring.&lt;/strong&gt; From the hypervisors&amp;rsquo; §2.4 topology:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Node&lt;/th&gt;
&lt;th&gt;VMID&lt;/th&gt;
&lt;th&gt;net0&lt;/th&gt;
&lt;th&gt;net1&lt;/th&gt;
&lt;th&gt;net2&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;srv01hv&lt;/td&gt;
&lt;td&gt;105&lt;/td&gt;
&lt;td&gt;204&lt;/td&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv01hv&lt;/td&gt;
&lt;td&gt;106&lt;/td&gt;
&lt;td&gt;204&lt;/td&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;400 &lt;em&gt;(tap direct to &lt;code&gt;vmbr4nas&lt;/code&gt;, no &lt;code&gt;fwbr&lt;/code&gt;)&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv01hv&lt;/td&gt;
&lt;td&gt;107&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;10 (IoT)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;204&lt;/td&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv06hv&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;204&lt;/td&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv06hv&lt;/td&gt;
&lt;td&gt;101&lt;/td&gt;
&lt;td&gt;204&lt;/td&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv06hv&lt;/td&gt;
&lt;td&gt;102&lt;/td&gt;
&lt;td&gt;204&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;400&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv06hv&lt;/td&gt;
&lt;td&gt;103&lt;/td&gt;
&lt;td&gt;204&lt;/td&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv06hv&lt;/td&gt;
&lt;td&gt;104&lt;/td&gt;
&lt;td&gt;204&lt;/td&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;400 &lt;em&gt;(tap direct to &lt;code&gt;vmbr2nas&lt;/code&gt;, no &lt;code&gt;fwbr&lt;/code&gt;)&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv06hv&lt;/td&gt;
&lt;td&gt;110&lt;/td&gt;
&lt;td&gt;204&lt;/td&gt;
&lt;td&gt;200 &lt;em&gt;(tap direct to &lt;code&gt;vmbr1plc&lt;/code&gt;, no &lt;code&gt;fwbr&lt;/code&gt;)&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv06hv&lt;/td&gt;
&lt;td&gt;112&lt;/td&gt;
&lt;td&gt;204&lt;/td&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Constraint 3 — VMID 105 is &lt;code&gt;VM006-WIN&lt;/code&gt;&lt;/strong&gt;, per the LLDP chassis TLV on srv01hv,
so it is not a &lt;code&gt;vm*&lt;/code&gt; guest. That leaves srv01hv with &lt;strong&gt;no&lt;/strong&gt; free two-NIC slot.&lt;/p&gt;
&lt;p&gt;Applying all three:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Guest&lt;/th&gt;
&lt;th&gt;NIC profile&lt;/th&gt;
&lt;th&gt;Placement&lt;/th&gt;
&lt;th&gt;Confidence&lt;/th&gt;
&lt;th&gt;Basis&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;vm001-devel&lt;/td&gt;
&lt;td&gt;204, 200&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;srv06hv&lt;/strong&gt;, one of VMID 100/101/103/110/112&lt;/td&gt;
&lt;td&gt;node: high; VMID: unresolved&lt;/td&gt;
&lt;td&gt;Xeon CPU&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vm002-docker&lt;/td&gt;
&lt;td&gt;204, 200&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;srv06hv&lt;/strong&gt;, one of VMID 100/101/103/110/112&lt;/td&gt;
&lt;td&gt;node: high; VMID: unresolved&lt;/td&gt;
&lt;td&gt;Xeon CPU&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vm004-es&lt;/td&gt;
&lt;td&gt;204, 200&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;srv06hv&lt;/strong&gt;, one of VMID 100/101/103/110/112&lt;/td&gt;
&lt;td&gt;node: medium; VMID: unresolved&lt;/td&gt;
&lt;td&gt;only free 2-NIC slots are on srv06hv&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vm010-db&lt;/td&gt;
&lt;td&gt;204, 200&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;srv06hv&lt;/strong&gt;, one of VMID 100/101/103/110/112&lt;/td&gt;
&lt;td&gt;node: medium; VMID: unresolved&lt;/td&gt;
&lt;td&gt;as above&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vm011-jenkins&lt;/td&gt;
&lt;td&gt;204, 200&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;srv06hv&lt;/strong&gt;, one of VMID 100/101/103/110/112&lt;/td&gt;
&lt;td&gt;node: medium; VMID: unresolved&lt;/td&gt;
&lt;td&gt;as above&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vm012-clickhouse&lt;/td&gt;
&lt;td&gt;204↓, 400↓, 200&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;srv06hv VMID 102&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;high&lt;/td&gt;
&lt;td&gt;Xeon CPU + only 3-NIC profile whose net2 is VLAN 200 on that node&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vm005-obj&lt;/td&gt;
&lt;td&gt;204, 200, 400&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;srv01hv VMID 106 or srv06hv VMID 104&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;unresolved&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;profile matches both exactly; generic CPU gives no signal&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The five two-NIC guests exactly fill srv06hv&amp;rsquo;s five two-NIC slots
(100, 101, 103, 110, 112), which is a clean fit but &lt;em&gt;is&lt;/em&gt; a pigeonhole argument: it
holds only if all seven &lt;code&gt;vm*&lt;/code&gt; guests are Proxmox guests of these two nodes (their
&lt;code&gt;bc:24:11&lt;/code&gt; MAC prefix and &lt;code&gt;Virtualisation: kvm&lt;/code&gt; support this, and no third
Proxmox node exists in the estate) and if no other unscanned guest occupies one of
those slots. Treat the node assignment as strong, the VMID assignment as open.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;vm012-clickhouse = VMID 102 is the firmest single result here.&lt;/strong&gt; It is the only
guest with three NICs where net2 lands on VLAN 200; srv01hv&amp;rsquo;s only such profile is
VMID 107, which would have reported an AMD CPU. It follows that vm012&amp;rsquo;s dead
&lt;code&gt;ens18&lt;/code&gt; is on VLAN 204 and its dead &lt;code&gt;ens19&lt;/code&gt; is on &lt;strong&gt;VLAN 400, the storage
segment&lt;/strong&gt; — a live tap into storage on a NIC nobody has configured.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;One determinate conclusion survives the vm005-obj ambiguity.&lt;/strong&gt; Both candidate
slots — srv01hv &lt;code&gt;tap106i2&lt;/code&gt; → &lt;code&gt;vmbr4nas&lt;/code&gt; and srv06hv &lt;code&gt;tap104i2&lt;/code&gt; → &lt;code&gt;vmbr2nas&lt;/code&gt; — are
among the three taps that &lt;code&gt;NETWORK_TOPOLOGY.md&lt;/code&gt; &lt;code&gt;T-09&lt;/code&gt; identified as enslaved
directly to a bridge with no &lt;code&gt;fwbr&lt;/code&gt; interposed. So &lt;em&gt;whichever&lt;/em&gt; node it is on,
&lt;strong&gt;vm005-obj&amp;rsquo;s VLAN 400 interface has no per-VM filter bridge&lt;/strong&gt;. As &lt;code&gt;V-01&lt;/code&gt; shows,
this turns out not to matter, because the filter bridges enforce nothing anyway.&lt;/p&gt;
&lt;p&gt;A timing caveat: the guest reports were collected 2026-08-25 23:10–23:14 and the
hypervisor reports 2026-08-26 12:12/12:35, roughly 13 hours later. A live
migration or a start/stop in that window would invalidate the placement. Nothing
in the data suggests one occurred, but nothing rules it out either.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="5-exposed-ports-and-services"&gt;5. Exposed ports and services&lt;/h2&gt;
&lt;h3 id="51-the-governing-rule"&gt;5.1 The governing rule&lt;/h3&gt;
&lt;p&gt;A guest socket bound to &lt;code&gt;0.0.0.0&lt;/code&gt; or &lt;code&gt;::&lt;/code&gt; is reachable &lt;strong&gt;on every VLAN that guest
has an interface in&lt;/strong&gt;, with no per-VLAN distinction, because:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;No &lt;code&gt;vm*&lt;/code&gt; guest runs a host firewall (§2).&lt;/li&gt;
&lt;li&gt;The hypervisors&amp;rsquo; per-VM firewall chains are &lt;strong&gt;empty&lt;/strong&gt; (&lt;code&gt;V-01&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So the &amp;ldquo;Interfaces&amp;rdquo; column of each guest&amp;rsquo;s own section 5 is the answer, and its
&lt;code&gt;unknown — firewall data unavailable&lt;/code&gt; verdict resolves to &lt;strong&gt;reachable&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id="52-reachable-listeners-by-guest"&gt;5.2 Reachable listeners, by guest&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;✔&lt;/code&gt; = bound to a wildcard address and therefore reachable on that VLAN.
Loopback-bound sockets are listed separately and are &lt;strong&gt;not&lt;/strong&gt; reachable.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Guest&lt;/th&gt;
&lt;th&gt;Proto/Port&lt;/th&gt;
&lt;th&gt;Service&lt;/th&gt;
&lt;th&gt;Process&lt;/th&gt;
&lt;th&gt;VLAN 200&lt;/th&gt;
&lt;th&gt;VLAN 204&lt;/th&gt;
&lt;th&gt;VLAN 400&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;vm001-devel&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;tcp/22&lt;/td&gt;
&lt;td&gt;SSH&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sshd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;tcp/111, udp/111&lt;/td&gt;
&lt;td&gt;RPC portmapper&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rpcbind&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;tcp/443&lt;/td&gt;
&lt;td&gt;HTTPS&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nginx&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;tcp/5355, udp/5355&lt;/td&gt;
&lt;td&gt;LLMNR&lt;/td&gt;
&lt;td&gt;&lt;code&gt;systemd-resolved&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;vm002-docker&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;tcp/22&lt;/td&gt;
&lt;td&gt;SSH&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sshd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;tcp/80, tcp/443&lt;/td&gt;
&lt;td&gt;Traefik ingress&lt;/td&gt;
&lt;td&gt;&lt;code&gt;docker-proxy&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;tcp/111, udp/111&lt;/td&gt;
&lt;td&gt;RPC portmapper&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rpcbind&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;tcp/389&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;LDAP (cleartext)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dockerd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;tcp/1514&lt;/td&gt;
&lt;td&gt;syslog / agent enrolment&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dockerd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;tcp/1688&lt;/td&gt;
&lt;td&gt;KMS emulator (&lt;code&gt;vlmcsd&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;docker-proxy&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;tcp/2222&lt;/td&gt;
&lt;td&gt;alternate SSH (container)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dockerd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;tcp/2377&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Swarm cluster management&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dockerd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;tcp/7946, udp/7946&lt;/td&gt;
&lt;td&gt;Swarm gossip&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dockerd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;udp/4789&lt;/td&gt;
&lt;td&gt;VXLAN overlay&lt;/td&gt;
&lt;td&gt;&lt;em&gt;(kernel)&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;vm004-es&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;tcp/22&lt;/td&gt;
&lt;td&gt;SSH&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sshd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;tcp/80, tcp/443&lt;/td&gt;
&lt;td&gt;reverse proxy&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nginx&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;tcp/111, udp/111&lt;/td&gt;
&lt;td&gt;RPC portmapper&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rpcbind&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;vm005-obj&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;tcp/22&lt;/td&gt;
&lt;td&gt;SSH&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sshd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;tcp/80, tcp/443&lt;/td&gt;
&lt;td&gt;reverse proxy&lt;/td&gt;
&lt;td&gt;&lt;code&gt;openresty&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;tcp/111, udp/111&lt;/td&gt;
&lt;td&gt;RPC portmapper&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rpcbind&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;tcp/36105, tcp/50647, udp/45714, udp/53735&lt;/td&gt;
&lt;td&gt;NFS status monitor&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rpc.statd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;tcp/41877, tcp/46691, udp/44413, udp/46796&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;unattributed&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;vm010-db&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;tcp/22&lt;/td&gt;
&lt;td&gt;SSH&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sshd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;tcp/111, udp/111&lt;/td&gt;
&lt;td&gt;RPC portmapper&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rpcbind&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;tcp/3306&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;MariaDB&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mariadbd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;tcp/6379&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Valkey / Redis&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;valkey-server&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;vm011-jenkins&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;tcp/22&lt;/td&gt;
&lt;td&gt;SSH&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sshd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;tcp/111, udp/111&lt;/td&gt;
&lt;td&gt;RPC portmapper&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rpcbind&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;tcp/433&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;HTTPS &lt;strong&gt;on the wrong port&lt;/strong&gt;, IPv6 only&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nginx&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;tcp/443&lt;/td&gt;
&lt;td&gt;HTTPS, IPv4 only&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nginx&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;tcp/5355, udp/5355&lt;/td&gt;
&lt;td&gt;LLMNR&lt;/td&gt;
&lt;td&gt;&lt;code&gt;systemd-resolved&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;tcp/8080&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Jenkins, direct&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;java&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;vm012-clickhouse&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;tcp/22&lt;/td&gt;
&lt;td&gt;SSH&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sshd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;tcp/80, tcp/443&lt;/td&gt;
&lt;td&gt;reverse proxy&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nginx&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;tcp/111, udp/111&lt;/td&gt;
&lt;td&gt;RPC portmapper&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rpcbind&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;tcp/8123&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;ClickHouse HTTP&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;clickhouse&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;tcp/9000&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;ClickHouse native protocol&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;clickhouse&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;tcp/9004&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;ClickHouse MySQL wire protocol&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;clickhouse&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;tcp/9005&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;ClickHouse PostgreSQL wire protocol&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;clickhouse&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;tcp/9090&lt;/td&gt;
&lt;td&gt;Vector metrics/API&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vector&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;udp/43060&lt;/td&gt;
&lt;td&gt;ClickHouse (secondary)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;clickhouse&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="53-correctly-confined-listeners"&gt;5.3 Correctly confined listeners&lt;/h3&gt;
&lt;p&gt;These are bound to &lt;code&gt;127.0.0.1&lt;/code&gt;/&lt;code&gt;::1&lt;/code&gt; and are &lt;strong&gt;not&lt;/strong&gt; reachable from any VLAN.
They are listed because they show the pattern the estate &lt;em&gt;does&lt;/em&gt; get right in
places, which makes the wildcard binds above look like oversights rather than
policy.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Guest&lt;/th&gt;
&lt;th&gt;Loopback-only sockets&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;vm001-devel&lt;/td&gt;
&lt;td&gt;tcp/8686 &lt;code&gt;vector&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vm002-docker&lt;/td&gt;
&lt;td&gt;tcp/8686 &lt;code&gt;vector&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vm004-es&lt;/td&gt;
&lt;td&gt;tcp/9200 + tcp/9300 &lt;code&gt;elasticsearch&lt;/code&gt;, tcp/5601 &lt;code&gt;kibana&lt;/code&gt;, tcp/8686 &lt;code&gt;vector&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vm005-obj&lt;/td&gt;
&lt;td&gt;tcp/3900–3904 &lt;code&gt;garage&lt;/code&gt;, udp/809 &lt;code&gt;rpc.statd&lt;/code&gt;, tcp/8686 &lt;code&gt;vector&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vm010-db&lt;/td&gt;
&lt;td&gt;tcp/8686 &lt;code&gt;vector&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vm011-jenkins&lt;/td&gt;
&lt;td&gt;tcp/8686 &lt;code&gt;vector&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vm012-clickhouse&lt;/td&gt;
&lt;td&gt;tcp/8686 &lt;code&gt;vector&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;vm004-es and vm005-obj are the models: the data-plane service (Elasticsearch,
Garage) listens only on loopback and a reverse proxy on 80/443 is the sole network
entry point. vm010-db, vm011-jenkins and vm012-clickhouse run a reverse proxy
&lt;em&gt;and&lt;/em&gt; expose the backend directly alongside it, which defeats the proxy.&lt;/p&gt;
&lt;h3 id="54-vm002-docker-published-container-ports"&gt;5.4 vm002-docker published container ports&lt;/h3&gt;
&lt;p&gt;25 containers publish ports. The collector correctly marks 80, 443 and 1688 as
&lt;code&gt;container-bypass&lt;/code&gt;: Docker&amp;rsquo;s DNAT rules are inserted ahead of any host firewall,
so these are reachable regardless of host policy. On this guest there is no host
policy to bypass in the first place.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Container&lt;/th&gt;
&lt;th&gt;Image&lt;/th&gt;
&lt;th&gt;Published&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;traefik_traefik&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;traefik:v3.7&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0.0.0.0:80→80&lt;/code&gt;, &lt;code&gt;[::]:80→80&lt;/code&gt;, &lt;code&gt;0.0.0.0:443→443&lt;/code&gt;, &lt;code&gt;[::]:443→443&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;vlmcsd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vlmcsd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0.0.0.0:1688→1688&lt;/code&gt;, &lt;code&gt;[::]:1688→1688&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gitlab_gitlab&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;gitlab/gitlab-ce:18.10.1-ce.0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;22, 80, 443&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;vaultwarden_vaultwarden&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vaultwarden/server:latest&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;80&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;netbox_postgres&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;postgres:17-alpine&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;5432&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;netbox_redis&lt;/code&gt;, &lt;code&gt;netbox_redis-cache&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;valkey/valkey:8.1-alpine&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;6379&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;wiki_wiki&lt;/code&gt;, &lt;code&gt;wiki&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ghcr.io/requarks/wiki:latest&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;3000, 3443&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;wiki_wiki-db&lt;/code&gt;, &lt;code&gt;container-defs-wiki-db-1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;postgres:15-alpine&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;5432&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;grafana_grafana&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;grafana/grafana:latest&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;3000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;open-webui_open-webui&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ghcr.io/open-webui/open-webui:main&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;8080&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;drawio_drawio&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;jgraph/drawio:latest&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;8080, 8443&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;striling-pdf_stirling-pdf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;docker.stirlingpdf.com/stirlingtools/stirling-pdf:latest&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;8080&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;filestash_app&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;machines/filestash:latest&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;8334&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;polaris_app&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;registry.gitlab.com/connectical/container/polaris:latest&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;5050&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;vikunja_vikunja&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vikunja/vikunja:2.3.0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;3456&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pairdrop_pairdrop&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;lscr.io/linuxserver/pairdrop:latest&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;3000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;app-weighins&lt;/code&gt;, &lt;code&gt;app-omnibackend&lt;/code&gt;, &lt;code&gt;app-docviewer&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;registry.hub.home/apps/*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;3000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;app-vox-lunaris&lt;/code&gt;, &lt;code&gt;app-archivium&lt;/code&gt;, &lt;code&gt;app-bulletin&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;registry.hub.home/apps/*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;80&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Only Traefik and &lt;code&gt;vlmcsd&lt;/code&gt; publish to a host address; the rest expose ports on the
Swarm overlay reached through Traefik.&lt;/p&gt;
&lt;p&gt;The 25 container entries run 22 distinct images. &lt;strong&gt;14 of those 22 are pinned to
&lt;code&gt;:latest&lt;/code&gt;&lt;/strong&gt; — vaultwarden, wiki,
grafana, drawio, filestash, polaris, pairdrop, stirling-pdf and all six
&lt;code&gt;registry.hub.home/apps/*&lt;/code&gt; images — and &lt;code&gt;open-webui&lt;/code&gt; is pinned to the equally
mutable &lt;code&gt;:main&lt;/code&gt;. The running version of more than half the estate&amp;rsquo;s containerised
services is therefore not recoverable from configuration, which blocks both patch
verification and rollback. Only GitLab (&lt;code&gt;18.10.1-ce.0&lt;/code&gt;), Traefik (&lt;code&gt;v3.7&lt;/code&gt;), Vikunja
(&lt;code&gt;2.3.0&lt;/code&gt;), Postgres (&lt;code&gt;17-alpine&lt;/code&gt;, &lt;code&gt;15-alpine&lt;/code&gt;) and Valkey (&lt;code&gt;8.1-alpine&lt;/code&gt;) are
pinned to something reproducible.&lt;/p&gt;
&lt;h3 id="55-storage-dependencies"&gt;5.5 Storage dependencies&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Guest&lt;/th&gt;
&lt;th&gt;Mount&lt;/th&gt;
&lt;th&gt;Transport&lt;/th&gt;
&lt;th&gt;Served by&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;vm001-devel&lt;/td&gt;
&lt;td&gt;&lt;code&gt;//nas.home/lxsky&lt;/code&gt;, &lt;code&gt;//nas.home/home-tmpshare&lt;/code&gt;, &lt;code&gt;//nas.home/home-public&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;CIFS/SMB&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;srv04fs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vm001-devel, vm004-es, vm010-db, vm011-jenkins, vm012-clickhouse&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nas.home:/share-mnts/infra&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;NFSv4&lt;/td&gt;
&lt;td&gt;srv04fs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vm002-docker&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nas.home:/share-mnts/infra&lt;/code&gt; → &lt;code&gt;/share-nas&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;NFSv4&lt;/td&gt;
&lt;td&gt;srv04fs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vm005-obj&lt;/td&gt;
&lt;td&gt;&lt;code&gt;srv04fs.nas.home:/share-mnts/objects&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;NFSv4&lt;/td&gt;
&lt;td&gt;srv04fs, over VLAN 400&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vm005-obj&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nas.home:/share-mnts/infra&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;NFS&lt;/td&gt;
&lt;td&gt;srv04fs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Every guest mounts from srv04fs. Only vm005-obj has a VLAN 400 interface; the
other six reach the same file server &lt;strong&gt;through VLAN 200 and the TL-SE5226&lt;/strong&gt;, so
NFS and SMB traffic for six guests crosses the general-purpose internal VLAN
rather than the segment designated for it. &lt;code&gt;SRV_HOST_SECURITY_AUDIT.md&lt;/code&gt; already
notes srv04fs has no host firewall and serves 2049/tcp and 445/tcp on all
interfaces.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="6-vlan-inventory-as-seen-from-the-guests"&gt;6. VLAN inventory as seen from the guests&lt;/h2&gt;
&lt;p&gt;Roles and designated ranges from &lt;code&gt;Designated VLANs.md&lt;/code&gt;. &amp;ldquo;Audit scope&amp;rdquo; is the four
VLANs authorized in &lt;code&gt;TASK.md&lt;/code&gt;/&lt;code&gt;AGENTS.md&lt;/code&gt;; the designation file is a
network-design document, not an extension of scan authorization.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;VLAN&lt;/th&gt;
&lt;th&gt;Designated role&lt;/th&gt;
&lt;th&gt;Designated range&lt;/th&gt;
&lt;th&gt;Observed subnet&lt;/th&gt;
&lt;th&gt;Scan scope&lt;/th&gt;
&lt;th&gt;&lt;code&gt;vm*&lt;/code&gt; addresses&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;Main internal&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.1.1.0/20&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.1.0.0/20&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;in scope&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;vm005-obj &lt;code&gt;.2.31&lt;/code&gt;, vm011-jenkins &lt;code&gt;.2.68&lt;/code&gt;, vm004-es &lt;code&gt;.2.70&lt;/code&gt;, vm010-db &lt;code&gt;.2.71&lt;/code&gt;, vm002-docker &lt;code&gt;.2.73&lt;/code&gt;, vm012-clickhouse &lt;code&gt;.2.78&lt;/code&gt;, vm001-devel &lt;code&gt;.2.83&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;204&lt;/td&gt;
&lt;td&gt;VMs Interconnect&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.128.128.0/24&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.128.128.0/24&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;not in scope&lt;/td&gt;
&lt;td&gt;vm002-docker &lt;code&gt;.4&lt;/code&gt;, vm001-devel &lt;code&gt;.7&lt;/code&gt;, vm005-obj &lt;code&gt;.13&lt;/code&gt;, vm011-jenkins &lt;code&gt;.15&lt;/code&gt;, vm004-es &lt;code&gt;.16&lt;/code&gt;, vm010-db &lt;code&gt;.17&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;400&lt;/td&gt;
&lt;td&gt;Network Storage&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.255.255.0/24&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.255.255.0/24&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;not in scope&lt;/td&gt;
&lt;td&gt;vm005-obj &lt;code&gt;10.255.255.8&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;IoT&lt;/td&gt;
&lt;td&gt;&lt;code&gt;172.17.1.0/16&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;172.17.0.0/16&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;in scope&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;none — but &lt;strong&gt;shadowed by &lt;code&gt;docker0&lt;/code&gt; on three guests&lt;/strong&gt; (&lt;code&gt;V-04&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Every guest address falls inside its designated range.&lt;/strong&gt; No guest is addressed
outside the design.&lt;/p&gt;
&lt;p&gt;A clear addressing convention emerges that is not written down anywhere in the
repository: within VLAN 200&amp;rsquo;s &lt;code&gt;10.1.0.0/20&lt;/code&gt;, &lt;strong&gt;&lt;code&gt;10.1.1.0/24&lt;/code&gt; holds infrastructure&lt;/strong&gt;
(srv02gate &lt;code&gt;.10&lt;/code&gt;, srv01hv &lt;code&gt;.11&lt;/code&gt;, srv03mm &lt;code&gt;.12&lt;/code&gt;, srv04fs &lt;code&gt;.13&lt;/code&gt;, srv05access &lt;code&gt;.14&lt;/code&gt;,
srv06hv &lt;code&gt;.15&lt;/code&gt;, switch &lt;code&gt;.3&lt;/code&gt;, unidentified gateway &lt;code&gt;.1&lt;/code&gt;) and &lt;strong&gt;&lt;code&gt;10.1.2.0/24&lt;/code&gt; holds
guests&lt;/strong&gt; (all seven &lt;code&gt;vm*&lt;/code&gt;). Both are DHCP-assigned. The split is consistent across
all thirteen collected hosts and is worth documenting before it is broken.&lt;/p&gt;
&lt;p&gt;Only VLAN 200 of the guests&amp;rsquo; three VLANs is inside the authorized scan scope.
VLANs 204 and 400 appear here solely because they were read from on-host
configuration; nothing was scanned in them.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="7-topology-diagrams"&gt;7. Topology diagrams&lt;/h2&gt;
&lt;h3 id="71-guest--hypervisor-bridge--vlan"&gt;7.1 Guest → hypervisor bridge → VLAN&lt;/h3&gt;
&lt;p&gt;Dashed edges are deduced placements (§4), solid edges are read directly from the
guest&amp;rsquo;s own configuration.&lt;/p&gt;
&lt;div class="mermaid"&gt;flowchart LR
subgraph HV6["srv06hv — Dell R740xd, Xeon Gold 6138"]
B60["vmbr0vm&lt;br/&gt;ens2f0.204&lt;br/&gt;10.128.128.2"]
B61["vmbr1plc&lt;br/&gt;ens2f0.200&lt;br/&gt;10.1.1.15"]
B62["vmbr2nas&lt;br/&gt;ens2f0.400&lt;br/&gt;10.255.255.1"]
end
subgraph HV1["srv01hv — Minisforum MS-A2, Ryzen 9 7940HX"]
B10["vmbr0vm&lt;br/&gt;eth0p0.204&lt;br/&gt;10.128.128.20"]
B11["vmbr1plc&lt;br/&gt;enp3s0.200&lt;br/&gt;10.1.1.11"]
B14["vmbr4nas&lt;br/&gt;eth0p0.400&lt;br/&gt;10.255.255.7"]
end
V1["vm001-devel&lt;br/&gt;.128.7 / 10.1.2.83"]
V2["vm002-docker&lt;br/&gt;.128.4 / 10.1.2.73"]
V4["vm004-es&lt;br/&gt;.128.16 / 10.1.2.70"]
V10["vm010-db&lt;br/&gt;.128.17 / 10.1.2.71"]
V11["vm011-jenkins&lt;br/&gt;.128.15 / 10.1.2.68"]
V12["vm012-clickhouse = VMID 102&lt;br/&gt;10.1.2.78&lt;br/&gt;ens18, ens19 DOWN"]
V5["vm005-obj&lt;br/&gt;.128.13 / 10.1.2.31 / 10.255.255.8&lt;br/&gt;node UNRESOLVED"]
V1 --- B60
V1 --- B61
V2 --- B60
V2 --- B61
V4 --- B60
V4 --- B61
V10 --- B60
V10 --- B61
V11 --- B60
V11 --- B61
V12 --- B61
V12 -.-&gt;|"ens18 DOWN"| B60
V12 -.-&gt;|"ens19 DOWN"| B62
V5 -.-&gt;|"if VMID 104"| B60
V5 -.-&gt;|"if VMID 104"| B61
V5 -.-&gt;|"if VMID 104, no fwbr"| B62
V5 -.-&gt;|"if VMID 106"| B10
V5 -.-&gt;|"if VMID 106"| B11
V5 -.-&gt;|"if VMID 106, no fwbr"| B14
classDef vm fill:#e8f0fe,stroke:#4285f4
classDef br fill:#fff4e5,stroke:#f9ab00
class V1,V2,V4,V5,V10,V11,V12 vm
class B60,B61,B62,B10,B11,B14 br
&lt;/div&gt;
&lt;h3 id="72-reachability--what-listens-where"&gt;7.2 Reachability — what listens where&lt;/h3&gt;
&lt;div class="mermaid"&gt;flowchart TB
SW["TL-SE5226&lt;br/&gt;L3 gateway 10.1.1.3&lt;br/&gt;routes VLAN 200"]
subgraph VL200["VLAN 200 — Main internal, 10.1.0.0/20 — IN AUDIT SCOPE"]
direction LR
P200A["vm012-clickhouse 10.1.2.78&lt;br/&gt;22, 80, 111, 443&lt;br/&gt;8123, 9000, 9004, 9005, 9090"]
P200B["vm010-db 10.1.2.71&lt;br/&gt;22, 111, 3306, 6379"]
P200C["vm002-docker 10.1.2.73&lt;br/&gt;22, 80, 111, 389, 443&lt;br/&gt;1514, 1688, 2222, 2377, 7946"]
P200D["vm011-jenkins 10.1.2.68&lt;br/&gt;22, 111, 433, 443, 5355, 8080"]
P200E["vm001-devel 10.1.2.83&lt;br/&gt;22, 111, 443, 5355"]
P200F["vm004-es 10.1.2.70&lt;br/&gt;22, 80, 111, 443"]
P200G["vm005-obj 10.1.2.31&lt;br/&gt;22, 80, 111, 443, statd"]
end
subgraph VL204["VLAN 204 — VMs Interconnect, 10.128.128.0/24 — not in scan scope"]
direction LR
P204["identical listener set on&lt;br/&gt;10.128.128.4, .7, .13, .15, .16, .17&lt;br/&gt;every wildcard bind repeats here"]
end
subgraph VL400["VLAN 400 — Network Storage, 10.255.255.0/24 — not in scan scope"]
direction LR
P400["vm005-obj 10.255.255.8&lt;br/&gt;22, 80, 111, 443, statd&lt;br/&gt;no per-VM filter bridge"]
end
NAS["srv04fs — dual-homed, no host firewall&lt;br/&gt;10.1.1.13 on VLAN 200&lt;br/&gt;10.255.255.9 on VLAN 400&lt;br/&gt;NFS 2049, SMB 445 on all interfaces"]
SW --&gt; P200A
SW --&gt; P200B
SW --&gt; P200C
SW --&gt; P200D
SW --&gt; P200E
SW --&gt; P200F
SW --&gt; P200G
P200B -.-&gt;|"second NIC"| P204
P200C -.-&gt;|"second NIC"| P204
P200D -.-&gt;|"second NIC"| P204
P200E -.-&gt;|"second NIC"| P204
P200F -.-&gt;|"second NIC"| P204
P200G -.-&gt;|"second NIC"| P204
P200G -.-&gt;|"third NIC"| P400
P200A --&gt;|"NFS over VLAN 200"| NAS
P200B --&gt;|"NFS over VLAN 200"| NAS
P200C --&gt;|"NFS over VLAN 200"| NAS
P200D --&gt;|"NFS over VLAN 200"| NAS
P200E --&gt;|"NFS + CIFS over VLAN 200"| NAS
P200F --&gt;|"NFS over VLAN 200"| NAS
P400 --&gt;|"NFS over VLAN 400"| NAS
classDef inscope fill:#fce8e6,stroke:#d93025
classDef outscope fill:#f1f3f4,stroke:#9aa0a6
classDef nas fill:#e6f4ea,stroke:#137333
class P200A,P200B,P200C,P200D,P200E,P200F,P200G inscope
class P204,P400 outscope
class NAS nas
&lt;/div&gt;
&lt;p&gt;Only vm005-obj reaches the file server over the segment designated for storage
(&lt;code&gt;V-10&lt;/code&gt;). The other six cross VLAN 200, and vm012-clickhouse has a VLAN 400 NIC
that would carry it but is unconfigured (&lt;code&gt;V-08&lt;/code&gt;).&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="8-findings"&gt;8. Findings&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ID&lt;/th&gt;
&lt;th&gt;Summary&lt;/th&gt;
&lt;th&gt;Bears on&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;V-01&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Proxmox per-VM firewall chains are &lt;strong&gt;empty&lt;/strong&gt; — no guest traffic is filtered anywhere&lt;/td&gt;
&lt;td&gt;all guests&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;V-02&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Database and cache services bound to all interfaces with no filtering&lt;/td&gt;
&lt;td&gt;vm010-db, vm012-clickhouse&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;V-03&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Every wildcard-bound guest service is duplicated onto VLAN 204&lt;/td&gt;
&lt;td&gt;6 guests&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;V-04&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;docker0&lt;/code&gt;&amp;rsquo;s &lt;code&gt;172.17.0.0/16&lt;/code&gt; shadows the entire IoT VLAN&lt;/td&gt;
&lt;td&gt;vm001-devel, vm002-docker, vm011-jenkins&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;V-05&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;nginx listens on tcp/433 instead of 443 for IPv6&lt;/td&gt;
&lt;td&gt;vm011-jenkins&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;V-06&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Backend services exposed alongside the reverse proxy meant to front them&lt;/td&gt;
&lt;td&gt;vm010-db, vm011-jenkins, vm012-clickhouse&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;V-07&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;VLAN membership is invisible from inside the guest&lt;/td&gt;
&lt;td&gt;all guests&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;V-08&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Two configured-but-dead NICs, one of them on the storage VLAN&lt;/td&gt;
&lt;td&gt;vm012-clickhouse&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;V-09&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Cleartext LDAP and Swarm control plane published to VLAN 200&lt;/td&gt;
&lt;td&gt;vm002-docker&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;V-10&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Six of seven guests carry NFS/SMB traffic across VLAN 200, bypassing VLAN 400&lt;/td&gt;
&lt;td&gt;6 guests&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;V-11&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Collector mislabels a bridge-bound socket as loopback-only&lt;/td&gt;
&lt;td&gt;&lt;code&gt;collect_host_env.py&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;V-12&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Collector&amp;rsquo;s interface-stacking renderer misparents container &lt;code&gt;veth&lt;/code&gt;s&lt;/td&gt;
&lt;td&gt;&lt;code&gt;collect_host_env.py&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;V-13&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Unattributed listening sockets on vm005-obj&lt;/td&gt;
&lt;td&gt;vm005-obj&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;V-14&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;vm010-db clock unsynchronised; vm001-devel runs a &lt;code&gt;-dirty&lt;/code&gt; kernel&lt;/td&gt;
&lt;td&gt;vm010-db, vm001-devel&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="v-01--the-proxmox-per-vm-firewall-enforces-nothing"&gt;V-01 — The Proxmox per-VM firewall enforces nothing&lt;/h3&gt;
&lt;p&gt;This is the finding that determines the severity of every other one, so it is
stated first and with its evidence.&lt;/p&gt;
&lt;p&gt;Both hypervisors build the full Proxmox filter scaffolding — a &lt;code&gt;fwbr&amp;lt;vmid&amp;gt;i&amp;lt;n&amp;gt;&lt;/code&gt;
bridge with an &lt;code&gt;fwln&lt;/code&gt;/&lt;code&gt;fwpr&lt;/code&gt; veth pair for almost every guest NIC. That scaffolding
is what &lt;code&gt;NETWORK_TOPOLOGY.md&lt;/code&gt; &lt;code&gt;T-09&lt;/code&gt; was reasoning about when it flagged three taps
as &amp;ldquo;bypassing the per-VM firewall bridge&amp;rdquo;. Re-deriving from the raw
&lt;code&gt;fw.iptables&lt;/code&gt; appendix on both nodes shows the bridges are &lt;strong&gt;empty shells&lt;/strong&gt;:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;-A PVEFW-FORWARD -m conntrack --ctstate INVALID -j DROP
-A PVEFW-FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A PVEFW-FORWARD -m physdev --physdev-in fwln+ --physdev-is-bridged -j PVEFW-FWBR-IN
-A PVEFW-FORWARD -m physdev --physdev-out fwln+ --physdev-is-bridged -j PVEFW-FWBR-OUT
-A PVEFW-FWBR-IN -m conntrack --ctstate INVALID,NEW -j PVEFW-smurfs
-A PVEFW-FWBR-OUT
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;PVEFW-FWBR-IN&lt;/code&gt; contains one anti-smurf check and then returns. &lt;code&gt;PVEFW-FWBR-OUT&lt;/code&gt;
is completely empty. &lt;code&gt;PVEFW-FORWARD&lt;/code&gt; has no terminating DROP for the physdev path,
and the built-in &lt;code&gt;FORWARD&lt;/code&gt; policy is &lt;code&gt;ACCEPT&lt;/code&gt; on both nodes. A search of both
appendices for any rule referencing a &lt;code&gt;tap&lt;/code&gt; interface returns &lt;strong&gt;nothing&lt;/strong&gt; — there
are no per-VM rules at all. This is the signature of NIC-level &amp;ldquo;Firewall&amp;rdquo;
checkboxes left enabled while the VM-level firewall is disabled: PVE creates the
bridge, then installs no policy in it.&lt;/p&gt;
&lt;p&gt;Three consequences:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Every guest listener bound to a wildcard address is reachable from every VLAN
that guest is attached to. Combined with &amp;ldquo;no firewalld on any of the seven
guests&amp;rdquo; (§2), &lt;strong&gt;there is no packet filter anywhere between a guest service and
its VLAN.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;T-09&lt;/code&gt; is moot.&lt;/strong&gt; Whether a tap has an &lt;code&gt;fwbr&lt;/code&gt; in front of it or is enslaved
directly to the &lt;code&gt;vmbr&lt;/code&gt; makes no difference to what is filtered, because the
&lt;code&gt;fwbr&lt;/code&gt; path filters nothing. &lt;code&gt;T-09&lt;/code&gt; should be reclassified: the three
unfiltered taps are not three exceptions in an otherwise-filtered estate, they
are three cosmetic omissions in an entirely unfiltered one. That is a much
larger problem stated much more quietly.&lt;/li&gt;
&lt;li&gt;The hypervisors&amp;rsquo; own &lt;code&gt;GROUP-*-IN&lt;/code&gt; policies (&lt;code&gt;SRV_HOST_SECURITY_AUDIT.md&lt;/code&gt; §2.1)
are real and do protect the &lt;em&gt;hosts&lt;/em&gt; — &lt;code&gt;PVEFW-HOST-IN&lt;/code&gt; is populated and ends in
a drop. Only the &lt;em&gt;guest&lt;/em&gt; path is open. It is easy to look at the populated
host chains and conclude the node is firewalled.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Verify before acting: the raw ruleset is a point-in-time capture and PVE
regenerates these chains on configuration change. Confirm against
&lt;code&gt;/etc/pve/firewall/&amp;lt;vmid&amp;gt;.fw&lt;/code&gt; and &lt;code&gt;/etc/pve/firewall/cluster.fw&lt;/code&gt; before treating
this as settled.&lt;/p&gt;
&lt;h3 id="v-02--databases-and-caches-bound-to-all-interfaces-unfiltered"&gt;V-02 — Databases and caches bound to all interfaces, unfiltered&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Guest&lt;/th&gt;
&lt;th&gt;Port&lt;/th&gt;
&lt;th&gt;Service&lt;/th&gt;
&lt;th&gt;Bind&lt;/th&gt;
&lt;th&gt;Reachable from&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;vm010-db&lt;/td&gt;
&lt;td&gt;tcp/3306&lt;/td&gt;
&lt;td&gt;MariaDB&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0.0.0.0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;VLAN 200 &lt;code&gt;10.1.2.71&lt;/code&gt;, VLAN 204 &lt;code&gt;10.128.128.17&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vm010-db&lt;/td&gt;
&lt;td&gt;tcp/6379&lt;/td&gt;
&lt;td&gt;Valkey (Redis)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0.0.0.0&lt;/code&gt; &lt;strong&gt;and&lt;/strong&gt; &lt;code&gt;::&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;VLAN 200, VLAN 204&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vm012-clickhouse&lt;/td&gt;
&lt;td&gt;tcp/8123&lt;/td&gt;
&lt;td&gt;ClickHouse HTTP&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0.0.0.0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;VLAN 200 &lt;code&gt;10.1.2.78&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vm012-clickhouse&lt;/td&gt;
&lt;td&gt;tcp/9000&lt;/td&gt;
&lt;td&gt;ClickHouse native&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0.0.0.0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;VLAN 200&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vm012-clickhouse&lt;/td&gt;
&lt;td&gt;tcp/9004&lt;/td&gt;
&lt;td&gt;ClickHouse MySQL wire&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0.0.0.0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;VLAN 200&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vm012-clickhouse&lt;/td&gt;
&lt;td&gt;tcp/9005&lt;/td&gt;
&lt;td&gt;ClickHouse PostgreSQL wire&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0.0.0.0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;VLAN 200&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Redis/Valkey is the sharpest of these: it has no authentication by default, and
&lt;code&gt;6379&lt;/code&gt; is bound on both IPv4 and IPv6 wildcards. ClickHouse exposing MySQL &lt;em&gt;and&lt;/em&gt;
PostgreSQL wire protocols alongside its native and HTTP interfaces means four
independent authentication surfaces on one host, all on the main internal VLAN.&lt;/p&gt;
&lt;p&gt;Not verified: whether these services require credentials. The collector reads
socket state, not service configuration, and the engagement is read-only, so no
connection was attempted. The exposure is confirmed; the exploitability is not.&lt;/p&gt;
&lt;p&gt;Compare vm004-es, which runs Elasticsearch on &lt;code&gt;127.0.0.1:9200&lt;/code&gt; behind nginx. The
same pattern applied to vm010-db and vm012-clickhouse would close this finding.&lt;/p&gt;
&lt;h3 id="v-03--every-service-is-silently-duplicated-onto-vlan-204"&gt;V-03 — Every service is silently duplicated onto VLAN 204&lt;/h3&gt;
&lt;p&gt;VLAN 204 (VMs Interconnect) is a flat &lt;code&gt;/24&lt;/code&gt; shared by both hypervisors and six of
the seven guests. Because no guest binds per-interface, &lt;strong&gt;every wildcard listener
in §5.2 answers on the guest&amp;rsquo;s &lt;code&gt;10.128.128.x&lt;/code&gt; address as well as its &lt;code&gt;10.1.2.x&lt;/code&gt;
one.&lt;/strong&gt; MariaDB, Valkey, LDAP, the Swarm control plane and every SSH daemon are all
present on VLAN 204.&lt;/p&gt;
&lt;p&gt;This inverts the segment&amp;rsquo;s apparent purpose. A VLAN named &amp;ldquo;VMs Interconnect&amp;rdquo; reads
as a low-value plumbing network; in practice it is a second, parallel, equally
exposed copy of the entire guest attack surface — and unlike VLAN 200 it is
outside the authorized scan scope, so no external scan has ever looked at it. The
&lt;code&gt;results/&lt;/code&gt; external view, whatever it contains, cannot have covered this.&lt;/p&gt;
&lt;p&gt;Anything with a foothold on VLAN 204 — including srv01hv and srv06hv themselves at
&lt;code&gt;10.128.128.20&lt;/code&gt; and &lt;code&gt;10.128.128.2&lt;/code&gt; — reaches every guest service without crossing
the TL-SE5226 or any L3 boundary at all.&lt;/p&gt;
&lt;h3 id="v-04--docker0-shadows-the-entire-iot-vlan"&gt;V-04 — &lt;code&gt;docker0&lt;/code&gt; shadows the entire IoT VLAN&lt;/h3&gt;
&lt;p&gt;Docker&amp;rsquo;s default bridge uses &lt;code&gt;172.17.0.1/16&lt;/code&gt;. The designated IoT range (VLAN 10)
is &lt;code&gt;172.17.1.0/16&lt;/code&gt;, and every IoT interface in the estate is configured &lt;code&gt;/16&lt;/code&gt;:
srv02gate &lt;code&gt;172.17.1.2/16&lt;/code&gt;, srv05access &lt;code&gt;172.17.1.3/16&lt;/code&gt;, srv01hv &lt;code&gt;172.17.1.6/16&lt;/code&gt;.
&lt;strong&gt;These are the same &lt;code&gt;/16&lt;/code&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Three guests carry the resulting route in their main table:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Guest&lt;/th&gt;
&lt;th&gt;Route&lt;/th&gt;
&lt;th&gt;&lt;code&gt;docker0&lt;/code&gt; state&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;vm001-devel&lt;/td&gt;
&lt;td&gt;&lt;code&gt;172.17.0.0/16 dev docker0 proto kernel src 172.17.0.1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;DOWN&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vm002-docker&lt;/td&gt;
&lt;td&gt;&lt;code&gt;172.17.0.0/16 dev docker0 proto kernel src 172.17.0.1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;DOWN&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vm011-jenkins&lt;/td&gt;
&lt;td&gt;&lt;code&gt;172.17.0.0/16 dev docker0 proto kernel src 172.17.0.1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;DOWN&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;None of the three has a VLAN 10 interface, so absent the collision they would
route IoT traffic via the default gateway &lt;code&gt;10.1.1.3&lt;/code&gt;. Instead the connected
&lt;code&gt;docker0&lt;/code&gt; route wins on longest-prefix match and the packets go to a bridge that
is administratively down — they are dropped. &lt;strong&gt;These three guests cannot reach any
IoT host, and the failure mode is a silent blackhole, not a routing error.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The reverse direction is the part to watch. &lt;code&gt;docker0&lt;/code&gt; is DOWN on all three
&lt;em&gt;today&lt;/em&gt;. Start a container on any of them and Docker brings the bridge up and
begins allocating container addresses out of &lt;code&gt;172.17.0.0/16&lt;/code&gt; — the same space as
live IoT devices. Address collisions between a container and an IoT host become
possible, and on vm001-devel and vm011-jenkins &lt;code&gt;systemd-resolved&lt;/code&gt; is already bound
to &lt;code&gt;172.17.0.1:53&lt;/code&gt;, an address inside the IoT range.&lt;/p&gt;
&lt;p&gt;The exposure is systemic rather than local: Docker&amp;rsquo;s default address pool is
&lt;code&gt;172.16.0.0/12&lt;/code&gt;, which spans &lt;code&gt;172.16.0.0&lt;/code&gt;–&lt;code&gt;172.31.255.255&lt;/code&gt; and therefore contains
both the IoT VLAN (&lt;code&gt;172.17.x&lt;/code&gt;) &lt;em&gt;and&lt;/em&gt; the DMZ VLAN 1024 (&lt;code&gt;172.16.1.0/24&lt;/code&gt;,
configured &lt;code&gt;/16&lt;/code&gt; on every host). vm002-docker has already allocated &lt;code&gt;172.18.0.1&lt;/code&gt;,
&lt;code&gt;172.20.0.1&lt;/code&gt; and &lt;code&gt;172.22.0.1&lt;/code&gt; out of that pool. Those three do not currently
collide, but nothing prevents the next network Docker creates from landing on
&lt;code&gt;172.16.x&lt;/code&gt; or &lt;code&gt;172.17.x&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Remediation is configuration-only: set &lt;code&gt;default-address-pools&lt;/code&gt; in
&lt;code&gt;/etc/docker/daemon.json&lt;/code&gt; to a range outside &lt;code&gt;172.16.0.0/12&lt;/code&gt; — RFC 1918 space in
&lt;code&gt;10.201.0.0/16&lt;/code&gt; or similar — and set &lt;code&gt;bip&lt;/code&gt; for &lt;code&gt;docker0&lt;/code&gt;. Do this before the next
container starts, not after.&lt;/p&gt;
&lt;h3 id="v-05--nginx-listens-on-tcp433-instead-of-443-on-ipv6"&gt;V-05 — nginx listens on tcp/433 instead of 443 on IPv6&lt;/h3&gt;
&lt;p&gt;vm011-jenkins:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;tcp | 443 | 0.0.0.0 | nginx &amp;lt;- IPv4, correct
tcp | 433 | :: | nginx &amp;lt;- IPv6, transposed digits
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The IPv4 and IPv6 listeners are on different ports. This is a transposition in an
nginx &lt;code&gt;listen [::]:433 ...&lt;/code&gt; directive. Two effects: IPv6 clients get no HTTPS on
the expected port, and tcp/433 is open estate-wide on both VLAN 200 and VLAN 204.
An external scan would report 433/tcp as an unexpected open port with no obvious
owner. Low severity, trivial fix, but it will keep costing analyst time until it
is corrected.&lt;/p&gt;
&lt;h3 id="v-06--backends-exposed-alongside-the-proxy-that-is-supposed-to-front-them"&gt;V-06 — Backends exposed alongside the proxy that is supposed to front them&lt;/h3&gt;
&lt;p&gt;vm004-es and vm005-obj bind their data-plane services to loopback and expose only
nginx/OpenResty on 80/443. Three guests do the opposite:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Guest&lt;/th&gt;
&lt;th&gt;Proxy on&lt;/th&gt;
&lt;th&gt;Backend also exposed&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;vm011-jenkins&lt;/td&gt;
&lt;td&gt;tcp/443 (nginx)&lt;/td&gt;
&lt;td&gt;tcp/8080 Jenkins, directly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vm012-clickhouse&lt;/td&gt;
&lt;td&gt;tcp/80, tcp/443 (nginx)&lt;/td&gt;
&lt;td&gt;tcp/8123, 9000, 9004, 9005 ClickHouse&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vm010-db&lt;/td&gt;
&lt;td&gt;&lt;em&gt;(none)&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;tcp/3306, tcp/6379&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Where a reverse proxy carries authentication, TLS termination, rate limiting or
access logging, an exposed backend port bypasses all of it. Jenkins on 8080 is the
clearest case: whatever the nginx vhost enforces in front of it is optional for
any client that connects to 8080 directly.&lt;/p&gt;
&lt;h3 id="v-07--vlan-membership-is-invisible-from-inside-the-guest"&gt;V-07 — VLAN membership is invisible from inside the guest&lt;/h3&gt;
&lt;p&gt;None of the seven guests can determine which VLAN any of its NICs is in. There are
no &lt;code&gt;.1Q&lt;/code&gt; subinterfaces, no VLAN-aware bridge, and no naming convention that
encodes the segment — the interfaces are &lt;code&gt;ens18&lt;/code&gt;, &lt;code&gt;ens19&lt;/code&gt;, &lt;code&gt;ens20&lt;/code&gt;. Mapping
requires the hypervisor&amp;rsquo;s bridge topology, which is a separate report collected
from a separate host with separate credentials.&lt;/p&gt;
&lt;p&gt;Practical consequences:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;An operator on vm005-obj cannot tell that &lt;code&gt;ens20&lt;/code&gt; is the storage VLAN and
&lt;code&gt;ens19&lt;/code&gt; is the main internal one without going and looking at srv06hv.&lt;/li&gt;
&lt;li&gt;Per-interface bind decisions — exactly the control that would fix &lt;code&gt;V-02&lt;/code&gt; and
&lt;code&gt;V-03&lt;/code&gt; — require knowledge the guest does not have locally.&lt;/li&gt;
&lt;li&gt;The index-to-VLAN mapping is not even consistent across the estate: &lt;code&gt;ens19&lt;/code&gt; is
VLAN 200 on five guests, VLAN 400 on vm005-obj, and VLAN 400-but-down on
vm012-clickhouse.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The cheap fix is documentary: a &lt;code&gt;systemd-networkd&lt;/code&gt; &lt;code&gt;.link&lt;/code&gt; rename or a comment
block in &lt;code&gt;/etc/network/interfaces.d/&lt;/code&gt; naming the VLAN for each device. It costs
nothing and removes an entire class of bind-to-the-wrong-interface mistakes.&lt;/p&gt;
&lt;h3 id="v-08--vm012-clickhouse-has-a-live-storage-vlan-nic-that-is-unconfigured"&gt;V-08 — vm012-clickhouse has a live storage-VLAN NIC that is unconfigured&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;ens18&lt;/code&gt; and &lt;code&gt;ens19&lt;/code&gt; are present at runtime, carry Proxmox MACs, and appear in &lt;strong&gt;no&lt;/strong&gt;
on-disk network configuration — the collector flags them correctly. On the
hypervisor side the corresponding taps exist and are bridged: per the §4
deduction (VMID 102 on srv06hv), &lt;code&gt;ens18&lt;/code&gt; lands on &lt;code&gt;vmbr0vm&lt;/code&gt; (VLAN 204) and
&lt;strong&gt;&lt;code&gt;ens19&lt;/code&gt; lands on &lt;code&gt;vmbr2nas&lt;/code&gt; (VLAN 400, storage)&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;So the guest has a live layer-2 path into the storage segment on an interface
nobody configured, nobody monitors, and which will not survive a reboot as
anything other than an unconfigured device. It carries no IP today, so there is no
reachability today — but the tap is bridged, the segment is one &lt;code&gt;dhclient&lt;/code&gt;
invocation away, and any process on the guest that can bring an interface up can
reach VLAN 400 without crossing a router.&lt;/p&gt;
&lt;p&gt;The VLAN attribution rests on the §4 placement deduction, which is high-confidence
but not directly observed. Confirm from &lt;code&gt;/etc/pve/qemu-server/102.conf&lt;/code&gt; on
srv06hv, which will state the bridge and VLAN tag for &lt;code&gt;net0&lt;/code&gt;/&lt;code&gt;net1&lt;/code&gt;/&lt;code&gt;net2&lt;/code&gt;
explicitly. If the guest genuinely needs neither NIC, remove them from the VM
configuration rather than leaving them down.&lt;/p&gt;
&lt;h3 id="v-09--cleartext-ldap-and-the-swarm-control-plane-on-vlan-200"&gt;V-09 — Cleartext LDAP and the Swarm control plane on VLAN 200&lt;/h3&gt;
&lt;p&gt;vm002-docker publishes, on both VLAN 200 and VLAN 204:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Port&lt;/th&gt;
&lt;th&gt;What it is&lt;/th&gt;
&lt;th&gt;Concern&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;tcp/389&lt;/td&gt;
&lt;td&gt;LDAP, cleartext&lt;/td&gt;
&lt;td&gt;Directory bind credentials cross the wire unprotected; no 636/LDAPS listener accompanies it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tcp/2377&lt;/td&gt;
&lt;td&gt;Docker Swarm cluster management&lt;/td&gt;
&lt;td&gt;Control-plane port; joining a manager grants orchestration over every service on the swarm&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tcp/7946 tcp+udp&lt;/td&gt;
&lt;td&gt;Swarm node gossip&lt;/td&gt;
&lt;td&gt;Cluster membership&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;udp/4789&lt;/td&gt;
&lt;td&gt;VXLAN overlay data plane&lt;/td&gt;
&lt;td&gt;Carries all inter-service overlay traffic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tcp/2222&lt;/td&gt;
&lt;td&gt;Alternate SSH, &lt;em&gt;probably&lt;/em&gt; GitLab&amp;rsquo;s (it publishes 22/tcp internally)&lt;/td&gt;
&lt;td&gt;A second SSH surface with credentials separate from the host&amp;rsquo;s own tcp/22&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tcp/1514&lt;/td&gt;
&lt;td&gt;Syslog / agent enrolment, service &lt;strong&gt;not identified&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Ports in this role are commonly unauthenticated ingest&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tcp/1688&lt;/td&gt;
&lt;td&gt;KMS emulator (&lt;code&gt;vlmcsd&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Unlicensed activation service, published to the internal VLAN&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Swarm&amp;rsquo;s control plane is designed to run on a trusted management network. Here
2377, 7946 and 4789 are all reachable from the general-purpose internal VLAN and,
per &lt;code&gt;V-03&lt;/code&gt;, from VLAN 204 as well, with no filtering at either the guest or the
hypervisor. &lt;code&gt;vlmcsd&lt;/code&gt; is a separate matter — a KMS emulator is an unlicensed
activation service and is worth raising with the system owner independently of any
security question.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Caveat on attribution.&lt;/strong&gt; Ports 389, 1514, 2222, 2377 and 7946 are attributed by
&lt;code&gt;ss&lt;/code&gt; to &lt;code&gt;dockerd&lt;/code&gt; itself, not to a named container, because Swarm-published ports
are opened by the daemon rather than by a &lt;code&gt;docker-proxy&lt;/code&gt; child. The &lt;code&gt;docker&lt;/code&gt;
runtime table in §5.4 does not list 389, 1514 or 2222 against any container, so
&lt;strong&gt;which services back those three was not established.&lt;/strong&gt; The port numbers are
observed facts; the service names above are inference from convention. Run
&lt;code&gt;docker service ls&lt;/code&gt; / &lt;code&gt;docker service inspect&lt;/code&gt; to identify them before changing
anything.&lt;/p&gt;
&lt;h3 id="v-10--storage-traffic-for-six-guests-crosses-vlan-200"&gt;V-10 — Storage traffic for six guests crosses VLAN 200&lt;/h3&gt;
&lt;p&gt;VLAN 400 exists and is designated &amp;ldquo;Network Storage&amp;rdquo;. Exactly one guest, vm005-obj,
has an interface in it. The other six mount NFSv4 (and, on vm001-devel, three CIFS
shares) from the same file server over VLAN 200, routed through the TL-SE5226.&lt;/p&gt;
&lt;p&gt;The storage VLAN therefore carries a minority of the estate&amp;rsquo;s storage traffic,
while the general-purpose internal VLAN carries the majority — including SMB
sessions from vm001-devel. Since srv04fs runs no host firewall and serves 2049/tcp
and 445/tcp on all interfaces (&lt;code&gt;SRV_HOST_SECURITY_AUDIT.md&lt;/code&gt;), the file server&amp;rsquo;s
full NFS and SMB surface is reachable from VLAN 200 regardless.&lt;/p&gt;
&lt;p&gt;Either give the six guests a VLAN 400 NIC and pin the mounts to it, or accept that
VLAN 400 is a partial deployment and document it as such. The current state gets
the operational cost of a separate storage VLAN with little of its benefit.&lt;/p&gt;
&lt;h3 id="v-11--collector-reports-a-bridge-bound-socket-as-loopback-only"&gt;V-11 — Collector reports a bridge-bound socket as &amp;ldquo;loopback only&amp;rdquo;&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;collect_host_env.py&lt;/code&gt; defect. On vm001-devel and vm011-jenkins, section 5 renders:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;| tcp | 53 | systemd-resolved.service | 127.0.0.53, 127.0.0.54, 172.17.0.1 | docker0 | - | not-exposed | bound to loopback only |
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;172.17.0.1&lt;/code&gt; is &lt;code&gt;docker0&lt;/code&gt;, not loopback. The exposure analysis aggregates all
bind addresses for a &lt;code&gt;(proto, port, service)&lt;/code&gt; tuple into one row and then derives
a single verdict; because two of the three addresses are loopback, the row is
labelled &lt;code&gt;not-exposed — bound to loopback only&lt;/code&gt;, and the non-loopback bind
disappears from the finding.&lt;/p&gt;
&lt;p&gt;The same table&amp;rsquo;s own &amp;ldquo;Interfaces&amp;rdquo; column already says &lt;code&gt;docker0&lt;/code&gt;, contradicting the
verdict two columns to the right. The udp/53 row for the identical bind set is
labelled &lt;code&gt;unknown&lt;/code&gt; rather than &lt;code&gt;not-exposed&lt;/code&gt;, so the two are not even
self-consistent.&lt;/p&gt;
&lt;p&gt;Here the practical impact is nil — &lt;code&gt;docker0&lt;/code&gt; is DOWN on both guests — but the
logic is wrong in general: any service bound to both loopback and a live interface
will be reported as unexposed. Fix: derive the verdict per bind address and emit
the worst case, or split the row.&lt;/p&gt;
&lt;h3 id="v-12--collector-misparents-container-veths-in-the-stacking-tree"&gt;V-12 — Collector misparents container &lt;code&gt;veth&lt;/code&gt;s in the stacking tree&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;collect_host_env.py&lt;/code&gt; defect, visible in vm002-docker section 2.4. Three veths are
printed twice — once under their real bridge master, and again as children of the
physical NIC:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;br-70f3ee0fb257 ...
`-- vethfa8ae03
br-9e2a20ddf105 ...
|-- veth07e013b
`-- veth8a37a0f
...
ens18 [physical, virtio_net, -1Mb/s, UP] 10.128.128.4/24
|-- veth07e013b
|-- veth8a37a0f
`-- vethfa8ae03
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Section 2.3 gives their correct masters (&lt;code&gt;br-70f3ee0fb257&lt;/code&gt;, &lt;code&gt;br-9e2a20ddf105&lt;/code&gt;), so
the data is right and only the tree renderer is wrong. The likely cause is
resolving &lt;code&gt;iflink&lt;/code&gt; rather than &lt;code&gt;master&lt;/code&gt;: for a veth whose peer lives in a
container network namespace, the peer ifindex can collide with an ifindex in the
host namespace — here &lt;code&gt;ens18&lt;/code&gt; — and the renderer attaches it there.&lt;/p&gt;
&lt;p&gt;The consequence for an auditor is a false picture of guest-side segmentation: read
literally, the tree says three container interfaces are enslaved directly to the
VLAN 204 NIC. They are not. Fix: build the tree from &lt;code&gt;master&lt;/code&gt;, and ignore &lt;code&gt;iflink&lt;/code&gt;
when &lt;code&gt;link_netnsid&lt;/code&gt; is set.&lt;/p&gt;
&lt;h3 id="v-13--four-unattributed-listening-sockets-on-vm005-obj"&gt;V-13 — Four unattributed listening sockets on vm005-obj&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Proto&lt;/th&gt;
&lt;th&gt;Port&lt;/th&gt;
&lt;th&gt;Bind&lt;/th&gt;
&lt;th&gt;Process&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;tcp&lt;/td&gt;
&lt;td&gt;41877&lt;/td&gt;
&lt;td&gt;&lt;code&gt;::&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;(none resolved)&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tcp&lt;/td&gt;
&lt;td&gt;46691&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0.0.0.0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;(none resolved)&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;udp&lt;/td&gt;
&lt;td&gt;44413&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0.0.0.0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;(none resolved)&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;udp&lt;/td&gt;
&lt;td&gt;46796&lt;/td&gt;
&lt;td&gt;&lt;code&gt;::&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;(none resolved)&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;All four are in the ephemeral range and sit alongside four sockets that &lt;em&gt;were&lt;/em&gt;
attributed to &lt;code&gt;rpc.statd&lt;/code&gt; (36105, 50647, 45714, 53735). The most likely
explanation is kernel-side NFS — &lt;code&gt;lockd&lt;/code&gt; and the NFSv4 callback channel — which
have no userspace PID for &lt;code&gt;ss -p&lt;/code&gt; to report, which is exactly why the collector
leaves them blank. That is consistent with vm005-obj being the estate&amp;rsquo;s only
NFS-heavy guest.&lt;/p&gt;
&lt;p&gt;This is a hypothesis, not a conclusion. &lt;code&gt;rpcinfo -p&lt;/code&gt; on the host would settle it,
and is read-only. Until then these are four open ports on three VLANs with no
identified owner, and they should not be dismissed as &amp;ldquo;probably NFS&amp;rdquo; in the
deliverable. Note also that they are dynamically allocated, so an external scan
from a different day would see different port numbers — which is worth flagging to
anyone diffing scan results.&lt;/p&gt;
&lt;h3 id="v-14--clock-and-kernel-hygiene"&gt;V-14 — Clock and kernel hygiene&lt;/h3&gt;
&lt;p&gt;Two unrelated items, grouped because both are single-host and low severity.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;vm010-db reports &lt;code&gt;NTP synchronised: no&lt;/code&gt;&lt;/strong&gt; after 38 days of uptime. It is the
only host among all thirteen collected with unsynchronised time. On a database
host this affects transaction timestamps, replication ordering if replication is
ever configured, certificate validity checks and — most relevant to this
engagement — the ability to correlate its logs with anything else during an
incident.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;vm001-devel runs kernel &lt;code&gt;6.18.0-dirty&lt;/code&gt;.&lt;/strong&gt; The &lt;code&gt;-dirty&lt;/code&gt; suffix is emitted by the
kernel build system when the source tree contains uncommitted modifications, so
this is a locally built kernel from a tree whose exact contents are not
recoverable. It is the only non-distribution kernel in the estate. Consequences:
it is outside Debian&amp;rsquo;s security update path, &lt;code&gt;6.18.0&lt;/code&gt; is newer than every other
kernel here (the rest are &lt;code&gt;6.12.x&lt;/code&gt;), and the modifications cannot be reviewed.
For a host named &lt;code&gt;devel&lt;/code&gt; this may well be deliberate; it should nonetheless be
recorded, and the machine should not be treated as having the same patch posture
as the others.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="9-what-would-resolve-the-open-questions"&gt;9. What would resolve the open questions&lt;/h2&gt;
&lt;p&gt;Each of these is read-only and within the engagement&amp;rsquo;s constraints.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Question&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Resolves&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Which node and VMID is vm005-obj?&lt;/td&gt;
&lt;td&gt;&lt;code&gt;qm list&lt;/code&gt; on srv01hv and srv06hv&lt;/td&gt;
&lt;td&gt;§4 ambiguity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Confirm every guest&amp;rsquo;s VLAN tags&lt;/td&gt;
&lt;td&gt;&lt;code&gt;cat /etc/pve/qemu-server/*.conf&lt;/code&gt; on both nodes&lt;/td&gt;
&lt;td&gt;§4, &lt;code&gt;V-08&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Is the guest firewall genuinely off?&lt;/td&gt;
&lt;td&gt;&lt;code&gt;cat /etc/pve/firewall/cluster.fw /etc/pve/firewall/*.fw&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;V-01&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;What are vm005-obj&amp;rsquo;s unattributed ports?&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rpcinfo -p&lt;/code&gt; on vm005-obj&lt;/td&gt;
&lt;td&gt;&lt;code&gt;V-13&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;What backs vm002-docker&amp;rsquo;s tcp/389?&lt;/td&gt;
&lt;td&gt;&lt;code&gt;docker service ls&lt;/code&gt;, &lt;code&gt;docker service inspect&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;V-09&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Do the exposed databases require credentials?&lt;/td&gt;
&lt;td&gt;Service config review — &lt;strong&gt;not&lt;/strong&gt; a connection attempt&lt;/td&gt;
&lt;td&gt;&lt;code&gt;V-02&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Does the external view agree?&lt;/td&gt;
&lt;td&gt;Read access to &lt;code&gt;results/&lt;/code&gt; and &lt;code&gt;NETWORK_AUDIT_REPORT.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;whole document&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The last one is the most important. This report is built entirely from the on-host
view; &lt;code&gt;AGENTS.md&lt;/code&gt; is explicit that the on-host and external views are
complementary and that neither should be trusted alone. Until &lt;code&gt;results/&lt;/code&gt; can be
read, the reachability claims in §5 are derived from ruleset analysis rather than
confirmed by observation. Note that VLANs 204 and 400 are outside the authorized
scan scope, so for &lt;code&gt;V-03&lt;/code&gt; and &lt;code&gt;V-10&lt;/code&gt; no external corroboration can exist at all —
those must stand or fall on the configuration evidence presented here.&lt;/p&gt;</description></item><item><title>Month 1 Summary</title><link>https://vox.app.home/posts/lingua-latina/month-1/</link><pubDate>Sat, 27 Jun 2026 15:17:51 +0000</pubDate><guid>https://vox.app.home/posts/lingua-latina/month-1/</guid><description>&lt;p&gt;Month 1 of learning, covering topic 1-5 from the book &lt;em&gt;Learn Latin from the Romans&lt;/em&gt;.&lt;/p&gt;
&lt;h2 id="vocabulary--things-to-memorise"&gt;Vocabulary &amp;amp; Things to Memorise&lt;/h2&gt;
&lt;h3 id="nouns"&gt;Nouns&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;agricola&lt;/strong&gt;, &lt;em&gt;-ae&lt;/em&gt;, (&lt;em&gt;m.&lt;/em&gt;) - farmer&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;dea&lt;/strong&gt;, &lt;em&gt;-ae&lt;/em&gt;, (&lt;em&gt;f.&lt;/em&gt;) - goddess&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;deus&lt;/strong&gt;, &lt;em&gt;-&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;&lt;/em&gt;, (&lt;em&gt;m.&lt;/em&gt;) - god&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;po&lt;t-accent data-mark="-"&gt;e&lt;/t-accent&gt;ta&lt;/strong&gt;, &lt;em&gt;-ae&lt;/em&gt;, (&lt;em&gt;m.&lt;/em&gt;) - poet&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;puella&lt;/strong&gt;, &lt;em&gt;-ae&lt;/em&gt;, (&lt;em&gt;f.&lt;/em&gt;) - girl&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;amicus&lt;/strong&gt;, &lt;em&gt;-&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;&lt;/em&gt;, (&lt;em&gt;m.&lt;/em&gt;) - friend&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;equus&lt;/strong&gt;, &lt;em&gt;-&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;&lt;/em&gt;, (&lt;em&gt;m.&lt;/em&gt;) - horse&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;servus&lt;/strong&gt;, &lt;em&gt;-&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;&lt;/em&gt;, (&lt;em&gt;m.&lt;/em&gt;) - slave&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;oppidum&lt;/strong&gt;, &lt;em&gt;-&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;&lt;/em&gt;, (&lt;em&gt;n.&lt;/em&gt;) - town&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;bellum&lt;/strong&gt;, &lt;em&gt;-&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;&lt;/em&gt;, (&lt;em&gt;n.&lt;/em&gt;) - war&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;verbum&lt;/strong&gt;, &lt;em&gt;-&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;&lt;/em&gt;, (&lt;em&gt;n.&lt;/em&gt;) - word&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;c&lt;t-accent data-mark="-"&gt;o&lt;/t-accent&gt;nsilium&lt;/strong&gt;, &lt;em&gt;-&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;&lt;/em&gt;, (&lt;em&gt;n.&lt;/em&gt;) - advice, plan&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;epistula&lt;/strong&gt;, &lt;em&gt;-ae&lt;/em&gt;, (&lt;em&gt;f.&lt;/em&gt;) - letter&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;pec&lt;t-accent data-mark="-"&gt;u&lt;/t-accent&gt;nia&lt;/strong&gt;, &lt;em&gt;-ae&lt;/em&gt;, (&lt;em&gt;f.&lt;/em&gt;) - money&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="adjectives"&gt;Adjectives&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;bon&lt;em&gt;us&lt;/em&gt;&lt;/strong&gt;, &lt;em&gt;-a&lt;/em&gt;, &lt;em&gt;-um&lt;/em&gt; - good&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;magn&lt;em&gt;us&lt;/em&gt;&lt;/strong&gt;, &lt;em&gt;-a&lt;/em&gt;, &lt;em&gt;-um&lt;/em&gt; - big&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;me&lt;em&gt;us&lt;/em&gt;&lt;/strong&gt;, &lt;em&gt;-a&lt;/em&gt;, &lt;em&gt;-um&lt;/em&gt; - my&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;tu&lt;em&gt;us&lt;/em&gt;&lt;/strong&gt;, &lt;em&gt;-a&lt;/em&gt;, &lt;em&gt;-um&lt;/em&gt; - your (singular)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;nov&lt;em&gt;us&lt;/em&gt;&lt;/strong&gt;, &lt;em&gt;-a&lt;/em&gt;, &lt;em&gt;-um&lt;/em&gt; - new&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="others"&gt;Others&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;-ne&lt;/strong&gt;, &lt;em&gt;suffix&lt;/em&gt; - mark the question&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;et&lt;/strong&gt;, &lt;em&gt;conjunction&lt;/em&gt; - and&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;n&lt;t-accent data-mark="-"&gt;o&lt;/t-accent&gt;n&lt;/strong&gt;, &lt;em&gt;adverb&lt;/em&gt; - not&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="verbs"&gt;Verbs&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: center"&gt;&lt;strong&gt;I&lt;/strong&gt;&lt;/th&gt;
&lt;th style="text-align: center"&gt;&lt;strong&gt;II&lt;/strong&gt;&lt;/th&gt;
&lt;th style="text-align: center"&gt;&lt;strong&gt;III&lt;/strong&gt;&lt;/th&gt;
&lt;th style="text-align: center"&gt;&lt;strong&gt;IV&lt;/strong&gt;&lt;/th&gt;
&lt;th style="text-align: center"&gt;Translation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;curr&lt;i&gt;&lt;t-accent data-mark="-"&gt;o&lt;/t-accent&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;curr&lt;em&gt;ere&lt;/em&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;cucurr&lt;i&gt;&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;cursum&lt;/td&gt;
&lt;td style="text-align: center"&gt;run&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;d&lt;t-accent data-mark="-"&gt;u&lt;/t-accent&gt;c&lt;i&gt;&lt;t-accent data-mark="-"&gt;o&lt;/t-accent&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;d&lt;t-accent data-mark="-"&gt;u&lt;/t-accent&gt;c&lt;em&gt;ere&lt;/em&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;d&lt;t-accent data-mark="-"&gt;u&lt;/t-accent&gt;x&lt;i&gt;&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;ductum&lt;/td&gt;
&lt;td style="text-align: center"&gt;lead&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;em&lt;i&gt;&lt;t-accent data-mark="-"&gt;o&lt;/t-accent&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;em&lt;em&gt;ere&lt;/em&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;t-accent data-mark="-"&gt;e&lt;/t-accent&gt;m&lt;i&gt;&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;t-accent data-mark="-"&gt;e&lt;/t-accent&gt;mptum&lt;/td&gt;
&lt;td style="text-align: center"&gt;buy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;leg&lt;i&gt;&lt;t-accent data-mark="-"&gt;o&lt;/t-accent&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;leg&lt;em&gt;ere&lt;/em&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;l&lt;t-accent data-mark="-"&gt;e&lt;/t-accent&gt;g&lt;i&gt;&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;l&lt;t-accent data-mark="-"&gt;e&lt;/t-accent&gt;ctum&lt;/td&gt;
&lt;td style="text-align: center"&gt;read&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;mitt&lt;i&gt;&lt;t-accent data-mark="-"&gt;o&lt;/t-accent&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;mitt&lt;em&gt;ere&lt;/em&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;m&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;s&lt;i&gt;&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;missum&lt;/td&gt;
&lt;td style="text-align: center"&gt;send&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;p&lt;t-accent data-mark="-"&gt;o&lt;/t-accent&gt;n&lt;i&gt;&lt;t-accent data-mark="-"&gt;o&lt;/t-accent&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;p&lt;t-accent data-mark="-"&gt;o&lt;/t-accent&gt;n&lt;em&gt;ere&lt;/em&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;posu&lt;i&gt;&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;positum&lt;/td&gt;
&lt;td style="text-align: center"&gt;put&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;pet&lt;i&gt;&lt;t-accent data-mark="-"&gt;o&lt;/t-accent&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;pet&lt;em&gt;ere&lt;/em&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;pet&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;v&lt;i&gt;&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;pet&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;tum&lt;/td&gt;
&lt;td style="text-align: center"&gt;seek&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;reg&lt;i&gt;&lt;t-accent data-mark="-"&gt;o&lt;/t-accent&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;reg&lt;em&gt;ere&lt;/em&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;r&lt;t-accent data-mark="-"&gt;e&lt;/t-accent&gt;x&lt;i&gt;&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;r&lt;t-accent data-mark="-"&gt;e&lt;/t-accent&gt;ctum&lt;/td&gt;
&lt;td style="text-align: center"&gt;rule&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;scr&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;b&lt;i&gt;&lt;t-accent data-mark="-"&gt;o&lt;/t-accent&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;scr&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;b&lt;em&gt;ere&lt;/em&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;scr&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;ps&lt;i&gt;&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;scr&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;ptum&lt;/td&gt;
&lt;td style="text-align: center"&gt;write&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;vinc&lt;i&gt;&lt;t-accent data-mark="-"&gt;o&lt;/t-accent&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;vinc&lt;em&gt;ere&lt;/em&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;v&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;c&lt;i&gt;&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;victum&lt;/td&gt;
&lt;td style="text-align: center"&gt;conquer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;sum&lt;/td&gt;
&lt;td style="text-align: center"&gt;esse&lt;/td&gt;
&lt;td style="text-align: center"&gt;fu&lt;i&gt;&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;&lt;/i&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;fut&lt;t-accent data-mark="-"&gt;u&lt;/t-accent&gt;rus&lt;/td&gt;
&lt;td style="text-align: center"&gt;be&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id="irregular---sum"&gt;Irregular - &lt;em&gt;sum&lt;/em&gt;&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Present&lt;/th&gt;
&lt;th&gt;Future&lt;/th&gt;
&lt;th&gt;Perfect&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1s&lt;/td&gt;
&lt;td&gt;sum&lt;/td&gt;
&lt;td&gt;er&lt;t-accent data-mark="-"&gt;o&lt;/t-accent&gt;&lt;/td&gt;
&lt;td&gt;fu&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2s&lt;/td&gt;
&lt;td&gt;es&lt;/td&gt;
&lt;td&gt;eris&lt;/td&gt;
&lt;td&gt;fuist&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3s&lt;/td&gt;
&lt;td&gt;est&lt;/td&gt;
&lt;td&gt;erit&lt;/td&gt;
&lt;td&gt;fuit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1p&lt;/td&gt;
&lt;td&gt;sumus&lt;/td&gt;
&lt;td&gt;erimus&lt;/td&gt;
&lt;td&gt;fuimus&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2p&lt;/td&gt;
&lt;td&gt;estis&lt;/td&gt;
&lt;td&gt;eritis&lt;/td&gt;
&lt;td&gt;fuistis&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3p&lt;/td&gt;
&lt;td&gt;sunt&lt;/td&gt;
&lt;td&gt;erunt&lt;/td&gt;
&lt;td&gt;fu&lt;t-accent data-mark="-"&gt;e&lt;/t-accent&gt;runt&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="declension"&gt;Declension&lt;/h3&gt;
&lt;h4 id="declension-i---a-"&gt;Declension I ( &lt;em&gt;-a&lt;/em&gt; )&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;(-a)&lt;/th&gt;
&lt;th&gt;sg.&lt;/th&gt;
&lt;th&gt;pl.&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Nom.&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;-a&lt;/td&gt;
&lt;td&gt;-ae&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Acc.&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;-am&lt;/td&gt;
&lt;td&gt;-&lt;t-accent data-mark="-"&gt;a&lt;/t-accent&gt;s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Voc.&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;-a&lt;/td&gt;
&lt;td&gt;-ae&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Gen.&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;-ae&lt;/td&gt;
&lt;td&gt;-&lt;t-accent data-mark="-"&gt;a&lt;/t-accent&gt;rum&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id="declension-ii---us--um-"&gt;Declension II ( &lt;em&gt;-us&lt;/em&gt;, &lt;em&gt;-um&lt;/em&gt; )&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;(-us)&lt;/th&gt;
&lt;th&gt;sg.&lt;/th&gt;
&lt;th&gt;pl.&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Nom.&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;-us&lt;/td&gt;
&lt;td&gt;-&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Acc.&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;-um&lt;/td&gt;
&lt;td&gt;-&lt;t-accent data-mark="-"&gt;o&lt;/t-accent&gt;s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Voc.&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;-e&lt;/td&gt;
&lt;td&gt;-&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Gen.&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;-&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;&lt;/td&gt;
&lt;td&gt;-&lt;t-accent data-mark="-"&gt;o&lt;/t-accent&gt;rum&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;(-um)&lt;/th&gt;
&lt;th&gt;sg.&lt;/th&gt;
&lt;th&gt;pl.&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Nom.&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;-um&lt;/td&gt;
&lt;td&gt;-a&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Acc.&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;-um&lt;/td&gt;
&lt;td&gt;-a&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Voc.&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;-um&lt;/td&gt;
&lt;td&gt;-a&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Gen.&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;-&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;&lt;/td&gt;
&lt;td&gt;-&lt;t-accent data-mark="-"&gt;o&lt;/t-accent&gt;rum&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id="conjugations-of-active-indicative-group-iii-verbs"&gt;Conjugations of Active Indicative Group III Verbs&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;(-ere)&lt;/th&gt;
&lt;th&gt;Present&lt;/th&gt;
&lt;th&gt;Future&lt;/th&gt;
&lt;th&gt;Perfect&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1s&lt;/td&gt;
&lt;td&gt;-&lt;t-accent data-mark="-"&gt;o&lt;/t-accent&gt;&lt;/td&gt;
&lt;td&gt;-am&lt;/td&gt;
&lt;td&gt;-&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2s&lt;/td&gt;
&lt;td&gt;-is&lt;/td&gt;
&lt;td&gt;-&lt;t-accent data-mark="-"&gt;e&lt;/t-accent&gt;s&lt;/td&gt;
&lt;td&gt;-ist&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3s&lt;/td&gt;
&lt;td&gt;-it&lt;/td&gt;
&lt;td&gt;-et&lt;/td&gt;
&lt;td&gt;-it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1p&lt;/td&gt;
&lt;td&gt;-imus&lt;/td&gt;
&lt;td&gt;-&lt;t-accent data-mark="-"&gt;e&lt;/t-accent&gt;mus&lt;/td&gt;
&lt;td&gt;-imus&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2p&lt;/td&gt;
&lt;td&gt;-tis&lt;/td&gt;
&lt;td&gt;-&lt;t-accent data-mark="-"&gt;e&lt;/t-accent&gt;tis&lt;/td&gt;
&lt;td&gt;-istis&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3p&lt;/td&gt;
&lt;td&gt;-unt&lt;/td&gt;
&lt;td&gt;-ent&lt;/td&gt;
&lt;td&gt;-&lt;t-accent data-mark="-"&gt;e&lt;/t-accent&gt;runt&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;em&gt;pp.&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;I&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;I&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;III&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;em&gt;pp. : Principle Part to get stem from&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="grammar--concepts"&gt;Grammar &amp;amp; Concepts&lt;/h2&gt;
&lt;h3 id="nouns-and-declension"&gt;Nouns and Declension&lt;/h3&gt;
&lt;p&gt;Each noun and its variations can be defined on 3 dimensional axes:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Genders&lt;/strong&gt;: Masculine, Feminine and Netur&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Quantity&lt;/strong&gt;: Singular, Plural&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cases&lt;/strong&gt;: Nominative, Accusative, Vocative, Genitive (4 of 6 cases covered in this month)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Each noun can have only one gender.&lt;/p&gt;
&lt;p&gt;Based on genitive suffix, a noun can be classified into different declension,
and each declension has their own rules of &amp;ldquo;declening&amp;rdquo; thing across the rest of dimensions.&lt;/p&gt;
&lt;p&gt;Specifically, each declension define it&amp;rsquo;s own subspace spanned by &lt;strong&gt;Quantity&lt;/strong&gt; and &lt;strong&gt;Cases&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The first two declensions and their rules:&lt;/p&gt;
&lt;h4 id="declension-i---a--1"&gt;Declension I ( &lt;em&gt;-a&lt;/em&gt; )&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;Most&lt;/em&gt; of the noun in this group is feminine.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;(-a)&lt;/th&gt;
&lt;th&gt;sg.&lt;/th&gt;
&lt;th&gt;pl.&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Nom.&lt;/td&gt;
&lt;td&gt;-a&lt;/td&gt;
&lt;td&gt;-ae&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Acc.&lt;/td&gt;
&lt;td&gt;-am&lt;/td&gt;
&lt;td&gt;-&lt;t-accent data-mark="-"&gt;a&lt;/t-accent&gt;s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Voc.&lt;/td&gt;
&lt;td&gt;-a&lt;/td&gt;
&lt;td&gt;-ae&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gen.&lt;/td&gt;
&lt;td&gt;-ae&lt;/td&gt;
&lt;td&gt;-&lt;t-accent data-mark="-"&gt;a&lt;/t-accent&gt;rum&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id="declension-ii---us--um--1"&gt;Declension II ( &lt;em&gt;-us&lt;/em&gt;, &lt;em&gt;-um&lt;/em&gt; )&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;Most&lt;/em&gt; of the noun in this group is masculine or netur.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;(-us)&lt;/th&gt;
&lt;th&gt;sg.&lt;/th&gt;
&lt;th&gt;pl.&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Nom.&lt;/td&gt;
&lt;td&gt;-us&lt;/td&gt;
&lt;td&gt;-&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Acc.&lt;/td&gt;
&lt;td&gt;-um&lt;/td&gt;
&lt;td&gt;-&lt;t-accent data-mark="-"&gt;o&lt;/t-accent&gt;s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Voc.&lt;/td&gt;
&lt;td&gt;-e&lt;/td&gt;
&lt;td&gt;-&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gen.&lt;/td&gt;
&lt;td&gt;-&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;&lt;/td&gt;
&lt;td&gt;-&lt;t-accent data-mark="-"&gt;o&lt;/t-accent&gt;rum&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;(-um)&lt;/th&gt;
&lt;th&gt;sg.&lt;/th&gt;
&lt;th&gt;pl.&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Nom.&lt;/td&gt;
&lt;td&gt;-um&lt;/td&gt;
&lt;td&gt;-a&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Acc.&lt;/td&gt;
&lt;td&gt;-um&lt;/td&gt;
&lt;td&gt;-a&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Voc.&lt;/td&gt;
&lt;td&gt;-um&lt;/td&gt;
&lt;td&gt;-a&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gen.&lt;/td&gt;
&lt;td&gt;-&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;&lt;/td&gt;
&lt;td&gt;-&lt;t-accent data-mark="-"&gt;o&lt;/t-accent&gt;rum&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id="cases"&gt;Cases&lt;/h4&gt;
&lt;p&gt;Cases indicate the grammatic role of the noun:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Nominative: Denote the subject that initiate the action.&lt;/li&gt;
&lt;li&gt;Accusative: Denote the &lt;em&gt;direct&lt;/em&gt; reciever of the action.&lt;/li&gt;
&lt;li&gt;Vocative: Calling of the object.&lt;/li&gt;
&lt;li&gt;Genitive: Denote the possession relationship, that the noun (object) is the owner of something else.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="adjectives-1"&gt;Adjectives&lt;/h3&gt;
&lt;p&gt;An adjective is used to describe the noun.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The adjective and its noun must be agreed in &lt;em&gt;case, gender and quantity&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;For this reason, adjectives have variants of all three genders.&lt;/p&gt;
&lt;h3 id="verbs-tense-and-conjugation"&gt;Verbs, Tense and Conjugation&lt;/h3&gt;
&lt;p&gt;Each verb and its variations can be defined in a 4 dimensional configuration space, spanned by the axes:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Pronouns&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;first person singular (1s)&lt;/li&gt;
&lt;li&gt;second person singular (2s)&lt;/li&gt;
&lt;li&gt;third person singular (3s)&lt;/li&gt;
&lt;li&gt;first person plural (1p)&lt;/li&gt;
&lt;li&gt;second person plural (2p)&lt;/li&gt;
&lt;li&gt;third person plural (3p)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tenses&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Present (Pr)&lt;/li&gt;
&lt;li&gt;Future (Fu)&lt;/li&gt;
&lt;li&gt;Perfect (Pe)&lt;/li&gt;
&lt;li&gt;Imperfect (Im) &lt;em&gt;(Not Covered)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Pluperfect (Pp) &lt;em&gt;(Not Covered)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Future Perfect (Fp) &lt;em&gt;(Not Covered)&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Voice&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;Active&lt;/li&gt;
&lt;li&gt;Passive &lt;em&gt;(Not Covered)&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Form &amp;amp; Mood&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;Indicative&lt;/li&gt;
&lt;li&gt;Subjunctive &lt;em&gt;(Not Covered)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Imperative &lt;em&gt;(Not Covered)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Indefinitive&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;With three additional forms for verb-noun, verb-adjectives which will be covered in later topics.&lt;/p&gt;
&lt;h4 id="conjugation-of-verbs"&gt;Conjugation of Verbs&lt;/h4&gt;
&lt;p&gt;Similar to noun&amp;rsquo;s declension, conjugation of the verb defines the how suffix changes as it moves
through the &amp;ldquo;configuration space&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;The indefinitive form of the verb gives conjugation group of the verb.&lt;/p&gt;
&lt;p&gt;The key of any conjugation rules is to identify the &lt;strong&gt;stem&lt;/strong&gt; and the list of compatible suffixes.&lt;/p&gt;
&lt;h4 id="principle-parts---giving-the-desired-stem"&gt;Principle Parts - Giving the Desired Stem&lt;/h4&gt;
&lt;p&gt;Each verb has four principle parts.&lt;/p&gt;
&lt;p&gt;From these parts, all the variations in the configuration space can be dervied by attaching compatible
suffixes.&lt;/p&gt;
&lt;p&gt;The four principle parts (pp):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;I&lt;/strong&gt; Present Active First Person Singular Indicative (1sPrAInd)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;II&lt;/strong&gt; Indefinitive&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;III&lt;/strong&gt; Perfect Active First Person Singular Indicative (1sPeAInd)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;IV&lt;/strong&gt; Supine&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="suffixes---determining-the-variants"&gt;Suffixes - Determining the Variants&lt;/h4&gt;
&lt;p&gt;Suffixes varies from dimensions to dimensions.&lt;/p&gt;
&lt;p&gt;Each suffix must be paired with specific stem for a valid conjugation.&lt;/p&gt;
&lt;p&gt;Current we have learned 3 tense and 6 pronouns of &lt;strong&gt;active indicative, conjugation III&lt;/strong&gt;.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;(-ere)&lt;/th&gt;
&lt;th&gt;Present&lt;/th&gt;
&lt;th&gt;Future&lt;/th&gt;
&lt;th&gt;Perfect&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1s&lt;/td&gt;
&lt;td&gt;-&lt;t-accent data-mark="-"&gt;o&lt;/t-accent&gt;&lt;/td&gt;
&lt;td&gt;-am&lt;/td&gt;
&lt;td&gt;-&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2s&lt;/td&gt;
&lt;td&gt;-is&lt;/td&gt;
&lt;td&gt;-&lt;t-accent data-mark="-"&gt;e&lt;/t-accent&gt;s&lt;/td&gt;
&lt;td&gt;-ist&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3s&lt;/td&gt;
&lt;td&gt;-it&lt;/td&gt;
&lt;td&gt;-et&lt;/td&gt;
&lt;td&gt;-it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1p&lt;/td&gt;
&lt;td&gt;-imus&lt;/td&gt;
&lt;td&gt;-&lt;t-accent data-mark="-"&gt;e&lt;/t-accent&gt;mus&lt;/td&gt;
&lt;td&gt;-imus&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2p&lt;/td&gt;
&lt;td&gt;-tis&lt;/td&gt;
&lt;td&gt;-&lt;t-accent data-mark="-"&gt;e&lt;/t-accent&gt;tis&lt;/td&gt;
&lt;td&gt;-istis&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3p&lt;/td&gt;
&lt;td&gt;-unt&lt;/td&gt;
&lt;td&gt;-ent&lt;/td&gt;
&lt;td&gt;-&lt;t-accent data-mark="-"&gt;e&lt;/t-accent&gt;runt&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;em&gt;pp.&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;I&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;I&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;III&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Note: There are some cases where two supposely different tense share same suffix and stem,
for example &lt;em&gt;legit&lt;/em&gt; (3sPr) and &lt;em&gt;legit&lt;/em&gt; (3sPe), in this case, the disambigious will be the
length of the first vowel of the stem:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;short vowel for present tense&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;long vowel for perfect tense&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="tense"&gt;Tense&lt;/h4&gt;
&lt;p&gt;We currently only covered three tenses:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Present&lt;/strong&gt;: The action that is happening at the moment. It capture these two meaning
in English: a present fact (&lt;em&gt;I eat&lt;/em&gt;) or an action is happening now (&lt;em&gt;I am eating&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Future&lt;/strong&gt;: Action that will happen some point in the future, it is a destined. Same
as the one in English.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Perfect&lt;/strong&gt;: Action that happened in the past, Same as the one in English.&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote class="alert alert-note"&gt;
&lt;p class="alert-heading"&gt;
NOTE
&lt;/p&gt;
&lt;p&gt;For perfect sense, it is not clear whether the action is still ongoing or has been completed.
for this you will need to use other tense to clarify (namely: imperfect or pluperfect). More
on this in later topics.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="sentence-composition"&gt;Sentence Composition&lt;/h3&gt;
&lt;p&gt;Latin has flexible word order when composing a sentence.&lt;/p&gt;
&lt;p&gt;Generally speaking, the most common word order is the &lt;strong&gt;Subject-Object-Verb (SOV)&lt;/strong&gt; form.&lt;/p&gt;
&lt;p&gt;For example, &lt;em&gt;Verba scr&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;b&lt;t-accent data-mark="-"&gt;o&lt;/t-accent&gt;&lt;/em&gt; (Words I am writing $\rightarrow$ I am writing words).&lt;/p&gt;
&lt;h4 id="forming-the-question"&gt;Forming the Question&lt;/h4&gt;
&lt;p&gt;For forming a question. Put the verb as the first word of the sentence and appened suffix &lt;em&gt;-ne&lt;/em&gt; to it.&lt;/p&gt;
&lt;p&gt;For example: &lt;em&gt;Scr&lt;t-accent data-mark="-"&gt;i&lt;/t-accent&gt;psitne verba&lt;/em&gt; (Did he/she write words)?&lt;/p&gt;</description></item></channel></rss>