Homelab — Cowrie
Cowrie SSH Honeypot Cloud-to-SIEM Threat Intelligence Lab
Homelab — Cowrie
Cowrie SSH Honeypot Cloud-to-SIEM Threat Intelligence Lab
Medium-interaction SSH honeypot deployed on AWS EC2, streaming live attacker telemetry through Tailscale mesh VPN to a hybrid SIEM stack (Splunk Enterprise + Wazuh) running on-premise. Built to capture, analyze, and visualize real-world brute-force attacks against exposed infrastructure.

Project Goals
This lab was built as part of my Cybersecurity Officer studies at Technigo to demonstrate hands-on capability in:
- Deception technology Deploy a honeypot that survives internet exposure
- Cloud security Secure a public-facing service while keeping admin access private. Learn about cloud hosting.
- SIEM integration Manage logs input to SIEM on homelab from VPS.
- Threat intelligence Analyze real attacker behavior on my honeypot to gather information.
- Blue-team practice Custom detection rules, dashboards, and incident triage
The result is a live threat intel source capturing SSH brute-force attacks in real time, with all findings queryable in Splunk and Wazuh.
Architecture
┌─────────────────────────────────────┐
│ Internet (port 22) │
└────────────────┬────────────────────┘
│
▼
┌────────────────────────────────────────────────┐
│ AWS EC2 (Ubuntu 22.04, t2.micro) │
│ ┌─────────────────────────────────────────┐ │
│ │ Cowrie 2.9.12 (port 22, via authbind) │ │
│ │ └─→ /opt/cowrie/var/log/cowrie.json │ │
│ └────────────────────┬────────────────────┘ │
│ │ │
│ ┌────────────────────┴────────────────────┐ │
│ │ Splunk UF 10.2.2 │ Wazuh Agent 4.x │ │
│ └────────┬─────────────────────┬──────────┘ │
└───────────┼─────────────────────┼──────────────┘
│ │
▼ ▼
┌────────────────────────────────────────┐
│ Tailscale Mesh VPN (100.x.x.x) │
└────────────────────┬───────────────────┘
│
▼
┌────────────────────────────────────────────────┐
│ Home Lab (Proxmox on HP EliteDesk G3) │
│ │
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ Splunk Enterprise│ │ Wazuh Manager │ │
│ │ (LXC 103) │ │ (VM 201) │ │
│ │ port 9997 / 8k │ │ ports 1514/1515 │ │
│ └──────────────────┘ └──────────────────┘ │
│ │
│ Dashboards │ Alerts │ Rules │ Forensics │
└────────────────────────────────────────────────┘
Admin SSH (port 2222) is locked to a single IP via AWS Security Group. Port 22 is deliberately exposed to attract attackers. Authbind allows the unprivileged cowrie user to bind port 22 without root minimizing blast radius if the honeypot is compromised.
Tech Stack
Layer Technology Cloud compute AWS EC2 (Ubuntu 22.04 LTS, t2.micro) Honeypot Cowrie 2.9.12 (Python/Twisted) Privilege separation authbind (non-root bind to port 22) Splunk Universal Forwarder 10.2.2 Wazuh Agent Transport Tailscale WireGuard mesh VPN SIEM 1 Splunk Enterprise (on-prem LXC) SIEM 2 Wazuh 4.x Manager (on-prem VM) Home hypervisor Proxmox VE
Deployment Walkthrough
1. AWS EC2
Spun up a t2.micro Ubuntu 22.04 instance in EC2. Two security group rules:
Port Source Purpose 22 TCP 0.0.0.0/0 Honeypot deliberately exposed
2222 TCP Admin IP Real SSH IP-restricted
Moved the real OpenSSH to port 2222 via /etc/ssh/sshd_config so port 22 is free for Cowrie.
2. Cowrie Install (git clone method)
sudo apt install -y git python3-venv libssl-dev libffi-dev build-essential \\
libpython3-dev python3-minimal authbind
sudo adduser --disabled-password cowrie
sudo su - cowrie
git clone <https://github.com/cowrie/cowrie.git> /opt/cowrie
cd /opt/cowrie
git checkout v2.9.12
python3 -m venv cowrie-env
source cowrie-env/bin/activate
pip install --upgrade pip
pip install -e .
3. Authbind (non-root bind to port 22)
sudo apt install -y authbind
sudo touch /etc/authbind/byport/22
sudo chown cowrie:cowrie /etc/authbind/byport/22
sudo chmod 770 /etc/authbind/byport/22
Starting Cowrie with authbind wrapping inherits the preload into all child processes (--deep is essential because Twisted spawns subprocesses):
authbind --deep cowrie start
4. Cowrie Configuration
Key changes in /opt/cowrie/etc/cowrie.cfg:
[honeypot]
hostname = webserver01
[ssh]
listen_endpoints = tcp:22:interface=0.0.0.0
5. Realistic Credential Policy
Default Cowrie accepts almost any credentials and even “no password”, which floods logs with meaningless successes and gives to much successfull login intel. Custom etc/userdb.txt built around three principles:
- Deny trivial guesses (
root/root,root/123456, etc.) forces bots to work a bit harder - Allow realistic but guessable passwords so bots eventually succeed and we can log shell activity
- Deny everything else (removed the
:*:*fallback)
# Deny trivial guesses
root:x:!root
root:x:!123456
root:x:!password
root:x:!toor
root:x:!admin
# Allow realistic (but easy to brute force) passwords
root:x:admin123
root:x:P@ssw0rd2024
root:x:webserver01
admin:x:admin123
ubuntu:x:ubuntu
phil:x:phil123
# Deny everything else (including empty)
*:*:!
Gotcha logged: Cowrie’s userdb parser uses ASCII codec. Swedish characters (å/ä/ö) in comments crash the auth handler with
UnicodeDecodeError. Kept all comments ASCIIonly.
6. Decoy Files (Rickroll)
Planted base64-encoded rickroll URLs in plausible locations to trap curious attackers.
fsctl /opt/cowrie/src/cowrie/data/fs.pickle
> cd /root
> touch backup_urls.txt
> touch .bash_history
> cd /home/phil && mkdir .config && cd .config
> touch deploy.conf
Example decoy /root/backup_urls.txt:
# Production server backup locations
# Encoded for security - decode with: base64 -d
Primary backup endpoint:
aHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1kUXc0dzlXZ1hjUQo=
The base64 decodes to a youtube link with a classic rickroll.
Future Improvement: replace these with Canarytokens to receive email notifications when an attacker decodes and visits the URL. Converts decoys into active alerts.
7. Tailscale Mesh VPN
Installed Tailscale on both AWS EC2 and the on-prem Wazuh VM (Splunk LXC was already on the tailnet). This eliminates exposing Splunk/Wazuh ports to the public internet while allowing cross-site log shipping over encrypted tunnels.
curl -fsSL <https://tailscale.com/install.sh> | sh
sudo tailscale up
8. Splunk Universal Forwarder
Installed Splunk UF 10.2.2 as the splunkfwd user:
cd /opt && sudo tar xzf splunkforwarder-*.tgz
sudo chown -R splunkfwd:splunkfwd /opt/splunkforwarder
sudo -u splunkfwd /opt/splunkforwarder/bin/splunk start \\
--accept-license --answer-yes --no-prompt
sudo -u splunkfwd /opt/splunkforwarder/bin/splunk add forward-server \\
100.104.168.45:9997 -auth admin:<pass>
sudo -u splunkfwd /opt/splunkforwarder/bin/splunk add monitor \\
/opt/cowrie/var/log/cowrie/cowrie.json \\
-index cowrie -sourcetype cowrie -auth admin:<pass>
sudo /opt/splunkforwarder/bin/splunk enable boot-start \\
-user splunkfwd -systemd-managed 1 -create-polkit-rules 1
On the Splunk indexer, /opt/splunk/etc/system/local/props.conf:
[cowrie]
KV_MODE = json
TIME_FORMAT = %Y-%m-%dT%H:%M:%S.%6NZ
TIME_PREFIX = "timestamp":"
SHOULD_LINEMERGE = false
9. Wazuh Agent
Deployed via the Wazuh dashboard’s “Deploy new agent” wizard (generates exact install command with manager address and agent name).
Added Cowrie log to /var/ossec/etc/ossec.conf:
<localfile>
<log_format>json</log_format>
<location>/opt/cowrie/var/log/cowrie/cowrie.json</location>
</localfile>
Enabled full archive mode on the manager by setting <logall_json>yes</logall_json> in ossec.conf so all Cowrie events are captured (not just rule-matched alerts).
Splunk Dashboard
The Splunk dashboard Cowrie Honeypot Overview surfaces the metrics a SOC analyst actually cares about:

