Brute-force login attacks on web admin panels happen constantly in the wild. What if you could catch them in real time — watching the exact moment someone hammers your login page? That's exactly what I set up here.

In this walkthrough, I'll show you how to deploy a password-protected Apache web server on Ubuntu, simulate failed login attempts from a Kali Linux machine, and write custom Snort3 rules that fire alerts the moment those attempts hit your network. You'll see both the fast log and full log format outputs — side by side.

This is a hands-on, practical setup. Every command here was actually run and verified.


Problem Statement

Default web servers expose their admin pages with zero intrusion visibility. An attacker can keep hammering /admin with wrong credentials for hours, and without a detection layer, you'd never know. The goal here is to:

  1. Set up a realistic web server with a password-protected /admin endpoint
  2. Simulate unauthorized access from a separate attacker machine
  3. Write Snort3 detection rules that catch those attempts in real time

Lab Environment

Machine OS Role
Ubuntu (Server) Ubuntu 24.x Web server + Snort3 IDS
Kali Linux (Attacker) Kali 2025/2026 Attack simulation
Network Host-only / NAT VirtualBox

Step 1 — Install and Verify Apache2

On the Ubuntu machine, start by installing the Apache web server and the utilities package needed for password protection:

sudo apt update
sudo apt install apache2 -y
sudo apt install apache2-utils -y
Enter fullscreen mode Exit fullscreen mode

Verify Apache is running:

sudo systemctl status apache2
Enter fullscreen mode Exit fullscreen mode

You should see Active: active (running) in the output.


Step 2 — Create the Admin Web Page

Apache serves files from /var/www/html/. Create a new directory for the admin area and set up a basic HTML page:

sudo mkdir /var/www/html/admin
sudo nano /var/www/html/admin/index.html
Enter fullscreen mode Exit fullscreen mode

Paste this minimal HTML:

<!DOCTYPE html>
<html>
<body>
    Welcome to Admin Page
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Save and exit. Then remove the default Apache index page to keep things clean:

sudo rm /var/www/html/index.html
Enter fullscreen mode Exit fullscreen mode


Step 3 — Password-Protect the Admin Directory

Create an admin user with a password. The -c flag creates a new password file:

sudo htpasswd -c /etc/apache2/.htpasswd adminuser
Enter fullscreen mode Exit fullscreen mode

You'll be prompted to enter and confirm a password (e.g., 1234). Then set the correct permissions on the admin folder:

sudo chmod -R 755 /var/www/html/admin
Enter fullscreen mode Exit fullscreen mode


Step 4 — Configure Apache to Protect the Admin Route

Edit the default Apache virtual host config:

sudo nano /etc/apache2/sites-available/000-default.conf
Enter fullscreen mode Exit fullscreen mode

Add the following block inside the <VirtualHost *:80> section:

<Directory "/var/www/html/admin">
    AuthType Basic
    AuthName "Restricted Admin Area"
    AuthUserFile /etc/apache2/.htpasswd
    Require valid-user
</Directory>
Enter fullscreen mode Exit fullscreen mode

Enable the headers module and restart Apache:

sudo a2enmod headers
sudo systemctl restart apache2
sudo systemctl status apache2
Enter fullscreen mode Exit fullscreen mode


Step 5 — Confirm the Admin Page is Live

Check Ubuntu's IP address:

ip a
Enter fullscreen mode Exit fullscreen mode

Note the IP (e.g., 192.168.1.104). Then from the Kali machine, open a browser and navigate to:

http://<UBUNTU_IP>/admin
Enter fullscreen mode Exit fullscreen mode

You should see a browser login prompt asking for username and password.


Step 6 — Write the Custom Snort3 Detection Rule

Back on Ubuntu, open the local Snort rules file:

sudo nano /usr/local/etc/rules/local-rules/local.rules
Enter fullscreen mode Exit fullscreen mode

Add this rule to detect HTTP traffic to port 80 that contains an Authorization header — which is what HTTP Basic Auth sends on every login attempt:

alert tcp any any -> any 80 (
    msg:"Unauthorized Access to admin page";
    content:"Authorization";
    sid:1000011;
    rev:2;
)
Enter fullscreen mode Exit fullscreen mode

