# Cowrie: an SSH and Telnet honeypot that records what attackers actually type

> Cowrie emulates a UNIX shell, proxies SSH and Telnet to a real host, or answers commands through an LLM backend. It suits operators who want session-level attacker data, not a port-scan counter.

**cowrie/cowrie** — Cowrie SSH/Telnet Honeypot https://docs.cowrie.org/

- Repository: https://github.com/cowrie/cowrie
- Website: https://www.cowrie.org/
- Stars: 6,569 · Forks: 1,070
- Language: Python
- License: NOASSERTION
- Published: 2026-09-22 · Updated: 2026-09-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/cowrie-cowrie

## What Cowrie logs that a firewall log cannot

A firewall records that something connected to port 22. Cowrie records what happened next. The README describes it as a medium to high interaction SSH and Telnet honeypot built to log brute force attacks and the shell interaction performed by the attacker. That second half is the point. When someone guesses a password and gets a prompt, Cowrie captures the commands they run, the files they cat, and the payloads they pull down with wget or curl.

The audience is narrow but well defined. Threat researchers who want command-level data. Incident responders who want to know which credentials are being tried against their address space. Operators running deception on a segment that has no legitimate SSH traffic. It is not a tool for hardening a real server, and the README never presents it as one.

## Emulated shell, proxy mode, and the experimental LLM backend

Cowrie has three operating shapes, and they differ in where the attacker's commands actually execute.

In the default emulated shell mode, Cowrie answers in Python. It ships a fake filesystem resembling a Debian 5.0 installation, stored in src/cowrie/data/fs.pickle. That pickle carries both metadata (path, uid, gid, size, mode) and embedded contents for the small files attackers commonly cat, so a request for /etc/passwd returns something plausible. Output for simple fake commands lives in src/cowrie/data/txtcmds/. Files the attacker downloads or uploads land in var/lib/cowrie/downloads/ for later inspection.

In proxy mode, Cowrie forwards SSH and Telnet to another system and monitors the session. The README also describes letting Cowrie manage a pool of QEMU emulated servers to provide the login targets, which pushes the interaction level higher at the cost of running real guests.

The third shape is marked experimental in the README: an LLM backend that uses large language models such as OpenAI GPT to generate shell responses dynamically. The stated advantage is that it handles any command without predefined responses and keeps conversation context across a session. Treat that as a research direction, not a production default. Session logs in all modes are written in a User Mode Linux compatible format and can be replayed with the playlog utility, and audit output goes to var/log/cowrie/cowrie.json as JSON.

## Installing Cowrie with pip and starting a first honeypot

The README gives three installation paths: pip, Docker, and a git checkout, and says pip and Docker are the easiest for a first honeypot. Python 3.10 or newer is required, along with python-virtualenv.

The pip route creates a virtual environment, installs the package, and then uses the cowrie command to write configuration and start the daemon.

```bash
$ mkdir my-honeypot && cd my-honeypot
$ python3 -m venv cowrie-env
$ source cowrie-env/bin/activate
(cowrie-env) $ pip install cowrie
(cowrie-env) $ cowrie init
(cowrie-env) $ cowrie start
```

After `cowrie init`, an etc/cowrie.cfg file exists in the current directory. The README is explicit that this file is operator-owned, and that src/cowrie/data/etc/cowrie.cfg.dist holds the bundled defaults you should not edit. Logs and downloads appear under var/. Credentials that grant access to the honeypot are configured in etc/userdb.txt.

If you would rather try it before committing to an install, the Docker image is on Docker Hub and the README's quick start publishes port 2222.

```bash
$ docker run -p 2222:2222 cowrie/cowrie:latest
$ ssh -p 2222 root@localhost
```

The second command connects to the honeypot on the loopback interface, which is how you confirm the emulated shell answers before exposing anything. Building the image yourself is a separate target, `make docker-build`, and the Makefile allows substituting another container runtime with `DOCKER=podman make docker-build`.

## Where Cowrie is the wrong tool

The emulated filesystem is a snapshot, not a live system. The README describes the bundled fake filesystem as resembling a Debian 5.0 installation and notes that only minimal file contents are included. An attacker who probes hard enough will find gaps, and an outdated distribution banner is itself a signal. If you need every command to behave exactly as it would on a real host, proxy mode or the QEMU pool is the honest answer, and both cost far more to run.

