<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: ZeroTrust Architect</title>
    <description>The latest articles on DEV Community by ZeroTrust Architect (@goodguy11).</description>
    <link>https://dev.to/goodguy11</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3884886%2F67e8fbca-1ebb-4614-acff-8ba90b868ad3.png</url>
      <title>DEV Community: ZeroTrust Architect</title>
      <link>https://dev.to/goodguy11</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/goodguy11"/>
    <language>en</language>
    <item>
      <title>Your ISP Box Was Never Designed to Protect You — Here's What We Did About It</title>
      <dc:creator>ZeroTrust Architect</dc:creator>
      <pubDate>Thu, 28 May 2026 06:07:06 +0000</pubDate>
      <link>https://dev.to/goodguy11/your-isp-box-was-never-designed-to-protect-you-heres-what-we-did-about-it-2h4p</link>
      <guid>https://dev.to/goodguy11/your-isp-box-was-never-designed-to-protect-you-heres-what-we-did-about-it-2h4p</guid>
      <description>&lt;p&gt;We talk to a lot of small business owners. And when we ask them what's protecting their network, we get the same answer almost every time.&lt;/p&gt;

&lt;p&gt;They point at the box their internet provider gave them.&lt;/p&gt;

&lt;p&gt;That box. The one blinking in the corner. The one nobody ever touches.&lt;/p&gt;

&lt;p&gt;Here's the thing nobody tells them: &lt;strong&gt;that box was never designed to protect you.&lt;/strong&gt; It was designed to connect you. Two very different jobs.&lt;/p&gt;

&lt;p&gt;🧑‍💻 &lt;strong&gt;Experienced with networking?&lt;/strong&gt; The basics are covered in the first two sections — feel free to jump straight to So we put ourselves in the chain.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4dveq676cj1rzsn7xgme.png" alt="ISP Router without Protections" width="800" height="533"&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  What the ISP box actually does
&lt;/h2&gt;

&lt;p&gt;Your router forwards traffic. That's it. When you visit a website, it passes the request along. When the response comes back, it delivers it to your device. It does this for everything — legitimate requests, malware callbacks, phishing traffic, all of it — without asking a single question.&lt;/p&gt;

&lt;p&gt;It's not a flaw. It's by design. ISP routers are built to be universal and simple. Security is simply not their job.&lt;/p&gt;

&lt;p&gt;So if something on your network gets compromised — a laptop, a phone, even a printer — your router will happily forward whatever traffic that device generates. Nobody's watching.&lt;/p&gt;




&lt;h2&gt;
  
  
  Two concepts that unlock everything
&lt;/h2&gt;

&lt;p&gt;Before we built &lt;a href="https://www.cacheguard.com" rel="noopener noreferrer"&gt;CacheGuard&lt;/a&gt;, we spent a lot of time figuring out how to explain the problem to non-technical people. We landed on two ideas that make everything else click.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. An IP address is a postal address for a device
&lt;/h3&gt;

&lt;p&gt;Every device on your network has one. Your laptop, your phone, your printer — each has a unique number like &lt;code&gt;192.168.1.42&lt;/code&gt;. When your laptop sends a request to a website, it includes that address so the network knows where to deliver the response. That's all an IP address is.&lt;/p&gt;

&lt;p&gt;Two flavours matter here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Private IP&lt;/strong&gt; — used inside your office. Devices talk to each other, but the internet can't reach them directly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Public IP&lt;/strong&gt; — the address your ISP assigns your router. It's how the outside world sees your entire network.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. A default route is just a rule: "when in doubt, ask the gateway"
&lt;/h3&gt;

&lt;p&gt;When a device wants to reach something on the internet and doesn't know the exact path, it follows its &lt;strong&gt;default route&lt;/strong&gt; — a rule that points it toward a gateway device. The gateway figures out the next step.&lt;/p&gt;

&lt;p&gt;In a typical office:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Your devices → Router (ISP box) → ISP → Internet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every device in the office has a default route pointing at the router. The router has a default route pointing at the ISP. Simple chain.&lt;/p&gt;

&lt;p&gt;Here's the insight: &lt;strong&gt;whoever controls the gateway controls the traffic.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  So we put ourselves in the chain
&lt;/h2&gt;

&lt;p&gt;That's exactly what CacheGuard does. It inserts itself between your devices and your ISP router:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Your devices → CacheGuard → ISP Router → Internet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your devices' default route now points to CacheGuard. CacheGuard's default route points to the ISP router. The chain still works — but now there's a checkpoint in the middle that can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Block malicious domains and malware&lt;/li&gt;
&lt;li&gt;Filter content by category&lt;/li&gt;
&lt;li&gt;Cache web content to speed up browsing&lt;/li&gt;
&lt;li&gt;Log and monitor all network activity&lt;/li&gt;
&lt;li&gt;Control access by device or user&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9e03rpa18d4u5mt3zu1t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9e03rpa18d4u5mt3zu1t.png" alt="Network Gateway for Small Business with CacheGuard" width="799" height="250"&gt;&lt;/a&gt;&lt;br&gt;
And the ISP router? &lt;strong&gt;It needs zero changes.&lt;/strong&gt; It keeps doing what it always did.&lt;/p&gt;




&lt;h2&gt;
  
  
  What the setup actually looks like
&lt;/h2&gt;

&lt;p&gt;CacheGuard runs on any standard PC or virtual machine. It needs two network interfaces:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;WAN&lt;/strong&gt; — connected to your ISP router&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LAN&lt;/strong&gt; — connected to your office switch
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Internet]
    |
[ISP Router]        ← e.g. 192.168.1.1  (unchanged)
    |
[CacheGuard]        ← WAN: 192.168.1.2 / LAN: 10.0.0.1
    |
[Office switch]
    |
[All your devices]  ← default route: 10.0.0.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At the IP level:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;CacheGuard WAN&lt;/strong&gt; gets an IP on the ISP router's subnet (e.g. &lt;code&gt;192.168.1.2&lt;/code&gt;). Its default route points to the ISP router (&lt;code&gt;192.168.1.1&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CacheGuard LAN&lt;/strong&gt; gets an IP on a separate subnet (e.g. &lt;code&gt;10.0.0.1&lt;/code&gt;). This becomes the gateway for all office devices.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your devices&lt;/strong&gt; get their default route updated to &lt;code&gt;10.0.0.1&lt;/code&gt; — easiest done by letting CacheGuard act as your DHCP server.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 You don't need to reconfigure your ISP router at all. CacheGuard simply inserts itself and the router carries on as before.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqcqjupxhz21xh0apzhic.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqcqjupxhz21xh0apzhic.png" alt="Implementing a Network Gateway with CacheGuard" width="800" height="297"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why free and open-source
&lt;/h2&gt;

&lt;p&gt;A small dental practice faces the same phishing attacks as a large corporation. A five-person agency is just as vulnerable to ransomware. The difference is resources — and we think that's the wrong reason for someone to go unprotected.&lt;/p&gt;

&lt;p&gt;CacheGuard is free, open-source, and built to be deployed by someone who isn't a network engineer. The web-based admin interface walks you through configuration, and the defaults are sensible and secure out of the box.&lt;/p&gt;




&lt;h2&gt;
  
  
  Where to go from here
&lt;/h2&gt;

&lt;p&gt;👉 &lt;a href="https://www.cacheguard.com/network-gateway-for-small-business/" rel="noopener noreferrer"&gt;Full plain-English setup guide&lt;/a&gt;&lt;br&gt;
📖 &lt;a href="https://www.cacheguard.com/cacheguard-documentation/" rel="noopener noreferrer"&gt;CacheGuard Documentation&lt;/a&gt;&lt;br&gt;
💬 &lt;a href="https://help.cacheguard.net/" rel="noopener noreferrer"&gt;Community forum&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also worth reading if you want to go deeper on network architecture: &lt;a href="https://www.cacheguard.com/what-is-a-dmz-network/" rel="noopener noreferrer"&gt;What is a DMZ network?&lt;/a&gt;&lt;/p&gt;

</description>
      <category>networking</category>
      <category>security</category>
      <category>opensource</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Blocking Adult Content at the Proxy Layer: Mandatory HTTPS Enforcement, Category Filtering, and Always-On VPN</title>
      <dc:creator>ZeroTrust Architect</dc:creator>
      <pubDate>Wed, 20 May 2026 07:58:36 +0000</pubDate>
      <link>https://dev.to/goodguy11/blocking-adult-content-at-the-proxy-layer-mandatory-https-enforcement-category-filtering-and-4k65</link>
      <guid>https://dev.to/goodguy11/blocking-adult-content-at-the-proxy-layer-mandatory-https-enforcement-category-filtering-and-4k65</guid>
      <description>&lt;p&gt;DNS-based adult content filtering is the most commonly recommended approach and the least reliable technically. Here is why it fails and how to implement proxy-layer filtering that cannot be bypassed with a DNS settings change.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fic8atykt32i9ptpuy1uo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fic8atykt32i9ptpuy1uo.png" alt="Blocking Adult Content at the Home Gateway" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why DNS filtering fails for adult content blocking
&lt;/h2&gt;

&lt;p&gt;DNS filtering intercepts name resolution queries and returns &lt;code&gt;NXDOMAIN&lt;/code&gt; for blocked domains. Three bypass vectors make it unreliable:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Manual DNS override&lt;/strong&gt; (30 seconds, no technical knowledge required):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# iOS: Settings → Wi-Fi → [network] → Configure DNS → Manual → 8.8.8.8
# Android: Settings → Network → Private DNS → dns.google
# Windows: Network adapter settings → IPv4 → DNS servers → 8.8.8.8
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Result: queries go to Google's resolver, which does not enforce your blocklist.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. DNS over HTTPS (DoH)&lt;/strong&gt; — enabled by default in several environments:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Firefox: uses Cloudflare DoH by default (&lt;code&gt;about:config → network.trr.mode = 2&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Windows 11: DoH supported natively, configurable without admin rights&lt;/li&gt;
&lt;li&gt;Chrome: uses DoH when the configured DNS server supports it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;DoH encrypts DNS queries in HTTPS, making them indistinguishable from regular web traffic. Your DNS filter never sees the query.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Mobile data&lt;/strong&gt; — bypasses the home network entirely. No DNS filtering, no network controls.&lt;/p&gt;

&lt;h2&gt;
  
  
  Proxy-layer enforcement architecture
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Client] → [iptables REDIRECT] → [Squid proxy] → [Category filter] → [Internet]
                                        ↑
                    Cannot bypass: traffic physically redirected by kernel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 1: Mandatory proxy via iptables
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Redirect all HTTP to transparent Squid port&lt;/span&gt;
iptables &lt;span class="nt"&gt;-t&lt;/span&gt; nat &lt;span class="nt"&gt;-A&lt;/span&gt; PREROUTING &lt;span class="nt"&gt;-i&lt;/span&gt; eth1 &lt;span class="nt"&gt;-p&lt;/span&gt; tcp &lt;span class="nt"&gt;--dport&lt;/span&gt; 80 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; 192.168.1.1 &lt;span class="nt"&gt;-j&lt;/span&gt; REDIRECT &lt;span class="nt"&gt;--to-port&lt;/span&gt; 3128

&lt;span class="c"&gt;# Block direct HTTPS bypassing the proxy&lt;/span&gt;
&lt;span class="c"&gt;# (Squid handles HTTPS via CONNECT in explicit mode)&lt;/span&gt;
&lt;span class="c"&gt;# Force all clients to use explicit proxy for HTTPS:&lt;/span&gt;
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-p&lt;/span&gt; tcp &lt;span class="nt"&gt;--dport&lt;/span&gt; 443 &lt;span class="nt"&gt;-j&lt;/span&gt; DROP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For explicit proxy mode: configure clients to use &lt;code&gt;192.168.1.1:3128&lt;/code&gt; as proxy. The &lt;code&gt;FORWARD DROP&lt;/code&gt; rule ensures any device that ignores the proxy configuration cannot reach port 443 directly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Squid adult content category filtering
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# /etc/squid/squid.conf

url_rewrite_program /usr/bin/squidGuard -c /etc/squidguard/squidGuard.conf
url_rewrite_children 5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="c"&gt;# /etc/squidguard/squidGuard.conf
&lt;/span&gt;
&lt;span class="n"&gt;dbhome&lt;/span&gt; /&lt;span class="n"&gt;var&lt;/span&gt;/&lt;span class="n"&gt;lib&lt;/span&gt;/&lt;span class="n"&gt;squidguard&lt;/span&gt;/&lt;span class="n"&gt;db&lt;/span&gt;
&lt;span class="n"&gt;logdir&lt;/span&gt; /&lt;span class="n"&gt;var&lt;/span&gt;/&lt;span class="n"&gt;log&lt;/span&gt;/&lt;span class="n"&gt;squidguard&lt;/span&gt;

&lt;span class="n"&gt;dest&lt;/span&gt; &lt;span class="n"&gt;adult&lt;/span&gt; {
    &lt;span class="n"&gt;domainlist&lt;/span&gt; &lt;span class="n"&gt;adult&lt;/span&gt;/&lt;span class="n"&gt;domains&lt;/span&gt;
    &lt;span class="n"&gt;urllist&lt;/span&gt;    &lt;span class="n"&gt;adult&lt;/span&gt;/&lt;span class="n"&gt;urls&lt;/span&gt;
}

&lt;span class="n"&gt;dest&lt;/span&gt; &lt;span class="n"&gt;anonymizers&lt;/span&gt; {
    &lt;span class="n"&gt;domainlist&lt;/span&gt; &lt;span class="n"&gt;anonymizers&lt;/span&gt;/&lt;span class="n"&gt;domains&lt;/span&gt;
}