Example attack case study
One attacker from 47.114.107.233 (Alibaba Cloud, China) generated 347 events in under an hour, a clear automated brute-force pattern. Analysis query:
index=cowrie src_ip="47.114.107.233" (eventid=cowrie.login.failed OR eventid=cowrie.login.success)
| stats count by username, password
| sort - count
Lessons Learned
Documented gotchas that cost time during deployment, worth knowing before attempting this yourself:
- Cowrie startup scripts moved —
bin/cowrie startwas replaced by thecowriepip entry point. Install withpip install -e .and invoke directly. - Github vs Docker, Deployed through docker my first time but was very limited in adjusting content and password etc. Prefered way in git clone install.
- userdb.txt is ASCII-only, if you´re Swedish like me write in english.
- Honeyfs files won’t show in
lsunless they're also added tofs.pickleviafsctlorcreatefs. - Wazuh only stores rule-matched events by default — enable
<logall_json>yes</logall_json>or write custom rules to surface events. - AWS default public IPs change on instance stop/start — allocate an Elastic IP (or accept occasional rebinding pain).
- scp uses
Pfor port, ssh usesp— yes, this is inconsistent; yes, it will catch you out. - Admin SSH must stay IP-locked when port 22 is opened to
0.0.0.0/0— otherwise you compete with attackers on the same port.
메타데이터
- post_id
- 07d71fd4f59b
- slug
- homelab-cowrie-07d71fd4f59b
- url
- https://medium.com/@ipzen/homelab-cowrie-07d71fd4f59b
- canonical_url
- https://medium.com/@ipzen/homelab-cowrie-07d71fd4f59b
- author_url
- https://medium.com/@ipzen
- status
- ok
- fetched_at
- 2026-07-11 02:55:32