Home Network Monitoring

Dec 7, 2025 min read

I recently acquired a Juniper EX4200 switch. Since I’ve been studying for GCIA and in the process learning tools like Snort/Suricata, Zeek and SiLK, I decided to start using them at home w/ the help of my new hardware.

If you saw my previous home networking post, I showed off how I had a trunk running from a physical switch to my OPNSense firewall which is virtualized in Proxmox. I moved away from this to mirror the uplink from the switch to firewall w/o any VLAN tags as recommended for use with the monitoring/security tools.

Home Network

This simplified my home network. No more VLANs on the Proxmox virtual bridges and virtual NICs. All I needed to add were:

  • Route(s)
  • NAT

OPNSense Config

OPNSense needs to know how to reach the networks on the other side of the switch. I used a static route to 10.17.96.0/20, giving me (16) possible /24 ranges (10.17.96.1-10.17.111.254). It also just happened to fit the two networks I picked before figuring out the details: 10.17.100.0/24 and 10.17.110.0/24.

System > Gateway

  • Add gateway w/ IP address of switch

System > Routes

  • Add newly created Gateway w/ network address 10.17.96.0/20

By default OPNSense will add a NAT rule automatically for directly connected networks, but since OPNSense isn’t directly connected to the networks behind my switch I needed to manually configure this. Luckily it’s very straight forward:

Firewall > Aliases

  • Created an Alias for the 10.17.96.0/20 network

Firewall > NAT > Outbound

  1. Changed the Mode to “Hybrid outbound NAT rule generation”
  2. Created a new NAT entry:
  • Inteface: WAN
  • Source address: the Alias I just created
  • Translation/target: Interface address

Juniper Switch Config

This wasn’t bad to get working initially, but it honestly took some time figuring out how to route the traffic between VLANs on the switch to the Firewall for rule application before possibly being sent back to the switch. This does create duplicate traffic to the monitoring tools for Inter-VLAN traffic, but this can possibly be prevented with further rule creation in the mirror policy.

Policy-Based Forwarding (PBF) Config:

When send-all-to-firewall is matched (from any source), the packet is sent to the routing-instance FIREWALL-ROUTING.inet.0, instead of the main routing table inet.0. Using the seperate routing instance I can override the default routing that would send packets to the directly connected VLANs.

routing-options {
    interface-routes {
        rib-group inet FBF-RIB;
    }
    rib-groups {
        FBF-RIB {
            import-rib [ inet.0 FIREWALL-ROUTING.inet.0 ];
        }
    }
}
firewall {
    family inet {
        filter INTER-VLAN-TO-FIREWALL {
            term send-all-to-firewall {
                from {
                    source-address {
                        0.0.0.0/0;
                    }
                }
                then {
                    routing-instance FIREWALL-ROUTING;
                }
            }
        }
    }
}
routing-instances {
    FIREWALL-ROUTING {
        instance-type forwarding;
        routing-options {
            static {
                route 0.0.0.0/0 next-hop 10.17.1.1;
            }
        }
    }
}

Span/Mirror Config:

All traffic on the uplink to the firewall is mirrored to a spare interface (ge-0/0/47).

ethernet-switching-options {
    analyzer SPAN-MONITOR {
        input {
            ingress {
                interface ge-0/0/20.0;
            }
            egress {
                interface ge-0/0/20.0;
            }
        }
        output {
            interface {
                ge-0/0/47.0;
            }
        }
    }
    storm-control {
        interface all;
    }
}

ge-0/0/47 on the switch goes into the Mini PC where I’m running Proxmox w/ OPNSense virtualized. I pass through the NIC to a Debian VM.

Zeek

Here we can see some the DNS requests noticed by Zeek, and if you pay close attention you can see that my DNS server is blocking a few of the domains (reply with A record to address 0.0.0.0).