&lt;span class="n"&gt;acl&lt;/span&gt; {
    &lt;span class="n"&gt;default&lt;/span&gt; {
        &lt;span class="n"&gt;pass&lt;/span&gt; !&lt;span class="n"&gt;adult&lt;/span&gt; !&lt;span class="n"&gt;anonymizers&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt;
        &lt;span class="n"&gt;redirect&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;://&lt;span class="m"&gt;192&lt;/span&gt;.&lt;span class="m"&gt;168&lt;/span&gt;.&lt;span class="m"&gt;1&lt;/span&gt;.&lt;span class="m"&gt;1&lt;/span&gt;/&lt;span class="n"&gt;blocked&lt;/span&gt;.&lt;span class="n"&gt;html&lt;/span&gt;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;anonymizers&lt;/code&gt; category blocks web-based proxy services that could be used to route around the adult content filter.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: HTTPS filtering via CONNECT method
&lt;/h3&gt;

&lt;p&gt;In explicit proxy mode, HTTPS connections use the HTTP CONNECT method. The proxy sees the destination hostname in plaintext before the TLS handshake:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;CONNECT www.adult-site.com:443 HTTP/1.1
Host: www.adult-site.com:443
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Squid evaluates ACLs against the CONNECT target:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;acl adult_ssl ssl::server_name_regex -i "/etc/squid/adult_domains.txt"
http_access deny CONNECT adult_ssl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For category-based HTTPS filtering without SSL decryption, this provides hostname-level blocking. For URL-path-level filtering on HTTPS, SSL inspection (ssl-bump) is required.&lt;/p&gt;

&lt;h2&gt;
  
  
  Extending filtering outside the home: always-on IKEv2 VPN
&lt;/h2&gt;

&lt;p&gt;Mobile devices on cellular data bypass all home network controls. An always-on VPN routes all device traffic through the home gateway regardless of the underlying network:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="c"&gt;# /etc/ipsec.conf — StrongSwan full-tunnel VPN
&lt;/span&gt;&lt;span class="err"&gt;conn&lt;/span&gt; &lt;span class="err"&gt;family-devices&lt;/span&gt;
    &lt;span class="py"&gt;keyexchange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;ikev2&lt;/span&gt;
    &lt;span class="py"&gt;leftsubnet&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;0.0.0.0/0    # Route all traffic through tunnel&lt;/span&gt;
    &lt;span class="py"&gt;rightsourceip&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;10.9.0.0/24&lt;/span&gt;
    &lt;span class="py"&gt;rightdns&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;192.168.1.1    # Internal DNS&lt;/span&gt;
    &lt;span class="py"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;add&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;iOS always-on VPN&lt;/strong&gt; (via configuration profile):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;OnDemandEnabled&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;integer&amp;gt;&lt;/span&gt;1&lt;span class="nt"&gt;&amp;lt;/integer&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;OnDemandRules&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;array&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;Action&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;Connect&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;    &lt;span class="c"&gt;&amp;lt;!-- Connect on any network --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/array&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Android always-on VPN&lt;/strong&gt;: Settings → Network → VPN → [profile] → Always-on VPN + Block connections without VPN.&lt;/p&gt;

&lt;p&gt;Once the device is on the VPN, all traffic routes to the home gateway → through the Squid proxy → through the category filter → then to the internet. The adult content filter applies regardless of the physical connection.&lt;/p&gt;

&lt;h2&gt;
  
  
  URL blacklist maintenance
&lt;/h2&gt;

&lt;p&gt;Category databases require regular updates. Options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Free community-maintained lists (variable quality, manual update)&lt;/li&gt;
&lt;li&gt;Commercial subscription databases (higher coverage, automated updates)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For automated updates via cron:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Update squidGuard category database&lt;/span&gt;
0 3 &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; /usr/bin/squidGuard &lt;span class="nt"&gt;-C&lt;/span&gt; all &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; /usr/bin/squid &lt;span class="nt"&gt;-k&lt;/span&gt; reconfigure
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;CacheGuard&lt;/strong&gt; ships Squid + SquidGuard + mandatory proxy enforcement + IKEv2 VPN pre-integrated, with an optional URL blacklist subscription for continuously updated adult content categories.&lt;/p&gt;

&lt;p&gt;→ &lt;a href="https://www.cacheguard.com/block-adult-content-home-network/" rel="noopener noreferrer"&gt;https://www.cacheguard.com/block-adult-content-home-network/&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://www.cacheguard.com/block-adult-content-home-network/" rel="noopener noreferrer"&gt;CacheGuard Blog&lt;/a&gt;. CacheGuard is free and open source — &lt;a href="https://github.com/cacheguard/CacheGuard-OS" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>networking</category>
      <category>linux</category>
      <category>selfhosted</category>
    </item>
    <item>
      <title>Implementing a Three-Zone DMZ With a Single Firewall: iptables Rules, Zone Isolation, and Traffic Flow Analysis</title>
      <dc:creator>ZeroTrust Architect</dc:creator>
      <pubDate>Wed, 20 May 2026 07:57:48 +0000</pubDate>
      <link>https://dev.to/goodguy11/implementing-a-three-zone-dmz-with-a-single-firewall-iptables-rules-zone-isolation-and-traffic-1fbc</link>
      <guid>https://dev.to/goodguy11/implementing-a-three-zone-dmz-with-a-single-firewall-iptables-rules-zone-isolation-and-traffic-1fbc</guid>
      <description>&lt;p&gt;A DMZ is implemented by placing internet-facing servers in a network zone that is accessible from the internet but isolated from the internal LAN. A single firewall with three network interfaces is sufficient for most SME deployments. Here is the technical implementation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9tgm7v81ztxdur01xa7z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9tgm7v81ztxdur01xa7z.png" alt="DMZ Network"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Network topology
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Internet]
    |
   eth0 (WAN: 203.0.113.1)
    |
[Firewall/Gateway]
    |           |
   eth1        eth2
(DMZ:        (Internal LAN:
192.168.10.0/24)  192.168.1.0/24)
    |
[Web server: 192.168.10.5]
[Email server: 192.168.10.6]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Default zone policies
&lt;/h2&gt;

&lt;p&gt;The firewall's default posture for each zone crossing:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;From → To&lt;/th&gt;
&lt;th&gt;Default policy&lt;/th&gt;
&lt;th&gt;Rationale&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Internet → DMZ&lt;/td&gt;
&lt;td&gt;Deny (explicit permits only)&lt;/td&gt;
&lt;td&gt;Only specific published services allowed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Internet → Internal&lt;/td&gt;
&lt;td&gt;Deny all&lt;/td&gt;
&lt;td&gt;No direct external access to internal LAN&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DMZ → Internal&lt;/td&gt;
&lt;td&gt;Deny all&lt;/td&gt;
&lt;td&gt;Compromised DMZ server cannot reach internal&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Internal → DMZ&lt;/td&gt;
&lt;td&gt;Permit&lt;/td&gt;
&lt;td&gt;Internal hosts manage DMZ servers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Internal → Internet&lt;/td&gt;
&lt;td&gt;Permit&lt;/td&gt;
&lt;td&gt;Outbound internal traffic allowed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DMZ → Internet&lt;/td&gt;
&lt;td&gt;Permit (restricted)&lt;/td&gt;
&lt;td&gt;DMZ servers can reach external resources&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  iptables implementation
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Flush existing rules&lt;/span&gt;
iptables &lt;span class="nt"&gt;-F&lt;/span&gt; FORWARD
iptables &lt;span class="nt"&gt;-P&lt;/span&gt; FORWARD DROP   &lt;span class="c"&gt;# Default deny all zone crossings&lt;/span&gt;

&lt;span class="c"&gt;# === INTERNET → DMZ ===&lt;/span&gt;
&lt;span class="c"&gt;# Allow inbound HTTPS to web server&lt;/span&gt;
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-o&lt;/span&gt; eth1 &lt;span class="nt"&gt;-d&lt;/span&gt; 192.168.10.5 &lt;span class="nt"&gt;-p&lt;/span&gt; tcp &lt;span class="nt"&gt;--dport&lt;/span&gt; 443 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
&lt;span class="c"&gt;# Allow inbound SMTP to email server&lt;/span&gt;
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-o&lt;/span&gt; eth1 &lt;span class="nt"&gt;-d&lt;/span&gt; 192.168.10.6 &lt;span class="nt"&gt;-p&lt;/span&gt; tcp &lt;span class="nt"&gt;--dport&lt;/span&gt; 25 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
&lt;span class="c"&gt;# Allow established/related return traffic&lt;/span&gt;
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-i&lt;/span&gt; eth1 &lt;span class="nt"&gt;-o&lt;/span&gt; eth0 &lt;span class="nt"&gt;-m&lt;/span&gt; state &lt;span class="nt"&gt;--state&lt;/span&gt; ESTABLISHED,RELATED &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT

&lt;span class="c"&gt;# === INTERNET → INTERNAL ===&lt;/span&gt;
&lt;span class="c"&gt;# Default DROP already covers this (no explicit permit)&lt;/span&gt;

&lt;span class="c"&gt;# === DMZ → INTERNAL ===&lt;/span&gt;
&lt;span class="c"&gt;# Default DROP covers this.&lt;/span&gt;
&lt;span class="c"&gt;# Explicit permit: web server to internal database only&lt;/span&gt;
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-i&lt;/span&gt; eth1 &lt;span class="nt"&gt;-s&lt;/span&gt; 192.168.10.5 &lt;span class="nt"&gt;-o&lt;/span&gt; eth2 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; 192.168.1.20 &lt;span class="nt"&gt;-p&lt;/span&gt; tcp &lt;span class="nt"&gt;--dport&lt;/span&gt; 5432 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-i&lt;/span&gt; eth2 &lt;span class="nt"&gt;-s&lt;/span&gt; 192.168.1.20 &lt;span class="nt"&gt;-o&lt;/span&gt; eth1 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; 192.168.10.5 &lt;span class="nt"&gt;-m&lt;/span&gt; state &lt;span class="nt"&gt;--state&lt;/span&gt; ESTABLISHED,RELATED &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT

&lt;span class="c"&gt;# === INTERNAL → DMZ ===&lt;/span&gt;
&lt;span class="c"&gt;# Allow internal management access to all DMZ servers&lt;/span&gt;
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-i&lt;/span&gt; eth2 &lt;span class="nt"&gt;-o&lt;/span&gt; eth1 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-i&lt;/span&gt; eth1 &lt;span class="nt"&gt;-o&lt;/span&gt; eth2 &lt;span class="nt"&gt;-m&lt;/span&gt; state &lt;span class="nt"&gt;--state&lt;/span&gt; ESTABLISHED,RELATED &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT

&lt;span class="c"&gt;# === INTERNAL → INTERNET ===&lt;/span&gt;
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-i&lt;/span&gt; eth2 &lt;span class="nt"&gt;-o&lt;/span&gt; eth0 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-o&lt;/span&gt; eth2 &lt;span class="nt"&gt;-m&lt;/span&gt; state &lt;span class="nt"&gt;--state&lt;/span&gt; ESTABLISHED,RELATED &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT

&lt;span class="c"&gt;# === DMZ → INTERNET ===&lt;/span&gt;
&lt;span class="c"&gt;# DMZ servers can reach the internet for updates, API calls&lt;/span&gt;
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-i&lt;/span&gt; eth1 &lt;span class="nt"&gt;-o&lt;/span&gt; eth0 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-o&lt;/span&gt; eth1 &lt;span class="nt"&gt;-m&lt;/span&gt; state &lt;span class="nt"&gt;--state&lt;/span&gt; ESTABLISHED,RELATED &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT

&lt;span class="c"&gt;# === NAT ===&lt;/span&gt;
iptables &lt;span class="nt"&gt;-t&lt;/span&gt; nat &lt;span class="nt"&gt;-A&lt;/span&gt; POSTROUTING &lt;span class="nt"&gt;-o&lt;/span&gt; eth0 &lt;span class="nt"&gt;-j&lt;/span&gt; MASQUERADE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Traffic flow verification
&lt;/h2&gt;

&lt;p&gt;After applying rules, verify each permitted and denied flow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Should succeed: internal host reaching DMZ web server&lt;/span&gt;
curl &lt;span class="nt"&gt;-k&lt;/span&gt; https://192.168.10.5  &lt;span class="c"&gt;# from 192.168.1.x host&lt;/span&gt;

&lt;span class="c"&gt;# Should succeed: internet reaching DMZ web server (test with external tool)&lt;/span&gt;
curl &lt;span class="nt"&gt;-k&lt;/span&gt; https://203.0.113.1   &lt;span class="c"&gt;# after DNAT rule (see below)&lt;/span&gt;

&lt;span class="c"&gt;# Should fail: DMZ server reaching internal LAN (not the database)&lt;/span&gt;
&lt;span class="c"&gt;# From 192.168.10.5:&lt;/span&gt;
ping 192.168.1.1    &lt;span class="c"&gt;# Expected: no response (FORWARD DROP)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  DNAT for public service exposure
&lt;/h2&gt;

&lt;p&gt;To expose DMZ services to the internet via the gateway's public IP:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# DNAT: inbound HTTPS on public IP → DMZ web server&lt;/span&gt;
iptables &lt;span class="nt"&gt;-t&lt;/span&gt; nat &lt;span class="nt"&gt;-A&lt;/span&gt; PREROUTING &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-p&lt;/span&gt; tcp &lt;span class="nt"&gt;--dport&lt;/span&gt; 443 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-j&lt;/span&gt; DNAT &lt;span class="nt"&gt;--to-destination&lt;/span&gt; 192.168.10.5:443
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Reverse proxy in the DMZ
&lt;/h2&gt;

&lt;p&gt;A more secure architecture places a reverse proxy in the DMZ rather than the web server directly. The reverse proxy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Terminates TLS (holds the certificate private key)&lt;/li&gt;
&lt;li&gt;Applies WAF inspection (ModSecurity + OWASP CRS)&lt;/li&gt;
&lt;li&gt;Forwards clean requests to backend servers in the internal zone
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Internet] → eth0 → [DMZ: Reverse Proxy + WAF] → eth2 → [Internal: App server]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The app server is never directly reachable from the internet. Only the reverse proxy is in the DMZ. WAF inspection happens before any request reaches the application.&lt;/p&gt;

&lt;h2&gt;
  
  
  CacheGuard zone architecture
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;CacheGuard&lt;/strong&gt; implements this via its native zone model: external zone (eth0), internal/web zone (eth1) with optional rweb VLAN for web servers, and auxiliary zone (eth2) for general DMZ services. Zone policies are configured through the web interface without writing iptables rules directly.&lt;/p&gt;

