RELAX Eases Lockdown And Xgress
A lightweight, config-driven firewall framework for Linux. Define granular ingress/egress rules per interface with simple YAML configuration.
____ _____ _ _ __ __
| _ \| ____| | / \ \ \/ /
| |_) | _| | | / _ \ \ /
| _ <| |___| |___ / ___ \ / \
|_| \_\_____|_____/_/ \_\/_/\_\
- Simple YAML config - No complex iptables syntax
- Per-interface control - Different rules for each interface
- Granular ingress/egress - Control both directions independently
- Presets - One command to open ports for common services
- Portable - Works on servers, VMs, embedded devices, cloud instances
- Persistent - Survives reboots
- Servers - Expose only needed services per interface
- Multi-homed systems - Different policies for management vs public interfaces
- VPN gateways - Full access on tunnel, restricted on physical NICs
- Development boxes - Quick port management during testing
- Remote access systems - Secure management via VPN, limited exposure elsewhere
- IoT/Embedded - Lightweight firewall for resource-constrained devices
git clone https://github.com/YOUR_USERNAME/relax.git
cd relax
sudo ./install.sh
relax statusEdit /etc/relax/config.yml:
# Define each interface with granular ingress/egress control
#
# ingress: all | ports | none
# egress: all | ports | none
#
# When set to "ports", rules come from:
# - base.conf (permanent)
# - active.conf (temporary, cleared on reset)
interfaces:
# Management interface - full access
wg0:
ingress: all
egress: all
# Public interface - restricted inbound, full outbound
eth0:
ingress: ports
egress: all
# Internal network - restricted both directions
eth1:
ingress: ports
egress: ports
# Isolated - no traffic at all
# eth2:
# ingress: none
# egress: none
# Policy for unlisted interfaces
default_policy:
ingress: none
egress: none
# Stateful firewall (allow established connections)
stateful: true
# Logging
logging:
enabled: false
limit: "5/min"
prefix: "[RELAX] "| Level | Ingress | Egress | Use Case |
|---|---|---|---|
all |
Everything allowed | Everything allowed | Management, trusted networks |
ports |
Only base.conf + active.conf | Only base.conf + active.conf | Controlled access |
none |
Nothing allowed | Nothing allowed | Blocked/isolated |
Port rules are stored in config files with the format: interface:direction:port/proto
base.conf - Permanent ports (survive relax reset)
# Example base.conf
eth0:in:443/tcp
eth0:in:8080:8099/tcp
eth0:out:22/tcp
wlan0:in:80/tcp
active.conf - Temporary ports (cleared on relax reset)
# Added via: relax add <interface> <in|out> <port>
eth0:in:445/tcp
eth0:in:137/udp
relax status Show current firewall state
relax interfaces List all interfaces and policies
relax add <iface> <in|out> <port> Add a port rule
relax remove <iface> <in|out> <port> Remove a port rule
relax load <iface> <in|out> <preset> Load a preset
relax unload <iface> <in|out> <preset> Unload a preset
relax reset Clear all active ports
relax reload Reload firewall rules
relax presets List available presets
relax config [edit] View or edit configuration
# Check status
relax status
# Add ingress ports to specific interface
relax add eth0 in 443 # Allow incoming TCP 443 on eth0
relax add eth0 in 8080:8090 # Allow incoming TCP range on eth0
relax add wlan0 in 161/udp # Allow incoming UDP 161 on wlan0
# Add egress ports
relax add eth0 out 22 # Allow outgoing TCP 22 on eth0
relax add eth0 out 53/udp # Allow outgoing UDP 53 on eth0
# Remove ports
relax remove eth0 in 443
relax remove eth0 out 22
# Load presets for ingress
relax load eth0 in http # Open HTTP ports for incoming on eth0
relax load eth1 in responder # Open Responder ports for incoming on eth1
# Load presets for egress
relax load eth0 out http # Open HTTP ports for outgoing on eth0
# Unload presets
relax unload eth0 in http
# Reset all active ports
relax reset
# Edit config
relax config edit
relax reloadBuilt-in presets for common services:
| Preset | Ports | Description |
|---|---|---|
http |
80, 443, 8000, 8080, 8443 | Web servers |
dns |
53/tcp, 53/udp | DNS servers |
smb |
445, 139, 137/udp, 138/udp | SMB/CIFS |
ldap |
389, 636, 389/udp | LDAP/LDAPS |
responder |
Multiple | LLMNR/NBT-NS/mDNS |
mitm6 |
547/udp, 80, 445, 53, 389 | IPv6 services |
coercion |
445, 139, 80 | Auth coercion |
# Load for ingress (incoming traffic)
relax load eth0 in responder
# Load for egress (outgoing traffic)
relax load eth0 out http
# Unload
relax unload eth0 in responderCreate /etc/relax/presets/myservice:
# My custom service
# Usage: relax load <interface> <in|out> myservice
3000/tcp
3001/tcp
8080/tcp
Then: relax load eth0 in myservice
┌─────────────────────────────────────┐
│ YOUR BOX │
│ │
┌───────────────┤ wg0 ingress: all │
│ VPN/Mgmt │ egress: all │
└───────────────┤ │
│ │
┌───────────────┤ eth0 ingress: ports │
│ Network A │ egress: all │
└───────────────┤ │
│ │
┌───────────────┤ eth1 ingress: ports │
│ Network B │ egress: ports │
└───────────────┤ │
│ │
┌───────────────┤ wlan0 ingress: none │
│ Untrusted │ egress: all │
└───────────────┴─────────────────────────────────────┘
/etc/relax/
├── config.yml # Main configuration (interface policies)
├── base.conf # Permanent port rules (interface:direction:port/proto)
├── active.conf # Temporary port rules (cleared on reset)
└── presets/ # Service presets
├── http
├── dns
├── smb
├── ldap
├── responder
├── mitm6
└── coercion
/usr/local/bin/relax
- Linux with iptables
- Bash 4+
- Root access
Tested on: Debian, Ubuntu, Kali, Parrot, Alpine, RHEL/CentOS
git clone https://github.com/YOUR_USERNAME/relax.git
cd relax
sudo ./install.shsudo /path/to/relax/uninstall.shMIT
PRs welcome. Add presets, features, or improvements.
Stop wrestling with iptables. Just RELAX.