Cowrie SSH and Telnet Honeypot on AWS User Guide
Overview
This image runs Cowrie, the open source medium interaction SSH and Telnet honeypot. Cowrie presents a convincing but entirely sandboxed fake UNIX shell, so anyone who brute forces their way in is given a realistic environment while every login attempt, every command they run, and every file they try to download is recorded. It is one of the most widely deployed honeypots for studying automated attacks and for placing an early warning tripwire inside a network. The image is delivered as a ready to use appliance: cowrie.service is enabled and starts on boot, so the moment you connect over SSH the honeypot is already listening.
This is a headless service. There is no web interface. Cowrie's decoy SSH listens on port 2222 and its decoy Telnet on port 2223. These decoy ports are deliberately separate from the real administrative sshd on port 22, so deploying the honeypot never interferes with how you manage the instance. The image never redirects port 22 to the honeypot. Because a honeypot should only ever be exposed on purpose, the shipped security group opens port 22 only: the decoy ports are closed until you deliberately open them.
There are no shared or baked in host identities. Cowrie ships no real login credential, and a fresh decoy SSH host key is generated on each instance's first boot so honeypots do not all share one fingerprint. Every interaction is written as a structured JSON event you can ship to your SIEM or analytics pipeline.
The honeypot's home, including its captured logs, replayable session recordings and downloaded payload samples, is placed on a dedicated, independently resizable EBS data volume mounted at /home/cowrie, so a busy sensor's growing evidence store lives on durable storage you can expand without touching the boot volume.
Prerequisites
Before you deploy this image you need:
- An Amazon Web Services account where you can launch EC2 instances
- IAM permissions to launch instances, create security groups, and subscribe to AWS Marketplace products
- An EC2 key pair in the target Region for SSH access to the instance
- A VPC and subnet in the target Region, with a security group allowing inbound port 22 from your management network
- The AWS CLI (version 2) installed locally if you plan to deploy from the command line
Step 1: Launch the Instance from the AWS Marketplace
Sign in to the AWS Management Console, open the EC2 service, and select Launch instance. Under Application and OS Images choose AWS Marketplace AMIs and search for Cowrie. Select the cloudimg listing and choose Select, then Continue on the subscription summary.
Pick an instance type of m5.large or larger. Choose your EC2 key pair under Key pair (login). Under Network settings select your VPC and subnet, and either create or select a security group that opens port 22 from your management network. Leave the root volume at the default size or larger.
Select Launch instance. First boot initialisation takes a short time after the instance state becomes Running and the status checks pass: the image resolves the instance address, writes the per instance welcome notes, generates a unique decoy host key, and starts the honeypot.
Step 2: Launch the Instance from the AWS CLI
The following block launches an instance from the cloudimg Cowrie Marketplace AMI into an existing subnet and security group. Replace <ami-id> with the AMI ID shown on the Marketplace listing, <key-name> with your EC2 key pair name, <subnet-id> with your subnet ID, and <security-group-id> with a security group that opens port 22 from your management network.
aws ec2 run-instances \
--image-id <ami-id> \
--instance-type m5.large \
--key-name <key-name> \
--subnet-id <subnet-id> \
--security-group-ids <security-group-id> \
--metadata-options "HttpTokens=required" \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=cowrie}]'
When the instance state is Running and both status checks pass, note its public or private IP address for the SSH step.
Step 3: Connect over SSH
Connect to the instance on the real administrative port 22 with your key pair. This is your normal, untouched admin access; it is not the honeypot. The login user depends on the operating system variant you launched.
Connecting to your instance
| OS variant | SSH login user |
|---|---|
| Ubuntu 24.04 | ubuntu |
ssh -i /path/to/<key-name>.pem ubuntu@<public-ip>
Step 4: Read the Per-Instance Welcome Notes
On first boot the image writes a root only notes file recording this instance's decoy ports and the paths where captured evidence is stored. It is an information file, not a credential file: Cowrie ships no real login secret.
sudo cat /root/cowrie-info.txt
You will see the decoy SSH and Telnet port numbers, the JSON and text event log paths, the session recording and downloaded payload directories, and the fake user database path:
# Cowrie 3.0.8 - generated on first boot. Unique to this instance.
COWRIE_ADMIN_SSH_PORT=22
COWRIE_SSH_DECOY_PORT=2222
COWRIE_TELNET_DECOY_PORT=2223
COWRIE_JSON_LOG=/home/cowrie/cowrie/var/log/cowrie/cowrie.json
COWRIE_TTY_DIR=/home/cowrie/cowrie/var/lib/cowrie/tty
COWRIE_USERDB=/home/cowrie/cowrie/etc/userdb.txt
Step 5: Confirm the Honeypot Is Running
Check that the honeypot service is active:
systemctl is-active cowrie.service
The command returns active. For the full unit detail, including the Python process running the honeypot:

