================================================================
SD Tech Solutions — Basic Firewall Policy Template  (v1.0)
================================================================
Default-deny baseline for a small-business perimeter. Recipe (A)
is the vendor-neutral policy table (drop into pfSense/WatchGuard/
FortiGate as rules); recipe (B) is a ready nftables ruleset for a
Linux edge host. Replace ALL <PLACEHOLDER> values.

----------------------------------------------------------------
(A) POLICY TABLE — vendor-neutral (order matters, first match wins)
----------------------------------------------------------------
 #  FROM            TO                 PORT/PROTO       ACTION  LOG
 1  MGMT-hosts      firewall mgmt UI   443/tcp,22/tcp   allow   yes
 2  any WAN         firewall mgmt UI   any              DENY    yes   <- never expose mgmt
 3  LAN (VLAN10)    internet           80,443,853,123   allow   no
 4  LAN (VLAN10)    internal servers   app ports only   allow   no
 5  GUEST (VLAN30)  internet           80,443,853       allow   no
 6  GUEST (VLAN30)  RFC1918 (all)      any              DENY    yes   <- guest isolation
 7  VOICE (VLAN20)  PBX/SIP provider   5060-5061,RTP    allow   no
 8  any LAN         firewall DNS       53/tcp+udp       allow   no
 9  any LAN         internet           53/tcp+udp       DENY    yes   <- force internal DNS
10  WAN             published services per port-forward  allow   yes  <- each one justified
11  any             any                any              DENY    yes   <- the default

PRINCIPLES
 - Default deny both directions between zones; every allow has an owner.
 - Management plane (rule 1-2): reachable only from MGMT VLAN/VPN.
 - Egress control (rule 9): blocking outbound DNS breaks most
   malware C2 cheaply. Add 25/tcp outbound DENY unless a mail
   server legitimately sends.
 - Log every DENY that faces WAN + every allow that faces in.
 - Review the ruleset quarterly; delete rules nobody claims.

----------------------------------------------------------------
(B) LINUX EDGE — /etc/nftables.conf (default-deny inbound)
----------------------------------------------------------------
flush ruleset
table inet filter {
  chain input {
    type filter hook input priority 0; policy drop;
    ct state established,related accept
    ct state invalid drop
    iifname "lo" accept
    icmp type { echo-request, destination-unreachable, time-exceeded } accept
    icmpv6 type { echo-request, nd-neighbor-solicit, nd-neighbor-advert,
                  nd-router-advert, destination-unreachable, time-exceeded,
                  packet-too-big, parameter-problem } accept
    # --- management: SSH only from trusted sources
    ip saddr { <VPN_SUBNET>, <TRUSTED_MGMT_IP>/32 } tcp dport <SSH_PORT> accept
    # --- published services (justify EVERY line)
    tcp dport { 80, 443 } accept
    # udp dport 51820 accept              # WireGuard, if this box hosts it
    log prefix "nft-drop-in: " counter drop
  }
  chain forward {
    type filter hook forward priority 0; policy drop;
    # only present if this box routes; add explicit zone pairs here
  }
  chain output {
    type filter hook output priority 0; policy accept;
    # tighten later: e.g. block outbound 25/tcp unless mail server
    # tcp dport 25 log prefix "nft-smtp-out: " drop
  }
}

APPLY SAFELY (never lock yourself out):
  nft -c -f /etc/nftables.conf        # 1. syntax check
  # 2. schedule a revert before applying over SSH:
  echo "systemctl restart nftables" | at now + 5 minutes
  nft -f /etc/nftables.conf           # 3. apply
  # 4. new SSH session works? ->  atrm <job>   (cancel the revert)

Deployed by SD Tech Solutions · sd-techsolutions.com
