This project documents the defensive portion of a tutorial-guided Linux firewall lab using Python, Scapy, tcpdump, and iptables.
I used my own Linux virtual machine to monitor incoming TCP SYN traffic, manually create and remove firewall rules, configure a Python virtual environment, install Scapy, run the supplied firewall script, and analyze how it detected repeated activity and temporarily blocked source IP addresses.
The original lab design and Python script were created by the credited tutorial author (Gnar Coding)). I did not independently author the original script. My work focused on configuring the defensive environment, running and testing the supplied code, troubleshooting dependencies, examining its behavior, and documenting the project.
- π Python Firewall Script
- π Complete Lab Process
- π My Code Analysis
- π οΈ Limitations and Future Improvements
- π Third-Party Attribution
- βοΈ Original Script License
This project followed the tutorial Firewall That Tells Hackers to Try Harder and uses the Python script provided through the tutorial creatorβs repository.
- Tutorial: View on YouTube
- Original source code: gnarcoding/firewall_try_harder
- Original license: MIT License
- Script included here: firewall_try_harder.py
The original lab design and Python script were not authored by me.
For my portion of the project, I:
- Configured the defensive environment on my own virtual machine
- Monitored TCP traffic with
tcpdump - Added and removed firewall rules with
iptables - Created and activated a Python virtual environment
- Installed and configured Scapy
- Ran and tested the supplied script
- Reviewed temporary blocking behavior
- Analyzed the code and documented its limitations
- Project type: Tutorial-guided personal cybersecurity lab
- Completed portion: Defensive environment only
- Environment: Linux virtual machine
- Primary focus: Packet monitoring, firewall administration, Python environment setup, and automated defensive response
- Attacker environment: Not recreated
- Production use: No
This lab was completed only in an authorized environment.
| Technology or Concept | How It Was Used |
|---|---|
| Linux | Hosted the defensive lab environment |
| Python 3 | Ran the supplied firewall automation script |
| Scapy | Inspected and created network packets |
tcpdump |
Displayed incoming TCP and SYN traffic |
iptables |
Added, listed, removed, and flushed firewall rules |
| Python virtual environment | Isolated the Scapy dependency |
| TCP SYN flag | Identified the beginning of TCP connection attempts |
| Nmap activity | Represented scan-related traffic in the tutorial workflow |
| Threading | Allowed packet sniffing and unblock checks to operate together |
| Firewall automation | Connected packet observations to temporary IP blocking |
flowchart LR
Source[Source Host]
subgraph DefensiveVM["Defensive Linux VM"]
Interface[Network Interface]
Tcpdump[tcpdump Monitoring]
Script[Python and Scapy Script]
Tracker[Per-Source Activity Tracker]
Firewall[iptables Firewall]
end
Source -->|TCP SYN Packets| Interface
Interface --> Tcpdump
Interface --> Script
Script --> Tracker
Tracker -->|Threshold Exceeded| Firewall
Firewall -->|DROP Rule| Source
flowchart TD
A[Observe Incoming SYN Traffic] --> B[Identify Source IP and Destination Port]
B --> C[Update Per-Source Counter]
C --> D{Count Greater Than Five?}
D -->|No| E[Send Educational Packet Response]
E --> A
D -->|Yes| F[Check Whether IP Is Already Blocked]
F --> G[Add iptables INPUT DROP Rule]
G --> H[Schedule Rule Removal]
H --> I[Remove Rule After Ten Minutes]
I used tcpdump to inspect TCP traffic reaching the defensive VM.
tcpdump -i eth0 'tcp[tcpflags] & tcp-syn != 0'This filter displays packets with the TCP SYN flag enabled.
sudo tcpdump -i any tcp and not port 22 -XThis helped reduce noise from SSH administration traffic while displaying packet contents.
tcpdump -i any src host <source-ip> -XThis limits the displayed traffic to one source IP address.
Before running the Python automation, I practiced managing source-IP blocks directly with iptables.
sudo iptables -A INPUT -s <source-ip> -j DROPsudo iptables -L -n -vsudo iptables -D INPUT -s <source-ip> -j DROPsudo iptables -FThis helped demonstrate the difference between monitoring traffic and actively preventing a source from completing a connection.
I created a project directory and Python file:
mkdir firewall
cd firewall
nano firewall_try_harder.pyI then attempted to install Scapy.
sudo apt install python3-pip
pip install scapyThe initial installation process produced environment and dependency errors. To avoid changing system-wide Python packages, I created a virtual environment.
python3 -m venv ./firewall_venvWhen virtual-environment support was unavailable, I installed it:
sudo apt install python3.12-venvI removed the incomplete environment and created it again:
rm -rf firewall_venv/
python3 -m venv ./firewall_venvI then activated it and installed Scapy:
source firewall_venv/bin/activate
pip install scapyThis troubleshooting process helped me practice reading Linux error messages, managing dependencies, and isolating Python packages.
The script is available here:
I ran it from the configured Python environment:
sudo python3 firewall_try_harder.pyElevated permissions were required because the script inspected network packets and modified firewall rules.
The Python dependency is recorded in:
Install it with:
pip install -r requirements.txtThe supplied script combines packet inspection and firewall automation.
The packet handler looks for TCP packets whose flags indicate a SYN packet:
if TCP in packet and packet[TCP].flags == "S":It then extracts:
- Source IP address
- Source port
- Destination port
The script maintains a counter and timestamp for each observed source address.
scan_tracker = defaultdict(
lambda: {"count": 0, "timestamp": None}
)Each matching SYN packet increases the sourceβs count.
The blocking condition is:
if scan_tracker[src_ip]["count"] > 5:This means the blocking path begins when the sourceβs count becomes greater than five.
The script adds the following type of rule:
sudo iptables -A INPUT -s <source-ip> -j DROPIt first checks whether the address appears to already be blocked so that it does not repeatedly add the same rule.
The configured block duration is ten minutes:
BLOCK_DURATION = timedelta(minutes=10)The script records an unblock time and later removes the rule:
sudo iptables -D INPUT -s <source-ip> -j DROPBefore the blocking threshold is exceeded, the script creates:
- A SYN-ACK packet
- A follow-up packet containing the text:
try harder
This is an experimental packet-level behavior intended for the lab. It is most appropriately observed through packet capture and should not be treated as a normal application response or a production security control.
After running the script, I reviewed the active rules using:
sudo iptables -L -n -vThis allowed me to see addresses that had been added to the firewallβs DROP rules.
The intended process was:
Repeated SYN activity
β
Source counter exceeds threshold
β
DROP rule is added
β
Source traffic is blocked
β
Ten-minute duration expires
β
DROP rule is removed
I created a separate analysis explaining the supplied scriptβs components, strengths, and technical limitations:
The analysis covers:
- Packet inspection
- Per-source counters
- Firewall commands
- Temporary blocking
- Threading
- In-memory state
- Packet crafting
- IPv4 assumptions
- Rule persistence
- False-positive risks
The tutorial discusses detecting scans across multiple ports, but the supplied script increases the count for every matching SYN packet from an IP address.
It does not maintain a set of unique destination ports.
This means several legitimate TCP connections from one source could potentially trigger the threshold.
The threshold and ten-minute duration are hard-coded.
The script does not consider:
- Baseline network behavior
- Type of service
- Trusted sources
- Unique destination ports
- Source reputation
- Known vulnerability scanners
The script does not automatically exclude:
- Administrative systems
- Monitoring tools
- Approved scanners
- Local management addresses
- Other trusted sources
Counters and unblock tasks are lost if the script stops or the VM restarts.
Rules added through iptables may not survive a restart unless firewall persistence is configured separately.
The script needs substantial permissions to capture packets and change firewall rules. A coding error or incorrect configuration could interfere with legitimate network access.
Manually creating SYN-ACK and data packets can interact unpredictably with the operating systemβs TCP stack.
The playful try harder response is useful for demonstrating packet construction, but a serious defensive implementation would normally prioritize logging, blocking, alerting, and evidence preservation.
This lab helped me understand the relationship between:
Network traffic
β
Packet inspection
β
Detection logic
β
Firewall action
I gained experience with:
- Monitoring SYN traffic
- Understanding the beginning of a TCP connection
- Managing Linux firewall rules
- Reading an existing Python security script
- Installing Python dependencies
- Creating virtual environments
- Troubleshooting Linux configuration errors
- Connecting packet observations to an automated response
- Evaluating the limitations of a security tool
One of the largest takeaways was that automation should be evaluated carefully. Automatically blocking an address may reduce unwanted activity, but poorly defined thresholds can also interrupt legitimate traffic.
- Linux administration
- Python fundamentals
- Scapy
tcpdumpiptables- TCP/IP
- SYN packet analysis
- Packet inspection
- Firewall-rule management
- Python virtual environments
- Dependency troubleshooting
- Network-defense fundamentals
- Security automation
- Technical documentation
- Code analysis
- The project followed a public tutorial
- The original script was not authored by me
- I completed the defensive portion only
- I used my own VM instead of recreating the DigitalOcean environment
- I did not reproduce the separate attacker machine
- The original screenshots were not preserved
- Exact traffic and blocking metrics were not recorded
- The script was not tested as a production security control
- No formal false-positive analysis was performed
- No company systems or production data were involved
Additional details are available here:
View Limitations and Future Improvements
These were not part of the original completed tutorial. They are later ideas for improving the concept:
- Count unique destination ports rather than all SYN packets
- Use a defined detection time window
- Add trusted-source allowlisting
- Use a dedicated firewall chain
- Add structured JSON logging
- Save state across restarts
- Add safer shutdown and firewall cleanup
- Add IPv6 support
- Make the threshold and duration configurable
- Separate detection logic from firewall commands
- Add unit tests
- Test normal activity for false positives
- Add alert notifications
- Preserve screenshots and quantitative results
- Remove the playful packet response from a serious version
Only run packet-capture, network-scanning, and firewall-testing tools on systems and networks you own or are explicitly authorized to test.
Incorrect firewall automation can interrupt legitimate access, including your own administrative connection to the VM.
scapy-iptables-firewall-lab/
βββ README.md
βββ THIRD_PARTY_NOTICE.md
βββ requirements.txt
βββ src/
β βββ firewall_try_harder.py
βββ documentation/
β βββ lab-process.md
β βββ code-analysis.md
β βββ limitations-and-future-improvements.md
βββ third-party-licenses/
βββ firewall_try_harder-LICENSE
I completed this project independently as a personal home lab by following the credited tutorial.
My original notes recorded the commands, defensive setup, Python environment troubleshooting, script execution, tutorial transcript, and source links.
I later created this GitHub repository to:
- Organize the surviving documentation
- Make the substantial Python script easy to locate
- Preserve the original attribution and license
- Explain what I personally completed
- Analyze how the supplied code works
- Document limitations and possible improvements
- Avoid presenting third-party code as my own