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:
SsSnake
2026-03-24 06:59:06 -07:00
parent 1092689f45
commit da53899f66
382 changed files with 15277 additions and 493964 deletions

View File

@@ -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."""