Files
honeydany/app/config.go
T
2025-09-28 21:28:39 +01:00

208 lines
7.1 KiB
Go

package app
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
)
// WebServiceConfig defines configuration for a custom web honeypot service
type WebServiceConfig struct {
Enabled bool `json:"enabled"`
Port int `json:"port"`
Name string `json:"name"` // Service name (e.g., "admin-panel", "webmail")
Path string `json:"path"` // URL path (e.g., "/login", "/admin")
TemplateName string `json:"template_name"` // Template filename (e.g., "admin-login.html")
UseHTTPS bool `json:"use_https"` // Whether to use HTTPS
}
// WebServicesConfig holds configuration for custom web services
type WebServicesConfig struct {
Generic []WebServiceConfig `json:"generic"`
}
// Config contains runtime configuration for the honeypot
type Config struct {
LogMode string `json:"log_mode"` // "file" | "stdout" | "sqlite"
LogPath string `json:"log_path"`
Web struct {
Enabled bool `json:"enabled"`
Bind string `json:"bind"`
Port int `json:"port"`
HTTPTemplateName string `json:"http_template_name"` // Optional template for HTTP service
HTTPSTemplateName string `json:"https_template_name"` // Optional template for HTTPS service
} `json:"web"`
Services struct {
HTTP bool `json:"http"`
HTTPS bool `json:"https"`
SSH bool `json:"ssh"`
FTP bool `json:"ftp"`
SMTP bool `json:"smtp"`
IMAP bool `json:"imap"`
Telnet bool `json:"telnet"`
MySQL bool `json:"mysql"`
PostgreSQL bool `json:"postgresql"`
MongoDB bool `json:"mongodb"`
RDP bool `json:"rdp"`
SMB bool `json:"smb"`
SIP bool `json:"sip"`
VNC bool `json:"vnc"`
} `json:"services"`
WebServices WebServicesConfig `json:"web_services"`
Ports struct {
HTTP int `json:"http"`
HTTPS int `json:"https"`
SSH int `json:"ssh"`
FTP int `json:"ftp"`
SMTP int `json:"smtp"`
IMAP int `json:"imap"`
Telnet int `json:"telnet"`
MySQL int `json:"mysql"`
PostgreSQL int `json:"postgresql"`
MongoDB int `json:"mongodb"`
RDP int `json:"rdp"`
SMB int `json:"smb"`
SIP int `json:"sip"`
VNC int `json:"vnc"`
} `json:"ports"`
Security struct {
MaxInputLength int `json:"max_input_length"` // Maximum input length per command
MaxConnDuration string `json:"max_conn_duration"` // Maximum connection duration (e.g., "5m")
MaxCommands int `json:"max_commands"` // Maximum commands per connection
RateLimitWindow string `json:"rate_limit_window"` // Rate limiting window (e.g., "1m")
MaxConnPerIP int `json:"max_conn_per_ip"` // Maximum concurrent connections per IP
ReadTimeout string `json:"read_timeout"` // Read timeout for each operation
WriteTimeout string `json:"write_timeout"` // Write timeout for each operation
EnableRateLimit bool `json:"enable_rate_limit"` // Enable rate limiting
BlockHighThreatIPs bool `json:"block_high_threat_ips"` // Automatically block high threat IPs
ThreatScoreThreshold int `json:"threat_score_threshold"` // Threshold for automatic blocking
} `json:"security"`
// Certificates allows overriding default certificate/key locations.
Certificates struct {
// SSHHostKeyPath points to a PEM-encoded RSA private key to use as SSH host key.
// If empty, a persistent key will be created in the same directory as LogPath.
SSHHostKeyPath string `json:"ssh_host_key_path"`
// TLSCertPath and TLSKeyPath are used by TLS-capable services if provided.
// If empty, a self-signed certificate will be generated and stored next to LogPath.
TLSCertPath string `json:"tls_cert_path"`
TLSKeyPath string `json:"tls_key_path"`
} `json:"certificates"`
}
// LastConfigPath holds the last path used to load/save config.json
var LastConfigPath string
// EnsureConfig writes a default config file if the given path doesn't exist
func EnsureConfig(path string) error {
if _, err := os.Stat(path); os.IsNotExist(err) {
if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
return fmt.Errorf("create config dir: %w", err)
}
def := defaultConfig()
b, _ := json.MarshalIndent(def, "", " ")
if err := os.WriteFile(path, b, 0644); err != nil {
return fmt.Errorf("write default config: %w", err)
}
}
return nil
}
// LoadConfig loads JSON config from path
func LoadConfig(path string) (Config, error) {
var cfg Config
b, err := os.ReadFile(path)
if err != nil {
return cfg, err
}
if err := json.Unmarshal(b, &cfg); err != nil {
return cfg, err
}
LastConfigPath = path
return cfg, nil
}
// SaveConfig writes the given config to the provided path
func SaveConfig(path string, cfg Config) error {
b, err := json.MarshalIndent(cfg, "", " ")
if err != nil {
return err
}
if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
return err
}
return os.WriteFile(path, b, 0644)
}
func defaultConfig() Config {
var c Config
c.LogMode = "file"
c.LogPath = "honeypot.log"
c.Web.Enabled = true
c.Web.Bind = "127.0.0.1"
c.Web.Port = 6333
// Enable common services by default
c.Services.HTTP = true
c.Services.HTTPS = false
c.Services.SSH = true
c.Services.FTP = true
c.Services.SMTP = true
c.Services.Telnet = true
c.Services.MySQL = false
c.Services.PostgreSQL = false
c.Services.MongoDB = false
c.Services.IMAP = false
c.Services.RDP = false
c.Services.SMB = false
c.Services.SIP = false
c.Services.VNC = false
// Standard ports
c.Ports.HTTP = 8080
c.Ports.HTTPS = 8443
c.Ports.SSH = 2222
c.Ports.FTP = 2121
c.Ports.SMTP = 2525
c.Ports.IMAP = 1143
c.Ports.Telnet = 2323
c.Ports.MySQL = 3306
c.Ports.PostgreSQL = 5432
c.Ports.MongoDB = 27017
c.Ports.RDP = 3389
c.Ports.SIP = 5060
c.Ports.VNC = 5900
// Security defaults
c.Security.MaxInputLength = 4096
c.Security.MaxConnDuration = "5m"
c.Security.MaxCommands = 100
c.Security.RateLimitWindow = "1m"
c.Security.MaxConnPerIP = 10
c.Security.ReadTimeout = "30s"
c.Security.WriteTimeout = "10s"
c.Security.EnableRateLimit = true
c.Security.BlockHighThreatIPs = false
c.Security.ThreatScoreThreshold = 80
// Web services defaults - only generic services, configurable from dashboard
c.WebServices.Generic = []WebServiceConfig{
{
Enabled: false,
Port: 9001,
Name: "admin-panel",
Path: "/admin",
TemplateName: "admin-login.html",
UseHTTPS: false,
},
}
return c
}