diff --git a/Linode/c2.yml b/Linode/c2.yml index 7bbd2a2..5a53103 100644 --- a/Linode/c2.yml +++ b/Linode/c2.yml @@ -9,10 +9,9 @@ - vars.yaml vars: # Default values for required variables - ssh_user: "{{ ssh_user | default('root') }}" linode_region: "{{ linode_region | default(region_choices | random) }}" - plan: "{{ plan | default('g6-standard-1') }}" - image: "{{ image | default('linode/debian11') }}" + plan: "{{ plan | default('g6-standard-2') }}" + image: "{{ image | default('linode/kali') }}" # Generate random instance name if not provided c2_name: "{{ c2_name | default('node-' + 9999999999 | random | to_uuid | hash('md5') | truncate(8, True, '')) }}" @@ -31,7 +30,7 @@ type: "{{ plan }}" region: "{{ linode_region }}" image: "{{ image }}" - root_pass: "{{ lookup('password', '/dev/null length=24 chars=ascii_letters,digits') }}" + root_pass: "{{ lookup('password', '/dev/null length=16') }}" authorized_keys: - "{{ lookup('file', ssh_key_path) }}" state: present @@ -72,12 +71,13 @@ msg: "Could not connect to C2 server via SSH after multiple attempts" when: ssh_test.rc != 0 + # Fix: use hardcoded "root" instead of a nested templating expression - name: Add C2 to inventory add_host: name: "c2" groups: "c2servers" ansible_host: "{{ c2_ip }}" - ansible_user: "root" # Hard-coded instead of using ssh_user + ansible_user: "root" ansible_ssh_private_key_file: "{{ ssh_key_path | replace('.pub', '') }}" ansible_ssh_common_args: "-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" diff --git a/Linode/redirector.yml b/Linode/redirector.yml index 5f2f7f8..e61746b 100644 --- a/Linode/redirector.yml +++ b/Linode/redirector.yml @@ -9,10 +9,9 @@ - vars.yaml vars: # Default values for required variables - ssh_user: "{{ ssh_user | default('root') }}" linode_region: "{{ linode_region | default(region_choices | random) }}" - plan: "{{ plan | default('g6-standard-1') }}" - image: "{{ image | default('linode/debian11') }}" + plan: "{{ plan | default('g6-nanode-1') }}" + image: "{{ image | default('linode/kali') }}" # Generate random instance name if not provided redirector_name: "{{ redirector_name | default('srv-' + 9999999999 | random | to_uuid | hash('md5') | truncate(8, True, '')) }}" @@ -34,7 +33,7 @@ type: "{{ plan }}" region: "{{ linode_region }}" image: "{{ image }}" - root_pass: "{{ lookup('password', '/dev/null length=24 chars=ascii_letters,digits') }}" + root_pass: "{{ lookup('password', '/dev/null length=16') }}" authorized_keys: - "{{ lookup('file', ssh_key_path) }}" state: present @@ -45,7 +44,7 @@ redirector_ip: "{{ redirector_instance.instance.ipv4[0] }}" redirector_instance_id: "{{ redirector_instance.instance.id }}" - # Enhanced SSH wait task for Linode/redirector.yml + # Enhanced SSH wait task with better retry mechanism - name: Wait for redirector SSH to be available block: - name: Initial wait for port to be open @@ -75,12 +74,15 @@ msg: "Could not connect to redirector via SSH after multiple attempts" when: ssh_test.rc != 0 + # Fix: Use hardcoded "redirector" for the name and "root" for the user - name: Add redirector to inventory add_host: - name: "{{ redirector_name }}" + name: "redirector" + groups: "redirectors" ansible_host: "{{ redirector_ip }}" - ansible_user: "root" # Or directly use the user you need + ansible_user: "root" ansible_ssh_private_key_file: "{{ ssh_key_path | replace('.pub', '') }}" + ansible_ssh_common_args: "-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" - name: Configure redirector server hosts: redirectors @@ -89,7 +91,7 @@ vars_files: - vars.yaml vars: - c2_ip: "{{ c2_ip | default('127.0.0.1') }}" + c2_ip: "{{ hostvars['localhost']['c2_ip'] | default('127.0.0.1') }}" redirector_subdomain: "{{ redirector_subdomain | default('cdn') }}" tasks: - name: Wait for apt to be available @@ -115,9 +117,6 @@ - name: Include common redirector configuration tasks include_tasks: "../tasks/configure_redirector.yml" - - name: Include common security hardening tasks - include_tasks: "../tasks/security_hardening.yml" - - name: Print deployment summary debug: msg: diff --git a/deploy.py b/deploy.py index 8ae25be..edae349 100644 --- a/deploy.py +++ b/deploy.py @@ -436,10 +436,23 @@ def select_random_region(config): if provider == "aws": region_choices = config.get("aws_region_choices", []) elif provider == "linode": - # Look for multiple possible key names in the Linode config + # Look for both variations of the key name region_choices = config.get("region_choices", []) + + # Debug the vars_data content + logging.debug(f"Linode config keys: {config.keys()}") + if not region_choices: - region_choices = config.get("linode_region_choices", []) + # Load directly from vars.yaml as fallback + try: + vars_file = "Linode/vars.yaml" + if os.path.exists(vars_file): + with open(vars_file, 'r') as f: + vars_data = yaml.safe_load(f) + region_choices = vars_data.get('region_choices', []) + logging.debug(f"Loaded region_choices directly from {vars_file}: {region_choices}") + except Exception as e: + logging.warning(f"Failed to load regions from vars file: {e}") elif provider == "flokinet": region_choices = config.get("flokinet_region_choices", []) @@ -505,6 +518,15 @@ def run_ansible_playbook(playbook, inventory, config, debug=False): # Convert config dict to JSON for extra-vars # Filter out None values and complex objects extra_vars = {k: v for k, v in config.items() if v is not None and not isinstance(v, (dict, list, tuple))} + + # Explicitly set hard-coded user values rather than using templated defaults + if 'ssh_user' in extra_vars: + extra_vars.pop('ssh_user') + if config['provider'] == 'linode': + extra_vars['ssh_user'] = 'root' + else: + extra_vars['ssh_user'] = 'kali' + extra_vars_json = json.dumps(extra_vars) # Build command @@ -561,6 +583,12 @@ def deploy_infrastructure(config): if config.get('linode_token'): os.environ['LINODE_TOKEN'] = config['linode_token'] + # IMPORTANT: Ensure ssh_user is explicitly set to avoid template recursion + if provider == "linode": + config['ssh_user'] = "root" + elif provider == "aws": + config['ssh_user'] = "kali" + # Select random region if not specified if not config.get('region'): config['region'] = select_random_region(config) @@ -1097,6 +1125,10 @@ C2itAll - Red Team Infrastructure Setup # Provider settings config['provider'] = args.provider + # Copy all values from vars_data to config first + for key, value in vars_data.items(): + config[key] = value + # AWS settings if args.provider == "aws": config['aws_access_key'] = args.aws_key or vars_data.get('aws_access_key') @@ -1110,6 +1142,7 @@ C2itAll - Red Team Infrastructure Setup elif args.provider == "linode": config['linode_token'] = args.linode_token or vars_data.get('linode_token') config['linode_region'] = args.linode_region or args.region or vars_data.get('linode_region') + # Ensure region_choices are correctly set config['region_choices'] = vars_data.get('region_choices', []) config['plan'] = args.size or vars_data.get('plan', 'g6-standard-2') config['image'] = vars_data.get('image', 'linode/kali') @@ -1121,8 +1154,14 @@ C2itAll - Red Team Infrastructure Setup config['flokinet_region_choices'] = vars_data.get('flokinet_region_choices', []) config['ssh_port'] = vars_data.get('ssh_port', 22) - # SSH settings - config['ssh_user'] = args.ssh_user or vars_data.get('ssh_user') or (DEFAULT_SSH_USER.get(args.provider) if args.provider else None) + # SSH settings - explicitly set SSH user to avoid template recursion + if args.provider == "linode": + config['ssh_user'] = "root" + elif args.provider == "aws": + config['ssh_user'] = "kali" + else: + config['ssh_user'] = args.ssh_user or vars_data.get('ssh_user') or (DEFAULT_SSH_USER.get(args.provider) if args.provider else None) + if args.ssh_key: config['ssh_key'] = os.path.expanduser(args.ssh_key) else: