{"id":13594438,"url":"https://github.com/ginger51011/pandoras_pot","last_synced_at":"2025-04-09T07:32:17.436Z","repository":{"id":219169980,"uuid":"744694756","full_name":"ginger51011/pandoras_pot","owner":"ginger51011","description":"HTTP honeypot to punish and educate unruly web crawlers, written in Rust (🚀)","archived":false,"fork":false,"pushed_at":"2024-10-29T18:12:59.000Z","size":333,"stargazers_count":95,"open_issues_count":2,"forks_count":4,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-10-29T20:18:12.052Z","etag":null,"topics":["deception","honeypot","http","rust","server","stress","web"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ginger51011.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-01-17T20:23:55.000Z","updated_at":"2024-10-29T18:11:56.000Z","dependencies_parsed_at":"2024-02-26T20:31:09.500Z","dependency_job_id":"6572bd6f-c36c-49a6-ba2b-dcc865a84346","html_url":"https://github.com/ginger51011/pandoras_pot","commit_stats":null,"previous_names":["ginger51011/pandoras_pot"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ginger51011%2Fpandoras_pot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ginger51011%2Fpandoras_pot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ginger51011%2Fpandoras_pot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ginger51011%2Fpandoras_pot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ginger51011","download_url":"https://codeload.github.com/ginger51011/pandoras_pot/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223375334,"owners_count":17135353,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["deception","honeypot","http","rust","server","stress","web"],"created_at":"2024-08-01T16:01:33.520Z","updated_at":"2024-11-06T16:31:22.849Z","avatar_url":"https://github.com/ginger51011.png","language":"Rust","readme":"\u003cdiv align=\"center\"\u003e\n    \u003ch1\u003e🔥pandoras_pot🍯\u003c/h1\u003e\n    \u003ci\u003eUnleash Unfathomable Curses on Unsuspecting Bots... In Rust!\u003c/i\u003e\n\u003cbr /\u003e\n\u003cbr /\u003e\n\n\n[![GitHub Repo](https://img.shields.io/badge/GitHub-ginger51011%2Fpandoras__pot-FFA400?style=flat\u0026logo=github)](https://github.com/ginger51011/pandoras_pot)\n[![Crates.io (pandoras_pot)](https://img.shields.io/crates/v/pandoras_pot)](https://crates.io/crates/pandoras_pot)\n[![GitHub License](https://img.shields.io/github/license/ginger51011/pandoras_pot)](https://github.com/ginger51011/pandoras_pot/blob/main/LICENSE)\n[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/ginger51011/pandoras_pot/ci.yml)](https://github.com/ginger51011/pandoras_pot/actions/)\n\u003c/div\u003e\n\n# Summary\n\nInspired by [HellPot](https://github.com/yunginnanet/HellPot), `pandoras_pot`\nis an HTTP honeypot that aims to bring even more misery on unruly web crawlers that\ndon't respect your `robots.txt`.\n\nThe goal with `pandoras_pot` is to have maximum data output sent to incoming\nunwanted connections, while not using up all the resources of your webserver\nthat probably could be doing better things with its time.\n\nTo ensure that bots don't detect `pandoras_pot`, it generates random data that kind\nof looks like a website (to a bot), really *really* fast. Like crazy fast. One could even\nsay blazingly fast. *Hopefully*.\n\n`pandoras_pot` supports multiple modes of generation, depending on its\nconfiguration. It can for example generate random strings as data, or \"actual\"\nsentances using Markov chains. Neato!\n\n# Features\n\n- Blazingly fast\n- Written in Rust\n- TOML configuration format, see example below (but sane defaults without config!)\n- Optional health port, for reverse proxy health checks\n- Multiple generator modes, and it is very easy to add more! Send plain random data, text generated using Markov chains, or a static file!\n- Configurable abuse protection (max concurrent producing connections, time and size limits)\n- Did I mention that it is written in Rust?\n\n# Setting it up\n\n## Web and Reverse Proxy\n\nThe most likely use-case is to use another server as a reverse proxy, and then\nselect some paths that should be forwarded to `pandoras_pot`, like\n`/wp-login.php`, `/.git/config`, and `/.env`.\n\nNote that the URIs you use should have `Disallow` set in your `/robots.txt`,\notherwise you might get in trouble from things like googlebot who will dislike\nyour strange page of death. For the paths above, you could have a `robots.txt`\nlike the one below:\n\n```\nUser-agent: *\nDisallow: /wp-login.php\nDisallow: /.git\nDisallow: /.env\n```\n\nCommon reverse proxies include `nginx`, `httpd` (apache), and `Caddy`.\n\nIn Caddy you could add the following to match the `/robots.txt` we have already created:\n\n```Caddyfile\n(pandorust) {\n    @pandorust_paths {\n        path /wp-login.php /.git* /.env*\n    }\n    handle @pandorust_paths {\n        reverse_proxy localhost:6669 # Or whatever you run pandoras_pot on\n    }\n}\n\n# ...\n\nexample.com {\n    # ...\n    # Your actual website\n    # ...\n\n    import pandorust\n}\n```\n\nAfter this you can simply run (if you installed using `cargo install pandoras_pot`):\n\n```sh\npandoras_pot --help\n```\n\nto get more info.\n\nDone!\n\n## Using Docker\n\nThe easiest way to set up `pandoras_pot` is using docker. You can optionally\npass an argument to a config file using the docker `--build-arg CONFIG=\u003cpath to\nyour config\u003e` flag (but it should be available in the build context).\n\nStart by cloning the repo by running\n\n```sh\ngit clone git@github.com:ginger51011/pandoras_pot.git\ncd pandoras_pot\n```\n\nThen you can build an image and deploy it, here naming and tagging it with `pandoras_pot`\nand making it available on port `localhost:6669`:\n\n```sh\ndocker build -t pandoras_pot . # You can add --build-arg CONFIG=\u003c...\u003e here\ndocker run --name=pandoras_pot --restart=always -p 6669:8080 -d pandoras_pot\n```\n\n## `systemd` Service\n\nYou can also easily set up a `systemd` service. This requires you to\n[install Rust](https://www.rust-lang.org/tools/install), but requires one less\nbloated docker image and makes reloading configurations easier. In this example\nI will set up a new user, `pandora-user`, but you can use any user you want\n(but we will lock `pandora-user` down).\n\n_Note: With the exception of cloning and building pandoras_pot, most commands here\nwill require root._\n\nStart by cloning the repo and building `pandoras_pot` (after installing Rust):\n\n```sh\ngit clone git@github.com:ginger51011/pandoras_pot.git\ncd pandoras_pot\ncargo build --release\n\n# Move the binary to a better place\ncp ./target/release/pandoras_pot /usr/bin/\n```\n\nWe then create the user that will run the process; this user won't be root and\ncannot even login:\n\n```sh\nadduser --disabled-password --gecos '' --shell /sbin/nologin --no-create-home --home /iamadirandidontexist 'pandora-user'\n```\n\nThen we create a directory to keep our configuration (and also things like the\n`data` file for some generators):\n\n```sh\nmkdir /etc/pandoras_pot\n\n# Ensure the config file exists; you can copy the default one in this README\n# into this file\ntouch /etc/pandoras_pot/config.toml\n\n# Optionally you can create your data file here. You need to point to it from\n# the config.\n\n# Make pandora-user the owner of this dir\nchown -R pandora-user:pandora-user /etc/pandoras_pot\n```\n\nNow we create the actual service. If you have used the examples here, you can\njust copy-paste this into a new file at `/etc/systemd/system/pandorad.service`:\n\n```\n[Unit]\nDescription=Pandora's Pot \"service\"\nAfter=network.target\nStartLimitIntervalSec=0\n\n[Service]\n# Change to another user/group if needed\nUser=pandora-user\nGroup=pandora-user\n\nRestart=always\nRestartSec=1\n\nWorkingDirectory=/etc/pandoras_pot/\n\n# Requires that the file /etc/pandoras_pot/config.toml exists; you can also\n# remove config.toml to use plain default settings.\nExecStart=/usr/bin/pandoras_pot config.toml\n\n###\n## Hardening; this is optional and can be commented out, but is generally\n## good practice. Some might prevent pandoras_pot from functioning, see below.\n##\n## Other settings may exist and be suitable.\n##\n## For more info, see systemd.exec(5)\n##\nMemoryDenyWriteExecute=yes\nNoNewPrivileges=yes\nPrivateDevices=yes\nPrivateTmp=yes\nPrivateUsers=yes\nProtectClock=yes\nProtectControlGroups=yes\nProtectHostname=yes\nProtectKernelLogs=yes\nProtectKernelModules=yes\nProtectKernelTunables=yes\nRestrictNamespaces=yes\nRestrictSUIDSGID=yes\n\n# These might prevent pandoras_pot from writing to a log file if ReadWritePaths is misconfigured.\nProtectHome=yes\nProtectSystem=strict\n\n# This should point to the output log file; this is the default value.\n# It should be the same as `logging.output_path` in the config.toml.\n# A sane alternative is `/var/log/pandoras.log`.\nReadWritePaths=/etc/pandoras_pot/pandoras.log\n\n##\n## End of hardening\n###\n\n[Install]\nWantedBy=multi-user.target\n```\n\nThen you need to reload some daemons, enable and start your service:\n\n```sh\nsystemctl daemon-reload\nsystemctl enable pandorad.service\nsystemctl start pandorad.service\n```\n\nYou can check if everything looks good:\n\n```sh\nsystemctl status pandorad.service\n```\n\nDone!\n\n## Configuration\n\n`pandoras_pot` uses toml as a configuration format. If you are not using docker,\nyou can either pass a config like an argument like so:\n\n```sh\npandoras_pot \u003cpath-to-config\u003e\n```\n\nor put it in a file at `$HOME/.config/pandoras_pot/config.toml`.\n\nYou can always get the default configuration using\n\n```sh\npandoras_pot --print-default-config\n```\n\nA sample file can be found below:\n\n```toml\n[http]\n# Make sure this matches your Dockerfile's \"EXPOSE\" if using Docker\nport = \"8080\"\n# Routes to send misery to. Is overridden by `http.catch_all`\nroutes = [\"/wp-login.php\", \"/.env\"]\n# If all routes are to be served.\ncatch_all = true\n# How many connections that can be made over `http.rate_limit_period` seconds. Will\n# not set any limit if set to 0.\nrate_limit = 0\n# Amount of seconds that `http.rate_limit` checks on. Does nothing if rate limit is set\n# to 0.\nrate_limit_period = 300 # 5 minutes\n# Enables `http.health_port` to be used for health checks (to see if\n# `pandoras_pot` is running). Useful if you want to use your chad gaming PC\n# that might not always be up and running to back up an instance running on\n# your RPi 3 web server.\nhealth_port_enabled = false\n# Port to be used for health checks. Should probably not be accessible from the\n# outside. Has no effect if `http.health_port_enabled` is `false`.\nhealth_port = \"8081\"\n# The `Content-Type` header set in responses.\ncontent_type = \"text/html; charset=utf-8\"\n\n[generator]\n# The size of each generated chunk in bytes. Has a big impact on performance, so\n# play around a bit! Note that if this is set too low (like 10 bytes), `pandoras_pot`\n# will refuse to run.\nchunk_size = 16384 # 1024 * 16\n# The type of generator to be used\ntype = { name = \"random\" }\n\n# For generator.type it is also possible to set a markov chain generator, using\n# a text file as a source of data. Then you can use this (but uncommented, duh):\n# type = { name = \"markov_chain\", data = \"\u003cpath to some text file\u003e\" }\n\n# Another alternative is a static generator, that always outputs the full contents\n# of a file. Does not respect chunking.\n# type = { name = \"static\", data = \"\u003cpath to some file\u003e\" }\n\n# The max amount of simultaneous generators that can produce output.\n# Useful for preventing abuse. `0` means no limit.\nmax_concurrent = 100\n\n# The amount of time in seconds a generator can be active before\n# it stops sending. `0` means no limit.\ntime_limit = 0\n\n# The amount of data in bytes that a generator can\n# send before it stops sending. `0` means no limit.\nsize_limit = 0\n\n# How many chunks should be buffered for each connection. Higher values mean\n# more memory usage, but may lead to increased performance. Must be \u003e= 1.\nchunk_buffer = 20\n\n# Prefix that will be used for the first message to an incoming connection.\n# Usually used to set an HTML prefix. Can be set to \"\" to disable.\n#\n# Example usage: Set to \"{\" for a static generator using a JSON file to make\n# output look like a valid stream of JSON that will eventually end (it won't).\nprefix = \"\u003c!DOCTYPE html\u003e\u003chtml\u003e\u003cbody\u003e\"\n\n[logging]\n# Output file for logs.\noutput_path = \"pandoras.log\"\n\n# If pretty logs should be written to standard output.\nprint_pretty_logs = true\n\n# If no logs at all should be printed to stdout. Overrides other stdout logging\n# settings.\nno_stdout = false\n```\n\n# Measuring Output\n\nYou can easily measure how fast your setup sends data by using `curl`. Note that using\n`localhost` might not be reliable, as it does not show what an outsider might see. A better\noption might be to use another machine.\n\nThis example assume that you have `http.catch_all` enabled, otherwise you should add a\nvalid route.\n\n```sh\ncurl localhost:8080/ \u003e\u003e /dev/null\n```\n\n# Support\n\nI do not accept any donations. If you however find any software I\nwrite for fun useful, please consider donating to an efficient charity that\nsave or improve lives the most per `$CURRENCY`.\n\n[GiveWell.org](https://givewell.org) is an excellent website that can help you\ndonate to the world's most efficient charities. Alternatives listing the current\nbest charities for helping our planet is [Founders Pledge](https://www.founderspledge.com/funds/climate-change-fund), and for\nanimal welfare [Animal Charity Evaluators](https://animalcharityevaluators.org/donation-advice/recommended-charity-fund/).\n\n- Residents of Sweden can do tax-deductable donations to GiveWell via [Ge Effektivt](https://geeffektivt.se)\n- Residents of Norway can do the same via [Gi Effektivt](https://gieffektivt.no/)\n\nThis list is not exhaustive; your country may have an equivalent.\n","funding_links":[],"categories":["Rust"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fginger51011%2Fpandoras_pot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fginger51011%2Fpandoras_pot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fginger51011%2Fpandoras_pot/lists"}