Honeynet is a scalable, cloud-native honeypot deployment framework that uses Terraform and Ansible to provision distributed honeypot infrastructure, collect attacker activity, and transform raw logs into centralized threat intelligence.
The current validated implementation uses Cowrie as the active honeypot and AWS as the active cloud target, but the project is structured as a broader framework that can grow to support additional honeypots, richer schemas, and wider multi-cloud deployment over time.
This project is designed to help security teams and researchers:
- deploy honeypots across multiple geographic regions
- capture attacker behavior from realistic cloud targets
- centralize raw logs instead of losing them on instance termination
- enrich attacker activity with external threat intelligence
- query the resulting dataset for investigation and analysis
The currently implemented and validated path is:
Cowrie -> Fluent Bit -> raw S3 -> Lambda enrichment -> enriched S3 -> Glue -> Athena
What is implemented today:
- multi-region EC2 honeypot deployment with Terraform
- Ansible automation for Cowrie installation
- Fluent Bit log forwarding from honeypot nodes into S3
- Lambda-based AbuseIPDB enrichment
- Glue crawler schema discovery
- Athena queries over enriched attack logs
What the framework is intended to support over time:
- additional honeypots such as Dionaea, Conpot, or web honeypots
- additional cloud providers
- normalized schemas across honeypot types
- dashboards and analyst playbooks
- stronger automation and validation around telemetry
Controller / Operator Machine
|
| Terraform + Ansible
v
Multi-region Honeypot Nodes
|
| Cowrie JSON logs
v
Fluent Bit
|
| S3 upload
v
Raw S3 Log Sink
|
| S3 ObjectCreated trigger
v
Lambda Enrichment (AbuseIPDB)
|
v
Enriched S3 Logs
|
| Glue crawler
v
Athena SQL Queries
For more detail, see architecture.md.
honeynet/
├── ansible/
│ ├── inventory.ini
│ ├── playbooks/
│ │ ├── install_honeypot.yml
│ │ └── install_log_forwarder.yml
│ └── templates/
│ ├── cowrie.cfg.j2
│ └── fluent-bit.conf.j2
├── docs/
│ └── architecture.md
├── lambda/
│ └── enrichment/
│ └── handler.py
├── scripts/
│ └── deploy_honeypots.sh
├── terraform/
│ ├── main.tf
│ ├── provider.tf
│ ├── variables.tf
│ └── modules/
│ ├── honeypot/
│ └── telemetry/
└── CONTRIBUTING.md
This section walks through the full local environment setup from AWS login through deployment and testing.
Install the following on your local machine:
- Git
- Terraform 1.5+
- Ansible
jq- AWS CLI v2
- SSH client
Recommended verification:
git --version
terraform version
ansible --version
jq --version
aws --version
ssh -VYou need an AWS account with permission to manage:
- EC2
- IAM
- S3
- Lambda
- Secrets Manager
- Glue
- Athena
- CloudWatch Logs
If you are using IAM Identity Center, federated login, or an IAM user, make sure the credentials you use locally can create and modify these resources.
Configure AWS CLI locally:
aws configureProvide:
- AWS Access Key ID
- AWS Secret Access Key
- default region, for example
us-east-1 - output format, for example
json
Verify the active identity:
aws sts get-caller-identityIf that command fails, fix AWS authentication before trying to deploy the project.
Create a dedicated SSH keypair if you do not already have one:
ssh-keygen -t ed25519 -f ~/.ssh/honeynet_keyThis gives you:
- private key:
~/.ssh/honeynet_key - public key:
~/.ssh/honeynet_key.pub
The current Terraform defaults expect the public key path defined in variables.tf. Update that variable if your key lives elsewhere.
The enrichment Lambda uses AbuseIPDB to append threat intelligence fields to attacker IPs.
Create an account at:
https://www.abuseipdb.com/
Generate an API key and store it locally in an ignored tfvars file.
Create:
terraform/secrets.auto.tfvars
with:
abuseipdb_api_key = "your_abuseipdb_api_key"This file is ignored by git and should never be committed.
git clone https://github.com/c2siorg/honeynet.git
cd honeynetOpen variables.tf and check these values:
name_prefixenvironmentssh_public_key_pathhoneypot_instance_typetelemetry_region
Defaults are provided, but you may want to customize:
- naming
- instance size
- SSH public key path
- environment label
cd terraform
terraform init
terraform validate
cd ..Use the deployment script:
./scripts/deploy_honeypots.shThis script:
- runs
terraform init - runs
terraform apply - reads Terraform outputs
- writes
ansible/inventory.ini - installs Cowrie on the deployed nodes
- installs and configures Fluent Bit on those nodes
After deployment, Terraform should output:
- honeypot IPs
- raw log sink bucket
- enriched logs bucket
- Glue database
- Athena workgroup
- telemetry region
You can re-check outputs manually:
cd terraform
terraform output
cd ..Open AWS EC2 and confirm three instances are present in:
us-east-1eu-west-1ap-south-1
Use the generated inventory or the public IPs to connect as ubuntu:
ssh -i ~/.ssh/honeynet_key ubuntu@<public-ip>On a honeypot node:
sudo systemctl status cowrie --no-pager
sudo journalctl -u cowrie -n 50 --no-pagerTrigger a Cowrie session on port 2222:
ssh root@<public-ip> -p 2222Try a password and run a few commands if Cowrie presents a fake shell, for example:
whoami
ls
uname -a
sudo apt install nginxDepending on the session, Cowrie may provide a fake shell or may terminate after authentication. Both behaviors can still generate attack telemetry.
On the honeypot node:
ls -la /home/ubuntu/cowrie/var/log/cowrie
tail -n 20 /home/ubuntu/cowrie/var/log/cowrie/cowrie.jsonYou should see events such as:
cowrie.session.connectcowrie.login.successcowrie.login.failedcowrie.command.input
On the honeypot node:
sudo systemctl status fluent-bit --no-pager
sudo journalctl -u fluent-bit -n 100 --no-pagerIn AWS S3, check the raw log sink bucket. You should see objects under:
raw/<sensor_id>/YYYY/MM/DD/
Check the Lambda function:
honeynet-ip-enrichment
Review CloudWatch logs:
aws logs tail /aws/lambda/honeynet-ip-enrichment --since 30m --region us-east-1You should see it processing raw objects and writing enriched output.
In the enriched bucket, check for objects under:
enriched/raw/<sensor_id>/YYYY/MM/DD/
Sample enriched fields include:
abuse_scorecountry_codeispdomainis_torenrichment_sourceenriched_at
Start the crawler manually the first time:
aws glue start-crawler --name honeynet-attack-log-crawler --region us-east-1Check status:
aws glue get-crawler --name honeynet-attack-log-crawler --region us-east-1Wait until the crawler state returns to READY.
Use Athena workgroup:
honeynet-attack-analysis
Use database:
honeynet_attacks
Then run queries against table:
enriched
Example:
SELECT src_ip, eventid, input, abuse_score, country_code, isp
FROM enriched
ORDER BY enriched_at DESC
LIMIT 20;More example queries:
SELECT src_ip, COUNT(*) AS attempts
FROM enriched
GROUP BY src_ip
ORDER BY attempts DESC
LIMIT 10;SELECT country_code, COUNT(*) AS attacks
FROM enriched
GROUP BY country_code
ORDER BY attacks DESC
LIMIT 10;SELECT username, password, COUNT(*) AS tries
FROM enriched
WHERE eventid = 'cowrie.login.failed'
GROUP BY username, password
ORDER BY tries DESC
LIMIT 20;The current codebase is validated around Cowrie because it provides a clear SSH interaction path and structured event output. That is the current implemented honeypot, not the architectural limit of the project.
The repo is intentionally moving toward:
- more honeypot types
- richer telemetry normalization
- stronger multi-cloud support
- better analyst workflows on top of enriched data
ansible/inventory.iniis generated during deploymentterraform/modules/telemetry/lambda_enrichment.zipis generated by Terraform and should not be committed- when
lambda/enrichment/handler.pychanges, runterraform applyagain so AWS Lambda is updated - when Terraform modules change, rerun
terraform initif Terraform asks to reinitialize
Check:
- Lambda CloudWatch logs
- S3 bucket notification configuration
- whether Fluent Bit uploads are gzip-compressed and Lambda can read them
Check:
- EC2 instance profile attachment
aws_credentialsmessages injournalctl -u fluent-bit- IAM permissions to the raw log sink bucket
Check:
sudo systemctl status cowrie/home/ubuntu/cowrie/var/log/cowrie/cowrie.json- the deployed Cowrie config template
Check:
- Glue crawler has completed successfully
- the
honeynet-attack-analysisworkgroup is selected - Athena output location is configured
See CONTRIBUTING.md.
This project is licensed under the Apache 2.0 License. See LICENSE for details.