English | 日本語
Azazel-Zero is a prototype of a “Substitute Barrier” running on Raspberry Pi Zero 2 W.
It brings the Azazel System’s delaying action into a practical form while returning to the roots of the Substitute Barrier and Barrier Maze.
-
Azazel-Pi
- A Portable Security Gateway (Cyber Scapegoat Gateway) based on Raspberry Pi 5
- A concept model to cheaply protect small temporary networks
- Heavily experimental for trying multiple technical elements
-
Azazel-Zero
- A trimmed, lightweight edition with narrowed scope, designed for real operation
- A physical barrier focused on portability and practicality
- Unlike the concept-model Azazel-Pi, this is a deployable, practical model
- Portability: fits in a shirt pocket
- Inevitability: forcibly interposes between device and external network
- Simplicity: plug USB and the firewall is in place
- Delaying defense: waste the attacker’s time (core of the Azazel System)
- Raspberry Pi Zero 2 W
- USB OTG gadget mode
- Single USB cable supplies power and virtual networking
- Plug into a laptop and it boots immediately
- Blocking/latency via iptables/nftables
- Delay/jitter injection with tc (Traffic Control)
- Custom Python scripts for dynamic control and notifications
- Wi-Fi Safety Sensor (Python +
iw+tcpdump) detects Evil AP / MITM / DNS & DHCP spoofing, issues danger tags, and auto-disconnects
- E-Paper
- 2.13" monochrome (250×122)
- Compact view of threat level/action/RTT/queue state/captive-portal detection
Uses a deterministic two-layer engine that runs even on Pi Zero 2 W.
-
Layer 1: Wi-Fi Safety Sensor
py/azazel_zero/sensors/wifi_safety.pyinspectsiw dev … linkand shorttcpdumpcaptures to detect ARP/DHCP/DNS anomalies.- Emits tags and metadata such as
evil_ap,mitm,arp_spoof,dhcp_spoof,dns_spoof,tls_downgrade,captive_portal,phish.
-
Layer 2: Mock-LLM Core
py/azazel_zero/core/mock_llm_core.pymaps inputs to legacy categories (scan,bruteforce,exploit,malware,sqli,dos,unknown).- Modernized from regex + randomness to hash-based deterministic replies, outputting risk (1–5) and rationale consistently.
- Profile
"zero"raises risk when Evil AP / MITM tags exist, ensuring Danger/Disconnect decisions.
-
Threat Judge wrapper
py/azazel_zero/app/threat_judge.pybundles tags and final decisions into JSON that UI/automation can consume (e.g., immediate disconnect forrisk >= 4orevil_ap).
Heavyweight ML remains a future research theme; the current deterministic stack alone provides the automation needed for a portable shield.
-
TUI (terminal UI)
py/azazel_zero/cli_unified.pyis the unified monitoring TUI showing Wi-Fi state, threat level, channel congestion, control rules in real time.- Colorful icons and color-coding for intuitive situational awareness.
- Manual refresh mode ([U] key).
-
tmux console
py/azazel_menu.pyis a curses menu with Wi-Fi selector, Portal/Shield/Lockdown scripts, OpenCanary control, and E-Paper tests.py/azazel_status.pyis a telemetry panel showing SSID/BSSID, USB gadget IP, RSSI, captive-portal indicators, etc.
-
Bootstrap tools
tools/bootstrap_zero.shinstalls dependencies, systemd units, minimal Suricata rules, and smoke tests in one shot.- Flags
--no-epd,--no-enable,--no-suricata,--dry-runtailor for lab/production.
sudo python3 py/azazel_zero/cli_unified.py┌─────────────────────────────────────────────────────────────┐
│ Azazel-Zero | 📶 SSID: MyWiFi | ⬇️ usb0 | ⬆️ wlan0 | 🕐 12:34:56 │ ← Status bar
│ View: SNAPSHOT (manual) Age: 🟢 00:00:15 │ ← Data freshness
├─────────────────────────────────────────────────────────────┤
│ ✅ SAFE Recommendation: keep as-is │ ← State badge (inverted)
│ Reason: probe ok / DNS ok │
│ Threat: [🟢🟢⚪⚪⚪] Low │ ← Threat level
│ Next: waiting for re-eval │
├──────────────────────┬──────────────────────────────────────┤
│ Connection │ Control / Safety │
│ BSSID: aa:bb:cc:... │ QUIC(UDP/443): ⛔ BLOCKED │
│ Channel: 🟢 Ch124 │ DoH(TCP/443): ⛔ BLOCKED │
│ - Low (31 APs) │ Degrade: ✓ OFF │
│ Signal: 🟩🟩🟩 -55dBm │ Probe: ✓ 5/5 ALL OK │
│ Gateway: 🏠 192.168… │ Stats: DNS: ✅ 45 ⚠️ 3 🔴 2 │
├──────────────────────┴──────────────────────────────────────┤
│ Evidence (last 90s) │
│ 🟢 Normal probe completed │
│ 🟡 DNS query to suspicious domain │
│ 💠 action: reprobe command sent │
│ ↳ decision: state=NORMAL suspicion=5 decay=0.9 │
├─────────────────────────────────────────────────────────────┤
│ Flow: PROBE → DEGRADED → NORMAL → ✅ SAFE │
│ [U] Refresh [A] Stage-Open [R] Re-Probe [C] Contain [L] Details [Q] Quit │
│ Hint: This screen does not auto-refresh. Press [U] when needed. │
└─────────────────────────────────────────────────────────────┘
| Icon | State | Color | Meaning |
|---|---|---|---|
| ⟳ | Checking | Cyan (inverted) | Initial scan |
| ✅ | Safe | Green (inverted, bold) | Network is safe |
| Limited | Yellow (inverted) | Restrictions like bandwidth limits | |
| ⛔ | Contained | Red (inverted) | Danger detected, containment mode |
| 👁 | Deception | Purple (inverted) | Decoy mode |
Threat: [🟢🟢⚪⚪⚪] Low ← Safe
Threat: [🟡🟡🟡⚪⚪] Med ← Caution
Threat: [🔴🔴🔴🔴🔴] Critical ← Dangerous
- 🟢 0–30s: freshest, trustworthy
- 🟡 30s–2m: slightly old, verify
- 🔴 2m+: stale, press [U] to refresh
| Display | Strength | Meaning |
|---|---|---|
| 🟩🟩🟩🟩 | >= -50dBm | Excellent |
| 🟩🟩🟩 | -50 to -60dBm | Good |
| 🟨🟨 | -60 to -70dBm | Fair |
| 🟧 | -70 to -80dBm | Weak |
| 🟥 | <= -80dBm | Very weak |
| Display | Congestion | APs | Meaning |
|---|---|---|---|
| 🟢 Clear/Low | Low | 0–2 | Open (comfortable) |
| 🟡 Medium | Medium | 3–5 | Normal |
| 🟧 High | High | 6–10 | Crowded |
| 🔴 Critical | Very high | 11+ | Extremely crowded |
※ APs around you are scanned when you press [U].
- 🏠 Green: private IP (normal)
⚠️ Yellow: public IP (check)
| Item | Icon | Color | Meaning |
|---|---|---|---|
| QUIC | ⛔ | Red | Blocked |
| QUIC | ✓ | Green | Allowed |
| Degrade | ⚡ | Yellow | Bandwidth limited |
| Degrade | ✓ | Green | No limit |
| Probe | ⚠ | Red | Probe detected problems |
| Probe | ✓ | Green | All good |
- ✅ Normal queries
⚠️ Suspicious queries- 🔴 Blocked queries
| Icon | Color | Meaning |
|---|---|---|
| 🔴 | Red (bold) | Anomaly / error (blocked, fail, hijack, etc.) |
| 🟡 | Yellow | Warning / caution (portal, dns, probe, etc.) |
| 🟢 | Green | Normal / success (ok, safe, normal, etc.) |
| 💠 | Cyan | Action (command, transition, etc.) |
| ⚪ | White | Other |
| Key | Function | Description |
|---|---|---|
| [U] | Refresh | Manually update data (runs Wi-Fi scan) |
| [A] | Stage-Open | Move from restricted to normal mode |
| [R] | Re-Probe | Run probe test again |
| [C] | Contain | Enter containment mode |
| [L] | Details | Detail view (30 evidence entries, internal state) |
| [Q] | Quit | Exit |
- Evidence history: last 30 evidence entries
- Internal state:
State: current state machine status (PROBE/NORMAL/DEGRADED/CONTAIN/DECEPTION)Suspicion: suspicion score (0–100)Decay: decay valueRules: control rule details
- Press [B] to return to main screen
| Color | Meaning | Where used |
|---|---|---|
| 🟢 Green | Good / normal / safe | SAFE, strong signal, clear channel, normal logs |
| 🟡 Yellow | Caution / warning / medium | LIMITED, weak signal, congestion, warning logs |
| 🔴 Red | Danger / error / abnormal | CONTAINED, very weak signal, severe congestion, error logs |
| 🟣 Purple | Special | DECEPTION |
| 🔵 Cyan | Info / technical | CHECKING, action logs, technical info |
| ⚪ White | Neutral / unknown | Other logs, unknown states |
See docs/setup-zero.md for details.
Use the automated setup script for reproducible installs.
sudo chmod +x tools/bootstrap_zero.sh
sudo tools/bootstrap_zero.shOptions:
--no-epd: skip E-Paper dependencies--no-enable: do not enable systemd services--no-suricata: skip lightweight Suricata rules--dry-run: print actions only
- Install Raspberry Pi OS Lite (64bit)
- Configure USB gadget mode
- Add
dtoverlay=dwc2to/boot/config.txt - Add
modules-load=dwc2,g_etherto/boot/cmdline.txt
- Add
- Install E-Paper control library (e.g., Waveshare Python)
- Deploy UI scripts to display threat level and delay state
- Enable systemd services to autostart shield/UI
See Boot_E-Paper_Splash_ja.md for details.
At boot, display SSID and IPv4 on the Waveshare E-Paper.
Script: py/boot_splash_epd.py
Setup
- Install dependencies together:
sudo bash bin/install_dependencies.sh --with-epd - Test:
sudo python3 ~/Azazel-Zero/py/boot_splash_epd.py - Enable service
azazel-epd.service(path managed in/etc/default/azazel-zero)
If your panel driver is not epd2in13_V4, change to V3 or V2.
bin/install_waveshare_epd.sh automates the official steps so Waveshare demos run immediately:
sudo bash bin/install_waveshare_epd.shScript contents (can run manually):
# Dependencies
sudo apt-get update
sudo apt-get install python3-pip
sudo apt-get install python3-pil
sudo apt-get install python3-numpy
sudo python3 -m pip install spidev
# gpiozero (only if missing)
sudo apt-get update
sudo apt install python3-gpiozero
sudo apt install python-gpiozero
# Fetch Waveshare demos
git clone https://github.com/waveshare/e-Paper.git
cd e-Paper/RaspberryPi_JetsonNano/
wget https://files.waveshare.com/upload/7/71/E-Paper_code.zip
unzip E-Paper_code.zip -d e-Paper
# Alternative: use 7zip
sudo apt-get install p7zip-full
7z x E-Paper_code.zip -O./e-Paper
# Run demo (2.13in mono V4)
cd e-Paper/RaspberryPi_JetsonNano/python/examples/
python3 epd_2in13b_V4_test.pyinstall_waveshare_epd.sh installs the library under /opt/waveshare-epd and fetches E-Paper_code.zip. Add --run-demo to automatically execute the demo at the end.