Deploying Canary Tokens
Introduction
Canary Tokens is an open-source honeypot and threat detection platform that creates decoy resources to detect and alert on unauthorized access and suspicious activity. By deploying fake credentials, files, URLs, and infrastructure components throughout your network and systems, Canary Tokens provides early warning of security breaches and data exfiltration attempts. Deploy Canary Tokens on Klutch.sh to create a self-hosted threat detection system that monitors network activity and alerts you when attackers interact with your deployed decoys.
Key Features
- Web Hook Tokens: Generate URLs that trigger alerts when visited by attackers
- DNS Tokens: Create decoy DNS names that alert when resolved
- AWS Infrastructure Tokens: Detect unauthorized AWS account exploration and resource access
- Fake Credentials: Deploy honeypot AWS API keys, database credentials, and tokens
- Document Tokens: Embed tracking in Microsoft Office documents for access detection
- QR Code Tokens: Track when attackers scan fake QR codes
- Log4Shell Detection: Identify CVE-2021-44228 exploitation attempts
- Database Tokens: Create fake SQL Server, MySQL, and database dumps for detection
- File System Tokens: Deploy fake files and folders that trigger alerts on access
- Email Tokens: Generate unique email addresses to detect unauthorized access
- Azure Tokens: Detect Azure service principal and Entra ID credential misuse
- API Integration: REST API for programmatic token creation and management
- Alert Management: Centralized dashboard for viewing and managing token events
- Email Notifications: Automated email alerts when tokens are triggered
- Webhook Support: Send alerts to external systems via webhooks
- Alert Filtering: Throttle and filter alerts to reduce noise
- Custom Domains: Use your own domains for token generation
- IP Geolocation: Track attacker location and network information
- Token History: Complete audit trail of token interactions
- Multiple Alert Providers: Support for Mailgun, Sendgrid, Mandrill, and SMTP
- User Management: Multi-user support with role-based access control
Prerequisites
Before deploying Canary Tokens on Klutch.sh, ensure you have:
- A Klutch.sh account with access to the dashboard
- A GitHub repository for your Canary Tokens deployment (public or private)
- An email service configured for sending alerts (Mailgun, Sendgrid, SMTP, etc.)
- Understanding of security concepts and threat detection strategies
- A custom domain (recommended for token generation)
Important Considerations
Deployment Steps
Create a Dockerfile
Create a
Dockerfilein the root of your repository with Canary Tokens configured for Docker deployment:FROM python:3.11-slim# Install system dependenciesRUN apt-get update && apt-get install -y \build-essential \postgresql-client \curl \git \&& rm -rf /var/lib/apt/lists/*# Clone Canary Tokens repositoryRUN git clone https://github.com/thinkst/canarytokens.git /appWORKDIR /app# Install Python dependenciesRUN pip install --no-cache-dir -r requirements.txt# Create necessary directoriesRUN mkdir -p /data /config /uploads# Expose web interface and API portsEXPOSE 8080# Create entrypoint scriptCOPY entrypoint.sh /app/entrypoint.shRUN chmod +x /app/entrypoint.sh# Start Canary TokensCMD ["/app/entrypoint.sh"]Create Configuration Files
Create
frontend.envfor frontend configuration:# Frontend ConfigurationCANARY_DOMAINS=example-app.klutch.shCANARY_NXDOMAINS=dns.example-app.klutch.sh,www.example-app.klutch.shCANARY_WEB_IMAGE_UPLOAD_PATH=/uploadsLOG_FILE=/data/frontend.logDEBUG=False# Optional: Google API Key for maps in web interfaceCANARY_GOOGLE_API_KEY=Create
switchboard.envfor backend/alert configuration:# Switchboard ConfigurationCANARY_PUBLIC_IP=0.0.0.0CANARY_PUBLIC_DOMAIN=example-app.klutch.shCANARY_FORCE_HTTPS=True# Email Configuration (choose one provider)# Mailgun ConfigurationCANARY_MAILGUN_DOMAIN_NAME=mg.example.comCANARY_MAILGUN_API_KEY=key-xxxxxxxxxxxx# OR SMTP ConfigurationCANARY_SMTP_SERVER=smtp.gmail.comCANARY_SMTP_PORT=587CANARY_SMTP_USERNAME=your-email@gmail.comCANARY_SMTP_PASSWORD=your-app-password# Alert SettingsCANARY_ALERT_EMAIL_FROM_ADDRESS=canarytoken@example.comCANARY_ALERT_EMAIL_FROM_DISPLAY=Canarytoken AlerterCANARY_ALERT_EMAIL_SUBJECT=Canarytoken AlertCANARY_MAX_ALERTS_PER_MINUTE=1000# Optional: IP Info API Key for geolocationCANARY_IPINFO_API_KEY=# LoggingLOG_FILE=/data/switchboard.logDEBUG=FalseCreate Entrypoint Script
Create an
entrypoint.shfile for container initialization:#!/bin/bashset -eecho "Initializing Canary Tokens..."# Create data directorymkdir -p /datamkdir -p /uploads# Load environment variablesexport $(cat /config/frontend.env | xargs)export $(cat /config/switchboard.env | xargs)# Run database migrations if neededpython manage.py migrate 2>/dev/null || true# Start frontend process in backgroundecho "Starting frontend process..."python frontend.py &FRONTEND_PID=$!# Start switchboard processecho "Starting switchboard process..."python switchboard.py &SWITCHBOARD_PID=$!# Wait for processeswait $FRONTEND_PID $SWITCHBOARD_PIDMake it executable:
Terminal window chmod +x entrypoint.shCreate Environment Variables File
Create a
.env.examplefile for configuration documentation:# Canary Tokens Configuration# Frontend SettingsCANARY_DOMAINS=example-app.klutch.shCANARY_NXDOMAINS=dns.example-app.klutch.shCANARY_WEB_IMAGE_UPLOAD_PATH=/uploads# Alert ConfigurationCANARY_ALERT_EMAIL_FROM_ADDRESS=canarytoken@example.comCANARY_ALERT_EMAIL_FROM_DISPLAY=Canarytoken AlerterCANARY_ALERT_EMAIL_SUBJECT=Canarytoken Alert# Email Provider (Mailgun)CANARY_MAILGUN_DOMAIN_NAME=CANARY_MAILGUN_API_KEY=# OR Email Provider (SMTP)CANARY_SMTP_SERVER=smtp.gmail.comCANARY_SMTP_PORT=587CANARY_SMTP_USERNAME=CANARY_SMTP_PASSWORD=# Security SettingsCANARY_FORCE_HTTPS=TrueCANARY_MAX_ALERTS_PER_MINUTE=1000# Optional ServicesCANARY_IPINFO_API_KEY=CANARY_GOOGLE_API_KEY=# LoggingDEBUG=FalseLOG_LEVEL=infoCreate .gitignore File
Create a
.gitignorefile to exclude sensitive files:# Environment and configuration files with secretsfrontend.envswitchboard.env.env.env.local*.key*.pem*.crt# Data files/data//uploads/*.db*.sqlite# Logs*.log*.txt# Python cache__pycache__/*.pyc*.pyo*.egg-info/dist/build/# IDE and OS files.DS_Store.vscode/.idea/Thumbs.dbCreate Docker Compose for Local Testing
Create a
docker-compose.ymlfor local development and testing (not for Klutch.sh deployment):version: '3.8'services:canarytokens:build: .container_name: canarytokens-devports:- "8080:8080"volumes:- ./frontend.env:/config/frontend.env- ./switchboard.env:/config/switchboard.env- canary_data:/data- canary_uploads:/uploadsenvironment:- PYTHONUNBUFFERED=1networks:- canary-networkvolumes:canary_data:canary_uploads:networks:canary-network:driver: bridgePush to GitHub
Push your repository to GitHub with all configuration files:
Terminal window git add Dockerfile entrypoint.sh frontend.env switchboard.env \docker-compose.yml .env.example .gitignoregit commit -m "Initial Canary Tokens deployment configuration"git push origin mainDeploy on Klutch.sh
- Navigate to klutch.sh/app and log in to your dashboard
- Click Create New App
- Select Docker as the deployment method (detected automatically from your Dockerfile)
- Connect your GitHub repository containing the Canary Tokens deployment files
- Confirm the Dockerfile is detected from your root directory
- Click Deploy to start the deployment process
- Wait for the deployment to complete and your app to become active
Configure Traffic Rules and Persistent Volume
- In your app dashboard, navigate to Traffic settings
- Select HTTP as the traffic type
- Set the internal port to 8080 (Canary Tokens web interface default)
- Save your traffic configuration
- Navigate to Volumes settings
- Click Add Volume
- Enter mount path:
/data - Set volume size to 20GB (adjust based on expected token volume)
- Click Attach to create and mount the persistent volume
- Your Canary Tokens server will be accessible at
example-app.klutch.sh
Initial Setup and Configuration
After deploying Canary Tokens on Klutch.sh, access the web interface and configure your alert system.
Access the Web Interface
- Navigate to
http://example-app.klutch.sh:8080/in your browser - You’ll see the Canary Tokens dashboard
- The interface shows your deployed tokens and alert history
- Create your first token to get started
Create Your First Token
- Click the Create Token button
- Select a token type:
- Web Hook: URL that alerts when visited
- DNS: Domain name that alerts when resolved
- AWS Infrastructure: Detect AWS account exploration
- AWS Keys: Honeypot AWS API credentials
- Database: Fake database credentials
- Document: Embed tracking in Office documents
- Configure token settings:
- Add a memorable name
- Set notification email addresses
- Configure webhook endpoint (optional)
- Click Generate to create the token
- Copy the generated token and deploy it in your infrastructure
Configure Alert Email
- Click Settings in the web interface
- Configure your email provider:
- Mailgun: Add domain and API key
- Sendgrid: Add API key
- SMTP: Configure SMTP server details
- Set notification email address for alerts
- Test email configuration by clicking Send Test Email
- Save settings
Set Up Webhook Alerts
- In Settings, scroll to Webhooks
- Enter your webhook URL for receiving token alerts
- Select which events trigger webhook notifications
- Canary Tokens will POST alert JSON to your webhook endpoint
- Configure your webhook handler to process alert data
Monitor Token Activity
- Dashboard shows real-time token interactions
- View alert history with:
- Timestamp of interaction
- Attacker IP address
- Geographic location
- Detailed event information
- Filter alerts by:
- Token type
- Date range
- Source IP
- Export alert data for analysis and reporting
Deploy Tokens in Your Infrastructure
- Web Hook tokens can be placed in accessible locations for discovery
- DNS tokens should be used in network monitoring tools
- AWS tokens can be deployed in test/staging environments
- Document tokens can be included in honeypot files
- Database tokens can be added to development databases
Environment Variables
Basic Configuration
Configure these environment variables through your deployment:
CANARY_DOMAINS=example-app.klutch.sh- Primary domain for token generationCANARY_NXDOMAINS=dns.example-app.klutch.sh- DNS token domains (non-existent)CANARY_WEB_IMAGE_UPLOAD_PATH=/uploads- Path for uploaded token imagesCANARY_ALERT_EMAIL_FROM_ADDRESS=canarytoken@example.com- Alert email sender addressDEBUG=False- Debug mode (set to True only for troubleshooting)
Production Environment Variables
For production deployments using Nixpacks, configure these environment variables:
# Domain ConfigurationCANARY_DOMAINS=example-app.klutch.shCANARY_NXDOMAINS=dns.example-app.klutch.sh,tokens.example-app.klutch.shCANARY_AWSID_URL=
# Email Configuration (Mailgun)CANARY_MAILGUN_DOMAIN_NAME=mg.example.comCANARY_MAILGUN_API_KEY=key-xxxxxCANARY_MAILGUN_BASE_URL=https://api.mailgun.net
# OR Email Configuration (SMTP)CANARY_SMTP_SERVER=smtp.gmail.comCANARY_SMTP_PORT=587CANARY_SMTP_USERNAME=your-email@example.comCANARY_SMTP_PASSWORD=your-app-passwordCANARY_SMTP_ENABLE_TLS=True
# OR Email Configuration (Sendgrid)CANARY_SENDGRID_API_KEY=SG.xxxxx
# Alert SettingsCANARY_ALERT_EMAIL_FROM_ADDRESS=noreply@example.comCANARY_ALERT_EMAIL_FROM_DISPLAY=Canarytoken Security AlertCANARY_ALERT_EMAIL_SUBJECT=Canarytoken Alert - Action RequiredCANARY_MAX_ALERTS_PER_MINUTE=1000MAX_ALERT_FAILURES=5
# SecurityCANARY_FORCE_HTTPS=TrueCANARY_PUBLIC_IP=0.0.0.0CANARY_PUBLIC_DOMAIN=example-app.klutch.sh
# IP GeolocationCANARY_IPINFO_API_KEY=xxxxx
# Optional ServicesCANARY_GOOGLE_API_KEY=
# LoggingLOG_FILE=/data/switchboard.logLOG_LEVEL=infoDEBUG=False
# PerformanceCANARY_THREAD_POOL_SIZE=10CANARY_REQUEST_TIMEOUT=30Code Examples
Python - Canary Tokens API Client
# Canary Tokens API Client for Token Managementimport requestsimport jsonfrom datetime import datetimefrom typing import List, Dict, Optional
class CanaryTokensClient: def __init__(self, base_url="http://example-app.klutch.sh:8080", api_key=None): self.base_url = base_url self.api_key = api_key self.session = requests.Session() if api_key: self.session.headers.update({"Authorization": f"Bearer {api_key}"})
def create_web_token(self, memo: str, webhook_url: Optional[str] = None) -> Dict: """Create a web hook token""" try: payload = { "type": "web", "memo": memo, } if webhook_url: payload["webhook_url"] = webhook_url
response = self.session.post( f"{self.base_url}/api/tokens/create", json=payload, timeout=30 ) return response.json() except Exception as e: print(f"Error creating web token: {e}") return {}
def create_dns_token(self, memo: str, dns_name: str) -> Dict: """Create a DNS resolution token""" try: payload = { "type": "dns", "memo": memo, "dns_name": dns_name } response = self.session.post( f"{self.base_url}/api/tokens/create", json=payload, timeout=30 ) return response.json() except Exception as e: print(f"Error creating DNS token: {e}") return {}
def create_aws_token(self, memo: str, aws_account_id: str) -> Dict: """Create an AWS infrastructure token""" try: payload = { "type": "aws_infra", "memo": memo, "aws_account_id": aws_account_id } response = self.session.post( f"{self.base_url}/api/tokens/create", json=payload, timeout=30 ) return response.json() except Exception as e: print(f"Error creating AWS token: {e}") return {}
def get_all_tokens(self) -> List[Dict]: """Get all deployed tokens""" try: response = self.session.get( f"{self.base_url}/api/tokens/list", timeout=30 ) return response.json().get("tokens", []) except Exception as e: print(f"Error fetching tokens: {e}") return []
def get_token_alerts(self, token_id: str, limit: int = 100) -> List[Dict]: """Get alerts for a specific token""" try: response = self.session.get( f"{self.base_url}/api/tokens/{token_id}/alerts", params={"limit": limit}, timeout=30 ) return response.json().get("alerts", []) except Exception as e: print(f"Error fetching token alerts: {e}") return []
def get_all_alerts(self, limit: int = 500) -> List[Dict]: """Get all alerts across all tokens""" try: response = self.session.get( f"{self.base_url}/api/alerts/all", params={"limit": limit}, timeout=30 ) return response.json().get("alerts", []) except Exception as e: print(f"Error fetching all alerts: {e}") return []
def delete_token(self, token_id: str) -> bool: """Delete a token""" try: response = self.session.delete( f"{self.base_url}/api/tokens/{token_id}", timeout=30 ) return response.status_code == 200 except Exception as e: print(f"Error deleting token: {e}") return False
def export_alerts_json(self, output_file: str) -> bool: """Export all alerts to JSON file""" try: alerts = self.get_all_alerts() with open(output_file, 'w') as f: json.dump({ "export_date": datetime.now().isoformat(), "alert_count": len(alerts), "alerts": alerts }, f, indent=2) print(f"Alerts exported to {output_file}") return True except Exception as e: print(f"Error exporting alerts: {e}") return False
def get_statistics(self) -> Dict: """Get deployment statistics""" try: response = self.session.get( f"{self.base_url}/api/stats", timeout=30 ) return response.json() except Exception as e: print(f"Error fetching statistics: {e}") return {}
# Usage exampleif __name__ == "__main__": client = CanaryTokensClient("http://example-app.klutch.sh:8080")
# Create tokens print("Creating web hook token...") web_token = client.create_web_token( memo="Production server honeypot", webhook_url="https://your-webhook-handler.example.com/alerts" ) print(f"Web token: {web_token}")
# Get all tokens print("\nListing all tokens...") tokens = client.get_all_tokens() for token in tokens: print(f" - {token['memo']}: {token['id']}")
# Get all alerts print("\nFetching all alerts...") alerts = client.get_all_alerts(limit=10) print(f"Total alerts: {len(alerts)}") for alert in alerts[:5]: print(f" - {alert['timestamp']}: {alert['description']}")
# Export alerts print("\nExporting alerts...") client.export_alerts_json("canary_alerts.json")Bash - Canary Tokens Management Script
#!/bin/bash
# Canary Tokens Server Management Script# Requires: curl, jq (optional for JSON formatting)
CANARY_HOST="example-app.klutch.sh"CANARY_PORT="8080"CANARY_URL="http://${CANARY_HOST}:${CANARY_PORT}"
# Color outputRED='\033[0;31m'GREEN='\033[0;32m'YELLOW='\033[1;33m'BLUE='\033[0;34m'NC='\033[0m' # No Color
# Check server statuscheck_status() { echo -e "${BLUE}Checking Canary Tokens server status...${NC}"
if curl -s "${CANARY_URL}/" > /dev/null 2>&1; then echo -e "${GREEN}✓ Canary Tokens server is online${NC}" return 0 else echo -e "${RED}✗ Canary Tokens server is offline${NC}" return 1 fi}
# Create a web tokencreate_web_token() { local memo=$1
if [ -z "$memo" ]; then echo -e "${RED}Usage: create_web_token <memo>${NC}" return 1 fi
echo -e "${YELLOW}Creating web token: $memo${NC}"
curl -s -X POST "${CANARY_URL}/api/tokens/create" \ -H "Content-Type: application/json" \ -d "{\"type\": \"web\", \"memo\": \"$memo\"}" | \ jq . 2>/dev/null || echo "Token created (jq not available)"}
# Create a DNS tokencreate_dns_token() { local memo=$1 local dns_name=$2
if [ -z "$memo" ] || [ -z "$dns_name" ]; then echo -e "${RED}Usage: create_dns_token <memo> <dns_name>${NC}" return 1 fi
echo -e "${YELLOW}Creating DNS token: $memo${NC}"
curl -s -X POST "${CANARY_URL}/api/tokens/create" \ -H "Content-Type: application/json" \ -d "{\"type\": \"dns\", \"memo\": \"$memo\", \"dns_name\": \"$dns_name\"}" | \ jq . 2>/dev/null || echo "Token created (jq not available)"}
# List all tokenslist_tokens() { echo -e "${BLUE}Listing all tokens:${NC}"
curl -s "${CANARY_URL}/api/tokens/list" | \ jq '.tokens[] | {id: .id, memo: .memo, type: .type, created: .created_at}' 2>/dev/null || \ curl -s "${CANARY_URL}/api/tokens/list" | head -50}
# Get all alertsget_alerts() { local limit=${1:-100}
echo -e "${BLUE}Fetching alerts (limit: $limit):${NC}"
curl -s "${CANARY_URL}/api/alerts/all?limit=$limit" | \ jq '.alerts[] | {timestamp: .timestamp, token: .token_memo, source_ip: .source_ip}' 2>/dev/null || \ curl -s "${CANARY_URL}/api/alerts/all?limit=$limit"}
# Get alerts for specific tokenget_token_alerts() { local token_id=$1 local limit=${2:-50}
if [ -z "$token_id" ]; then echo -e "${RED}Usage: get_token_alerts <token_id> [limit]${NC}" return 1 fi
echo -e "${BLUE}Fetching alerts for token $token_id:${NC}"
curl -s "${CANARY_URL}/api/tokens/${token_id}/alerts?limit=$limit" | \ jq '.alerts[] | {timestamp: .timestamp, source_ip: .source_ip, description: .description}' 2>/dev/null || \ curl -s "${CANARY_URL}/api/tokens/${token_id}/alerts?limit=$limit"}
# Export alertsexport_alerts() { local output_file=${1:-canary_alerts.json}
echo -e "${YELLOW}Exporting alerts to $output_file${NC}"
curl -s "${CANARY_URL}/api/alerts/all?limit=10000" > "$output_file" && \ echo -e "${GREEN}✓ Alerts exported${NC}" || \ echo -e "${RED}✗ Export failed${NC}"}
# Monitor alerts in real-timemonitor_alerts() { echo -e "${YELLOW}Monitoring Canary Tokens (press Ctrl+C to stop)...${NC}"
while true; do clear echo -e "${BLUE}=== Canary Tokens Monitor ===${NC}" echo "Time: $(date)" echo ""
echo "Recent Alerts:" curl -s "${CANARY_URL}/api/alerts/all?limit=20" | \ jq '.alerts[] | "\(.timestamp): \(.source_ip) - \(.description)"' 2>/dev/null || \ echo "Fetching alerts..."
sleep 10 done}
# Display statisticsshow_stats() { echo -e "${BLUE}Canary Tokens Statistics:${NC}"
curl -s "${CANARY_URL}/api/stats" | \ jq . 2>/dev/null || \ curl -s "${CANARY_URL}/api/stats"}
# Main menucase "${1:-help}" in status) check_status ;; create-web) create_web_token "$2" ;; create-dns) create_dns_token "$2" "$3" ;; list) list_tokens ;; alerts) get_alerts "${2:-100}" ;; token-alerts) get_token_alerts "$2" "${3:-50}" ;; export) export_alerts "${2:-canary_alerts.json}" ;; monitor) monitor_alerts ;; stats) show_stats ;; *) echo -e "${YELLOW}Canary Tokens Management${NC}" echo "Usage: $0 {status|create-web|create-dns|list|alerts|token-alerts|export|monitor|stats} [args]" echo "" echo "Commands:" echo " status - Check server status" echo " create-web <memo> - Create a web hook token" echo " create-dns <memo> <name> - Create a DNS token" echo " list - List all tokens" echo " alerts [limit] - Get all alerts (default: 100)" echo " token-alerts <id> [limit] - Get alerts for token" echo " export [file] - Export alerts to JSON" echo " monitor - Monitor alerts in real-time" echo " stats - Show statistics" ;;esacShell - Canary Tokens Alert Processor
#!/bin/sh
# Canary Tokens Alert Processor# Process and respond to incoming webhook alerts
WEBHOOK_PORT=9000ALERT_LOG="canary_alerts.log"ALERT_SCRIPT="process_alert.sh"
# Create alert processorstart_alert_processor() { echo "Starting alert processor on port $WEBHOOK_PORT..."
# Simple HTTP server using netcat while true; do { echo -ne "HTTP/1.1 200 OK\r\nContent-Length: 2\r\n\r\nOK" cat } | nc -l -p $WEBHOOK_PORT -q 1 | while read line; do # Log incoming alerts echo "[$(date)] Alert received: $line" >> "$ALERT_LOG"
# Call alert processing script if exists if [ -x "$ALERT_SCRIPT" ]; then "./$ALERT_SCRIPT" "$line" & fi done done}
# Process alert dataprocess_alert() { local alert_data=$1
echo "[$(date)] Processing alert: $alert_data"
# Extract key information from JSON alert local token_id=$(echo "$alert_data" | grep -o '"token_id":"[^"]*' | cut -d'"' -f4) local source_ip=$(echo "$alert_data" | grep -o '"source_ip":"[^"]*' | cut -d'"' -f4) local timestamp=$(echo "$alert_data" | grep -o '"timestamp":"[^"]*' | cut -d'"' -f4)
echo "Token ID: $token_id" echo "Source IP: $source_ip" echo "Timestamp: $timestamp"
# Send alert to external system notify_security_team "$token_id" "$source_ip"}
# Notify security teamnotify_security_team() { local token_id=$1 local source_ip=$2
local message="CANARY TOKEN TRIGGERED!Token: $token_idSource IP: $source_ipTime: $(date)Action Required: Investigate immediately"
# Send notification (customize for your system) echo "ALERT: $message"
# Could send to Slack, PagerDuty, SIEM, etc. # curl -X POST https://your-slack-webhook.example.com \ # -d "text=$message"}
# Analyze alert patternsanalyze_patterns() { echo "Analyzing alert patterns..."
# Count alerts by IP echo "" echo "Top attacking IPs:" grep -o '"source_ip":"[^"]*' "$ALERT_LOG" | cut -d'"' -f4 | \ sort | uniq -c | sort -rn | head -10
# Count alerts by token type echo "" echo "Token types triggered:" grep -o '"token_type":"[^"]*' "$ALERT_LOG" | cut -d'"' -f4 | \ sort | uniq -c | sort -rn
# Timeline of alerts echo "" echo "Alert frequency (hourly):" grep -o '\[.*\]' "$ALERT_LOG" | \ cut -d':' -f1-2 | sort | uniq -c | sort -rn}
# Export alerts for analysisexport_for_analysis() { local output_file="alert_analysis_$(date +%s).txt"
echo "Exporting alerts to $output_file..."
{ echo "=== Canary Tokens Alert Analysis ===" echo "Generated: $(date)" echo ""
echo "=== Alert Summary ===" grep -c . "$ALERT_LOG" | xargs echo "Total alerts:"
echo "" echo "=== Recent Alerts ===" tail -20 "$ALERT_LOG"
echo "" echo "=== IP Analysis ===" analyze_patterns } > "$output_file"
echo "Analysis exported to $output_file"}
# Main functioncase "${1:-help}" in start) start_alert_processor ;; process) process_alert "$2" ;; analyze) analyze_patterns ;; export) export_for_analysis ;; *) echo "Canary Tokens Alert Processor" echo "Usage: $0 {start|process|analyze|export} [args]" echo "" echo "Commands:" echo " start - Start webhook alert processor" echo " process <json> - Process alert data" echo " analyze - Analyze alert patterns" echo " export - Export analysis report" ;;esacBest Practices
- Strategic Placement: Deploy tokens in areas attackers would likely explore during reconnaissance
- Realistic Naming: Use convincing names for tokens to increase discovery likelihood
- Monitor Alerts: Set up reliable alert delivery through multiple providers (email + webhook)
- Alert Response: Create runbooks for responding to token triggers
- Regular Review: Periodically review token activity and effectiveness
- Rotate Tokens: Refresh tokens periodically to maintain deception
- Document Strategy: Document which tokens exist and where they’re deployed
- Test Alerts: Verify alert delivery works before relying on tokens in production
- Limit Scope: Start with a small number of tokens and expand gradually
- Track ROI: Monitor how many false positives vs. actual threats you detect
- Integrate with SIEM: Send alerts to your security information and event management system
- Tune Thresholds: Adjust alert throttling based on your environment’s baseline activity
Troubleshooting
Issue: Alerts not being received
- Verify email provider configuration in switchboard.env
- Test email settings by sending a test alert from the web interface
- Check spam/junk folders for alert emails
- Verify webhook endpoint is accessible and returning 200 OK
- Review logs for SMTP or webhook errors
Issue: Tokens not triggering
- Verify tokens are correctly deployed in target environments
- Confirm network connectivity between token location and server
- Check that tokens haven’t been cached or ignored by security tools
- Test token manually to ensure it’s working
- Review server logs for incoming requests
Issue: High false positive rate
- Adjust CANARY_MAX_ALERTS_PER_MINUTE to filter excessive alerts
- Review which systems are legitimately accessing tokens
- Consider moving tokens to less frequently accessed locations
- Implement IP-based whitelisting for known-safe systems
- Enable alert throttling to reduce noise
Issue: Server performance issues
- Monitor available disk space for alert storage
- Check if alert database has grown too large
- Consider archiving old alerts
- Adjust thread pool size based on token volume
- Monitor memory usage and connection limits
Issue: Configuration not loading
- Verify environment variables are set correctly
- Check that env files are properly formatted
- Ensure email provider settings are exclusive (only one provider)
- Review application logs for configuration errors
- Restart container after changing environment variables
Update Instructions
To update Canary Tokens to the latest version:
- Update Dockerfile: Modify base image or clone latest from repository
- Test Locally: Build and test with docker-compose before deployment
- Backup Data: Create a backup of persistent volumes before updating
- Push Changes: Commit and push updated Dockerfile to GitHub
- Redeploy: In Klutch.sh dashboard, trigger a manual redeploy
- Verify: Test token creation and alert delivery after update
Example Dockerfile update:
# Update the repository checkout to latestRUN git clone --depth 1 https://github.com/thinkst/canarytokens.git /appUse Cases
- Breach Detection: Detect when attackers access honeypot credentials or systems
- Network Reconnaissance: Identify when attackers probe your infrastructure
- Insider Threat Detection: Monitor for unauthorized access to sensitive resources
- Incident Response Validation: Confirm threat actor capabilities and intentions
- Compliance Monitoring: Maintain audit trail of suspicious activities
- Threat Intelligence: Gather information about attacker patterns and techniques
- Early Warning System: Get notified before actual production systems are compromised
- Security Posture Assessment: Evaluate your organization’s detection capabilities
- Forensic Investigations: Provide evidence of breach timeline and scope
- Security Testing: Validate detection and response capabilities
Additional Resources
- Canary Tokens Official Website - Main documentation and interface
- GitHub Repository - Source code and issue tracker
- Documentation - Comprehensive guide and API reference
- Thinkst Blog - Security research and threat insights
- Community Forum - Community support and discussions
- Docker Installation - Docker-specific setup guide
- OWASP Honeypot - Honeypot concepts and strategies
- Threat Detection Best Practices - Security monitoring strategies
- Token Types Reference - Detailed token type documentation
- Alert Integration Guide - Setting up alert delivery
Conclusion
Deploying Canary Tokens on Klutch.sh provides a self-hosted threat detection system for identifying unauthorized access and suspicious activity in your infrastructure. By following this guide, you’ve set up a production-ready Canary Tokens server with persistent storage for managing your honeypot tokens.
Your Canary Tokens deployment is now ready to deploy decoy resources throughout your network and receive alerts when attackers interact with them. Whether you’re protecting production systems, testing your security monitoring capabilities, or detecting insider threats, Canary Tokens provides powerful early warning capabilities.
For advanced configurations, webhook integration, or troubleshooting assistance, refer to the official Canary Tokens documentation and community resources linked above. Regular monitoring and analysis of token activity will help you understand threats to your organization and improve your security posture.