&lt;p&gt;→ &lt;a href="https://www.cacheguard.com/what-is-a-dmz-network/" rel="noopener noreferrer"&gt;https://www.cacheguard.com/what-is-a-dmz-network/&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://www.cacheguard.com/what-is-a-dmz-network/" rel="noopener noreferrer"&gt;CacheGuard Blog&lt;/a&gt;. CacheGuard is free and open source — &lt;a href="https://github.com/cacheguard/CacheGuard-OS" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>networking</category>
      <category>linux</category>
      <category>devops</category>
    </item>
    <item>
      <title>GDPR Article 32 and NIS2 Article 21: Mapping Cybersecurity Requirements to Concrete Network Controls</title>
      <dc:creator>ZeroTrust Architect</dc:creator>
      <pubDate>Wed, 20 May 2026 07:57:31 +0000</pubDate>
      <link>https://dev.to/goodguy11/gdpr-article-32-and-nis2-article-21-mapping-cybersecurity-requirements-to-concrete-network-controls-5bgn</link>
      <guid>https://dev.to/goodguy11/gdpr-article-32-and-nis2-article-21-mapping-cybersecurity-requirements-to-concrete-network-controls-5bgn</guid>
      <description>&lt;p&gt;Both GDPR and NIS2 specify technical security requirements in principle-based language. This guide maps those principles to concrete network security controls — what each requirement means technically, and which controls satisfy it.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is a technical guide, not legal advice.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3vdda6xtp0u93vmq62gc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3vdda6xtp0u93vmq62gc.png" alt="Network Security Compliance" width="800" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  GDPR Article 32: Technical Requirements
&lt;/h2&gt;

&lt;p&gt;Article 32 requires "appropriate technical and organizational measures" and specifically mentions:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;GDPR Article 32 requirement&lt;/th&gt;
&lt;th&gt;Technical interpretation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Pseudonymization and encryption of personal data&lt;/td&gt;
&lt;td&gt;Encryption in transit (TLS/IPsec) and at rest (disk encryption)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Confidentiality, integrity, availability, resilience&lt;/td&gt;
&lt;td&gt;Network segmentation, redundancy, access control&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ability to restore availability&lt;/td&gt;
&lt;td&gt;Failover, backup, tested recovery procedures&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Regular testing and evaluation&lt;/td&gt;
&lt;td&gt;Vulnerability scanning, penetration testing, log review&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Encryption in transit: IPsec VPN implementation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="c"&gt;# StrongSwan IKEv2 — encrypts remote worker traffic
&lt;/span&gt;&lt;span class="err"&gt;conn&lt;/span&gt; &lt;span class="err"&gt;gdpr-remote-access&lt;/span&gt;
    &lt;span class="py"&gt;keyexchange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;ikev2&lt;/span&gt;
    &lt;span class="py"&gt;left&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;%any&lt;/span&gt;
    &lt;span class="py"&gt;leftcert&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;server.crt&lt;/span&gt;
    &lt;span class="py"&gt;leftsubnet&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;0.0.0.0/0    # Full tunnel — all remote traffic encrypted&lt;/span&gt;
    &lt;span class="py"&gt;right&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;%any&lt;/span&gt;
    &lt;span class="py"&gt;rightsourceip&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;10.8.0.0/24&lt;/span&gt;
    &lt;span class="py"&gt;ike&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;aes256-sha256-ecp256!&lt;/span&gt;
    &lt;span class="py"&gt;esp&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;aes256-sha256!&lt;/span&gt;
    &lt;span class="py"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;add&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This satisfies encryption in transit for remote workers. Encryption at rest (full-disk encryption, database encryption) is a separate control at the endpoint/server layer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Network segmentation: zone-based firewall
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Zone isolation: separate VLAN for servers holding personal data&lt;/span&gt;
&lt;span class="c"&gt;# Default deny between zones&lt;/span&gt;
iptables &lt;span class="nt"&gt;-I&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-i&lt;/span&gt; eth1.servers &lt;span class="nt"&gt;-o&lt;/span&gt; eth1.workstations &lt;span class="nt"&gt;-j&lt;/span&gt; DROP
iptables &lt;span class="nt"&gt;-I&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-i&lt;/span&gt; eth1.workstations &lt;span class="nt"&gt;-o&lt;/span&gt; eth1.servers &lt;span class="nt"&gt;-j&lt;/span&gt; DROP

&lt;span class="c"&gt;# Explicit permit: specific application only&lt;/span&gt;
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-i&lt;/span&gt; eth1.workstations &lt;span class="nt"&gt;-d&lt;/span&gt; 192.168.10.5 &lt;span class="nt"&gt;-p&lt;/span&gt; tcp &lt;span class="nt"&gt;--dport&lt;/span&gt; 443 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Zone segmentation limits the blast radius of a compromise. An attacker who compromises a workstation cannot directly reach database servers in a different zone.&lt;/p&gt;

&lt;h2&gt;
  
  
  NIS2 Article 21: Ten Mandatory Cybersecurity Measures
&lt;/h2&gt;

&lt;p&gt;For in-scope organizations, Article 21 specifies ten mandatory measures. The network-relevant ones:&lt;/p&gt;

&lt;h3&gt;
  
  
  Access control and identity management
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Squid LDAP authentication — restrict proxy access to authenticated users
auth_param basic program /usr/lib/squid/basic_ldap_auth \
  -b dc=example,dc=com -f '(&amp;amp;(sAMAccountName=%s))' -h ldap.example.com
auth_param basic children 10
auth_param basic realm Network Access

acl authenticated proxy_auth REQUIRED
http_access deny !authenticated
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Network segmentation (same as GDPR above)
&lt;/h3&gt;

&lt;p&gt;NIS2 is more explicit: it requires documented network segmentation policies, not just technical controls. The iptables rules above need accompanying documentation describing the segmentation design and rationale.&lt;/p&gt;

&lt;h3&gt;
  
  
  Encryption
&lt;/h3&gt;

&lt;p&gt;Same controls as GDPR — IPsec for remote access, TLS for internal service communication, certificate management.&lt;/p&gt;

&lt;h3&gt;
  
  
  Incident detection and response
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# iptables logging for anomaly detection&lt;/span&gt;
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-j&lt;/span&gt; LOG &lt;span class="nt"&gt;--log-prefix&lt;/span&gt; &lt;span class="s2"&gt;"FORWARD: "&lt;/span&gt; &lt;span class="nt"&gt;--log-level&lt;/span&gt; 4

&lt;span class="c"&gt;# Review logs for:&lt;/span&gt;
&lt;span class="c"&gt;# - Unusual outbound connection volumes&lt;/span&gt;
&lt;span class="c"&gt;# - Connections to unexpected external IPs&lt;/span&gt;
&lt;span class="c"&gt;# - Internal zone crossing attempts not matching permit rules&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;NIS2 requires incident reporting within 24 hours. This is an organizational process, not a technical control — but logs from the gateway provide the evidence needed to determine what happened and when.&lt;/p&gt;

&lt;h3&gt;
  
  
  Malware protection
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# ICAP antivirus — gateway malware scanning
icap_enable on
icap_service av_service reqmod_precache bypass=0 icap://127.0.0.1:1344/squid_clamav
adaptation_service_set request_services av_service
adaptation_access request_services allow all
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;bypass=0&lt;/code&gt; means: if the ICAP service is unavailable, deny the request rather than allowing unscanned content through. This is the correct setting for a compliance posture.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a network appliance does NOT cover for compliance
&lt;/h2&gt;

&lt;p&gt;Critical controls outside the network layer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Encryption at rest&lt;/strong&gt;: implement at the OS level (LUKS, BitLocker) or database level&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MFA&lt;/strong&gt;: implement at the application layer (identity provider, TOTP)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data breach notification (72h GDPR / 24h NIS2)&lt;/strong&gt;: organizational process, documented procedures&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Business continuity&lt;/strong&gt;: backup testing, recovery time objectives, documented procedures&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Supply chain security&lt;/strong&gt;: vendor risk assessments, contractual requirements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A gateway UTM satisfies the network security technical controls. The compliance posture requires these additional layers on top.&lt;/p&gt;

&lt;h2&gt;
  
  
  CacheGuard as implementation
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0jw8yc32ninqsqekotq8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0jw8yc32ninqsqekotq8.png" alt="Implement GPDR &amp;amp; NIS2 with CacheGuard" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CacheGuard&lt;/strong&gt; implements the gateway-layer technical controls above — zone firewall, IPsec VPN, gateway antivirus (ClamAV via ICAP with bypass=0), URL filtering, SSL inspection, WAF (ModSecurity + OWASP CRS), and traffic logging — in a single pre-integrated appliance.&lt;/p&gt;

&lt;p&gt;→ &lt;a href="https://www.cacheguard.com/network-security-compliance-gdpr-nis2/" rel="noopener noreferrer"&gt;https://www.cacheguard.com/network-security-compliance-gdpr-nis2/&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://www.cacheguard.com/network-security-compliance-gdpr-nis2/" rel="noopener noreferrer"&gt;CacheGuard Blog&lt;/a&gt;. CacheGuard is free and open source — &lt;a href="https://github.com/cacheguard/CacheGuard-OS" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>devops</category>
      <category>networking</category>
      <category>linux</category>
    </item>
    <item>
      <title>pfSense vs Integrated UTM Appliance: Plugin Dependency Graphs, Update Risk, and When Each Architecture Wins</title>
      <dc:creator>ZeroTrust Architect</dc:creator>
      <pubDate>Tue, 19 May 2026 09:01:11 +0000</pubDate>
      <link>https://dev.to/goodguy11/pfsense-vs-integrated-utm-appliance-plugin-dependency-graphs-update-risk-and-when-each-2kh1</link>
      <guid>https://dev.to/goodguy11/pfsense-vs-integrated-utm-appliance-plugin-dependency-graphs-update-risk-and-when-each-2kh1</guid>
      <description>&lt;p&gt;pfSense and OPNsense are the default homelab firewall recommendation. The recommendation is often correct — and sometimes not. The decision depends on understanding the architectural trade-off between the platform model and the integrated appliance model. Here is the technical picture.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqna44trzn6ekfwc352bt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqna44trzn6ekfwc352bt.png" alt="Homlab Network"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The platform model's dependency graph
&lt;/h2&gt;

&lt;p&gt;Reaching full UTM functionality on pfSense/OPNsense requires assembling a plugin stack. Each plugin introduces a dependency node:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pfSense/OPNsense (FreeBSD base)
├── Squid package (web proxy)
│   ├── c-icap (ICAP connector)
│   │   └── ClamAV (antivirus engine)
│   └── ssl-bump (TLS inspection)
│       └── CA certificate (PKI management)
├── SquidGuard or pfBlockerNG (URL filtering)
│   └── Category blocklists (external URLs)
├── Suricata or Snort (IDS/IPS)
│   └── Rule sources (ET, Snort VRT)
└── ModSecurity (WAF — limited integration path)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each arrow represents a compatibility surface. When the FreeBSD base updates (pfSense 2.x → 2.x+1), each package must also update. If a package maintainer is behind, you have three options:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Skip the FreeBSD update (accumulate security debt)&lt;/li&gt;
&lt;li&gt;Update and break the package (lose functionality)&lt;/li&gt;
&lt;li&gt;Wait for the package to catch up (delays on your timeline)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The c-icap → ClamAV boundary is particularly fragile. ClamAV major versions (0.103 → 0.104 → 1.x) changed API interfaces that broke c-icap compatibility. The result: after a ClamAV update, the antivirus silently stops scanning traffic — Squid receives no ICAP error, just an empty response, and continues delivering unscanned content.&lt;/p&gt;

&lt;p&gt;Detection requires actively monitoring ICAP responses:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Verify ICAP connectivity and ClamAV health&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"OPTIONS icap://127.0.0.1:1344/squid_clamav ICAP/1.0&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s2"&gt;Host: 127.0.0.1&lt;/span&gt;&lt;span class="se"&gt;\r\n\r\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | nc 127.0.0.1 1344
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A healthy response: &lt;code&gt;ICAP/1.0 200 OK&lt;/code&gt;. Silent failure: connection refused or no response — but Squid is not told, and content keeps flowing unscanned.&lt;/p&gt;

&lt;h2&gt;
  
  
  Packet filtering: FreeBSD pf vs Linux nftables
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;pfSense/OPNsense&lt;/strong&gt; uses OpenBSD's &lt;code&gt;pf&lt;/code&gt;. Last-match-wins semantics, stateful firewall, excellent NAT support:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# pf rule syntax
pass out on em0 proto { tcp, udp } from any to any
block in on em0 proto tcp from &amp;lt;blocklist&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Linux (CacheGuard, custom LFS)&lt;/strong&gt; uses &lt;code&gt;nftables&lt;/code&gt; (or iptables). First-match-wins with explicit jumps, better performance at scale via sets and maps:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# nftables equivalent&lt;/span&gt;
nft add rule inet filter input tcp dport &lt;span class="o"&gt;{&lt;/span&gt; 80, 443 &lt;span class="o"&gt;}&lt;/span&gt; accept
nft add rule inet filter input ip saddr @blocklist drop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At homelab traffic volumes (&amp;lt; 1 Gbps), neither has a measurable performance advantage. The syntactic differences matter more in practice than the performance characteristics.&lt;/p&gt;

&lt;h2&gt;
  
  
  The integrated appliance model
&lt;/h2&gt;

&lt;p&gt;An integrated appliance OS ships all UTM components from a single versioned release. The dependency graph collapses:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CacheGuard-OS (custom LFS-based Linux)
└── All components version-locked at release time:
    Squid + ClamAV + c-icap + ModSecurity + StrongSwan + iproute2
    ↑
    Tested together before release. No inter-component compatibility surface.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When CacheGuard updates, the Squid → c-icap → ClamAV chain has been verified by the release process. There is no scenario where ClamAV updates independently and silently breaks ICAP.&lt;/p&gt;

&lt;p&gt;Trade-off: you cannot substitute components. If you want a different proxy engine, a custom Suricata ruleset at the config level, or per-packet access to the BSD network stack, the integrated model is a constraint, not a feature.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to choose which
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Choose pfSense/OPNsense if:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Learning network security configuration is the explicit goal (plugin assembly = education)&lt;/li&gt;
&lt;li&gt;You need advanced routing (BGP, OSPF, MPLS simulation)&lt;/li&gt;
&lt;li&gt;You require IPS with custom Suricata/Snort rules&lt;/li&gt;
&lt;li&gt;Your lab simulates enterprise BSD network environments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Choose integrated appliance (CacheGuard) if:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The security layer is infrastructure for other lab work, not the lab work itself&lt;/li&gt;
&lt;li&gt;You want a working Squid+ClamAV+WAF stack without integration debugging&lt;/li&gt;
&lt;li&gt;You prefer a single update operation over coordinated multi-package updates&lt;/li&gt;
&lt;li&gt;You are running a self-hosted homelab with production-like security requirements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both run on identical x86 hardware. Both are free. Both support multiple network interfaces and VLAN trunking.&lt;/p&gt;

&lt;p&gt;→ &lt;a href="https://www.cacheguard.com/homelab-firewall/" rel="noopener noreferrer"&gt;https://www.cacheguard.com/homelab-firewall/&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://www.cacheguard.com/homelab-firewall/" rel="noopener noreferrer"&gt;CacheGuard Blog&lt;/a&gt;. CacheGuard is free and open source — &lt;a href="https://github.com/cacheguard/CacheGuard-OS" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>networking</category>
      <category>security</category>
      <category>selfhosted</category>
      <category>linux</category>
    </item>
    <item>
      <title>Full-Tunnel IPsec VPN for Remote Workers: StrongSwan Config, Split vs Full Tunnel, and Gateway Security Stack</title>
      <dc:creator>ZeroTrust Architect</dc:creator>
      <pubDate>Tue, 19 May 2026 09:00:19 +0000</pubDate>
      <link>https://dev.to/goodguy11/full-tunnel-ipsec-vpn-for-remote-workers-strongswan-config-split-vs-full-tunnel-and-gateway-5gbh</link>
      <guid>https://dev.to/goodguy11/full-tunnel-ipsec-vpn-for-remote-workers-strongswan-config-split-vs-full-tunnel-and-gateway-5gbh</guid>
      <description>&lt;p&gt;Most remote work VPN deployments use split tunneling: only traffic destined for internal corporate IP ranges goes through the VPN tunnel; direct internet traffic bypasses it. This is the wrong default for security. Here is why, and how to configure full-tunnel mode correctly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbq3mgaph2g8ippk02omh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbq3mgaph2g8ippk02omh.png" alt="Full-Tunnel IPsec VPN for Remote Workers"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Split tunnel vs full tunnel: the security difference
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Split tunnel:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Remote device → [VPN tunnel] → Internal resources (192.168.1.0/24)
Remote device → [Direct internet] → Web browsing (no gateway inspection)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Full tunnel:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Remote device → [VPN tunnel] → Gateway → Web browsing (gateway inspection)
Remote device → [VPN tunnel] → Gateway → Internal resources
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In split-tunnel mode, a remote worker's web browsing bypasses the office gateway entirely. Gateway antivirus, URL filtering, and traffic logging do not apply. The worker's laptop connects to the office for file access and connects directly to the internet for everything else — with only endpoint security between them and web-borne threats.&lt;/p&gt;

&lt;p&gt;Full-tunnel mode routes all traffic through the gateway. The remote worker gets the same gateway-level protections as an on-site employee.&lt;/p&gt;

&lt;h2&gt;
  
  
  StrongSwan IKEv2 configuration for full tunnel
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="c"&gt;# /etc/ipsec.conf
&lt;/span&gt;&lt;span class="err"&gt;conn&lt;/span&gt; &lt;span class="err"&gt;remote-workers&lt;/span&gt;
    &lt;span class="py"&gt;keyexchange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;ikev2&lt;/span&gt;
    &lt;span class="py"&gt;left&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;%any&lt;/span&gt;
    &lt;span class="py"&gt;leftid&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;@vpn.example.com&lt;/span&gt;
    &lt;span class="py"&gt;leftcert&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;server.crt&lt;/span&gt;
    &lt;span class="py"&gt;leftsendcert&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;always&lt;/span&gt;
    &lt;span class="py"&gt;leftsubnet&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;0.0.0.0/0    # ← Full tunnel: route ALL traffic through VPN&lt;/span&gt;
    &lt;span class="py"&gt;leftfirewall&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;yes&lt;/span&gt;

    &lt;span class="py"&gt;right&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;%any&lt;/span&gt;
    &lt;span class="py"&gt;rightauth&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;pubkey&lt;/span&gt;
    &lt;span class="py"&gt;rightsourceip&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;10.8.0.0/24   # Virtual IP pool for remote workers&lt;/span&gt;
    &lt;span class="py"&gt;rightdns&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;10.8.0.1           # Internal DNS resolver&lt;/span&gt;

    &lt;span class="py"&gt;ike&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;aes256-sha256-ecp256!&lt;/span&gt;
    &lt;span class="py"&gt;esp&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;aes256-sha256!&lt;/span&gt;
    &lt;span class="py"&gt;dpdaction&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;restart&lt;/span&gt;
    &lt;span class="py"&gt;dpddelay&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;30s&lt;/span&gt;
    &lt;span class="py"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;add&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The critical line is &lt;code&gt;leftsubnet=0.0.0.0/0&lt;/code&gt;. This tells IKEv2 to install a default route through the tunnel on the client — all traffic, not just traffic to internal subnets, routes through the VPN.&lt;/p&gt;

&lt;h2&gt;
  
  
  Traffic selectors for full tunnel
&lt;/h2&gt;

&lt;p&gt;In IKEv2, traffic selectors (TS) define which traffic flows through the SA. For full tunnel:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TSi (initiator): 0.0.0.0/0 (all traffic from client)
TSr (responder): 0.0.0.0/0 (to anywhere)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The client installs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;default via 10.8.0.1 dev tun0   #&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;All internet traffic → VPN tunnel
&lt;span class="gp"&gt;10.8.0.0/24 via tun0            #&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;VPN subnet direct
&lt;span class="gp"&gt;192.168.1.0/24 via tun0         #&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Internal LAN
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Gateway forwarding for VPN traffic
&lt;/h2&gt;

&lt;p&gt;The gateway must forward VPN client traffic to the internet and apply the same inspection stack as local clients:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Enable IP forwarding&lt;/span&gt;
&lt;span class="nb"&gt;echo &lt;/span&gt;1 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /proc/sys/net/ipv4/ip_forward

&lt;span class="c"&gt;# NAT VPN traffic to external interface&lt;/span&gt;
iptables &lt;span class="nt"&gt;-t&lt;/span&gt; nat &lt;span class="nt"&gt;-A&lt;/span&gt; POSTROUTING &lt;span class="nt"&gt;-s&lt;/span&gt; 10.8.0.0/24 &lt;span class="nt"&gt;-o&lt;/span&gt; eth0 &lt;span class="nt"&gt;-j&lt;/span&gt; MASQUERADE

&lt;span class="c"&gt;# Redirect VPN client HTTP through proxy (same as LAN clients)&lt;/span&gt;
iptables &lt;span class="nt"&gt;-t&lt;/span&gt; nat &lt;span class="nt"&gt;-A&lt;/span&gt; PREROUTING &lt;span class="nt"&gt;-s&lt;/span&gt; 10.8.0.0/24 &lt;span class="nt"&gt;-p&lt;/span&gt; tcp &lt;span class="nt"&gt;--dport&lt;/span&gt; 80 &lt;span class="nt"&gt;-j&lt;/span&gt; REDIRECT &lt;span class="nt"&gt;--to-port&lt;/span&gt; 3128

&lt;span class="c"&gt;# VPN clients subject to same FORWARD rules as LAN clients&lt;/span&gt;
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-s&lt;/span&gt; 10.8.0.0/24 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Client profile generation
&lt;/h2&gt;

&lt;p&gt;For iOS/macOS (native IKEv2):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- mobileconfig excerpt --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;VPNType&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;IKEv2&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;RemoteAddress&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;vpn.example.com&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;RemoteIdentifier&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;vpn.example.com&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;LocalIdentifier&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;worker@example.com&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;PayloadCertificateUUID&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;&lt;span class="c"&gt;&amp;lt;!-- UUID of client cert payload --&amp;gt;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- IPv4 routing: send all traffic through VPN --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;IPv4&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;OverridePrimary&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;integer&amp;gt;&lt;/span&gt;1&lt;span class="nt"&gt;&amp;lt;/integer&amp;gt;&lt;/span&gt;   &lt;span class="c"&gt;&amp;lt;!-- Full tunnel --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For Windows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Add-VpnConnection&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Work VPN"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;`
&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;-ServerAddress&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vpn.example.com"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;`
&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;-TunnelType&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;IKEv2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;`
&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;-AuthenticationMethod&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;MachineCertificate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;`
&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;-SplitTunneling&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;$false&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c"&gt;# ← Full tunnel: route all traffic&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What the remote worker gets
&lt;/h2&gt;

&lt;p&gt;With full-tunnel mode and a properly configured gateway:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Web traffic scanned by gateway antivirus (same as office)&lt;/li&gt;
&lt;li&gt;URL filtering applied (same categories and policies as office)&lt;/li&gt;
&lt;li&gt;Traffic logged at gateway (same visibility as office)&lt;/li&gt;
&lt;li&gt;Internal resources accessible as if on-site&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The home network becomes a transport layer. Everything meaningful happens at the gateway.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CacheGuard&lt;/strong&gt; implements this: IKEv2 VPN with StrongSwan in full-tunnel mode, integrated with the gateway antivirus, URL filtering, and logging stack. Client profiles generated for all major platforms through the web interface.&lt;/p&gt;

&lt;p&gt;→ &lt;a href="https://www.cacheguard.com/network-security-for-remote-workers/" rel="noopener noreferrer"&gt;https://www.cacheguard.com/network-security-for-remote-workers/&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://www.cacheguard.com/network-security-for-remote-workers/" rel="noopener noreferrer"&gt;CacheGuard Blog&lt;/a&gt;. CacheGuard is free and open source — &lt;a href="https://github.com/cacheguard/CacheGuard-OS" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>networking</category>
      <category>linux</category>
      <category>devops</category>
    </item>
    <item>
      <title>Enforcing Social Media Blocks at the Proxy Layer: Mandatory Proxy, LDAP Group Policies, and Time-Based ACLs</title>
      <dc:creator>ZeroTrust Architect</dc:creator>
      <pubDate>Tue, 19 May 2026 08:59:44 +0000</pubDate>
      <link>https://dev.to/goodguy11/enforcing-social-media-blocks-at-the-proxy-layer-mandatory-proxy-ldap-group-policies-and-5ajc</link>
      <guid>https://dev.to/goodguy11/enforcing-social-media-blocks-at-the-proxy-layer-mandatory-proxy-ldap-group-policies-and-5ajc</guid>
      <description>&lt;p&gt;DNS-based social media blocking fails against DoH-enabled browsers and manual DNS overrides. The reliable approach is enforcement at the proxy layer with mandatory routing. Here is the full technical implementation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fch2wu3gtk8c51avoyabd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fch2wu3gtk8c51avoyabd.png" alt="Enforcing Social Media Blocks at the Proxy Layer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why DNS filtering cannot reliably block social media
&lt;/h2&gt;

&lt;p&gt;DNS filtering returns &lt;code&gt;NXDOMAIN&lt;/code&gt; for blocked domains. Bypass vectors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Manual DNS override&lt;/strong&gt;: set &lt;code&gt;8.8.8.8&lt;/code&gt; on the device → DNS queries bypass your resolver&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DNS over HTTPS (DoH)&lt;/strong&gt;: Firefox, Chrome, and Windows 11 can use DoH by default, encrypting DNS queries and sending them to a third-party resolver (Cloudflare, Google) that ignores your blocklist&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DNS over TLS (DoT)&lt;/strong&gt;: same bypass mechanism as DoH&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Result: on a modern device fleet, DNS-based filtering may already be partially ineffective without any deliberate bypass attempt.&lt;/p&gt;

&lt;h2&gt;
  
  
  Proxy-layer enforcement architecture
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Client] → [Squid proxy] → [URL filter] → [Internet]
                ↑
    iptables REDIRECT intercepts all HTTP/HTTPS
    (device cannot bypass — traffic physically routed through proxy)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 1: Make proxy mandatory with iptables
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Redirect all HTTP traffic to Squid transparent proxy port&lt;/span&gt;
iptables &lt;span class="nt"&gt;-t&lt;/span&gt; nat &lt;span class="nt"&gt;-A&lt;/span&gt; PREROUTING &lt;span class="nt"&gt;-i&lt;/span&gt; eth1 &lt;span class="nt"&gt;-p&lt;/span&gt; tcp &lt;span class="nt"&gt;--dport&lt;/span&gt; 80 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; 192.168.1.1 &lt;span class="nt"&gt;-j&lt;/span&gt; REDIRECT &lt;span class="nt"&gt;--to-port&lt;/span&gt; 3128

&lt;span class="c"&gt;# Block any HTTPS traffic that doesn't originate from the proxy process (UID 13 = proxy)&lt;/span&gt;
&lt;span class="c"&gt;# This forces all HTTPS through explicit proxy (CONNECT method)&lt;/span&gt;
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; OUTPUT &lt;span class="nt"&gt;-p&lt;/span&gt; tcp &lt;span class="nt"&gt;--dport&lt;/span&gt; 443 &lt;span class="nt"&gt;-m&lt;/span&gt; owner &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nt"&gt;--uid-owner&lt;/span&gt; 13 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-p&lt;/span&gt; tcp &lt;span class="nt"&gt;--dport&lt;/span&gt; 443 &lt;span class="nt"&gt;-j&lt;/span&gt; DROP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second rule drops any HTTPS traffic from internal clients that attempts to reach port 443 directly, without going through the proxy. The only path to port 443 on the internet is through Squid's CONNECT handling.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Category-based social media blocking in Squid
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# /etc/squid/squid.conf