steve@debian-13-1:~/zeek$ ls -lah
total 3.8M
drwxrwxr-x 2 steve steve 4.0K Dec  8 08:10 .
drwx------ 6 steve steve 4.0K Dec  8 09:23 ..
-rw-r--r-- 1 steve  steve   680 Dec  8 08:10 analyzer.log
-rw-r--r-- 1 steve  steve  1.6M Dec  8 12:51 conn.log
-rw-r--r-- 1 steve  steve  1.3M Dec  8 12:51 dns.log
-rw-r--r-- 1 steve  steve   52K Dec  8 12:51 files.log
-rw-r--r-- 1 steve  steve  195K Dec  8 12:51 http.log
-rw-r--r-- 1 steve  steve   27K Dec  8 12:51 ntp.log
-rw-r--r-- 1 steve  steve  1.7K Dec  8 12:51 ocsp.log
-rw-r--r-- 1 steve  steve   251 Dec  8 09:29 packet_filter.log
-rw-r--r-- 1 steve  steve   97K Dec  8 12:50 quic.log
-rw-r--r-- 1 steve  steve   415 Dec  8 08:10 reporter.log
-rw-r--r-- 1 steve  steve  2.2K Dec  8 10:58 ssh.log
-rw-r--r-- 1 steve  steve  519K Dec  8 12:51 ssl.log
-rw-r--r-- 1 steve  steve   22K Dec  8 12:51 weird.log
-rw-r--r-- 1 steve  steve   11K Dec  8 12:31 x509.log
steve@debian-13-1:~/zeek$ tail dns.log
1765216296.924581	CYxQQU1DKrgsUYR5T7	10.17.110.2	55401	10.17.40.2	53	udp	60	0.016056	support.broadcom.com	1C_INTERNET	1	A	0	NOERROR	F	F	T	T	0	support.broadcom.com.cdn.cloudflare.net,162.159.140.167,172.66.0.165	182.000000,182.000000,182.000000	F
1765216300.680188	CBjnwR1VENvnorNaOf	10.17.100.18	42023	10.17.40.2	53	udp	11121	0.000651	logs.netflix.com	1C_INTERNET	1	A	0	NOERROR	F	F	T	T	0	0.0.0.0	10.000000	F
1765216303.544930	CUaLsH1SVyGFk4ETFb	10.17.100.18	40465	10.17.40.2	53	udp	61202	0.000776	www.youtube.com	1	C_INTERNET	1	A	0	NOERROR	F	F	T	T	0	0.0.0.0	10.000000	F
1765216311.325498	CxlBwe100pUJCK5Spi	10.17.110.2	44760	10.17.40.2	53	udp	35740	0.018863	api.open-meteo.com	1C_INTERNET	28	AAAA	0	NOERROR	F	F	T	T	0	2a01:4f8:13b:2e04::2	31.000000	F
1765216311.325498	CAxx654nqQeyuDTdhl	10.17.110.2	35032	10.17.40.2	53	udp	60180	0.019045	api.open-meteo.com	1C_INTERNET	1	A	0	NOERROR	F	F	T	T	0	94.130.142.35	192.000000	F
1765216313.358163	C2a6ks3XXKm4EXLfMi	10.17.110.2	34145	10.17.40.2	53	udp	17521	0.016152	waa-pa.clients6.google.com	1	C_INTERNET	1	A	0	NOERROR	F	F	T	T	0	172.253.132.95	300.000000	F
1765216313.358162	ClFR9H1PbLJpNc302	10.17.110.2	46805	10.17.40.2	53	udp	27120	0.017896	waa-pa.clients6.google.com	1	C_INTERNET	28	AAAA	0	NOERROR	F	F	T	T	0	2607:f8b0:4023:2c03::5f	70.000000	F
1765216313.415845	Cevj463Y11MejuK4pd	10.17.110.2	33050	10.17.40.2	53	udp	52422	-	waa-pa.clients6.google.com	1C_INTERNET	65	HTTPS	0	NOERROR	F	F	T	F	0	-	-	F
1765216315.648933	CkH3iy1w17LKRUeo5	10.17.100.18	45974	10.17.40.2	53	udp	35616	0.000900	www.youtube.com	1	C_INTERNET	1	A	0	NOERROR	F	F	T	T	0	0.0.0.0	10.000000	F
1765216317.107622	Cpjt46VftfwACCBz6	10.17.100.18	37163	10.17.40.2	53	udp	41204	0.017899	firetvcaptiveportal.com	1C_INTERNET	1	A	0	NOERROR	F	F	T	T	0	52.4.230.20,3.232.210.128,34.226.47.239,3.209.24.38,34.239.199.104,98.82.73.92,13.217.68.112,34.204.154.4	30.000000,30.000000,30.000000,30.000000,30.000000,30.000000,30.000000,30.000000	F

SiLK

Just looking at the largest flows seen, in size of bytes.

rwfilter --type=all --start-date=2025/12/01 --end-date=2025/12/09 --proto=0- --pass=stdout | rwstats --bytes -dip --count 5'
INPUT: 100762 Records for 1640 Bins and 49412723139 Total Bytes
OUTPUT: Top 5 Bins by Bytes
                                    dIP|               Bytes|    %Bytes|   cumul_%|
                           10.17.100.20|         13319790526| 26.956196| 26.956196|
                           10.17.100.12|         13026269709| 26.362177| 53.318373|
                           10.17.100.18|          9379651782| 18.982260| 72.300634|
                           10.17.100.24|          5520193748| 11.171604| 83.472238|
                            10.17.110.2|          4757063327|  9.627203| 93.099441|