AUTARCH v1.9 — remote monitoring, SSH manager, daemon, vault, cleanup
- Add Remote Monitoring Station with PIAP device profile system - Add SSH/SSHD manager with fail2ban integration - Add privileged daemon architecture for safe root operations - Add encrypted vault, HAL memory, HAL auto-analyst - Add network security suite, module creator, codex training - Add start.sh launcher script and GTK3 desktop launcher - Remove Output/ build artifacts, installer files, loose docs - Update .gitignore for runtime data and build artifacts - Update README for v1.9 with new launch method, screenshots, and features Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
160
core/config.py
160
core/config.py
@@ -82,6 +82,32 @@ class Config:
|
||||
'secret_key': '',
|
||||
'mcp_port': '8081',
|
||||
},
|
||||
'mcp': {
|
||||
'enabled': 'false',
|
||||
'auto_start': 'false',
|
||||
'transport': 'sse',
|
||||
'host': '0.0.0.0',
|
||||
'port': '8081',
|
||||
'log_level': 'INFO',
|
||||
'instructions': 'AUTARCH security framework tools',
|
||||
'auth_enabled': 'false',
|
||||
'auth_token': '',
|
||||
'rate_limit': '',
|
||||
'mask_errors': 'false',
|
||||
'request_timeout': '120',
|
||||
'max_message_size': '10485760',
|
||||
'cors_origins': '*',
|
||||
'ssl_enabled': 'false',
|
||||
'ssl_cert': '',
|
||||
'ssl_key': '',
|
||||
'disabled_tools': '',
|
||||
'nmap_timeout': '120',
|
||||
'tcpdump_timeout': '30',
|
||||
'whois_timeout': '15',
|
||||
'dns_timeout': '10',
|
||||
'geoip_timeout': '10',
|
||||
'geoip_endpoint': 'http://ip-api.com/json/',
|
||||
},
|
||||
'revshell': {
|
||||
'enabled': 'true',
|
||||
'host': '0.0.0.0',
|
||||
@@ -112,6 +138,23 @@ class Config:
|
||||
'n_gpu_layers': '-1',
|
||||
'n_threads': '4',
|
||||
},
|
||||
'agents': {
|
||||
'backend': 'local',
|
||||
'local_max_steps': '20',
|
||||
'local_verbose': 'true',
|
||||
'claude_enabled': 'false',
|
||||
'claude_model': 'claude-sonnet-4-6',
|
||||
'claude_max_tokens': '16384',
|
||||
'claude_max_steps': '30',
|
||||
'openai_enabled': 'false',
|
||||
'openai_model': 'gpt-4o',
|
||||
'openai_base_url': 'https://api.openai.com/v1',
|
||||
'openai_max_tokens': '16384',
|
||||
'openai_max_steps': '30',
|
||||
},
|
||||
'hal_memory': {
|
||||
'max_bytes': str(4 * 1024 * 1024 * 1024), # 4GB default
|
||||
},
|
||||
'autonomy': {
|
||||
'enabled': 'false',
|
||||
'monitor_interval': '3',
|
||||
@@ -267,6 +310,42 @@ class Config:
|
||||
'save_raw_output': self.get_bool('pentest', 'save_raw_output', True),
|
||||
}
|
||||
|
||||
def _get_secret(self, key: str, fallback_section: str = '', fallback_key: str = 'api_key') -> str:
|
||||
"""Get a secret from the vault, falling back to plaintext config.
|
||||
|
||||
This allows a gradual migration: existing plaintext keys still work,
|
||||
but new keys go to the vault. When a plaintext key is found, it's
|
||||
automatically migrated to the vault on next save.
|
||||
"""
|
||||
try:
|
||||
from core.vault import get_vault
|
||||
vault = get_vault()
|
||||
val = vault.get(key, '')
|
||||
if val:
|
||||
return val
|
||||
except Exception:
|
||||
pass
|
||||
# Fallback to plaintext config
|
||||
if fallback_section:
|
||||
return self.get(fallback_section, fallback_key, '')
|
||||
return ''
|
||||
|
||||
def _set_secret(self, key: str, value: str, config_section: str = '', config_key: str = 'api_key'):
|
||||
"""Store a secret in the vault and clear the plaintext config value."""
|
||||
if not value:
|
||||
return
|
||||
try:
|
||||
from core.vault import get_vault
|
||||
vault = get_vault()
|
||||
vault.set(key, value)
|
||||
# Clear plaintext from config file for security
|
||||
if config_section:
|
||||
self.set(config_section, config_key, '')
|
||||
except Exception:
|
||||
# Vault not available — store in config as before
|
||||
if config_section:
|
||||
self.set(config_section, config_key, value)
|
||||
|
||||
def get_claude_settings(self) -> dict:
|
||||
"""Get all Claude API settings as a dictionary.
|
||||
|
||||
@@ -274,7 +353,7 @@ class Config:
|
||||
Dictionary with Claude API settings properly typed
|
||||
"""
|
||||
return {
|
||||
'api_key': self.get('claude', 'api_key', ''),
|
||||
'api_key': self._get_secret('claude_api_key', 'claude', 'api_key'),
|
||||
'model': self.get('claude', 'model', 'claude-sonnet-4-20250514'),
|
||||
'max_tokens': self.get_int('claude', 'max_tokens', 4096),
|
||||
'temperature': self.get_float('claude', 'temperature', 0.7),
|
||||
@@ -305,7 +384,7 @@ class Config:
|
||||
def get_huggingface_settings(self) -> dict:
|
||||
"""Get all HuggingFace Inference API settings as a dictionary."""
|
||||
return {
|
||||
'api_key': self.get('huggingface', 'api_key', ''),
|
||||
'api_key': self._get_secret('huggingface_api_key', 'huggingface', 'api_key'),
|
||||
'model': self.get('huggingface', 'model', 'mistralai/Mistral-7B-Instruct-v0.3'),
|
||||
'endpoint': self.get('huggingface', 'endpoint', ''),
|
||||
'provider': self.get('huggingface', 'provider', 'auto'),
|
||||
@@ -322,7 +401,7 @@ class Config:
|
||||
def get_openai_settings(self) -> dict:
|
||||
"""Get all OpenAI API settings as a dictionary."""
|
||||
return {
|
||||
'api_key': self.get('openai', 'api_key', ''),
|
||||
'api_key': self._get_secret('openai_api_key', 'openai', 'api_key'),
|
||||
'base_url': self.get('openai', 'base_url', 'https://api.openai.com/v1'),
|
||||
'model': self.get('openai', 'model', 'gpt-4o'),
|
||||
'max_tokens': self.get_int('openai', 'max_tokens', 4096),
|
||||
@@ -355,6 +434,35 @@ class Config:
|
||||
'mappings': self.get('upnp', 'mappings', ''),
|
||||
}
|
||||
|
||||
def get_mcp_settings(self) -> dict:
|
||||
"""Get all MCP server settings as a dictionary."""
|
||||
return {
|
||||
'enabled': self.get_bool('mcp', 'enabled', False),
|
||||
'auto_start': self.get_bool('mcp', 'auto_start', False),
|
||||
'transport': self.get('mcp', 'transport', 'sse'),
|
||||
'host': self.get('mcp', 'host', '0.0.0.0'),
|
||||
'port': self.get_int('mcp', 'port', 8081),
|
||||
'log_level': self.get('mcp', 'log_level', 'INFO'),
|
||||
'instructions': self.get('mcp', 'instructions', 'AUTARCH security framework tools'),
|
||||
'auth_enabled': self.get_bool('mcp', 'auth_enabled', False),
|
||||
'auth_token': self.get('mcp', 'auth_token', ''),
|
||||
'rate_limit': self.get('mcp', 'rate_limit', ''),
|
||||
'mask_errors': self.get_bool('mcp', 'mask_errors', False),
|
||||
'request_timeout': self.get_int('mcp', 'request_timeout', 120),
|
||||
'max_message_size': self.get_int('mcp', 'max_message_size', 10485760),
|
||||
'cors_origins': self.get('mcp', 'cors_origins', '*'),
|
||||
'ssl_enabled': self.get_bool('mcp', 'ssl_enabled', False),
|
||||
'ssl_cert': self.get('mcp', 'ssl_cert', ''),
|
||||
'ssl_key': self.get('mcp', 'ssl_key', ''),
|
||||
'disabled_tools': self.get('mcp', 'disabled_tools', ''),
|
||||
'nmap_timeout': self.get_int('mcp', 'nmap_timeout', 120),
|
||||
'tcpdump_timeout': self.get_int('mcp', 'tcpdump_timeout', 30),
|
||||
'whois_timeout': self.get_int('mcp', 'whois_timeout', 15),
|
||||
'dns_timeout': self.get_int('mcp', 'dns_timeout', 10),
|
||||
'geoip_timeout': self.get_int('mcp', 'geoip_timeout', 10),
|
||||
'geoip_endpoint': self.get('mcp', 'geoip_endpoint', 'http://ip-api.com/json/'),
|
||||
}
|
||||
|
||||
def get_revshell_settings(self) -> dict:
|
||||
"""Get all reverse shell settings as a dictionary."""
|
||||
return {
|
||||
@@ -364,6 +472,35 @@ class Config:
|
||||
'auto_start': self.get_bool('revshell', 'auto_start', False),
|
||||
}
|
||||
|
||||
def get_mcp_settings(self) -> dict:
|
||||
"""Get MCP server settings."""
|
||||
return {
|
||||
'enabled': self.get_bool('mcp', 'enabled', False),
|
||||
'auto_start': self.get_bool('mcp', 'auto_start', False),
|
||||
'transport': self.get('mcp', 'transport', 'sse'),
|
||||
'host': self.get('mcp', 'host', '0.0.0.0'),
|
||||
'port': self.get_int('mcp', 'port', 8081),
|
||||
'log_level': self.get('mcp', 'log_level', 'INFO'),
|
||||
'instructions': self.get('mcp', 'instructions', 'AUTARCH security framework tools'),
|
||||
'auth_enabled': self.get_bool('mcp', 'auth_enabled', False),
|
||||
'auth_token': self.get('mcp', 'auth_token', ''),
|
||||
'rate_limit': self.get('mcp', 'rate_limit', ''),
|
||||
'mask_errors': self.get_bool('mcp', 'mask_errors', False),
|
||||
'request_timeout': self.get_int('mcp', 'request_timeout', 120),
|
||||
'max_message_size': self.get_int('mcp', 'max_message_size', 10485760),
|
||||
'cors_origins': self.get('mcp', 'cors_origins', '*'),
|
||||
'ssl_enabled': self.get_bool('mcp', 'ssl_enabled', False),
|
||||
'ssl_cert': self.get('mcp', 'ssl_cert', ''),
|
||||
'ssl_key': self.get('mcp', 'ssl_key', ''),
|
||||
'disabled_tools': self.get('mcp', 'disabled_tools', ''),
|
||||
'nmap_timeout': self.get_int('mcp', 'nmap_timeout', 120),
|
||||
'tcpdump_timeout': self.get_int('mcp', 'tcpdump_timeout', 30),
|
||||
'whois_timeout': self.get_int('mcp', 'whois_timeout', 15),
|
||||
'dns_timeout': self.get_int('mcp', 'dns_timeout', 10),
|
||||
'geoip_timeout': self.get_int('mcp', 'geoip_timeout', 10),
|
||||
'geoip_endpoint': self.get('mcp', 'geoip_endpoint', 'http://ip-api.com/json/'),
|
||||
}
|
||||
|
||||
def get_tier_settings(self, tier: str) -> dict:
|
||||
"""Get settings for a model tier (slm, sam, lam)."""
|
||||
return {
|
||||
@@ -398,6 +535,23 @@ class Config:
|
||||
'log_max_entries': self.get_int('autonomy', 'log_max_entries', 1000),
|
||||
}
|
||||
|
||||
def get_agents_settings(self) -> dict:
|
||||
"""Get agent configuration settings."""
|
||||
return {
|
||||
'backend': self.get('agents', 'backend', 'local'),
|
||||
'local_max_steps': self.get_int('agents', 'local_max_steps', 20),
|
||||
'local_verbose': self.get_bool('agents', 'local_verbose', True),
|
||||
'claude_enabled': self.get_bool('agents', 'claude_enabled', False),
|
||||
'claude_model': self.get('agents', 'claude_model', 'claude-sonnet-4-6'),
|
||||
'claude_max_tokens': self.get_int('agents', 'claude_max_tokens', 16384),
|
||||
'claude_max_steps': self.get_int('agents', 'claude_max_steps', 30),
|
||||
'openai_enabled': self.get_bool('agents', 'openai_enabled', False),
|
||||
'openai_model': self.get('agents', 'openai_model', 'gpt-4o'),
|
||||
'openai_base_url': self.get('agents', 'openai_base_url', 'https://api.openai.com/v1'),
|
||||
'openai_max_tokens': self.get_int('agents', 'openai_max_tokens', 16384),
|
||||
'openai_max_steps': self.get_int('agents', 'openai_max_steps', 30),
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def get_templates_dir() -> Path:
|
||||
"""Get the path to the configuration templates directory."""
|
||||
|
||||
Reference in New Issue
Block a user