A Windows home server listens on more ports than the one service you installed for it. On our Beelink EQi12 (Intel Core i3-1215U, 16 GB RAM, Windows 11 + Docker Desktop), a full listener audit found 25 unique TCP ports across 36 listener bindings — including SMB, Hyper-V management, Jellyfin published on 0.0.0.0:8096, and two VPN client ports — plus 169 enabled inbound allow rules in Windows Defender Firewall. This page publishes the complete measured list, explains what each port is for, and shows the exact commands to reproduce the audit on your own machine. Every number comes from our public measurement repository (eqi12-measurement-data, CC BY 4.0), with the source file named under each table. Where we did not measure something, we say so.
If you came here from the Windows mini-PC home server roadmap, this is the hardening step that most guides skip: they tell you to install Docker and Jellyfin, then stop. Nobody shows you what the finished machine actually exposes to your LAN — and the answer is measurable, so we measured it.
Why audit a home server that never leaves the LAN
Three reasons, in order of how often they bite real people:
- Port forwarding accidents. The most common way a home server gets owned is not a LAN attacker — it is the owner forwarding a port on the router “just to test something” and forgetting it. When that happens, the audit list on this page is exactly what the internet can reach. Knowing your listener inventory before the accident is the difference between “oops, only Jellyfin was exposed” and “oops, SMB was exposed.”
- Windows adds allow rules silently. Every consumer app you install — Teams, OneDrive, game launchers, VPN clients — ships its own inbound allow rules. Our machine accumulated 169 of them, many for apps that have nothing to do with serving anything. Rules you never reviewed are rules you cannot trust.
- “It works” hides scope. A service answering on
localhostand the same service answering on0.0.0.0are two very different risk profiles that look identical in a browser tab. Only a listener dump shows the difference.
This audit pairs naturally with the Docker home server stability check: that page proves the stack keeps working, this page proves it exposes only what it should.
The method: two PowerShell commands
Reproduce everything on this page with two commands in an elevated PowerShell window. No third-party tools.
Step 1 — list every listening socket with the owning process ID:
Get-NetTCPConnection -State Listen |
Select-Object LocalAddress, LocalPort, OwningProcess |
Sort-Object LocalPortStep 2 — map process IDs to names so the output means something:
Get-Process -Id (Get-NetTCPConnection -State Listen).OwningProcess -ErrorAction SilentlyContinue |
Select-Object Id, ProcessName | Sort-Object Id -UniqueFor the firewall half of the audit:
Get-NetFirewallRule -Enabled True -Direction Inbound -Action Allow |
Select-Object DisplayName, Profile | Sort-Object DisplayNameWe ran this on the EQi12 on July 13, 2026 and saved the raw output as CSV files in the measurement repository. The tables below are that output, grouped for readability.
Result 1: the full listener inventory — 25 ports, 36 bindings
First, the headline numbers as a citable fact block:
| Fact | Measured value | Source file (measurement repo) |
|---|---|---|
| Unique TCP ports listening | 25 | EQi12_Security_02_TCP_LISTENERS.csv |
| Total listener bindings (port × interface) | 36 | same file |
| Enabled inbound allow rules | 169 | EQi12_Security_06_ENABLED_INBOUND_ALLOW.csv |
| Temporary firewall rules (before / after session) | 0 / 0 | EQi12_Security_07_TEMP_RULES_BEFORE.csv / EQi12_Security_08_TEMP_RULES_AFTER.csv |
| Jellyfin listener scope | 0.0.0.0:8096 (all interfaces) | EQi12_Security_02_TCP_LISTENERS.csv |
Measurement conditions: Beelink EQi12, Windows 11 + Docker Desktop + Jellyfin container, measured 2026-07-13 on the home LAN. Raw CSVs are published under CC BY 4.0.
Here is the same data grouped by what each port actually does. The full un-grouped table is in the repo file; the grouping below adds our interpretation, clearly marked as such.
Windows system and file-sharing ports
| Port | Bound to | Process | What it is |
|---|---|---|---|
| 135 | :: and 0.0.0.0 | svchost | RPC endpoint mapper — the front door for many Windows management protocols |
| 139 | 4 interfaces incl. 192.168.31.78 | System | NetBIOS session service (legacy SMB companion) |
| 445 | :: | System | SMB itself — file and printer sharing |
| 49664–49674 | loopback and all interfaces | lsass, wininit, svchost, spoolsv, services | The standard Windows RPC dynamic-port block; normal on every Windows machine |
Note the detail that matters: 445 is bound only to :: in our capture, while 139 is bound to four specific addresses including the Docker bridge interfaces (172.18.0.1, 172.20.160.1, 172.26.176.1) and the LAN IP. Binding scope, not port number, is what determines exposure — this is the single most useful thing a listener audit teaches.
Services you (or your software) installed
| Port | Bound to | Process | What it is |
|---|---|---|---|
| 8096 | 0.0.0.0 | jellyfin | Jellyfin HTTP — published by Docker Desktop, reachable from the whole LAN |
| 18080 | :: and ::1 | com.docker.backend / wslrelay | Docker Desktop’s internal backend proxy |
| 18096 | 127.0.0.1 | com.docker.backend | A second Docker-published service, loopback only |
| 2179 | :: and 0.0.0.0 | vmms | Hyper-V Virtual Machine Management Service |
| 5040 | 0.0.0.0 | svchost | Windows CDP (Connected Devices Platform) user service |
| 7680 | :: | svchost | Delivery Optimization — Windows Update P2P sharing |
| 19822 / 19827 / 19828 | 127.0.0.1 | lightningx-windows-amd64 | A commercial VPN client’s local management ports — loopback only |
| 51104 | 172.18.0.1 | lightningx-windows-amd64 | The same VPN client, but bound to a Docker bridge interface |
| 28385 / 28390 | 127.0.0.1 | System | Windows internal, loopback only |
| 42050 | ::1 | OneDrive.Sync.Service | OneDrive sync, loopback only |
| 49350 / 49351 | 127.0.0.1 | esrv_svc, esrv | Intel Energy Server telemetry, loopback only |
Three observations from our own machine that will likely apply to yours:
- A VPN client brought its own listeners. We installed a VPN tool for unrelated testing and it quietly added four sockets — three loopback (harmless) and one bound to a Docker bridge interface (worth knowing about). Consumer software adds listeners without asking; the audit is how you find out.
- Jellyfin on
0.0.0.0is Docker Desktop’s default, not an accident. Docker publishes ports on every interface unless told otherwise. For a media server this is usually what you want — but see the hardening section below for the scoped alternative. - Delivery Optimization (7680) is on every Windows 11 machine and is usually forgotten. It lets other machines on your LAN (and the internet, per Microsoft’s protocol design) fetch update pieces from you. Harmless for most homes, but it is a perfect example of a port nobody chose.
Result 2: 169 enabled inbound allow rules
The listener dump shows what is listening; the firewall rules show what is invited in. Our machine had 169 enabled inbound allow rules. Grouped highlights, all traceable to EQi12_Security_06_ENABLED_INBOUND_ALLOW.csv:
| Rule family (examples) | Profile | Audit note |
|---|---|---|
| File and Printer Sharing family (SMB-In, NB-Name-In, Echo Request, Spooler RPC, ~17 rules) | Public | The most surprising find: the full family is enabled on the Public profile, including File and Printer Sharing (SMB-In) |
| Network Discovery family (WSD-In, SSDP-In, UPnP-In, NB-Datagram-In, ~13 rules) | Private (some Domain) | Standard Windows discovery chatter; low risk on a home LAN, pointless on Public |
| Cast to Device family (RTSP/RTCP/HTTP-Streaming, qWave, SSDP, ~15 rules) | Mixed incl. Public | Media-casting endpoints enabled on Public — an unnecessary invitation on an untrusted network |
| Core Networking family (ICMPv4/v6, DHCP, Teredo, IPHTTPS, IGMP, ~20 rules) | Any | Windows fundamentals; leave alone |
| Remote Assistance family (DCOM-In, RA Server TCP-In, PNRP-In, ~7 rules) | Domain / Domain+Private | Unused on a headless server; candidates for disabling |
| Hyper-V family (WMI, RPC, MIG-TCP, REMOTE_DESKTOP, ~9 rules) | Any | Present because Hyper-V/WSL2 is installed; needed for Docker Desktop |
| Docker Desktop Backend (×2) | Public | The rule that makes 0.0.0.0:8096 reachable — the one to scope if tightening |
| Consumer apps (Microsoft Teams ×5, LocalSend ×4, Copilot, Edge mDNS, Sticky Notes, Solitaire, Weather…) | Mixed | Zero serving purpose on a headless server. Individually harmless, collectively noise |
| iperf3.exe (×2) | Public | Added by our own network performance testing; kept deliberately |
One more citable check: temporary firewall rules were zero before and zero after our measurement session (EQi12_Security_07/08), so nothing transient was hiding between the two snapshots. This matters because some installers create temporary rules and forget to remove them — a before/after diff catches exactly that.
What we changed (and what we deliberately left alone)
We treat this audit as measurement, not as a prescription to gut a working machine. The changes we consider justified on a headless home server, in descending order of value:
- Disable the Public-profile File and Printer Sharing family if your server’s interface ever lands on a Public profile. This is the only finding on our machine we classify as a real misconfiguration risk rather than noise — SMB accepting inbound on a Public network is never what a home server owner wants. (We kept it on our measurement box because the audit ran with the interface on the home LAN’s profile; your mileage depends on your profile hygiene.)
- Scope the Docker Desktop Backend rule to your LAN subnet instead of leaving it open. Playback from your own devices keeps working; the rule stops matching random interfaces. This pairs with the Docker Compose home server stack guide, where the published ports are first defined.
- Disable the Cast to Device and Remote Assistance families on a headless box. They serve no purpose there, and removing ~20 rules shortens every future review.
- Leave the Core Networking family alone. Breaking ICMPv6 or DHCP rules breaks things in confusing ways, for near-zero security gain.
We did not restrict Jellyfin’s 0.0.0.0 binding, because the whole point of the server is serving media to the LAN. If you want it tighter, the firewall scope route (change the rule, not the container) is the one that survives a docker compose up — container port publishing will always re-bind to all interfaces, so fighting it from the compose file is lost work.
Limitations, stated plainly
- This is one machine, one point in time (2026-07-13). Your port list will differ where your installed software differs; the method and the category breakdown are the transferable parts.
- The audit covers TCP listeners only. UDP listeners (mDNS, SSDP, WS-Discovery chatter) exist too and are part of why the Network Discovery rule family is noisy — we did not capture a UDP socket dump in this session.
- The 169-rule count includes Windows’ default consumer-app rules; we counted what
Get-NetFirewallRulereturned, without curating. The raw CSV is published so you can re-group it yourself. - IPv6 listeners bound to
::were reachable from the LAN in our setup; whether they are on yours depends on your router. The audit shows the binding, not the reachability — testing reachability from a second device is the natural next step, and we have not published that test yet.
Reproduce it and go further
The two PowerShell commands above take under a minute. Run them on your own server, then compare against the category table — anything in the “consumer apps” bucket that you do not recognize is your first candidate for a rule review, and any 0.0.0.0 binding for a service you thought was local-only is your second. To work through the whole audit systematically — listener inventory, binding triage, rule families, exposure path and a before/after diff — use the Port Audit Checklist Generator, which turns the method on this page into an ordered, copyable checklist tailored to your exposure plan.
For the broader picture of where this machine fits, see the Beelink EQi12 hardware page for the full test-bed specification, and the stability check page for the operational counterpart of this audit. Hardening is not a one-time act — the listener inventory changes every time you install something, so the audit command belongs in your setup ritual, right next to the first backup.
Cite this data
The raw CSVs behind every table on this page are published in the eqi12-measurement-data repository under CC BY 4.0. Suggested citation: “HomelabToolkit, EQi12 listener and firewall audit, measured 2026-07-13, https://github.com/sohasteve-pixel/eqi12-measurement-data (files: EQi12_Security_02_TCP_LISTENERS.csv, EQi12_Security_06_ENABLED_INBOUND_ALLOW.csv).”