- Python 81.7%
- C++ 15%
- Makefile 2.1%
- YARA 1.2%
| .github/workflows | Delete .github/workflows/python-package.yml | |
| test | Update hybrid_ids.cpp | |
| yara_rules | Upload files to "yara_rules" | |
| allowlist.txt | Upload files to "/" | |
| CONTRIBUTION.md | Update CONTRIBUTION.md | |
| demo1_IPS.PNG | Add files via upload | |
| hybrid_ids.py | Upload files to "/" | |
| ids_ctl.py | Upload files to "/" | |
| LICENSE | Initial commit | |
| README.md | Update README.md | |
| requirements.txt | Create requirements.txt | |
Hybrid Intrusion Detection & Prevention System (IDS/IPS) in Python
This project combines the functionality of an Intrusion Detection System (IDS) with an Intrusion Prevention System (IPS), written entirely in Python.
Want to contribute?
Check out CONTRIBUTION.md for guidelines and setup instructions.
Real-Time Packet Inspection
- Uses Scapy to sniff live traffic from a specified network interface.
- Verifies the interface exists and is up before sniffing, with a clear error (and a list of available interfaces) if not.
- Extracts metadata per packet:
- Total packet length
- Time-to-Live (TTL)
- Protocol type (TCP, UDP, etc.)
- Size of source payload bytes
- Per-source packet rate over a rolling 10s window
- Unique destination ports per source (port-scan signal)
- SYN-without-ACK flag (scan/flood signal)
Anomaly Detection (IDS)
- Powered by Isolation Forest, an unsupervised machine learning model.
- Initial baseline trained on the first 200 live packets.
- Rolling retraining: only traffic not flagged as anomalous is fed back into the training pool, and the model periodically retrains on a capped rolling window (default: every 500 clean packets, capped at 2000 samples). This lets the model adapt to legitimate traffic drift over time without an active attack poisoning the baseline.
- Flags statistically unusual traffic patterns as potential intrusions.
Automatic Intrusion Prevention (IPS)
- When an anomaly is detected:
- Identifies the source IP of the offending packet.
- Checks it against the allowlist first — allowlisted IPs/CIDRs are never blocked.
- Executes
iptables(viasubprocess.run, no shell interpolation) to block the IP dynamically. - Block is time-limited (default 15 minutes) — a background thread automatically removes the
iptablesrule once it expires, so false positives don't result in permanent bans. - Block/unblock state is persisted to
blocked_ips.jsonand restored automatically if the service restarts.
Allowlist
allowlist.txt— plain text, one IP or CIDR per line,#for comments.- A small hardcoded default allowlist also lives in the script itself (
DEFAULT_ALLOWLIST) as a safety net even if the file is missing. - Allowlisted sources are skipped entirely during analysis (not scored, not used for training).
- Hot-reloaded automatically — the running IDS watches
allowlist.txtfor changes (polled every ~5s) and reloads it without needing a restart. If an IP that's currently blocked becomes allowlisted, it's unblocked immediately rather than waiting out its TTL.
Management CLI (ids_ctl.py)
A separate command-line tool for inspecting and editing the block/allow lists while the IDS is running:
python3 ids_ctl.py status # overview of current state
python3 ids_ctl.py block list # show currently blocked IPs + time remaining
python3 ids_ctl.py block add 1.2.3.4 --minutes 30 # manually block an IP
python3 ids_ctl.py block remove 1.2.3.4 # unblock early
python3 ids_ctl.py block clear # unblock everything (asks for confirmation)
python3 ids_ctl.py allow list
python3 ids_ctl.py allow add 192.168.1.0/24
python3 ids_ctl.py allow remove 192.168.1.0/24
The CLI only edits the shared state files (blocked_ips.json, allowlist.txt) — it never touches iptables directly. The running IDS process is the sole thing that applies/removes firewall rules, picking up CLI edits within ~5 seconds. This avoids two processes racing to modify the same rules.
Note:
ids_ctl.pyand the IDS must be run from the same working directory (or be pointed at the same file paths) so they agree on whereblocked_ips.jsonandallowlist.txtlive — see the systemdWorkingDirectorysetting below.
Intelligent Alerts
- Alerts include detailed context:
- Source IP and Port
- Destination IP and Port
- Timestamp
- Packet Payload, shown in:
- Hexadecimal
- ASCII, for human readability
- Outputs are color-coded for visibility in terminal logs.
- All alerts, blocks, unblocks, and reloads are also written to
ids_alerts.log(disk), independent of terminal output — useful when running as a systemd service.
Lightweight & Extensible
- Pure Python implementation — no kernel modules.
- Easy to modify detection logic or add new defenses (e.g. email alerts, database logging).
Demo
sudo python3 hybrid_ids.py
Installation Guide: Hybrid IDS/IPS with Systemd Integration
This guide walks you through installing and running the Python-based Hybrid Intrusion Detection & Prevention System (IDS/IPS) as a Linux systemd service.
Requirements
- Python 3
- Packages:
scapy,pandas,scikit-learn,colorama - Root privileges (required for packet sniffing and
iptables) - Linux system with
systemd(Ubuntu, Debian, CentOS, Arch, etc.)
Install Dependencies
Debian/Ubuntu:
sudo apt update
sudo apt install python3-pip iptables -y
pip3 install scapy pandas scikit-learn colorama
Arch Linux:
sudo pacman -S python-pip iptables
pip install scapy pandas scikit-learn colorama
Copy the Files
You need all three files together in the same directory, since hybrid_ids.py and ids_ctl.py share allowlist.txt and blocked_ips.json via relative paths:
sudo mkdir -p /opt/hybrid-ids
sudo cp hybrid_ids.py ids_ctl.py allowlist.txt /opt/hybrid-ids/
sudo chmod +x /opt/hybrid-ids/hybrid_ids.py /opt/hybrid-ids/ids_ctl.py
Edit /opt/hybrid-ids/allowlist.txt to add your gateway, DNS resolver, and any management IPs/subnets before starting the service.
Check Your Network Interface
Find the correct interface name — it may not be eth0:
ip link show
Look for the interface that shows UP and LOWER_UP. Update the INTERFACE constant near the top of hybrid_ids.py accordingly.
Create systemd Service File
sudo nano /etc/systemd/system/ids-ips.service
Paste the following content:
[Unit]
Description=Hybrid IDS/IPS Python Service
After=network.target
[Service]
ExecStart=/usr/bin/python3 /opt/hybrid-ids/hybrid_ids.py
WorkingDirectory=/opt/hybrid-ids
Restart=on-failure
StandardOutput=journal
StandardError=journal
User=root
Group=root
[Install]
WantedBy=multi-user.target
WorkingDirectory matters here — it's what makes the relative paths (allowlist.txt, blocked_ips.json, ids_alerts.log) resolve to /opt/hybrid-ids/ instead of /root/ or wherever else.
Save and exit.
Enable and Start the Service
sudo systemctl daemon-reexec
sudo systemctl daemon-reload
sudo systemctl enable ids-ips.service
sudo systemctl start ids-ips.service
View Logs and Status
sudo systemctl status ids-ips.service
sudo journalctl -u ids-ips.service -f
Persistent alert history (independent of journald rotation) is also available at:
tail -f /opt/hybrid-ids/ids_alerts.log
Manage Block/Allow Lists While Running
Run the CLI from the same directory the service uses, so it edits the right files:
cd /opt/hybrid-ids
sudo python3 ids_ctl.py status
sudo python3 ids_ctl.py block list
sudo python3 ids_ctl.py allow add 192.168.1.0/24
Changes typically take effect within ~5 seconds without restarting the service.
Stop and Disable
sudo systemctl stop ids-ips.service
sudo systemctl disable ids-ips.service
Important Notes
- This service runs as
rootbecause raw socket access and firewall management (iptables) require elevated privileges. - The allowlist is your safety net — make sure your gateway, DNS, and any management/jump-box IPs are in it before enabling the service on a box you need to keep reachable.
- Customize script constants (
TRAIN_WINDOW,RETRAIN_EVERY,BLOCK_DURATION_SEC,FLOW_WINDOW_SEC,INTERFACE) near the top ofhybrid_ids.pyto tune behavior for your environment. - Customize the script or service file paths if needed.