# External URL category database integration
url_rewrite_program /usr/bin/squidGuard -c /etc/squidguard/squidGuard.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="c"&gt;# /etc/squidguard/squidGuard.conf
&lt;/span&gt;
&lt;span class="n"&gt;dbhome&lt;/span&gt; /&lt;span class="n"&gt;var&lt;/span&gt;/&lt;span class="n"&gt;lib&lt;/span&gt;/&lt;span class="n"&gt;squidguard&lt;/span&gt;/&lt;span class="n"&gt;db&lt;/span&gt;
&lt;span class="n"&gt;logdir&lt;/span&gt; /&lt;span class="n"&gt;var&lt;/span&gt;/&lt;span class="n"&gt;log&lt;/span&gt;/&lt;span class="n"&gt;squidguard&lt;/span&gt;

&lt;span class="n"&gt;dest&lt;/span&gt; &lt;span class="n"&gt;social_networks&lt;/span&gt; {
    &lt;span class="n"&gt;domainlist&lt;/span&gt; &lt;span class="n"&gt;social&lt;/span&gt;/&lt;span class="n"&gt;domains&lt;/span&gt;
    &lt;span class="n"&gt;urllist&lt;/span&gt;    &lt;span class="n"&gt;social&lt;/span&gt;/&lt;span class="n"&gt;urls&lt;/span&gt;
}

&lt;span class="n"&gt;dest&lt;/span&gt; &lt;span class="n"&gt;anonymizers&lt;/span&gt; {
    &lt;span class="n"&gt;domainlist&lt;/span&gt; &lt;span class="n"&gt;anonymizers&lt;/span&gt;/&lt;span class="n"&gt;domains&lt;/span&gt;
}

&lt;span class="c"&gt;# Time-based rule: block during business hours
&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="n"&gt;workhours&lt;/span&gt; {
    &lt;span class="n"&gt;M&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;W&lt;/span&gt; &lt;span class="n"&gt;H&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt; &lt;span class="m"&gt;09&lt;/span&gt;:&lt;span class="m"&gt;00&lt;/span&gt;-&lt;span class="m"&gt;18&lt;/span&gt;:&lt;span class="m"&gt;00&lt;/span&gt;
}