What this rule does:

  • alert tcp any any -> any 80 — watches all TCP traffic heading to port 80
  • content:"Authorization" — matches the HTTP header browsers send during Basic Auth login attempts
  • msg — the label you'll see in the alert log
  • sid — unique Snort rule ID


Step 7 — Validate the Snort3 Configuration

Before running Snort live, always test the config:

snort -c /usr/local/etc/snort/snort.lua -T
Enter fullscreen mode Exit fullscreen mode

Look for this at the end of the output:

Snort successfully validated the configuration (with 0 warnings).
Enter fullscreen mode Exit fullscreen mode


Step 8 — Start Snort3 in Alert Fast Mode

Run Snort on the active network interface (check yours with ip a — commonly enp0s3):

sudo snort -A alert_fast -i enp0s3 -c /usr/local/etc/snort/snort.lua
Enter fullscreen mode Exit fullscreen mode

Leave this running in one terminal window.


Step 9 — Simulate the Attack (More Than 3 Failed Logins)

On the Kali machine, open the browser and go to http://<UBUNTU_IP>/admin. Click Sign in with wrong credentials at least 4–5 times (all attempts should fail).


Step 10 — Generate Alerts in Full Log Format

Stop the previous Snort instance (Ctrl+C) and restart with the full log format:

sudo snort -A full -i enp0s3 -c /usr/local/etc/snort/snort.lua
Enter fullscreen mode Exit fullscreen mode

Repeat the failed login attempts from Kali. The full format gives you detailed packet-level information including TCP flags, sequence numbers, TTL, and more — useful for deeper analysis.


How to Verify Everything is Working

  • Apache is up: sudo systemctl status apache2 shows active (running)
  • Admin page is protected: Visiting http://<UBUNTU_IP>/admin shows a login popup
  • Snort is detecting: After login attempts, alerts appear in the terminal with the message "Unauthorized Access to admin page"
  • Snort config is valid: snort -c /usr/local/etc/snort/snort.lua -T returns 0 warnings
  • Full log works: Switching to -A full shows packet-level detail per alert

What I Learned

Working through this setup gave me a much clearer picture of how network-level detection actually works in practice. A few things stood out:

HTTP Basic Auth is surprisingly transparent to Snort. Every login attempt sends an Authorization header in cleartext (over HTTP), which makes it trivially detectable with a content-match rule. This reinforces why HTTPS is non-negotiable for anything sensitive.

Snort rules are very literal. The rule fires on every connection that contains the Authorization header — not just failed ones. To detect only failures, you'd need to correlate the server's 401 response, which requires stateful detection or threshold rules. This is a good next step to explore.

Fast vs. Full log formats serve different purposes. The fast format is great for real-time monitoring — clean, one-line-per-alert. The full format is better for post-incident forensics where you need packet details.

Configuration validation saves time. Running snort -T before going live catches rule syntax errors before they silently fail in production.


Common Mistakes

Mistake What Happens Fix
Not running sudo a2enmod headers Apache fails to restart after config edit Run sudo a2enmod headers then restart
Wrong network interface in -i flag Snort captures nothing Use ip a to confirm interface name (e.g., enp0s3)
Rule content keyword mismatch No alerts fire Check the exact string sent in HTTP headers using Wireshark
Using sid that already exists Snort config validation fails Use a unique SID (10000000+ range is safe for custom rules)
Forgetting to clear browser cache Old auth cookies auto-login without triggering alerts Clear cache or use incognito/private mode
Not testing with snort -T first Errors only appear after launching live capture Always validate config before live run

Conclusion

This setup takes under 30 minutes and gives you a fully functional intrusion detection demo for web admin brute-force attempts. The combination of Apache's Basic Auth, a targeted Snort3 content rule, and live packet capture on the interface creates a pipeline you can actually watch in action.

From here, there's a lot to build on — threshold rules to alert only after N attempts, suppression rules to reduce noise, or integrating with a SIEM to store and query alerts. But this foundation shows exactly how the detection layer works at the network level.

If you set this up or tweak the rules, let me know how it went in the comments.