docs: add project readme
This commit is contained in:
parent
b2cee02dd4
commit
18be5ba041
1 changed files with 300 additions and 0 deletions
300
README.md
Normal file
300
README.md
Normal file
|
@ -0,0 +1,300 @@
|
|||
# Eris
|
||||
|
||||
This is a sophisticated HTTP tarpit and honeypot stream designed to protect,
|
||||
delay, block and dare I say _troll_ malicious scanners and vulnerability probes
|
||||
while protecting **legitimate** web traffic.
|
||||
|
||||
## How Does It Work?
|
||||
|
||||
Eris works by sitting in front of your web server, intercepting all incoming
|
||||
HTTP requests and:
|
||||
|
||||
- **Allowing** legitimate requests to pass through to your actual web server
|
||||
- **Trapping and delaying** malicious requests using a tarpit technique
|
||||
- **Blocking** repeat offenders at the firewall level (goodbye fail2ban)
|
||||
|
||||
### Process Flow
|
||||
|
||||
1. Eris receives all incoming HTTP requests
|
||||
2. It analyzes each request against its list of trap patterns
|
||||
3. Legitimate requests are proxied directly to your backend server
|
||||
4. Suspicious requests are tarpitted:
|
||||
- Response is sent painfully slowly, byte-by-byte with random delays
|
||||
- Deceptive content is generated to waste attacker time
|
||||
- Connections are held open for extended periods to consume attacker
|
||||
resources
|
||||
5. Repeat offenders are automatically blocked at the firewall level
|
||||
|
||||
## Why Use Eris?
|
||||
|
||||
Traditional web application firewalls simply block malicious requests, which
|
||||
immediately alerts attackers they've been detected. Eris takes a deceptive
|
||||
approach:
|
||||
|
||||
- Wastes attacker time and resources on fake responses
|
||||
- Collects data about attack patterns and techniques
|
||||
- Reduces server load by handling malicious traffic efficiently
|
||||
- Provides valuable metrics and insights about attack traffic
|
||||
|
||||
## Key Features
|
||||
|
||||
The design I had in mind was minimal, but more features crept in while I was
|
||||
fixing things on to go. More features to come as I see fit.
|
||||
|
||||
- **Low-overhead tarpit**: Delays responses to suspicious requests byte-by-byte
|
||||
with random delays
|
||||
- **Markov chain response generation**: Creates realistic-looking fake responses
|
||||
to deceive attackers (success my vary depending on how sophisticated the
|
||||
attackers are)
|
||||
- **Firewall integration**: Automatically blocks repeat offenders using nftables
|
||||
(iptables is legacy, and not supported)
|
||||
- **Customizable response scripts**: Using Lua scripting to generate deceptive
|
||||
responses
|
||||
- **Prometheus metrics**: Tracks and exposes honeypot activity
|
||||
|
||||
## Installation
|
||||
|
||||
### From Source
|
||||
|
||||
```bash
|
||||
# Clone the repository
|
||||
git clone https://github.com/notashelf/eris
|
||||
cd eris
|
||||
|
||||
# Build the binary
|
||||
cargo build --release
|
||||
|
||||
# Create necessary directories
|
||||
mkdir -p ~/.local/share/eris/data
|
||||
mkdir -p ~/.local/share/eris/corpora
|
||||
mkdir -p ~/.local/share/eris/scripts
|
||||
```
|
||||
|
||||
### Pre-built Binaries
|
||||
|
||||
Pre-built binaries are not yet available.
|
||||
|
||||
## Deployment Architecture
|
||||
|
||||
### Static Sites
|
||||
|
||||
For static sites served by Nginx, the proper setup is to place Eris in front of
|
||||
Nginx. Here is a graph of how it's meant to be configured:
|
||||
|
||||
```
|
||||
Internet → [Eris (port 80)] → [Nginx (local port)]
|
||||
```
|
||||
|
||||
You will want to configure Eris to listen on port 80 (or 443 for SSL) and
|
||||
forward legitimate traffic to Nginx running on a local port:
|
||||
|
||||
```bash
|
||||
# Run Eris on port 80, forwarding legitimate requests to Nginx on port 8080
|
||||
eris --listen-addr 0.0.0.0:80 --backend-addr 127.0.0.1:8080
|
||||
```
|
||||
|
||||
Then, configure Nginx to serve your static site on the local port:
|
||||
|
||||
```nginx
|
||||
server {
|
||||
# XXX: Nginx listens on local port only and it is
|
||||
# not exposed to internet
|
||||
listen 127.0.0.1:8080;
|
||||
server_name example.com;
|
||||
|
||||
root /var/www/example.com; # your site's source
|
||||
index index.html;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ =404;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
With the setup above, several things will happen (in this order):
|
||||
|
||||
1. All traffic hits Eris first (on port 80)
|
||||
2. Eris inspects each request against its trap patterns
|
||||
3. Malicious requests get tarpitted by Eris
|
||||
4. Legitimate requests get proxied to Nginx on port 8080
|
||||
5. Nginx serves your static content as usual
|
||||
|
||||
## HTTPS Support
|
||||
|
||||
For HTTPS, you have two options:
|
||||
|
||||
### Option 1: Terminate SSL at Eris
|
||||
|
||||
```bash
|
||||
# SSL termination at Eris (requires cert files)
|
||||
eris --listen-addr 0.0.0.0:443 --backend-addr 127.0.0.1:8080 --ssl-cert /path/to/cert.pem --ssl-key /path/to/key.pem
|
||||
```
|
||||
|
||||
### Option 2: Use a separate SSL terminator
|
||||
|
||||
```
|
||||
Internet → [SSL Terminator (port 443)] → [Eris (local port)] → [Nginx (local port)]
|
||||
```
|
||||
|
||||
You can use Nginx, HAProxy, or Caddy as the SSL terminator, forwarding decrypted
|
||||
traffic to Eris.
|
||||
|
||||
## Configuration
|
||||
|
||||
### Command Line Options
|
||||
|
||||
```
|
||||
USAGE:
|
||||
eris [OPTIONS]
|
||||
|
||||
OPTIONS:
|
||||
--listen-addr <ADDR> Address to listen on [default: 0.0.0.0:8888]
|
||||
--metrics-port <PORT> Port for Prometheus metrics [default: 9100]
|
||||
--backend-addr <ADDR> Address of backend server [default: 127.0.0.1:80]
|
||||
--min-delay <MS> Minimum delay between tarpit bytes in ms [default: 1000]
|
||||
--max-delay <MS> Maximum delay between tarpit bytes in ms [default: 15000]
|
||||
--max-tarpit-time <SEC> Maximum time to hold a tarpit connection in seconds [default: 600]
|
||||
--block-threshold <COUNT> Block IPs after this many hits [default: 3]
|
||||
--base-dir <PATH> Base directory for all files (optional)
|
||||
--config-file <FILE> JSON configuration file (optional)
|
||||
--log-level <LEVEL> Log level (debug, info, warn, error) [default: info]
|
||||
```
|
||||
|
||||
### JSON Configuration File
|
||||
|
||||
For more complex configurations, use a JSON configuration file:
|
||||
|
||||
```json
|
||||
{
|
||||
"listen_addr": "0.0.0.0:8888",
|
||||
"metrics_port": 9100,
|
||||
"backend_addr": "127.0.0.1:80",
|
||||
"min_delay": 1000,
|
||||
"max_delay": 15000,
|
||||
"max_tarpit_time": 600,
|
||||
"block_threshold": 3,
|
||||
"trap_patterns": [
|
||||
"/vendor/phpunit",
|
||||
"eval-stdin.php",
|
||||
"/wp-admin",
|
||||
"/wp-login.php",
|
||||
"/xmlrpc.php",
|
||||
"/phpMyAdmin",
|
||||
"/solr/",
|
||||
"/.env",
|
||||
"/config",
|
||||
"/api/",
|
||||
"/actuator/"
|
||||
],
|
||||
"whitelist_networks": [
|
||||
"192.168.0.0/16",
|
||||
"10.0.0.0/8",
|
||||
"172.16.0.0/12",
|
||||
"127.0.0.0/8"
|
||||
],
|
||||
"markov_corpora_dir": "./corpora",
|
||||
"lua_scripts_dir": "./scripts",
|
||||
"data_dir": "./data"
|
||||
}
|
||||
```
|
||||
|
||||
## Extending and Customizing
|
||||
|
||||
### Adding Trap Patterns
|
||||
|
||||
Edit your configuration file to add additional trap patterns:
|
||||
|
||||
```json
|
||||
"trap_patterns": [
|
||||
"/vendor/phpunit",
|
||||
"eval-stdin.php",
|
||||
"/wp-admin",
|
||||
"/wp-login.php",
|
||||
"/xmlrpc.php",
|
||||
"/phpMyAdmin",
|
||||
"/solr/",
|
||||
"/.env",
|
||||
"/config",
|
||||
"/api/",
|
||||
"/actuator/",
|
||||
"/wp-content/debug.log",
|
||||
"/cgi-bin/",
|
||||
"/admin/"
|
||||
]
|
||||
```
|
||||
|
||||
### Custom Response Generation with Lua
|
||||
|
||||
> [!WARNING]
|
||||
> The Lua API is experimental, and might be subject to change. Breaking changes
|
||||
> will be
|
||||
|
||||
Create Lua scripts in your `lua_scripts_dir` to customize response generation:
|
||||
|
||||
```lua
|
||||
-- honeypot.lua
|
||||
function generate_honeytoken(token)
|
||||
local token_types = {"API_KEY", "AUTH_TOKEN", "SESSION_ID", "SECRET_KEY"}
|
||||
local prefix = token_types[math.random(#token_types)]
|
||||
local suffix = string.format("%08x", math.random(0xffffff))
|
||||
return prefix .. "_" .. token .. "_" .. suffix
|
||||
end
|
||||
|
||||
function enhance_response(text, response_type, path, token)
|
||||
local result = text
|
||||
local honeytoken = generate_honeytoken(token)
|
||||
|
||||
if response_type == "php_exploit" then
|
||||
result = result .. "\n<?php /* Debug mode enabled */ ?>"
|
||||
result = result .. "\n<!-- DEBUG TOKEN: " .. honeytoken .. " -->"
|
||||
elseif response_type == "wordpress" then
|
||||
result = result .. "\n<!-- WordPress debug: DB_PASSWORD='" .. honeytoken .. "' -->"
|
||||
elseif response_type == "api" then
|
||||
result = '{"error":"Unauthorized","message":"Invalid credentials",'
|
||||
result = result .. '"debug_token":"' .. honeytoken .. '"}'
|
||||
else
|
||||
result = result .. "\n<!-- Server: Apache/2.4.41 PHP/7.4.3 -->"
|
||||
result = result .. "\n<!-- Debug: " .. honeytoken .. " -->"
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
```
|
||||
|
||||
### Custom Markov Response Corpus
|
||||
|
||||
Create text files in your `markov_corpora_dir` to provide custom text for
|
||||
response generation:
|
||||
|
||||
- `generic.txt` - Default responses
|
||||
- `php_exploit.txt` - PHP-specific error messages
|
||||
- `wordpress.txt` - WordPress-style responses
|
||||
- `api.txt` - API error messages
|
||||
|
||||
## Metrics and Monitoring
|
||||
|
||||
Eris exposes Prometheus metrics on the configured metrics port (default: 9100):
|
||||
|
||||
- `eris_hits_total` - Total number of hits to honeypot paths
|
||||
- `eris_blocked_ips` - Number of IPs permanently blocked
|
||||
- `eris_active_connections` - Number of currently active connections in tarpit
|
||||
- `eris_path_hits_total` - Hits by path
|
||||
- `eris_ua_hits_total` - Hits by user agent
|
||||
|
||||
View current status at: `http://your-server:9100/status`
|
||||
|
||||
## Additional Security Considerations
|
||||
|
||||
Internally, Eris is designed with security and maximum performance in mind.
|
||||
Additionally you might want to consider:
|
||||
|
||||
- Running Eris as a non-privileged user
|
||||
- Placing Eris behind a CDN or DDoS protection service for high-traffic sites
|
||||
- Regularly reviewing logs to identify new attack patterns (and keeping verbose
|
||||
NGINX logs)
|
||||
- Hiding the metrics endpoint from public access
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT License - see the LICENSE file for
|
||||
details.
|
Loading…
Add table
Add a link
Reference in a new issue