I recently acquired a Juniper EX-4200 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.
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
- Changed the Mode to “Hybrid outbound NAT rule generation”
- 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|