&lt;span class="n"&gt;acl&lt;/span&gt; {
    &lt;span class="n"&gt;default&lt;/span&gt; &lt;span class="n"&gt;workhours&lt;/span&gt; {
        &lt;span class="n"&gt;pass&lt;/span&gt; !&lt;span class="n"&gt;social_networks&lt;/span&gt; !&lt;span class="n"&gt;anonymizers&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt;
        &lt;span class="n"&gt;redirect&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;://&lt;span class="m"&gt;192&lt;/span&gt;.&lt;span class="m"&gt;168&lt;/span&gt;.&lt;span class="m"&gt;1&lt;/span&gt;.&lt;span class="m"&gt;1&lt;/span&gt;/&lt;span class="n"&gt;blocked&lt;/span&gt;.&lt;span class="n"&gt;html&lt;/span&gt;
    }
    &lt;span class="n"&gt;default&lt;/span&gt; {
        &lt;span class="n"&gt;pass&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: LDAP group-based policies
&lt;/h3&gt;

&lt;p&gt;Different rules for different user groups — marketing team gets social media access, everyone else does not:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="c"&gt;# /etc/squidguard/squidGuard.conf — with LDAP group integration
&lt;/span&gt;
&lt;span class="n"&gt;ldapbinddn&lt;/span&gt; &lt;span class="n"&gt;cn&lt;/span&gt;=&lt;span class="n"&gt;squidguard&lt;/span&gt;,&lt;span class="n"&gt;dc&lt;/span&gt;=&lt;span class="n"&gt;example&lt;/span&gt;,&lt;span class="n"&gt;dc&lt;/span&gt;=&lt;span class="n"&gt;com&lt;/span&gt;
&lt;span class="n"&gt;ldapbindpass&lt;/span&gt; &lt;span class="n"&gt;secret&lt;/span&gt;
&lt;span class="n"&gt;ldapprotocol&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
&lt;span class="n"&gt;ldapbasedn&lt;/span&gt; &lt;span class="n"&gt;dc&lt;/span&gt;=&lt;span class="n"&gt;example&lt;/span&gt;,&lt;span class="n"&gt;dc&lt;/span&gt;=&lt;span class="n"&gt;com&lt;/span&gt;

&lt;span class="n"&gt;src&lt;/span&gt; &lt;span class="n"&gt;marketing&lt;/span&gt; {
    &lt;span class="n"&gt;ldapusersearch&lt;/span&gt; (&amp;amp;(&lt;span class="n"&gt;sAMAccountName&lt;/span&gt;=%&lt;span class="n"&gt;s&lt;/span&gt;)(&lt;span class="n"&gt;memberOf&lt;/span&gt;=&lt;span class="n"&gt;CN&lt;/span&gt;=&lt;span class="n"&gt;Marketing&lt;/span&gt;,&lt;span class="n"&gt;OU&lt;/span&gt;=&lt;span class="n"&gt;Groups&lt;/span&gt;,&lt;span class="n"&gt;DC&lt;/span&gt;=&lt;span class="n"&gt;example&lt;/span&gt;,&lt;span class="n"&gt;DC&lt;/span&gt;=&lt;span class="n"&gt;com&lt;/span&gt;))
}

&lt;span class="n"&gt;acl&lt;/span&gt; {
    &lt;span class="n"&gt;marketing&lt;/span&gt; {
        &lt;span class="n"&gt;pass&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt;    &lt;span class="c"&gt;# Marketing team: unrestricted
&lt;/span&gt;    }
    &lt;span class="n"&gt;default&lt;/span&gt; &lt;span class="n"&gt;workhours&lt;/span&gt; {
        &lt;span class="n"&gt;pass&lt;/span&gt; !&lt;span class="n"&gt;social_networks&lt;/span&gt; !&lt;span class="n"&gt;anonymizers&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt;
        &lt;span class="n"&gt;redirect&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;://&lt;span class="m"&gt;192&lt;/span&gt;.&lt;span class="m"&gt;168&lt;/span&gt;.&lt;span class="m"&gt;1&lt;/span&gt;.&lt;span class="m"&gt;1&lt;/span&gt;/&lt;span class="n"&gt;blocked&lt;/span&gt;.&lt;span class="n"&gt;html&lt;/span&gt;
    }
    &lt;span class="n"&gt;default&lt;/span&gt; {
        &lt;span class="n"&gt;pass&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Block CONNECT to social media domains (HTTPS)
&lt;/h3&gt;

&lt;p&gt;For HTTPS requests, the browser sends a CONNECT request to the proxy before the TLS handshake. Squid evaluates ACLs against the CONNECT target:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;acl social_ssl ssl::server_name_regex -i \
    facebook\.com \
    instagram\.com \
    tiktok\.com \
    twitter\.com \
    x\.com \
    linkedin\.com

http_access deny CONNECT social_ssl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: category databases handle this more comprehensively than a manual domain list — new social platforms are covered automatically.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Block anonymizer/redirector categories
&lt;/h3&gt;

&lt;p&gt;Prevent bypass via web-based proxy services:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;acl anonymizers_ssl ssl::server_name_regex -i "/etc/squid/anonymizer_domains.txt"
http_access deny CONNECT anonymizers_ssl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Verification
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Test that direct HTTPS to facebook.com is blocked&lt;/span&gt;
curl &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="nt"&gt;--connect-timeout&lt;/span&gt; 5 https://www.facebook.com
&lt;span class="c"&gt;# Expected: connection refused or timeout (iptables FORWARD DROP)&lt;/span&gt;

&lt;span class="c"&gt;# Test that proxy correctly blocks social media&lt;/span&gt;
curl &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="nt"&gt;-x&lt;/span&gt; http://192.168.1.1:3128 https://www.facebook.com
&lt;span class="c"&gt;# Expected: 403 Forbidden from Squid&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;CacheGuard&lt;/strong&gt; implements all of this — mandatory proxy enforcement, category-based blocking, time-of-day rules, and LDAP/AD group policies — through its integrated UTM web interface without manual iptables and SquidGuard configuration.&lt;/p&gt;

&lt;p&gt;→ &lt;a href="https://www.cacheguard.com/block-social-media-at-work/" rel="noopener noreferrer"&gt;https://www.cacheguard.com/block-social-media-at-work/&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://www.cacheguard.com/block-social-media-at-work/" rel="noopener noreferrer"&gt;CacheGuard Blog&lt;/a&gt;. CacheGuard is free and open source — &lt;a href="https://github.com/cacheguard/CacheGuard-OS" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>networking</category>
      <category>linux</category>
      <category>devops</category>
    </item>
    <item>
      <title>Reducing Office Bandwidth With Squid Caching, HTB QoS, and Category Filtering: A Technical Walkthrough</title>
      <dc:creator>ZeroTrust Architect</dc:creator>
      <pubDate>Tue, 19 May 2026 08:59:15 +0000</pubDate>
      <link>https://dev.to/goodguy11/reducing-office-bandwidth-with-squid-caching-htb-qos-and-category-filtering-a-technical-5aja</link>
      <guid>https://dev.to/goodguy11/reducing-office-bandwidth-with-squid-caching-htb-qos-and-category-filtering-a-technical-5aja</guid>
      <description>&lt;p&gt;Three techniques reduce office internet bandwidth consumption: web caching (reduce traffic volume), QoS (prioritize what reaches the connection), and content filtering (eliminate unnecessary traffic). Here is the technical implementation of each.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzkuoavcgcm524epf2zah.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzkuoavcgcm524epf2zah.png" alt="Reducing Office Bandwidth" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Web caching: Squid configuration and cache hit mechanics
&lt;/h2&gt;

&lt;p&gt;Squid is the standard open-source proxy cache. Cache hit rate — the proportion of requests served from cache — determines actual bandwidth savings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# /etc/squid/squid.conf — basic caching configuration
cache_mem 512 MB
maximum_object_size_in_memory 1 MB
cache_dir ufs /var/spool/squid 20000 16 256
maximum_object_size 200 MB
minimum_object_size 0 KB

# Cache freshness
refresh_pattern ^ftp:           1440    20%     10080
refresh_pattern ^gopher:        1440    0%      1440
refresh_pattern -i (/cgi-bin/|\?) 0     0%      0
refresh_pattern .               0       20%     4320
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What drives cache hit rate
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;Cache-Control&lt;/code&gt; response header determines cacheability:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;Cache&lt;/span&gt;-&lt;span class="n"&gt;Control&lt;/span&gt;: &lt;span class="n"&gt;max&lt;/span&gt;-&lt;span class="n"&gt;age&lt;/span&gt;=&lt;span class="m"&gt;86400&lt;/span&gt;      &lt;span class="c"&gt;# Cacheable for 24 hours → cache hit on repeat request
&lt;/span&gt;&lt;span class="n"&gt;Cache&lt;/span&gt;-&lt;span class="n"&gt;Control&lt;/span&gt;: &lt;span class="n"&gt;no&lt;/span&gt;-&lt;span class="n"&gt;store&lt;/span&gt;           &lt;span class="c"&gt;# Never cached → always fetches from origin
&lt;/span&gt;&lt;span class="n"&gt;Cache&lt;/span&gt;-&lt;span class="n"&gt;Control&lt;/span&gt;: &lt;span class="n"&gt;private&lt;/span&gt;            &lt;span class="c"&gt;# Browser cache only, not proxy → always fetches
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In practice, most SaaS application responses are &lt;code&gt;Cache-Control: no-store&lt;/code&gt; or &lt;code&gt;private&lt;/code&gt;. Static assets (CSS, JS, images, fonts, software packages) are typically cacheable. Realistic cache hit rates in an office environment: 15-40% of requests by count, but static assets are small — actual bandwidth savings may be 10-25% of bytes transferred.&lt;/p&gt;

&lt;h3&gt;
  
  
  HTTPS and the SSL inspection requirement
&lt;/h3&gt;

&lt;p&gt;HTTPS traffic is not cacheable without SSL inspection. The proxy cannot read &lt;code&gt;Cache-Control&lt;/code&gt; headers in an encrypted response. Enabling ssl-bump (TLS MITM) makes HTTPS content cacheable and dramatically increases hit rates:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# ssl-bump for HTTPS caching
http_port 3128 ssl-bump cert=/etc/squid/ca.pem key=/etc/squid/ca.key
ssl_bump stare all
ssl_bump bump all

# Exempt domains that use certificate pinning
acl no_ssl_bump ssl::server_name_regex -i apple.com google-update.com
ssl_bump splice no_ssl_bump
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  QoS: HTB + SFQ with tc
&lt;/h2&gt;

&lt;p&gt;HTB (Hierarchical Token Bucket) guarantees bandwidth minimums and allows borrowing from idle classes. SFQ (Stochastic Fairness Queuing) provides per-flow fairness within each class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Attach HTB root qdisc to WAN interface&lt;/span&gt;
tc qdisc add dev eth0 root handle 1: htb default 30

&lt;span class="c"&gt;# Total bandwidth: 100Mbit&lt;/span&gt;
tc class add dev eth0 parent 1: classid 1:1 htb rate 100mbit

&lt;span class="c"&gt;# Class 1:10 — Real-time (VoIP, video calls): 20Mbit guaranteed, burst to 100Mbit&lt;/span&gt;
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 20mbit ceil 100mbit prio 1

&lt;span class="c"&gt;# Class 1:20 — Business traffic: 70Mbit guaranteed&lt;/span&gt;
tc class add dev eth0 parent 1:1 classid 1:20 htb rate 70mbit ceil 100mbit prio 2

&lt;span class="c"&gt;# Class 1:30 — Bulk/background: 10Mbit guaranteed, capped at 30Mbit&lt;/span&gt;
tc class add dev eth0 parent 1:1 classid 1:30 htb rate 10mbit ceil 30mbit prio 3

&lt;span class="c"&gt;# Add SFQ to each leaf class for per-flow fairness&lt;/span&gt;
tc qdisc add dev eth0 parent 1:10 handle 10: sfq perturb 10
tc qdisc add dev eth0 parent 1:20 handle 20: sfq perturb 10
tc qdisc add dev eth0 parent 1:30 handle 30: sfq perturb 10

&lt;span class="c"&gt;# Classify traffic: DSCP EF (VoIP/video) → high priority class&lt;/span&gt;
tc filter add dev eth0 parent 1:0 protocol ip prio 1 u32 &lt;span class="se"&gt;\&lt;/span&gt;
  match ip tos 0xb8 0xfc flowid 1:10

&lt;span class="c"&gt;# Classify HTTP/HTTPS to business class&lt;/span&gt;
tc filter add dev eth0 parent 1:0 protocol ip prio 2 u32 &lt;span class="se"&gt;\&lt;/span&gt;
  match ip dport 443 0xffff flowid 1:20

&lt;span class="c"&gt;# Everything else → bulk class (default 30)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Content filtering: eliminate non-work bandwidth entirely
&lt;/h2&gt;

&lt;p&gt;Category-based URL filtering removes streaming, file-sharing, and social media traffic during business hours — not throttled, eliminated:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# SquidGuard integration for category-based filtering
url_rewrite_program /usr/bin/squidGuard -c /etc/squidguard/squidGuard.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="c"&gt;# /etc/squidguard/squidGuard.conf
&lt;/span&gt;&lt;span class="n"&gt;dbhome&lt;/span&gt; /&lt;span class="n"&gt;var&lt;/span&gt;/&lt;span class="n"&gt;lib&lt;/span&gt;/&lt;span class="n"&gt;squidguard&lt;/span&gt;/&lt;span class="n"&gt;db&lt;/span&gt;
&lt;span class="n"&gt;logdir&lt;/span&gt; /&lt;span class="n"&gt;var&lt;/span&gt;/&lt;span class="n"&gt;log&lt;/span&gt;/&lt;span class="n"&gt;squidguard&lt;/span&gt;

&lt;span class="n"&gt;dest&lt;/span&gt; &lt;span class="n"&gt;streaming&lt;/span&gt; {
    &lt;span class="n"&gt;domainlist&lt;/span&gt; &lt;span class="n"&gt;streaming&lt;/span&gt;/&lt;span class="n"&gt;domains&lt;/span&gt;
    &lt;span class="n"&gt;urllist&lt;/span&gt; &lt;span class="n"&gt;streaming&lt;/span&gt;/&lt;span class="n"&gt;urls&lt;/span&gt;
}

&lt;span class="n"&gt;dest&lt;/span&gt; &lt;span class="n"&gt;social&lt;/span&gt; {
    &lt;span class="n"&gt;domainlist&lt;/span&gt; &lt;span class="n"&gt;social&lt;/span&gt;/&lt;span class="n"&gt;domains&lt;/span&gt;
}

&lt;span class="n"&gt;acl&lt;/span&gt; {
    &lt;span class="c"&gt;# Apply during business hours
&lt;/span&gt;    &lt;span class="n"&gt;default&lt;/span&gt; {
        &lt;span class="n"&gt;pass&lt;/span&gt; !&lt;span class="n"&gt;streaming&lt;/span&gt; !&lt;span class="n"&gt;social&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt;
        &lt;span class="n"&gt;redirect&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;://&lt;span class="n"&gt;gateway&lt;/span&gt;/&lt;span class="n"&gt;blocked&lt;/span&gt;.&lt;span class="n"&gt;html&lt;/span&gt;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Time-based rules restrict blocking to business hours; outside those hours all traffic is permitted.&lt;/p&gt;

&lt;h2&gt;
  
  
  Combined effect
&lt;/h2&gt;

&lt;p&gt;On a typical 30-person office network:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Web caching (with SSL inspection): 15-30% of bytes served locally&lt;/li&gt;
&lt;li&gt;QoS: no bandwidth saved, but VoIP/video call quality maintained under load&lt;/li&gt;
&lt;li&gt;Content filtering (streaming blocked 9-18h): 20-40% reduction in peak-hour bytes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The sequence matters: cache first (reduce volume), shape second (manage what remains), filter third (eliminate unnecessary load).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CacheGuard&lt;/strong&gt; ships Squid, HTB+SFQ QoS, and URL filtering pre-integrated in a single appliance OS, configured through a browser-based interface.&lt;/p&gt;

&lt;p&gt;→ &lt;a href="https://www.cacheguard.com/reduce-internet-bandwidth-usage-office/" rel="noopener noreferrer"&gt;https://www.cacheguard.com/reduce-internet-bandwidth-usage-office/&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://www.cacheguard.com/reduce-internet-bandwidth-usage-office/" rel="noopener noreferrer"&gt;CacheGuard Blog&lt;/a&gt;. CacheGuard is free and open source — &lt;a href="https://github.com/cacheguard/CacheGuard-OS" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>networking</category>
      <category>linux</category>
      <category>devops</category>
      <category>opensource</category>
    </item>
    <item>
      <title>BYOD Network Security Without MDM: Zone Isolation, MAC Filtering, and Gateway-Level Controls</title>
      <dc:creator>ZeroTrust Architect</dc:creator>
      <pubDate>Tue, 19 May 2026 08:58:38 +0000</pubDate>
      <link>https://dev.to/goodguy11/byod-network-security-without-mdm-zone-isolation-mac-filtering-and-gateway-level-controls-5fjm</link>
      <guid>https://dev.to/goodguy11/byod-network-security-without-mdm-zone-isolation-mac-filtering-and-gateway-level-controls-5fjm</guid>
      <description>&lt;p&gt;MDM (Mobile Device Management) solves BYOD security by managing the device. Network-level controls solve it by managing the network around the device. The two approaches have different coverage profiles and different deployment requirements. Here is the technical comparison.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fndoy4vuwqe12ltszy0jj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fndoy4vuwqe12ltszy0jj.png" alt="BYOD Network Security Without MDM" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What MDM provides (and what it requires)
&lt;/h2&gt;

&lt;p&gt;MDM enrolls devices into a management platform and can enforce:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Certificate-based Wi-Fi authentication (802.1X/EAP-TLS)&lt;/li&gt;
&lt;li&gt;Remote wipe on lost/stolen devices&lt;/li&gt;
&lt;li&gt;App installation restrictions and containerization&lt;/li&gt;
&lt;li&gt;OS version compliance enforcement&lt;/li&gt;
&lt;li&gt;VPN profile distribution and always-on enforcement&lt;/li&gt;
&lt;li&gt;Full-disk encryption verification&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Requirements: enrollment agent on each device (accepted by the user), MDM server infrastructure (on-premises or cloud), ongoing management as devices change, and employee acceptance of management scope.&lt;/p&gt;

&lt;p&gt;For organizations that can meet these requirements, MDM provides the most comprehensive BYOD control. For those that cannot — typically SMEs without dedicated IT staff — the operational overhead is prohibitive and enrollment rates below 100% leave unmanaged devices with no controls at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  What network-level controls provide without MDM
&lt;/h2&gt;

&lt;p&gt;A zone-based network security appliance at the gateway applies controls to every device that connects, regardless of whether it is enrolled in anything.&lt;/p&gt;

&lt;h3&gt;
  
  
  VLAN isolation for BYOD devices
&lt;/h3&gt;

&lt;p&gt;Place BYOD devices on a dedicated VLAN, isolated from internal servers and sensitive resources:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# BYOD VLAN (ID 30) on gateway&lt;/span&gt;
ip &lt;span class="nb"&gt;link &lt;/span&gt;add &lt;span class="nb"&gt;link &lt;/span&gt;eth1 name eth1.30 &lt;span class="nb"&gt;type &lt;/span&gt;vlan &lt;span class="nb"&gt;id &lt;/span&gt;30
ip addr add 192.168.30.1/24 dev eth1.30
ip &lt;span class="nb"&gt;link set &lt;/span&gt;eth1.30 up

&lt;span class="c"&gt;# Block BYOD from reaching internal LAN by default&lt;/span&gt;
iptables &lt;span class="nt"&gt;-I&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-i&lt;/span&gt; eth1.30 &lt;span class="nt"&gt;-o&lt;/span&gt; eth1 &lt;span class="nt"&gt;-j&lt;/span&gt; DROP

&lt;span class="c"&gt;# Allow BYOD internet access&lt;/span&gt;
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-i&lt;/span&gt; eth1.30 &lt;span class="nt"&gt;-o&lt;/span&gt; eth0 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-m&lt;/span&gt; state &lt;span class="nt"&gt;--state&lt;/span&gt; ESTABLISHED,RELATED &lt;span class="nt"&gt;-o&lt;/span&gt; eth1.30 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Permit only specific internal resources that BYOD devices legitimately need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Allow BYOD to reach internal web application only (192.168.1.50:443)&lt;/span&gt;
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-i&lt;/span&gt; eth1.30 &lt;span class="nt"&gt;-d&lt;/span&gt; 192.168.1.50 &lt;span class="nt"&gt;-p&lt;/span&gt; tcp &lt;span class="nt"&gt;--dport&lt;/span&gt; 443 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-i&lt;/span&gt; eth1.30 &lt;span class="nt"&gt;-d&lt;/span&gt; 192.168.1.50 &lt;span class="nt"&gt;-m&lt;/span&gt; state &lt;span class="nt"&gt;--state&lt;/span&gt; ESTABLISHED,RELATED &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Gateway antivirus — independent of device endpoint security
&lt;/h3&gt;

&lt;p&gt;Route BYOD web traffic through a proxy with ICAP antivirus scanning. Personal devices may or may not have current endpoint AV — the gateway layer is independent of whatever is or is not on the device.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Redirect BYOD HTTP to transparent proxy&lt;/span&gt;
iptables &lt;span class="nt"&gt;-t&lt;/span&gt; nat &lt;span class="nt"&gt;-A&lt;/span&gt; PREROUTING &lt;span class="nt"&gt;-i&lt;/span&gt; eth1.30 &lt;span class="nt"&gt;-p&lt;/span&gt; tcp &lt;span class="nt"&gt;--dport&lt;/span&gt; 80 &lt;span class="nt"&gt;-j&lt;/span&gt; REDIRECT &lt;span class="nt"&gt;--to-port&lt;/span&gt; 3128

&lt;span class="c"&gt;# For HTTPS: require explicit proxy configuration or ssl-bump for transparent interception&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  URL filtering — policy enforcement without device configuration
&lt;/h3&gt;

&lt;p&gt;A Squid ACL applies URL category filtering to all BYOD traffic without any configuration on the devices:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Block malware and phishing categories for BYOD VLAN
acl byod_vlan src 192.168.30.0/24
acl blocked_categories dstdom_regex -i "/etc/squid/malware_domains.txt"
http_access deny byod_vlan blocked_categories
http_access allow byod_vlan
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Traffic visibility without endpoint agents
&lt;/h3&gt;

&lt;p&gt;Log forwarded traffic from the BYOD VLAN for anomaly detection:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;iptables &lt;span class="nt"&gt;-A&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-i&lt;/span&gt; eth1.30 &lt;span class="nt"&gt;-j&lt;/span&gt; LOG &lt;span class="nt"&gt;--log-prefix&lt;/span&gt; &lt;span class="s2"&gt;"BYOD-FORWARD: "&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives visibility into what unmanaged personal devices are doing on your network without any software on those devices.&lt;/p&gt;

&lt;h2&gt;
  
  
  The coverage gap: what network controls cannot do
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Control&lt;/th&gt;
&lt;th&gt;MDM&lt;/th&gt;
&lt;th&gt;Network-level&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Remote wipe&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;App restriction&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Disk encryption enforcement&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OS version enforcement&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Network isolation&lt;/td&gt;
&lt;td&gt;✅ (via 802.1X)&lt;/td&gt;
&lt;td&gt;✅ (VLAN)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gateway antivirus&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;URL filtering&lt;/td&gt;
&lt;td&gt;✅ (via VPN)&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Traffic logging&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Works on non-enrolled devices&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;/div&gt;

&lt;p&gt;Network-level controls are the right baseline for organizations that cannot deploy MDM. They do not replace MDM for organizations that need remote wipe or app containerization.&lt;/p&gt;

&lt;h2&gt;
  
  
  CacheGuard as implementation
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;CacheGuard&lt;/strong&gt; implements BYOD zone isolation, gateway antivirus, URL filtering, and traffic logging through its zone-based UTM architecture — without per-device configuration or enrollment.&lt;/p&gt;

&lt;p&gt;→ &lt;a href="https://www.cacheguard.com/byod-security-for-small-business/" rel="noopener noreferrer"&gt;https://www.cacheguard.com/byod-security-for-small-business/&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://www.cacheguard.com/byod-security-for-small-business/" rel="noopener noreferrer"&gt;CacheGuard Blog&lt;/a&gt;. CacheGuard is free and open source — &lt;a href="https://github.com/cacheguard/CacheGuard-OS" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>networking</category>
      <category>devops</category>
      <category>linux</category>
    </item>
    <item>
      <title>IoT Network Isolation: Zone Segmentation, Egress Filtering, and Why Your Smart TV Needs Its Own VLAN</title>
      <dc:creator>ZeroTrust Architect</dc:creator>
      <pubDate>Tue, 19 May 2026 08:58:00 +0000</pubDate>
      <link>https://dev.to/goodguy11/iot-network-isolation-zone-segmentation-egress-filtering-and-why-your-smart-tv-needs-its-own-vlan-2fj9</link>
      <guid>https://dev.to/goodguy11/iot-network-isolation-zone-segmentation-egress-filtering-and-why-your-smart-tv-needs-its-own-vlan-2fj9</guid>
      <description>&lt;p&gt;IoT devices cannot protect themselves. They cannot run endpoint security software, enforce their own firewall policies, or detect behavioral anomalies. The only security layer that reliably covers them is one that operates at the network level, independently of what the device can do. Here is how to implement that technically.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fruwftkj3jb9xz9rjpt3l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fruwftkj3jb9xz9rjpt3l.png" alt="IoT Network Isolation" width="800" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The threat model for IoT devices
&lt;/h2&gt;

&lt;p&gt;IoT compromise typically follows one of two paths: exploitation of a known vulnerability in the device's firmware (often never patched by the manufacturer), or brute-force of default or weak credentials via internet-exposed management interfaces.&lt;/p&gt;

&lt;p&gt;Once compromised, the device is typically used for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Botnet participation (DDoS, port scanning, spam relay)&lt;/li&gt;
&lt;li&gt;Lateral movement to other devices on the same network segment&lt;/li&gt;
&lt;li&gt;Data exfiltration if the device has access to sensitive internal resources&lt;/li&gt;
&lt;li&gt;Persistent backdoor installation for long-term access&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The key insight: &lt;strong&gt;the damage from a compromised IoT device is almost entirely determined by what else it can reach on the network&lt;/strong&gt;. A compromised camera that can only reach its manufacturer's cloud service causes minimal harm. The same camera with unrestricted access to your file server is a serious breach.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: VLAN segmentation for IoT isolation
&lt;/h2&gt;

&lt;p&gt;Place IoT devices on a dedicated VLAN, isolated from the internal LAN. The gateway enforces zone policy between VLANs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create IoT VLAN (ID 20) on Linux gateway&lt;/span&gt;
ip &lt;span class="nb"&gt;link &lt;/span&gt;add &lt;span class="nb"&gt;link &lt;/span&gt;eth1 name eth1.20 &lt;span class="nb"&gt;type &lt;/span&gt;vlan &lt;span class="nb"&gt;id &lt;/span&gt;20
ip addr add 192.168.20.1/24 dev eth1.20
ip &lt;span class="nb"&gt;link set &lt;/span&gt;eth1.20 up

&lt;span class="c"&gt;# Internal LAN on eth1 (untagged, 192.168.1.0/24)&lt;/span&gt;
&lt;span class="c"&gt;# IoT VLAN on eth1.20 (tagged, 192.168.20.0/24)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On your managed switch, configure ports connected to IoT devices as access ports on VLAN 20. Ports connected to computers and servers remain on the native VLAN.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Default-deny between IoT zone and internal LAN
&lt;/h2&gt;

&lt;p&gt;By default, block all traffic from the IoT VLAN to the internal LAN:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Drop all forwarded traffic from IoT VLAN to internal LAN&lt;/span&gt;
iptables &lt;span class="nt"&gt;-I&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-i&lt;/span&gt; eth1.20 &lt;span class="nt"&gt;-o&lt;/span&gt; eth1 &lt;span class="nt"&gt;-j&lt;/span&gt; DROP

&lt;span class="c"&gt;# Allow IoT to reach internet (via external interface eth0)&lt;/span&gt;
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-i&lt;/span&gt; eth1.20 &lt;span class="nt"&gt;-o&lt;/span&gt; eth0 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-m&lt;/span&gt; state &lt;span class="nt"&gt;--state&lt;/span&gt; ESTABLISHED,RELATED &lt;span class="nt"&gt;-o&lt;/span&gt; eth1.20 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If specific IoT devices need to reach specific internal resources (e.g., a printer that the internal network needs to reach), add explicit permit rules:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Allow internal LAN to initiate connections to IoT printer only&lt;/span&gt;
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-i&lt;/span&gt; eth1 &lt;span class="nt"&gt;-o&lt;/span&gt; eth1.20 &lt;span class="nt"&gt;-d&lt;/span&gt; 192.168.20.10 &lt;span class="nt"&gt;-p&lt;/span&gt; tcp &lt;span class="nt"&gt;--dport&lt;/span&gt; 9100 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-i&lt;/span&gt; eth1.20 &lt;span class="nt"&gt;-s&lt;/span&gt; 192.168.20.10 &lt;span class="nt"&gt;-o&lt;/span&gt; eth1 &lt;span class="nt"&gt;-m&lt;/span&gt; state &lt;span class="nt"&gt;--state&lt;/span&gt; ESTABLISHED,RELATED &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Egress filtering — restrict outbound destinations
&lt;/h2&gt;

&lt;p&gt;Even within the IoT zone, restrict what external destinations each device type can reach. A smart TV should reach streaming service CDNs and its manufacturer's cloud — nothing else.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Allow specific destination ranges for smart TV (192.168.20.5)&lt;/span&gt;
&lt;span class="c"&gt;# Block everything else from that device&lt;/span&gt;
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-i&lt;/span&gt; eth1.20 &lt;span class="nt"&gt;-s&lt;/span&gt; 192.168.20.5 &lt;span class="nt"&gt;-d&lt;/span&gt; 0.0.0.0/0 &lt;span class="nt"&gt;-j&lt;/span&gt; DROP
iptables &lt;span class="nt"&gt;-I&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-i&lt;/span&gt; eth1.20 &lt;span class="nt"&gt;-s&lt;/span&gt; 192.168.20.5 &lt;span class="nt"&gt;-d&lt;/span&gt; 52.0.0.0/8 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT   &lt;span class="c"&gt;# AWS (streaming CDNs)&lt;/span&gt;
iptables &lt;span class="nt"&gt;-I&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-i&lt;/span&gt; eth1.20 &lt;span class="nt"&gt;-s&lt;/span&gt; 192.168.20.5 &lt;span class="nt"&gt;-d&lt;/span&gt; 17.0.0.0/8 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT   &lt;span class="c"&gt;# Apple&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For broader category-based egress filtering (blocking known malicious IPs, C2 infrastructure, anonymizers) across the entire IoT VLAN, a URL filtering proxy in the traffic path is more maintainable than per-IP iptables rules.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Gateway antivirus via ICAP
&lt;/h2&gt;

&lt;p&gt;To scan traffic from IoT devices for malware (particularly relevant for devices that download firmware updates), route IoT web traffic through a Squid proxy with ICAP-based ClamAV scanning:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# squid.conf — transparent proxy for IoT VLAN
http_port 3128 intercept

# ICAP antivirus
icap_enable on
icap_service av_service reqmod_precache bypass=1 icap://127.0.0.1:1344/squid_clamav
adaptation_service_set av_service_set av_service
adaptation_access av_service_set allow all
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Redirect IoT VLAN HTTP traffic to the proxy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;iptables &lt;span class="nt"&gt;-t&lt;/span&gt; nat &lt;span class="nt"&gt;-A&lt;/span&gt; PREROUTING &lt;span class="nt"&gt;-i&lt;/span&gt; eth1.20 &lt;span class="nt"&gt;-p&lt;/span&gt; tcp &lt;span class="nt"&gt;--dport&lt;/span&gt; 80 &lt;span class="nt"&gt;-j&lt;/span&gt; REDIRECT &lt;span class="nt"&gt;--to-port&lt;/span&gt; 3128
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For HTTPS (dominant in modern IoT), transparent interception requires SSL inspection (ssl-bump). Without it, HTTPS traffic from IoT devices is tunneled uninspected.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Traffic logging for anomaly detection
&lt;/h2&gt;

&lt;p&gt;Log connection attempts from the IoT VLAN to destinations outside permitted ranges:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Log dropped IoT traffic for anomaly detection&lt;/span&gt;
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-i&lt;/span&gt; eth1.20 &lt;span class="nt"&gt;-j&lt;/span&gt; LOG &lt;span class="nt"&gt;--log-prefix&lt;/span&gt; &lt;span class="s2"&gt;"IoT-FORWARD-DROP: "&lt;/span&gt; &lt;span class="nt"&gt;--log-level&lt;/span&gt; 4
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-i&lt;/span&gt; eth1.20 &lt;span class="nt"&gt;-j&lt;/span&gt; DROP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unusual patterns — a camera suddenly connecting to dozens of external IPs it has never contacted before, or an IoT device attempting connections to internal LAN ranges — are detectable in these logs before they escalate.&lt;/p&gt;

&lt;h2&gt;
  
  
  CacheGuard as a pre-integrated implementation
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;CacheGuard&lt;/strong&gt; ships all of the above pre-integrated: zone-based firewall (external, internal/web with rweb VLAN, auxiliary/IoT zones), Squid transparent proxy with ICAP-based ClamAV, URL category filtering for egress control, and traffic logging — without manual iptables, Squid, and c-icap assembly.&lt;/p&gt;

&lt;p&gt;→ &lt;a href="https://www.cacheguard.com/secure-iot-devices-on-your-network/" rel="noopener noreferrer"&gt;https://www.cacheguard.com/secure-iot-devices-on-your-network/&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://www.cacheguard.com/secure-iot-devices-on-your-network/" rel="noopener noreferrer"&gt;CacheGuard Blog&lt;/a&gt;. CacheGuard is free and open source — &lt;a href="https://github.com/cacheguard/CacheGuard-OS" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>networking</category>
      <category>linux</category>
      <category>devops</category>
    </item>
    <item>
      <title>Network-Level Parental Controls: Enforcing Web Filtering With a Proxy, Firewall Rules, and an Always-On VPN</title>
      <dc:creator>ZeroTrust Architect</dc:creator>
      <pubDate>Tue, 19 May 2026 08:57:19 +0000</pubDate>
      <link>https://dev.to/goodguy11/network-level-parental-controls-enforcing-web-filtering-with-a-proxy-firewall-rules-and-an-2fn</link>
      <guid>https://dev.to/goodguy11/network-level-parental-controls-enforcing-web-filtering-with-a-proxy-firewall-rules-and-an-2fn</guid>
      <description>&lt;p&gt;Device-level parental controls — Screen Time, Family Link, router DNS filtering — share a common architectural weakness: they can all be bypassed by routing traffic around the enforcement point. This guide covers a network-level approach that closes those gaps technically.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9cpvt0oltijd8cfigsoh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9cpvt0oltijd8cfigsoh.png" alt="CacheGuard Parental Controls"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why DNS-based filtering fails first
&lt;/h2&gt;

&lt;p&gt;Most home router parental controls work at the DNS layer. The router intercepts DNS queries and returns &lt;code&gt;NXDOMAIN&lt;/code&gt; or a block page IP for blacklisted domains. The bypass is trivial:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Child changes DNS on their device&lt;/span&gt;
networksetup &lt;span class="nt"&gt;-setdnsservers&lt;/span&gt; Wi-Fi 8.8.8.8    &lt;span class="c"&gt;# macOS&lt;/span&gt;
&lt;span class="c"&gt;# or simply sets 1.1.1.1 in Android/iOS network settings&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No DNS query hits the router. The filter never sees the request. DNS filtering provides zero protection against a user who controls their own DNS resolver.&lt;/p&gt;

&lt;h2&gt;
  
  
  The proxy interception model
&lt;/h2&gt;

&lt;p&gt;A forward proxy operating at the HTTP application layer is bypass-resistant by a different mechanism. Traffic must physically pass through the proxy to reach the internet — there is no DNS-level workaround because the proxy intercepts at Layer 7, not Layer 3.&lt;/p&gt;

&lt;p&gt;In &lt;strong&gt;explicit proxy mode&lt;/strong&gt;, client devices are configured to send all HTTP and HTTPS requests to the proxy. HTTPS connections use the HTTP CONNECT method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;CONNECT www.example.com:443 HTTP/1.1
Host: www.example.com:443
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The proxy sees the full destination URL in plaintext before any TLS handshake — enabling URL category filtering on HTTPS traffic without SSL decryption. If the destination matches a blocked category, the proxy returns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt; &lt;span class="m"&gt;403&lt;/span&gt; &lt;span class="ne"&gt;Forbidden&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No content is delivered. No TLS session is established.&lt;/p&gt;

&lt;h2&gt;
  
  
  Making the proxy mandatory with a firewall rule
&lt;/h2&gt;

&lt;p&gt;Explicit proxy mode relies on client configuration — and a determined child can simply remove the proxy settings from their device. The fix is a firewall rule that makes bypassing the proxy impossible:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Block all outbound HTTPS traffic that does NOT originate from the proxy process&lt;/span&gt;
&lt;span class="c"&gt;# On the gateway, assuming proxy runs as user 'proxy' (UID 13 on Debian)&lt;/span&gt;
iptables &lt;span class="nt"&gt;-t&lt;/span&gt; nat &lt;span class="nt"&gt;-A&lt;/span&gt; OUTPUT &lt;span class="nt"&gt;-p&lt;/span&gt; tcp &lt;span class="nt"&gt;--dport&lt;/span&gt; 443 &lt;span class="nt"&gt;-m&lt;/span&gt; owner &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nt"&gt;--uid-owner&lt;/span&gt; 13 &lt;span class="nt"&gt;-j&lt;/span&gt; REDIRECT &lt;span class="nt"&gt;--to-port&lt;/span&gt; 3128
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-p&lt;/span&gt; tcp &lt;span class="nt"&gt;--dport&lt;/span&gt; 443 &lt;span class="nt"&gt;-j&lt;/span&gt; DROP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second rule drops any HTTPS traffic forwarded from internal clients that attempts to bypass the proxy. The client gets a connection timeout. The only path to port 443 on the internet is through the proxy — which applies the content filter.&lt;/p&gt;

&lt;p&gt;With Squid as the proxy engine, transparent interception for HTTP is straightforward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Redirect internal HTTP traffic to Squid transparent port&lt;/span&gt;
iptables &lt;span class="nt"&gt;-t&lt;/span&gt; nat &lt;span class="nt"&gt;-A&lt;/span&gt; PREROUTING &lt;span class="nt"&gt;-i&lt;/span&gt; eth1 &lt;span class="nt"&gt;-p&lt;/span&gt; tcp &lt;span class="nt"&gt;--dport&lt;/span&gt; 80 &lt;span class="nt"&gt;-j&lt;/span&gt; REDIRECT &lt;span class="nt"&gt;--to-port&lt;/span&gt; 3128
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For HTTPS in transparent mode, SNI-based filtering is possible but limited to hostname-level blocking. For full URL-path filtering on HTTPS, explicit mode with the CONNECT method is required.&lt;/p&gt;

&lt;h2&gt;
  
  
  Blocking anonymizer and redirector categories
&lt;/h2&gt;

&lt;p&gt;Web-based proxy and anonymizer services — sites that let users route traffic through external servers — bypass local filtering regardless of proxy enforcement, because the destination URL appears to be a legitimate website.&lt;/p&gt;

&lt;p&gt;The mitigation is category-based blocking. Most URL category databases include an &lt;code&gt;anonymizer&lt;/code&gt; or &lt;code&gt;proxy&lt;/code&gt; category. In Squid with SquidGuard:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# squidguard.conf
dest anonymizers {
    domainlist anonymizers/domains
    urllist anonymizers/urls
}

acl {
    default {
        pass !anonymizers all
        redirect http://gateway/blocked.html
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This blocks access to known anonymizer domains before the child can use them to route around the content filter.&lt;/p&gt;

&lt;h2&gt;
  
  
  Extending filtering to mobile devices outside the home
&lt;/h2&gt;

&lt;p&gt;Home gateway filtering only applies when devices are on the home network. When a child's smartphone switches to mobile data or a friend's hotspot, the gateway is bypassed entirely.&lt;/p&gt;

&lt;p&gt;The solution is an IPsec VPN server on the home gateway. Client devices connect to the VPN using IKEv2 with the gateway's certificate, routing all traffic through the home network — and through the web proxy — regardless of the underlying connection.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;StrongSwan server configuration (relevant excerpt):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="err"&gt;conn&lt;/span&gt; &lt;span class="err"&gt;parental-vpn&lt;/span&gt;
    &lt;span class="py"&gt;keyexchange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;ikev2&lt;/span&gt;
    &lt;span class="py"&gt;left&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;%any&lt;/span&gt;
    &lt;span class="py"&gt;leftid&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;@home.example.com&lt;/span&gt;
    &lt;span class="py"&gt;leftcert&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;gateway-cert.pem&lt;/span&gt;
    &lt;span class="py"&gt;leftsubnet&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;0.0.0.0/0      # Route all client traffic through gateway&lt;/span&gt;
    &lt;span class="py"&gt;right&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;%any&lt;/span&gt;
    &lt;span class="py"&gt;rightsourceip&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;10.9.0.0/24  # Virtual IPs for VPN clients&lt;/span&gt;
    &lt;span class="py"&gt;rightdns&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;10.9.0.1&lt;/span&gt;
    &lt;span class="py"&gt;ike&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;aes256-sha256-ecp256!&lt;/span&gt;
    &lt;span class="py"&gt;esp&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;aes256-sha256!&lt;/span&gt;
    &lt;span class="py"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;add&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;leftsubnet=0.0.0.0/0&lt;/code&gt; directive routes all client internet traffic through the VPN tunnel — not just traffic destined for the home network. Once the VPN client connects, all outbound traffic hits the gateway proxy and is filtered identically to home network traffic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enforcing always-on VPN on client devices:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;On iOS, a configuration profile with &lt;code&gt;OnDemandEnabled=1&lt;/code&gt; and &lt;code&gt;OnDemandRules&lt;/code&gt; set to activate on any network connection enforces the VPN without user interaction. The profile can be locked via Mobile Device Management or restricted using Screen Time's VPN settings control.&lt;/p&gt;

&lt;p&gt;On Android, &lt;code&gt;Settings → Network → VPN → [profile] → Always-on VPN&lt;/code&gt; with &lt;code&gt;Block connections without VPN&lt;/code&gt; enabled drops all traffic if the VPN is not active — no internet access without the tunnel.&lt;/p&gt;

&lt;h2&gt;
  
  
  URL blacklist management
&lt;/h2&gt;

&lt;p&gt;The content filter requires a category database mapping URLs to content categories. Options range from free community-maintained lists to commercially updated subscription databases.&lt;/p&gt;

&lt;p&gt;For a home deployment, the choice matters primarily on two dimensions: &lt;strong&gt;coverage&lt;/strong&gt; (how many URLs are categorized, particularly for adult content) and &lt;strong&gt;update frequency&lt;/strong&gt; (how quickly newly registered adult/malicious domains are added).&lt;/p&gt;

&lt;p&gt;Free lists are adequate for blocking well-established categories but lag significantly on newly registered domains — a common technique used to evade filters. A subscription database with daily or hourly updates provides meaningfully better coverage for the adult content category specifically.&lt;/p&gt;

&lt;h2&gt;
  
  
  CacheGuard as a complete implementation
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;CacheGuard&lt;/strong&gt; is a free, open-source network security appliance (LFS-based Linux) that ships all of the above pre-integrated:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Squid-based web proxy with URL filtering (explicit and transparent modes)&lt;/li&gt;
&lt;li&gt;IPsec VPN server (StrongSwan, IKEv2) with client profile generation for iOS, macOS, Android, Windows, Linux&lt;/li&gt;
&lt;li&gt;Zone-based stateful firewall with built-in rules for mandatory proxy enforcement&lt;/li&gt;
&lt;li&gt;SSL mediation (Squid ssl-bump) for full HTTPS content inspection&lt;/li&gt;
&lt;li&gt;Optional URL blacklist subscription with regularly updated category databases&lt;/li&gt;
&lt;li&gt;Browser-based management interface — no CLI required for standard configuration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It installs from a single ISO on any x86 machine or VM. The firewall rules enforcing mandatory proxy use and blocking direct HTTPS forwarding are configurable through the web interface without writing iptables commands manually.&lt;/p&gt;

&lt;p&gt;For parents who are comfortable with basic network concepts but do not want to assemble Squid, StrongSwan, iptables, and a PKI from scratch, it eliminates the integration overhead while remaining fully open source and free.&lt;/p&gt;

&lt;p&gt;→ &lt;a href="https://www.cacheguard.com/parental-controls-home-network/" rel="noopener noreferrer"&gt;https://www.cacheguard.com/parental-controls-home-network/&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://www.cacheguard.com/parental-controls-home-network/" rel="noopener noreferrer"&gt;CacheGuard Blog&lt;/a&gt;. CacheGuard is free and open source — &lt;a href="https://github.com/cacheguard/CacheGuard-OS" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>networking</category>
      <category>linux</category>
      <category>selfhosted</category>
    </item>
    <item>
      <title>Host-Based vs Network Firewall: Why Windows Firewall and Windows Defender Are Not Enough on Their Own</title>
      <dc:creator>ZeroTrust Architect</dc:creator>
      <pubDate>Sun, 17 May 2026 10:10:23 +0000</pubDate>
      <link>https://dev.to/goodguy11/host-based-vs-network-firewall-why-windows-firewall-and-windows-defender-are-not-enough-on-their-4f4</link>
      <guid>https://dev.to/goodguy11/host-based-vs-network-firewall-why-windows-firewall-and-windows-defender-are-not-enough-on-their-4f4</guid>
      <description>&lt;p&gt;Most Windows networks rely on two built-in security tools: Windows Firewall (Microsoft Defender Firewall) and Windows Defender. Both are enabled by default, both are maintained by Microsoft, and both are useful. Neither is a network firewall.&lt;/p&gt;

&lt;p&gt;Understanding why that distinction matters requires looking at where each tool operates in the security stack — and what attack surface they share.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4ftyss1p02oarxi2gvpa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4ftyss1p02oarxi2gvpa.png" alt="Why Windows Firewall and Windows Defender Are Not Enough"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Host-based vs network-level security: the architectural difference
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Windows Firewall&lt;/strong&gt; is a host-based stateful packet filter. It runs inside the Windows kernel via the Windows Filtering Platform (WFP). It applies rules to traffic arriving at or leaving the specific machine it runs on. It has no visibility into traffic between other devices on the same network segment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Windows Defender&lt;/strong&gt; is an endpoint antivirus and EDR solution. It scans files and processes on the machine it runs on. It operates after content has been delivered to the host — it is a post-arrival scanner, not a network-level interceptor.&lt;/p&gt;

&lt;p&gt;Both tools share the same attack surface: the Windows kernel, the Windows userspace, and the Windows security subsystem. A privilege escalation exploit, a kernel vulnerability, or a malicious driver that compromises the OS can potentially disable or circumvent both simultaneously — because both live inside the environment being attacked.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Windows machine]
  ├── Windows Kernel (WFP)
  │     └── Windows Firewall rules ← same attack surface
  └── Windows Defender service   ← same attack surface
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What neither tool covers
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Other devices on the LAN:&lt;/strong&gt; Windows Firewall protects the machine it runs on. Printers, NAS devices, IoT sensors, smart TVs, mobile phones, and macOS/Linux machines on the same network segment receive no protection from it. Each device is responsible for its own defenses — if it has any.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Network-level traffic interception:&lt;/strong&gt; Windows Firewall can allow or deny connections based on IP, port, and application. It cannot act as a proxy — it does not intercept, inspect, or modify traffic flows between internal machines and the internet. It has no concept of a web proxy CONNECT chain, no gateway antivirus scanning, and no URL filtering at the network level.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DoS flood protection at the perimeter:&lt;/strong&gt; Windows implements &lt;code&gt;SynAttackProtect&lt;/code&gt; at the TCP/IP stack level — a self-defense mechanism that adjusts SYN-ACK retransmission behavior when the local machine detects it is under a SYN flood. This protects that one machine's TCP stack. It does not rate-limit or absorb flood traffic before it reaches other devices on the LAN. In a network with no perimeter appliance, each device must defend itself individually.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Defense in Depth problem: heterogeneous layers
&lt;/h2&gt;

&lt;p&gt;NIST defines Defense in Depth as &lt;em&gt;"layering heterogeneous security technologies in the common attack vectors to ensure that attacks missed by one technology are caught by another."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The operative word is &lt;strong&gt;heterogeneous&lt;/strong&gt;. Two security tools that share an OS, a kernel, and an attack surface are not two independent layers — they are the same layer with two names. Compromising the shared substrate compromises both.&lt;/p&gt;

&lt;p&gt;A Linux-based network appliance sitting at the perimeter provides genuine architectural independence:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Internet]
     |
[Linux network appliance]   ← independent OS, independent kernel
     |                          no shared attack surface with Windows
[LAN switch]
     |
[Windows machines]
  ├── Windows Firewall     ← last line of defense
  └── Windows Defender     ← last line of defense
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An attacker who achieves kernel-level code execution on a Windows machine has no leverage over the Linux appliance. Different syscall interface, different process model, different binary format, different network stack implementation. The independence is architectural, not cosmetic.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a network appliance adds at each layer
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Perimeter firewall (zone-based):&lt;/strong&gt; The appliance enforces a default-deny policy on all unsolicited inbound connections from the external zone to the internal LAN — covering every device behind it regardless of OS. This is not per-machine configuration — it is a single policy applied at the chokepoint.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Web proxy (HTTP CONNECT chain):&lt;/strong&gt; Internal machines route web traffic through the proxy rather than connecting directly to upstream servers. In explicit proxy mode, HTTPS connections use the HTTP CONNECT method — the proxy sees the full destination URL in plaintext before the TLS handshake, enabling URL filtering without SSL decryption.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gateway antivirus:&lt;/strong&gt; Traffic passing through the proxy is scanned by an antivirus engine (ClamAV in the case of CacheGuard) before delivery to any device. This is a pre-arrival scanner, operating at a different point in the traffic flow than Windows Defender and on a completely independent codebase.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Perimeter DoS protection:&lt;/strong&gt; The appliance rate-limits SYN floods, RST floods, and UDP floods at the network boundary using &lt;code&gt;iptables&lt;/code&gt; rate-limiting rules — absorbing and dropping flood traffic before it reaches the LAN switch and propagates to individual devices.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Conceptual iptables rate-limiting for SYN flood at perimeter&lt;/span&gt;
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-p&lt;/span&gt; tcp &lt;span class="nt"&gt;--syn&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt; limit &lt;span class="nt"&gt;--limit&lt;/span&gt; 100/s &lt;span class="nt"&gt;--limit-burst&lt;/span&gt; 150 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; FORWARD &lt;span class="nt"&gt;-p&lt;/span&gt; tcp &lt;span class="nt"&gt;--syn&lt;/span&gt; &lt;span class="nt"&gt;-j&lt;/span&gt; DROP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  CacheGuard as a concrete implementation
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;CacheGuard&lt;/strong&gt; is a free, open-source network security appliance built on a custom Linux distribution (LFS-based) that has been in active development since 2002. It implements all of the above in a single integrated OS image:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Zone-based stateful firewall (external, internal/web, vpnipsec, auxiliary zones)&lt;/li&gt;
&lt;li&gt;Web proxy with URL filtering (Squid + category databases)&lt;/li&gt;
&lt;li&gt;Gateway antivirus (ClamAV via ICAP)&lt;/li&gt;
&lt;li&gt;SSL mediation (Squid ssl-bump)&lt;/li&gt;
&lt;li&gt;IPsec VPN (StrongSwan, IKEv2)&lt;/li&gt;
&lt;li&gt;QoS (HTB + SFQ via iproute2)&lt;/li&gt;
&lt;li&gt;Web caching (Squid)&lt;/li&gt;
&lt;li&gt;Built-in DoS protection (SYN flood, RST flood, UDP flood, bogon filtering, brute force protection)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It installs on any x86 machine or VM. Configuration is through a browser-based interface — no CLI required for standard deployments.&lt;/p&gt;

&lt;p&gt;The correct mental model is not "CacheGuard instead of Windows Firewall" but "CacheGuard at the network boundary + Windows Firewall on each endpoint." Two independent layers, two different OS stacks, two different interception points. This is what Defense in Depth actually looks like in a small network.&lt;/p&gt;

&lt;p&gt;→ &lt;a href="https://www.cacheguard.com/is-windows-firewall-enough/" rel="noopener noreferrer"&gt;https://www.cacheguard.com/is-windows-firewall-enough/&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://www.cacheguard.com/is-windows-firewall-enough/" rel="noopener noreferrer"&gt;CacheGuard Blog&lt;/a&gt;. CacheGuard is free and open source — &lt;a href="https://github.com/cacheguard/CacheGuard-OS" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>networking</category>
      <category>devops</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
