At home, in my homelab, I run multiple internal networks.
There’s one for trusted client devices, and another that’s less trusted — kind of like a DMZ. The DMZ hosts those VMs that need to be reachable from the internet at the network level.
The main goal is to safeguard the internal network and limit blast radius in case a box inside the untrusted DMZ gets popped.

Both networks are connected directly to my servers.

To keep them at least somewhat separated, I use a small Protectli box as a dedicated firewall, acting as a Layer 3 router to handle inter-network traffic and enforce segmentation.
On it, I’ve set up a basic but working iptables ruleset. It watches traffic between the networks and does simple stateful filtering — meaning it tracks connections and only allows replies if a connection was allowed to start.

For my own sanity (and safety), here’s a trimmed-down version of the setup — not everything, just the parts that show how it works:

#!/bin/bash
# ==========================================
# Simple Firewall Script with Logging
# Network Separation: Internal <-> Firewall <-> DMZ
# Internal: 192.168.0.0/24
# DMZ: 192.168.100.0/24
# ==========================================

### 1. Basic Cleanup ###
/sbin/iptables -F
/sbin/iptables -X
/sbin/iptables -t nat -F
/sbin/iptables -t nat -X

# Default Policies: Deny all traffic by default
/sbin/iptables -P INPUT DROP
/sbin/iptables -P OUTPUT DROP
/sbin/iptables -P FORWARD DROP

### 2. Allow Loopback Traffic ###
/sbin/iptables -A INPUT -i lo -j ACCEPT
/sbin/iptables -A OUTPUT -o lo -j ACCEPT

### 3. Allow Established and Related Connections ###
/sbin/iptables -A INPUT -m state –state ESTABLISHED,RELATED -j ACCEPT
/sbin/iptables -A OUTPUT -m state –state ESTABLISHED,RELATED -j ACCEPT
/sbin/iptables -A FORWARD -m state –state ESTABLISHED,RELATED -j ACCEPT

### 4. Allow ICMP (Ping etc.) ###
/sbin/iptables -A INPUT -p icmp -j ACCEPT
/sbin/iptables -A OUTPUT -p icmp -j ACCEPT
/sbin/iptables -A FORWARD -p icmp -j ACCEPT

### 5. Prevent Common Scans and Spoofing ###
# Block XMAS and NULL scans
/sbin/iptables -A INPUT -p tcp –tcp-flags ALL ALL -j DROP
/sbin/iptables -A INPUT -p tcp –tcp-flags ALL NONE -j DROP

# Block spoofed source addresses
/sbin/iptables -A INPUT -s 0.0.0.0/8 -j DROP
/sbin/iptables -A INPUT -s 127.0.0.0/8 ! -i lo -j DROP
/sbin/iptables -A INPUT -s 169.254.0.0/16 -j DROP
/sbin/iptables -A INPUT -s 224.0.0.0/4 -j DROP
/sbin/iptables -A INPUT -s 240.0.0.0/5 -j DROP

### 6. Allow Internal -> DMZ Traffic ###
/sbin/iptables -A FORWARD -s 192.168.0.0/24 -d 192.168.100.0/24 -j ACCEPT

# Allow Fluent Bit / OpenSearch from DMZ to internal Elasticsearch node
/sbin/iptables -A INPUT -p tcp -s 192.168.100.0/24 -d 192.168.0.38 –dport 9200 -j ACCEPT
/sbin/iptables -A FORWARD -p tcp -s 192.168.100.0/24 -d 192.168.0.38 –dport 9200 -j ACCEPT

### 7. Block DMZ -> Internal Traffic (unless explicitly allowed) ###
/sbin/iptables -A FORWARD -s 192.168.100.0/24 -d 192.168.0.0/24 -j DROP

### 8. Access to the Firewall (INPUT chain) ###
# Allow SSH to firewall from internal
/sbin/iptables -A INPUT -p tcp -d 192.168.0.254 –dport 22 -m state –state NEW -j ACCEPT

# Allow HTTP/HTTPS access to firewall (e.g. web interface)
/sbin/iptables -A INPUT -p tcp -d 192.168.0.254 –dport 80 -m state –state NEW -j ACCEPT
/sbin/iptables -A INPUT -p tcp -d 192.168.0.254 –dport 443 -m state –state NEW -j ACCEPT

### 9. Allow Internal <-> Internal ###
/sbin/iptables -A FORWARD -s 192.168.0.0/24 -d 192.168.0.0/24 -j ACCEPT

### 10. Outbound Traffic from the Firewall ###
# DNS, NTP, FTP, SSH, Mail, Web etc.
/sbin/iptables -A OUTPUT -p udp –dport 53 -j ACCEPT
/sbin/iptables -A OUTPUT -p tcp –dport 53 -j ACCEPT
/sbin/iptables -A OUTPUT -p udp –dport 123 -j ACCEPT
/sbin/iptables -A OUTPUT -p tcp –dport 20:21 -j ACCEPT
/sbin/iptables -A OUTPUT -p tcp –dport 22 -j ACCEPT
/sbin/iptables -A OUTPUT -p tcp –dport 25 -j ACCEPT
/sbin/iptables -A OUTPUT -p tcp –dport 43 -j ACCEPT
/sbin/iptables -A OUTPUT -p tcp –dport 80 -j ACCEPT
/sbin/iptables -A OUTPUT -p tcp –dport 443 -j ACCEPT
/sbin/iptables -A OUTPUT -p tcp –dport 465 -j ACCEPT
/sbin/iptables -A OUTPUT -p tcp –dport 587 -j ACCEPT
/sbin/iptables -A OUTPUT -p tcp –dport 9200 -j ACCEPT

### 11. Allow Forwarding of DNS, HTTP/S, and FTP from Intern/DMZ ###
# DNS
/sbin/iptables -A FORWARD -p udp –dport 53 -j ACCEPT
/sbin/iptables -A FORWARD -p tcp –dport 53 -j ACCEPT

# Web (HTTP/HTTPS)
/sbin/iptables -A FORWARD -p tcp –dport 80 -j ACCEPT
/sbin/iptables -A FORWARD -p tcp –dport 443 -j ACCEPT

# FTP
/sbin/iptables -A FORWARD -p tcp –dport 20 -j ACCEPT
/sbin/iptables -A FORWARD -p tcp –dport 21 -j ACCEPT

### 12. Logging of Dropped Packets (excluding Broadcast/Multicast) ###
/sbin/iptables -N LOGGING

# Ignore broadcast and multicast logging
/sbin/iptables -A LOGGING -m pkttype –pkt-type broadcast -j DROP
/sbin/iptables -A LOGGING -m pkttype –pkt-type multicast -j DROP

# Log everything else that’s dropped
/sbin/iptables -A LOGGING -m limit –limit 2/min -j LOG \
–log-prefix “IPTables-Dropped: ” –log-level 4
/sbin/iptables -A LOGGING -j DROP

# Send dropped INPUT and FORWARD traffic to LOGGING chain
/sbin/iptables -A INPUT -j LOGGING
/sbin/iptables -A FORWARD -j LOGGING

exit 0

 

By raphael

Leave a Reply