systemctl status cowrie.service --no-pager
Step 6: See the Two Separate SSH Surfaces
The whole point of this image is that the decoy SSH and your real administrative SSH are two entirely separate listeners. Confirm all three ports are bound: the real sshd on 22, the decoy SSH on 2222, and the decoy Telnet on 2223.
ss -ltn | grep -E ':(22|2222|2223)\b'
The decoy SSH deliberately presents a fake server identity so it looks like a different, older machine to an attacker, while the admin sshd on port 22 is your genuine access. You can see the two banners side by side:

echo "decoy SSH 2222:"; timeout 8 bash -c 'exec 3<>/dev/tcp/127.0.0.1/2222; head -1 <&3' | tr -d '\r'
echo "admin sshd 22:"; timeout 8 bash -c 'exec 3<>/dev/tcp/127.0.0.1/22; head -1 <&3' | tr -d '\r'
Step 7: Open the Decoy Ports to Start Attracting Activity
The shipped security group opens port 22 only, so out of the box nothing can reach the decoy. To begin luring and logging activity, open the decoy ports in the instance security group to the networks you want to observe. Only ever expose a honeypot deliberately and to networks you understand. Replace <security-group-id> with your instance's security group and <your-mgmt-cidr> with the range you want to watch.
aws ec2 authorize-security-group-ingress \
--group-id <security-group-id> \
--ip-permissions \
IpProtocol=tcp,FromPort=2222,ToPort=2223,IpRanges='[{CidrIp=<your-mgmt-cidr>}]'
Step 8: Watch a Captured Session in the JSON Event Log
Every connection, login attempt, command and download is written to the JSON event log as it happens. Tail it and watch the events arrive:
sudo tail -n 20 /home/cowrie/cowrie/var/log/cowrie/cowrie.json
A successful brute force login and the commands that follow appear as structured events, ready for a SIEM or analytics pipeline:

The cowrie.login.success event records the username and password the attacker tried, and each cowrie.command.input event records exactly what they ran inside the emulated shell.
Step 9: Replay a Recorded Session
Cowrie records each interactive session as a replayable TTY log under the session recordings directory. List the recordings, then replay one with the bundled playlog tool. Replace <session-id> with a filename from the listing.
sudo -u cowrie /home/cowrie/cowrie/bin/playlog /home/cowrie/cowrie/var/lib/cowrie/tty/<session-id>
Step 10: Tune the Fake User Database
Which username and password combinations the honeypot accepts is controlled by the fake user database at /home/cowrie/cowrie/etc/userdb.txt. Each line is a rule; the shipped default accepts common brute force guesses so the honeypot is inviting out of the box. To make the honeypot pickier or more permissive, edit this file and restart the service. Because this modifies the running honeypot, run it only when you are ready.
sudo -u cowrie nano /home/cowrie/cowrie/etc/userdb.txt # edit your accept/deny rules
sudo systemctl restart cowrie.service # apply the changes
Step 11: Optionally Expose the Decoy on the Standard SSH Port
Some operators want the decoy to answer on the standard SSH port 22 so it catches untargeted scans. Because port 22 is your real administrative access, first move your admin sshd to another port and confirm you can still log in there, then redirect inbound port 22 traffic to the decoy on 2222. This changes how you reach the instance, so plan it carefully. Replace <admin-port> with the new administrative port you have moved sshd to.
# Only AFTER you have moved your admin sshd to <admin-port> and confirmed access there:
sudo iptables -t nat -A PREROUTING -p tcp --dport 22 -j REDIRECT --to-port 2222
Step 12: The Captured Evidence and the Data Volume
The entire honeypot home at /home/cowrie, including the JSON and text logs, the TTY session recordings and any downloaded payload samples, lives on a dedicated, independently resizable EBS data volume rather than the operating system root. Confirm it is its own filesystem:
findmnt /home/cowrie
Because the evidence store is on its own disk, you can grow it as your sensor collects more data without touching the boot volume, and snapshots of just the evidence are simple to take.
Support
This image is published by cloudimg with 24/7 technical support by email and chat. We can help with the decoy service configuration, the fake filesystem and user database, JSON and SIEM output, session replay, downloaded payload handling, opening and placing the decoy ports safely, backups, and upgrade planning.
Cowrie is distributed under the BSD 3-Clause License. cloudimg is not affiliated with or endorsed by the Cowrie project or its authors. All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.