Building, auditing, and automating network defense policies with AI assistance — from iptables rules to Zero Trust architecture.
Firewall and access control configurations should only be modified on systems you own or are authorized to manage. Incorrect firewall rules can block legitimate traffic.
A firewall is a network security device that monitors and filters incoming and outgoing traffic based on a defined set of security rules. It acts as the first line of defense between trusted internal networks and untrusted external networks.
The simplest firewall type. Each packet is examined independently against an ordered list of rules. No awareness of connection state or application context.
Stateful firewalls maintain a connection table that tracks the state of every active session (NEW, ESTABLISHED, RELATED, INVALID).
| State | Meaning | Example |
|---|---|---|
| NEW | First packet of a connection | SYN packet initiating TCP handshake |
| ESTABLISHED | Part of an active connection | Subsequent packets after SYN/ACK |
| RELATED | Associated with an existing connection | FTP data channel from control channel |
| INVALID | Doesn't match any known connection | Orphaned ACK, malformed packet |
You can allow outbound traffic and only permit inbound packets that are part of ESTABLISHED or RELATED connections — dramatically reducing attack surface.
Next-Generation Firewalls combine traditional firewall capabilities with deep packet inspection, intrusion prevention, and application awareness.
iptables is the traditional Linux packet filtering framework. Rules are organized into tables (filter, nat, mangle) and chains (INPUT, OUTPUT, FORWARD).
# Structure: iptables -t TABLE -A CHAIN [match criteria] -j TARGET
# Allow incoming SSH from specific subnet
iptables -A INPUT -p tcp -s 10.0.1.0/24 --dport 22 -j ACCEPT
# Allow established/related connections
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Drop all other incoming traffic (default deny)
iptables -A INPUT -j DROP
Rules are evaluated top-to-bottom. First match wins. Order matters enormously.
#!/bin/bash
# Flush existing rules
iptables -F
iptables -X
# Default policies: deny all incoming, allow outgoing
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# Allow loopback
iptables -A INPUT -i lo -j ACCEPT
# Allow established and related connections
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Allow SSH from management subnet only
iptables -A INPUT -p tcp -s 10.0.100.0/24 --dport 22 -j ACCEPT
# Allow HTTP and HTTPS from anywhere
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# Allow ICMP (ping) with rate limiting
iptables -A INPUT -p icmp --icmp-type echo-request \
-m limit --limit 1/s --limit-burst 4 -j ACCEPT
# Log dropped packets (limited to avoid log flooding)
iptables -A INPUT -m limit --limit 5/min -j LOG \
--log-prefix "IPT-DROP: " --log-level 4
# Final explicit drop
iptables -A INPUT -j DROP
nftables replaces iptables with a cleaner syntax, better performance, and unified IPv4/IPv6 handling. It is the default on Debian 10+, RHEL 8+, and Ubuntu 20.04+.
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
# Allow loopback
iif "lo" accept
# Track connections
ct state established,related accept
ct state invalid drop
# SSH from management only
ip saddr 10.0.100.0/24 tcp dport 22 accept
# Web traffic
tcp dport { 80, 443 } accept
# ICMP rate limited
icmp type echo-request limit rate 1/second burst 4 packets accept
# Log and drop everything else
limit rate 5/minute log prefix "NFT-DROP: "
drop
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
Instead of memorizing complex syntax, describe your desired firewall behavior to an AI and have it generate rules.
"Generate nftables rules for a database server that: allows PostgreSQL (5432) only from the app-server subnet 10.0.2.0/24, allows SSH from the bastion host 10.0.100.5, blocks all other inbound traffic, rate-limits ICMP, and logs dropped connections."
AWS Security Groups are stateful virtual firewalls attached to EC2 instances. They allow rules only (no explicit deny) — anything not allowed is implicitly denied.
{
"GroupName": "web-server-sg",
"Description": "Security group for production web servers",
"IpPermissions": [
{
"IpProtocol": "tcp",
"FromPort": 443,
"ToPort": 443,
"IpRanges": [
{ "CidrIp": "0.0.0.0/0", "Description": "HTTPS from anywhere" }
]
},
{
"IpProtocol": "tcp",
"FromPort": 80,
"ToPort": 80,
"IpRanges": [
{ "CidrIp": "0.0.0.0/0", "Description": "HTTP (redirects to HTTPS)" }
]
},
{
"IpProtocol": "tcp",
"FromPort": 22,
"ToPort": 22,
"UserIdGroupPairs": [
{ "GroupId": "sg-0a1b2c3d4e5f", "Description": "SSH from bastion SG" }
]
}
]
}
Internet, AzureLoadBalancer, VirtualNetworkAll three clouds follow the same principle: least privilege by default. Only open what is explicitly needed, reference other security groups/tags instead of IPs when possible.
| Feature | AWS SG | Azure NSG | GCP Firewall |
|---|---|---|---|
| Stateful | Yes | Yes | Yes |
| Explicit Deny | No (implicit) | Yes | Yes |
| Attach To | ENI / Instance | Subnet / NIC | VPC (tag targets) |
| Rule Limit | 60 inbound + 60 outbound | 1000 per NSG | Varies by quota |
| Logging | VPC Flow Logs | NSG Flow Logs | Firewall Rules Logging |
| Identity-Based | SG references | ASGs | Service account targets |
A WAF operates at Layer 7 (application layer), inspecting HTTP/HTTPS requests to block web-specific attacks that network firewalls cannot see.
../../etc/passwd in URLsA network firewall sees packets and ports. A WAF sees HTTP headers, cookies, POST bodies, and query strings. They are complementary — use both.
ModSecurity is the most widely deployed open-source WAF. It runs as a module inside Apache, Nginx, or IIS and uses the OWASP Core Rule Set (CRS) for baseline protection.
# ModSecurity Configuration
SecRuleEngine On
SecRequestBodyAccess On
SecResponseBodyAccess Off
SecAuditEngine RelevantOnly
SecAuditLog /var/log/modsec_audit.log
# Block SQL injection in query string
SecRule ARGS "@detectSQLi" \
"id:1001,\
phase:2,\
deny,\
status:403,\
msg:'SQL Injection Detected',\
severity:'CRITICAL',\
tag:'attack-sqli',\
logdata:'Matched Data: %{TX.0}'"
# Block path traversal attempts
SecRule REQUEST_URI "@contains ../" \
"id:1002,\
phase:1,\
deny,\
status:403,\
msg:'Path Traversal Attempt',\
severity:'CRITICAL',\
tag:'attack-lfi'"
# Rate limit requests per IP (60 req/min)
SecRule IP:REQUESTS "@gt 60" \
"id:1003,\
phase:1,\
deny,\
status:429,\
msg:'Rate Limit Exceeded'"
{
"Name": "BlockSQLi",
"Priority": 1,
"Action": { "Block": {} },
"Statement": {
"SqliMatchStatement": {
"FieldToMatch": { "AllQueryArguments": {} },
"TextTransformations": [
{ "Priority": 0, "Type": "URL_DECODE" },
{ "Priority": 1, "Type": "HTML_ENTITY_DECODE" }
]
}
},
"VisibilityConfig": {
"SampledRequestsEnabled": true,
"CloudWatchMetricsEnabled": true,
"MetricName": "BlockSQLi"
}
}
"Never trust, always verify." Zero Trust assumes no implicit trust based on network location. Every request must be authenticated, authorized, and encrypted — regardless of origin.
Traditional: "Castle and moat" — trust everything inside the network. Zero Trust: every resource is behind its own access gate, regardless of network position.
| Component | Purpose | Tools |
|---|---|---|
| Identity Provider | Strong authentication (MFA, SSO) | Okta, Azure AD, Google Workspace |
| Device Trust | Verify device health and compliance | Intune, Jamf, CrowdStrike |
| Microsegmentation | Isolate workloads at granular level | Illumio, VMware NSX, Calico |
| ZTNA / SDP | Replace VPN with per-app access | Cloudflare Access, Zscaler, Tailscale |
| Policy Engine | Real-time access decisions | Open Policy Agent (OPA), Cedar |
| Continuous Monitoring | Detect anomalies, revoke access | SIEM, UEBA, EDR |
AI transforms how we create and maintain security policies. Instead of hand-crafting complex rule syntax, describe your security intent and let AI generate the implementation.
"Create an AWS security group for a three-tier web application: the web tier accepts HTTPS from the internet and talks to the app tier on port 8080; the app tier talks to the database tier on PostgreSQL 5432; the database tier only accepts connections from the app tier. All tiers allow SSH from the 10.0.100.0/24 management subnet."
# AI-generated AWS CLI commands for three-tier architecture
# Web Tier SG
aws ec2 create-security-group --group-name web-tier-sg \
--description "Web tier - accepts HTTPS, talks to app tier"
aws ec2 authorize-security-group-ingress --group-name web-tier-sg \
--protocol tcp --port 443 --cidr 0.0.0.0/0
aws ec2 authorize-security-group-ingress --group-name web-tier-sg \
--protocol tcp --port 22 --cidr 10.0.100.0/24
# App Tier SG
aws ec2 create-security-group --group-name app-tier-sg \
--description "App tier - accepts from web tier, talks to DB tier"
aws ec2 authorize-security-group-ingress --group-name app-tier-sg \
--protocol tcp --port 8080 \
--source-group web-tier-sg
aws ec2 authorize-security-group-ingress --group-name app-tier-sg \
--protocol tcp --port 22 --cidr 10.0.100.0/24
# DB Tier SG
aws ec2 create-security-group --group-name db-tier-sg \
--description "DB tier - accepts only from app tier"
aws ec2 authorize-security-group-ingress --group-name db-tier-sg \
--protocol tcp --port 5432 \
--source-group app-tier-sg
aws ec2 authorize-security-group-ingress --group-name db-tier-sg \
--protocol tcp --port 22 --cidr 10.0.100.0/24
Segmentation divides a network into isolated zones to limit lateral movement when a breach occurs. Each zone has its own firewall policies controlling inter-zone traffic.
| Zone | Purpose | Trust Level |
|---|---|---|
| DMZ | Public-facing services (web, email, DNS) | Low |
| Application | Internal app servers, APIs, middleware | Medium |
| Database | Data stores, caches, message queues | High |
| Management | Admin access, monitoring, CI/CD | Highest |
| User | Workstations, BYOD devices | Low-Medium |
| IoT / OT | Cameras, sensors, SCADA | Untrusted |
AI can analyze network traffic patterns and recommend optimal segmentation by identifying which services actually communicate with each other.
"Given these VPC Flow Logs showing traffic between 15 services, recommend network zones and firewall rules that minimize lateral movement risk while maintaining all required service communication."
Access control determines who can access what resources and under what conditions. Three major models dominate enterprise security.
Permissions assigned to roles, users assigned to roles. Simple, widely adopted.
admin → full accessdeveloper → read/write code, deploy stagingviewer → read-onlyDecisions based on attributes of user, resource, environment, and action.
System-enforced labels (e.g., TOP SECRET, SECRET, UNCLASSIFIED). Users cannot override — the system enforces rules based on security labels. Used in military/government (SELinux, AppArmor).
# RBAC Implementation Example
from functools import wraps
ROLES = {
"admin": {"read", "write", "delete", "deploy", "manage_users"},
"developer": {"read", "write", "deploy_staging"},
"analyst": {"read", "run_queries"},
"viewer": {"read"},
}
def require_permission(permission):
"""Decorator to enforce RBAC on API endpoints."""
def decorator(func):
@wraps(func)
def wrapper(user, *args, **kwargs):
user_perms = ROLES.get(user.role, set())
if permission not in user_perms:
raise PermissionError(
f"Role '{user.role}' lacks '{permission}' permission"
)
return func(user, *args, **kwargs)
return wrapper
return decorator
@require_permission("deploy")
def deploy_to_production(user, service, version):
"""Only admins can deploy to production."""
print(f"{user.name} deploying {service} v{version} to production")
@require_permission("deploy_staging")
def deploy_to_staging(user, service, version):
"""Developers and admins can deploy to staging."""
print(f"{user.name} deploying {service} v{version} to staging")
OPA uses the Rego policy language to make fine-grained, attribute-based access decisions.
# policy.rego — ABAC policy for API access
package api.authz
default allow = false
# Allow if user is in the same department as the resource owner
allow {
input.user.department == input.resource.owner_department
input.action == "read"
}
# Allow write only during business hours from corporate network
allow {
input.action == "write"
input.user.clearance >= input.resource.classification
is_business_hours
is_corporate_network
}
is_business_hours {
hour := time.clock(time.now_ns())[0]
hour >= 8
hour < 18
}
is_corporate_network {
net.cidr_contains("10.0.0.0/8", input.user.source_ip)
}
SELinux enforces MAC on Linux by labeling every process and file with a security context. Even root cannot bypass SELinux policies.
# View SELinux context of a file
$ ls -Z /var/www/html/index.html
system_u:object_r:httpd_sys_content_t:s0 /var/www/html/index.html
# View SELinux context of a process
$ ps -eZ | grep httpd
system_u:system_r:httpd_t:s0 1234 ? 00:00:05 httpd
# Policy: httpd_t can read httpd_sys_content_t
# If an attacker compromises Apache, they STILL can't read
# files labeled with other types (e.g., user_home_t, etc_t)
# Set SELinux to enforcing mode
$ sudo setenforce 1
# Check for policy violations
$ sudo ausearch -m avc -ts today
type=AVC msg=audit(1234567890.123:456): avc: denied { read } \
for pid=1234 comm="httpd" name="shadow" \
scontext=system_u:system_r:httpd_t:s0 \
tcontext=system_u:object_r:shadow_t:s0 tclass=file
Even if an attacker gets a shell through a web vulnerability, SELinux confines them to the httpd_t domain — they cannot read /etc/shadow, write to /tmp arbitrarily, or connect to unexpected network ports.
The most dangerous firewall is one full of rules that were "temporary" three years ago. AI excels at finding security gaps humans overlook.
0-65535 allowed where only specific ports needed"Analyze these iptables rules and identify: 1) overly permissive rules, 2) rules that could be tightened, 3) missing best practices, 4) potential bypass techniques an attacker could exploit."
# Problematic ruleset for AI to audit
iptables -A INPUT -p tcp --dport 22 -j ACCEPT # SSH open to world!
iptables -A INPUT -p tcp --dport 3306 -j ACCEPT # MySQL open to world!
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -p tcp --dport 8080:8090 -j ACCEPT # Broad port range
iptables -A INPUT -s 10.0.0.0/8 -j ACCEPT # Entire /8 trusted
iptables -A INPUT -j DROP
After AI audit, the ruleset is tightened with specific source restrictions, rate limiting, logging, and proper connection tracking.
#!/bin/bash
# AI-remediated iptables ruleset
iptables -F && iptables -X
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# Loopback
iptables -A INPUT -i lo -j ACCEPT
# Connection tracking (was missing)
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP
# SSH restricted to management subnet with rate limit
iptables -A INPUT -p tcp -s 10.0.100.0/24 --dport 22 \
-m conntrack --ctstate NEW \
-m limit --limit 3/min --limit-burst 5 -j ACCEPT
# MySQL restricted to app server subnet only
iptables -A INPUT -p tcp -s 10.0.2.0/24 --dport 3306 -j ACCEPT
# Web traffic from anywhere
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# Only specific ports instead of range
iptables -A INPUT -p tcp -s 10.0.2.0/24 --dport 8080 -j ACCEPT
iptables -A INPUT -p tcp -s 10.0.2.0/24 --dport 8081 -j ACCEPT
# Log before drop
iptables -A INPUT -m limit --limit 5/min \
-j LOG --log-prefix "IPT-DROP: "
iptables -A INPUT -j DROP
Use AI to continuously verify firewall rules comply with organizational policies and regulatory frameworks.
"""AI-assisted firewall compliance checker."""
import json
COMPLIANCE_RULES = {
"PCI-DSS-1.3.1": {
"desc": "Restrict inbound traffic to only that which is necessary",
"check": lambda r: r.get("source") != "0.0.0.0/0"
or r["port"] in [80, 443],
},
"PCI-DSS-1.3.2": {
"desc": "Limit inbound internet traffic to DMZ IPs",
"check": lambda r: r.get("zone") == "dmz"
if r.get("source") == "0.0.0.0/0" else True,
},
"CIS-9.2.1": {
"desc": "SSH must not be accessible from 0.0.0.0/0",
"check": lambda r: not (r["port"] == 22
and r.get("source") == "0.0.0.0/0"),
},
}
def audit_rules(security_group_rules):
"""Check rules against compliance framework."""
violations = []
for rule in security_group_rules:
for control_id, control in COMPLIANCE_RULES.items():
if not control["check"](rule):
violations.append({
"rule": rule,
"violation": control_id,
"description": control["desc"],
})
return violations
No single firewall layer is sufficient. A robust architecture layers multiple types of filtering at different points in the network.
| Layer | Technology | What It Catches |
|---|---|---|
| Edge / Perimeter | Cloud WAF, CDN firewall | DDoS, bot traffic, known bad IPs |
| Network Border | NGFW, IPS | Port scans, exploit attempts, C2 traffic |
| Subnet / VLAN | Security groups, NACLs | Lateral movement, unauthorized zone access |
| Host | iptables, Windows Firewall | Per-service access control, local policy |
| Application | WAF, API gateway | SQLi, XSS, API abuse, business logic attacks |
| Data | Encryption, DLP, MAC | Data exfiltration, unauthorized access |
Firewall rules without logging are security theater. You must know what is being blocked and what is being allowed.
Feed firewall logs to AI to: detect anomalous traffic patterns, identify rules that are never hit (cleanup candidates), and correlate blocked connection attempts with known threat intelligence.
iptables -C to check, nft --check to validate"Design and implement firewall rules to protect this network while maintaining required services."
| Criterion | Points |
|---|---|
| Default deny policy on all hosts | 20 |
| Correct inter-tier traffic flow (no shortcuts) | 25 |
| SSH restricted to bastion only | 15 |
| Connection tracking and logging | 15 |
| WAF rules for web server | 15 |
| Egress filtering on database tier | 10 |
Lesson 06: Secrets & Crypto — protecting sensitive data with encryption, key management, and AI-assisted secret detection.