Add configurable HTTP Server header for deception

Add SERVER_HEADER environment variable to customize the HTTP Server
  response header, defaulting to Apache/2.2.22 (Ubuntu). This allows the
  honeypot to masquerade as different web servers to attract attackers.

  - Add server_header field to Config dataclass
  - Override version_string() in Handler to return configured header
  - Update documentation and all deployment configs
This commit is contained in:
Phillip Tarrant
2025-12-26 07:53:05 -06:00
parent 749ffaff8e
commit 16aca9bba6
8 changed files with 13 additions and 1 deletions

View File

@@ -185,6 +185,7 @@ To customize the deception server installation several **environment variables**
| `CANARY_TOKEN_URL` | External canary token URL | None | | `CANARY_TOKEN_URL` | External canary token URL | None |
| `DASHBOARD_SECRET_PATH` | Custom dashboard path | Auto-generated | | `DASHBOARD_SECRET_PATH` | Custom dashboard path | Auto-generated |
| `PROBABILITY_ERROR_CODES` | Error response probability (0-100%) | `0` | | `PROBABILITY_ERROR_CODES` | Error response probability (0-100%) | `0` |
| `SERVER_HEADER` | HTTP Server header for deception | `Apache/2.2.22 (Ubuntu)` |
## robots.txt ## robots.txt
The actual (juicy) robots.txt configuration is the following The actual (juicy) robots.txt configuration is the following

View File

@@ -20,6 +20,7 @@ services:
- MAX_COUNTER=10 - MAX_COUNTER=10
- CANARY_TOKEN_TRIES=10 - CANARY_TOKEN_TRIES=10
- PROBABILITY_ERROR_CODES=0 - PROBABILITY_ERROR_CODES=0
- SERVER_HEADER=Apache/2.2.22 (Ubuntu)
# Optional: Set your canary token URL # Optional: Set your canary token URL
# - CANARY_TOKEN_URL=http://canarytokens.com/api/users/YOUR_TOKEN/passwords.txt # - CANARY_TOKEN_URL=http://canarytokens.com/api/users/YOUR_TOKEN/passwords.txt
# Optional: Set custom dashboard path (auto-generated if not set) # Optional: Set custom dashboard path (auto-generated if not set)

View File

@@ -14,4 +14,5 @@ data:
MAX_COUNTER: {{ .Values.config.maxCounter | quote }} MAX_COUNTER: {{ .Values.config.maxCounter | quote }}
CANARY_TOKEN_TRIES: {{ .Values.config.canaryTokenTries | quote }} CANARY_TOKEN_TRIES: {{ .Values.config.canaryTokenTries | quote }}
PROBABILITY_ERROR_CODES: {{ .Values.config.probabilityErrorCodes | quote }} PROBABILITY_ERROR_CODES: {{ .Values.config.probabilityErrorCodes | quote }}
SERVER_HEADER: {{ .Values.config.serverHeader | quote }}
CANARY_TOKEN_URL: {{ .Values.config.canaryTokenUrl | quote }} CANARY_TOKEN_URL: {{ .Values.config.canaryTokenUrl | quote }}

View File

@@ -73,6 +73,7 @@ config:
maxCounter: 10 maxCounter: 10
canaryTokenTries: 10 canaryTokenTries: 10
probabilityErrorCodes: 0 probabilityErrorCodes: 0
serverHeader: "Apache/2.2.22 (Ubuntu)"
# canaryTokenUrl: set-your-canary-token-url-here # canaryTokenUrl: set-your-canary-token-url-here
networkPolicy: networkPolicy:

View File

@@ -13,4 +13,5 @@ data:
MAX_COUNTER: "10" MAX_COUNTER: "10"
CANARY_TOKEN_TRIES: "10" CANARY_TOKEN_TRIES: "10"
PROBABILITY_ERROR_CODES: "0" PROBABILITY_ERROR_CODES: "0"
SERVER_HEADER: "Apache/2.2.22 (Ubuntu)"
# CANARY_TOKEN_URL: set-your-canary-token-url-here # CANARY_TOKEN_URL: set-your-canary-token-url-here

View File

@@ -21,6 +21,7 @@ class Config:
api_server_port: int = 8080 api_server_port: int = 8080
api_server_path: str = "/api/v2/users" api_server_path: str = "/api/v2/users"
probability_error_codes: int = 0 # Percentage (0-100) probability_error_codes: int = 0 # Percentage (0-100)
server_header: str = "Apache/2.2.22 (Ubuntu)"
@classmethod @classmethod
def from_env(cls) -> 'Config': def from_env(cls) -> 'Config':
@@ -44,5 +45,6 @@ class Config:
api_server_url=os.getenv('API_SERVER_URL'), api_server_url=os.getenv('API_SERVER_URL'),
api_server_port=int(os.getenv('API_SERVER_PORT', 8080)), api_server_port=int(os.getenv('API_SERVER_PORT', 8080)),
api_server_path=os.getenv('API_SERVER_PATH', '/api/v2/users'), api_server_path=os.getenv('API_SERVER_PATH', '/api/v2/users'),
probability_error_codes=int(os.getenv('PROBABILITY_ERROR_CODES', 5)) probability_error_codes=int(os.getenv('PROBABILITY_ERROR_CODES', 5)),
server_header=os.getenv('SERVER_HEADER', 'Apache/2.2.22 (Ubuntu)')
) )

View File

@@ -46,6 +46,10 @@ class Handler(BaseHTTPRequestHandler):
"""Extract user agent from request""" """Extract user agent from request"""
return self.headers.get('User-Agent', '') return self.headers.get('User-Agent', '')
def version_string(self) -> str:
"""Return custom server version for deception."""
return self.config.server_header
def _should_return_error(self) -> bool: def _should_return_error(self) -> bool:
"""Check if we should return an error based on probability""" """Check if we should return an error based on probability"""
if self.config.probability_error_codes <= 0: if self.config.probability_error_codes <= 0:

View File

@@ -31,6 +31,7 @@ def print_usage():
print(' DASHBOARD_SECRET_PATH - Secret path for dashboard (auto-generated if not set)') print(' DASHBOARD_SECRET_PATH - Secret path for dashboard (auto-generated if not set)')
print(' PROBABILITY_ERROR_CODES - Probability (0-100) to return HTTP error codes (default: 0)') print(' PROBABILITY_ERROR_CODES - Probability (0-100) to return HTTP error codes (default: 0)')
print(' CHAR_SPACE - Characters for random links') print(' CHAR_SPACE - Characters for random links')
print(' SERVER_HEADER - HTTP Server header for deception (default: Apache/2.2.22 (Ubuntu))')
def main(): def main():