There is also a risk the README does not address: a honeypot that accepts logins and stores uploaded files is holding attacker-supplied binaries. Nothing in the README describes sandboxing for those downloads, so isolating the host is an operational decision you make, not something the project does for you.

The LLM backend deserves separate scepticism. It is labelled experimental, it depends on an external model provider, and it will produce responses that no real UNIX system would produce. For a deception sensor whose value rests on realistic interaction, that is a trade-off worth naming rather than glossing over.

Finally, Cowrie is not a substitute for host security. It logs attackers; it does not stop them from reaching anything else.

## Cowrie against a low-interaction honeypot such as mailoney

The comparison that matters is interaction depth. A low-interaction honeypot listens on a port, accepts a connection, and records the attempt. It is cheap to run and nearly impossible to break out of, because there is almost nothing behind the port.

Cowrie sits a level above that. It emulates a shell, supports SFTP and SCP uploads, handles SSH exec commands, and logs direct-tcp connection attempts. The cost is a larger attack surface and a Python process that has to stay convincing.

Cowrie's own README points at a complementary tool rather than a rival: it can forward SMTP connections to an SMTP honeypot such as mailoney. That is the sensible arrangement. Run a low-interaction listener where you only want to know that a port is being probed, and put Cowrie where you want to read the transcript.

## Maintenance, licensing, and the cost of upgrading

The repository is not archived, and the last push was on 2026-09-21. Releases are frequent: v3.0.13 on 2026-08-24, v3.0.14 on 2026-09-14, and v3.0.15 on 2026-09-21. That cadence is the practical maintenance story, and it also means upgrades arrive often enough that pinning matters.

Dependencies in pyproject.toml and requirements.txt are pinned exactly, including attrs, bcrypt, cryptography, twisted[conch], treq and lark. The Python floor is 3.10 and the ceiling is below 4. The Makefile offers `make pip-upgrade` to move the environment to requirements.txt and `make pip-check` to verify the installed packages, which is the closest thing to an upgrade procedure the README documents.

Licensing needs care. The repository's licence is reported as NOASSERTION, while pyproject.toml declares `license="BSD-3-Clause"` and the source files carry `SPDX-License-Identifier: BSD-3-Clause` headers. The project also carries a LICENSES/ directory and a REUSE.toml, which indicates REUSE-compliant per-file licensing. Read LICENSE.rst and the LICENSES/ directory before redistributing, and get legal advice if the discrepancy matters to you. Nothing here is legal advice.

## Conclusion

Adopt Cowrie if you need attacker command transcripts rather than connection counts, and you can give it an isolated host plus a non-default SSH port. Do not adopt it as a production SSH server, and do not expect the LLM backend to be more than experimental. Verify first that Python 3.10 or newer is available, that port 2222 is free, and that `cowrie init` has written etc/cowrie.cfg in the directory you intend to keep.

## FAQ

### How do I install Cowrie on Ubuntu?

The README lists pip, Docker and a git checkout as the three installation paths, and says pip and Docker are easiest for a first honeypot. The pip route needs Python 3.10 or newer and python-virtualenv, then `pip install cowrie`, `cowrie init` and `cowrie start`.

### How do I install the Cowrie honeypot?

Create a virtual environment, install the cowrie package from PyPI, run `cowrie init` to write etc/cowrie.cfg in the current directory, then `cowrie start`. The README points to the installation guide for full instructions on all three methods.

### How do I install Cowrie?

Either `pip install cowrie` inside a virtual environment or `docker run -p 2222:2222 cowrie/cowrie:latest`. The README recommends a git checkout only for development or advanced scenarios where you want to modify Cowrie itself.

## Sources

- [cowrie/cowrie on GitHub](https://github.com/cowrie/cowrie)
- [Issues](https://github.com/cowrie/cowrie/issues)
- [Project website](https://www.cowrie.org/)
- [README](https://github.com/cowrie/cowrie/blob/main/README.md)
- [Releases](https://github.com/cowrie/cowrie/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/cowrie-cowrie
