Fix secret vars sourced from env, not config copy
create_extra_vars callers pass {**config} copies so linode_token never
landed in the original config dict. Pull provider credentials from the
environment (already set by set_provider_environment) so the temp-file
secret path works regardless of how config was constructed.
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
WEBRUNNER smoke test — 1 nanode, masscan-only, operator IP /32, port 22, auto-teardown.
|
||||
Run from c2itall root: python3 smoke_test_webrunner.py
|
||||
"""
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, os.path.dirname(__file__))
|
||||
|
||||
from utils.common import generate_deployment_id, setup_logging
|
||||
from utils.ssh_utils import generate_ssh_key
|
||||
from utils.deployment_engine import execute_playbook, set_provider_environment
|
||||
|
||||
OPERATOR_IP = "129.222.0.125"
|
||||
TARGET_CIDR = f"{OPERATOR_IP}/32"
|
||||
|
||||
config = {}
|
||||
config['deployment_id'] = generate_deployment_id()
|
||||
config['engagement'] = 'smoketest'
|
||||
config['deployment_type'] = 'webrunner'
|
||||
config['webrunner_deployment'] = True
|
||||
config['webrunner_name'] = f"wr-smoke-{config['deployment_id']}"
|
||||
|
||||
# Provider — cheapest Linode nanode
|
||||
config['providers'] = ['linode']
|
||||
config['provider'] = 'linode'
|
||||
config['linode_region'] = 'us-east'
|
||||
config['linode_instance_type'] = 'g6-nanode-1'
|
||||
config['linode_image'] = 'linode/debian12'
|
||||
|
||||
# Scan — masscan-only, single port, operator /32
|
||||
config['scan_mode'] = 'masscan-only'
|
||||
config['ports'] = [22]
|
||||
config['ports_str'] = '22'
|
||||
config['masscan_rate'] = 1000
|
||||
config['use_tor'] = False
|
||||
config['targets_file'] = ''
|
||||
config['total_ips'] = 1
|
||||
config['preset'] = 'sprint'
|
||||
config['chunk_size'] = 500_000
|
||||
|
||||
# OPSEC
|
||||
config['operator_ip'] = OPERATOR_IP
|
||||
config['enhanced_opsec'] = False
|
||||
config['teardown_after_scan'] = True
|
||||
|
||||
# SSH key
|
||||
ssh_key_path = generate_ssh_key(config['webrunner_name'])
|
||||
if not ssh_key_path:
|
||||
sys.exit('Failed to generate SSH key')
|
||||
config['ssh_key_path'] = f"{ssh_key_path}.pub"
|
||||
config['ssh_key_name'] = os.path.basename(ssh_key_path)
|
||||
|
||||
# Single node chunk targeting operator IP
|
||||
node_chunks = [{
|
||||
'idx': 0,
|
||||
'node_name': f"{config['webrunner_name']}-01",
|
||||
'provider': 'linode',
|
||||
'cidrs': [TARGET_CIDR],
|
||||
'ip_count': 1,
|
||||
}]
|
||||
|
||||
logs_dir = os.path.abspath('logs')
|
||||
os.makedirs(logs_dir, exist_ok=True)
|
||||
chunks_file = os.path.join(logs_dir, f"node_chunks_{config['deployment_id']}.json")
|
||||
with open(chunks_file, 'w') as f:
|
||||
json.dump(node_chunks, f)
|
||||
|
||||
config['node_chunks_file'] = chunks_file
|
||||
config['scanner_ip_log'] = os.path.join(logs_dir, f"scanner_ips_{config['webrunner_name']}.txt")
|
||||
config['results_dir'] = os.path.join(logs_dir, f"webrunner_{config['deployment_id']}")
|
||||
|
||||
log_file = setup_logging(config['deployment_id'], 'webrunner_smoketest')
|
||||
|
||||
print(f"\n[*] WEBRUNNER smoke test")
|
||||
print(f" ID: {config['deployment_id']}")
|
||||
print(f" Target: {TARGET_CIDR} (operator IP)")
|
||||
print(f" Mode: masscan-only, port 22")
|
||||
print(f" Node: g6-nanode-1 @ us-east (auto-teardown)\n")
|
||||
|
||||
set_provider_environment({**config, 'provider': 'linode'})
|
||||
|
||||
success = execute_playbook('providers/webrunner.yml', config)
|
||||
sys.exit(0 if success else 1)
|
||||
@@ -166,9 +166,21 @@ def execute_playbook(playbook, config):
|
||||
|
||||
# Write sensitive vars to a temp file (0o600) so they reach Ansible as
|
||||
# variables without appearing in process listings or the main extra-vars JSON.
|
||||
secret_vars = {k: v for k, v in config.items()
|
||||
if v is not None
|
||||
and any(s in k.lower() for s in _SECRET_KEYS)}
|
||||
# Read from environment (set by set_provider_environment) so this works even
|
||||
# when config was passed as a copy ({**config}) that didn't capture the token.
|
||||
secret_vars = {}
|
||||
if os.environ.get('LINODE_TOKEN'):
|
||||
secret_vars['linode_token'] = os.environ['LINODE_TOKEN']
|
||||
if os.environ.get('AWS_ACCESS_KEY_ID'):
|
||||
secret_vars['aws_access_key'] = os.environ['AWS_ACCESS_KEY_ID']
|
||||
if os.environ.get('AWS_SECRET_ACCESS_KEY'):
|
||||
secret_vars['aws_secret_key'] = os.environ['AWS_SECRET_ACCESS_KEY']
|
||||
if os.environ.get('FLOKINET_API_KEY'):
|
||||
secret_vars['flokinet_api_key'] = os.environ['FLOKINET_API_KEY']
|
||||
# Also pick up any remaining secret keys from config dict (e.g. smtp_auth_pass)
|
||||
for k, v in config.items():
|
||||
if v is not None and k not in secret_vars and any(s in k.lower() for s in _SECRET_KEYS):
|
||||
secret_vars[k] = v
|
||||
if secret_vars:
|
||||
fd, secret_vars_file = tempfile.mkstemp(suffix='.json', prefix='ansible_secret_')
|
||||
os.chmod(secret_vars_file, 0o600)
|
||||
|
||||
Reference in New Issue
Block a user