def _create_A_and_PTR_record(client, zone, name, record, description=None, ttl=None, yes_prompt=False): """Create A and PTR record IPv4.""" record_name = "%s.%s" % (name, zone) # Check if entry exist entry = try_assign(client.recordsets.get, zone, record_name) # If it exists if entry is not None: _show(entry) if yes_prompt or (click.confirm("Entry existed. Update entry instead?", abort=True)): click.echo("Updating A record for %s" % record_name) old_record_ip = ipaddress.ip_address(entry['records'][0]) old_ptr_record_name, old_ptr_zone = \ _get_ptr_name_zone(old_record_ip) update_data = _make_record_update_data(record.exploded, description, ttl) _show(client.recordsets.update(zone, record_name, update_data)) ptr_entry = try_assign(client.recordsets.get, old_ptr_zone, old_ptr_record_name) if ptr_entry is not None: _show(ptr_entry) if yes_prompt or (click.confirm("Delete old PTR record?", abort=True)): click.echo("Deleting PTR record for %s" % old_ptr_record_name) _show(client.recordsets.delete(old_ptr_zone, old_ptr_record_name)) else: click.echo("Creating A record for %s" % record_name) _show(client.recordsets.create(zone, record_name, 'A', [record.exploded], description, ttl)) ptr_record_name, ptr_zone = _get_ptr_name_zone(record) ptr_entry = try_assign(client.recordsets.get, ptr_zone, ptr_record_name) if ptr_entry is not None: _show(ptr_entry) if yes_prompt or (click.confirm("Entry existed. Update entry instead?", abort=True)): click.echo("Updating PTR record for %s" % ptr_record_name) update_data = _make_record_update_data(record_name, description, ttl) _show(client.recordsets.update(ptr_zone, ptr_record_name, update_data)) else: click.echo("Creating PTR record for %s" % ptr_record_name) _show(client.recordsets.create(ptr_zone, ptr_record_name, 'PTR', [record_name], description, ttl))
def free(network, display, limit): """Display defined PTR record for the given CIDR range.""" ds = designate_client.Client(session=get_session()) # Save the raw input of the network raw_network = network network = try_assign(ipaddress.ip_network, network, strict=False, exit=True) # Get the lead IP address to skip of the network lead_ip_address = raw_network.split('/')[0] # Break the network into /24 chunks for PTR search # if NETWORK prefix < 24 if (network.prefixlen < 24): network = network.subnets(new_prefix=24) else: network = [network] # Search the subnet for data records = [] for net in network: net_ptr, net_zone = _get_ptr_name_zone(net) records.extend(_find_free_entries(ds, net, net_zone)) _list(records, display, limit, lead_ip_address)
def delete(zone, name, yes): """Delete the A record and PTR reverse record.""" ds = designate_client.Client(session=get_session()) # Get the record name record_name = "%s.%s" % (name, zone) record = try_assign(ds.recordsets.get, zone, record_name, exit=True) # Delete A record if record['type'] in 'A': _show(record) if (yes or click.confirm("Are you sure you want to delete this record?", abort=True)): click.echo("Deleting A record for %s" % record_name) old_record_ip = ipaddress.ip_address(record['records'][0]) old_ptr_record_name, old_ptr_zone = \ _get_ptr_name_zone(old_record_ip) _show(ds.recordsets.delete(zone, record_name)) ptr_record = try_assign(ds.recordsets.get, old_ptr_zone, old_ptr_record_name) if ptr_record is not None: _show(ptr_record) if (yes or click.confirm("Do you want to delete PTR record?", abort=True)): print("Deleting PTR record for %s" % old_ptr_record_name) _show(ds.recordsets.delete(old_ptr_zone, old_ptr_record_name)) # Delete CNAME record elif record['type'] in 'CNAME': _show(record) if (yes or click.confirm("Are you sure you want to delete this record?", abort=True)): click.echo("Deleting CNAME record for %s" % record_name) _show(ds.recordsets.delete(zone, record_name))
def create(zone, name, type, record, description, ttl, yes): """Create a new designate NAME record in the fully qualified ZONE.""" ds = designate_client.Client(session=get_session()) if type in 'A': # Validate the record IP address ip_address = try_assign(ipaddress.ip_address, record, exit=True) _create_A_and_PTR_record(ds, zone, name, ip_address, description, ttl, yes) elif type in 'CNAME': _create_CNAME_record(ds, zone, name, record, description, ttl, yes) else: click.echo("Type")
def _create_CNAME_record(client, zone, name, record, description=None, ttl=None, yes_prompt=False): """Create CNAME record IPv4.""" record_name = "%s.%s" % (name, zone) # Check if entry exist entry = try_assign(client.recordsets.get, zone, record_name) if entry is not None: _show(entry) if yes_prompt or (click.confirm("Entry existed. Update entry instead?", abort=True)): click.echo("Updating CNAME record for %s" % record_name) update_data = _make_record_update_data(record, description, ttl) _show(client.recordsets.update(zone, record_name, update_data)) else: click.echo("Creating CNAME record for %s" % record_name) _show(client.recordsets.create(zone, record_name, 'CNAME', [record], description, ttl))
def _list_instances(nova, glance, keystone, allocation, aggregate, availability_zone, host, status, projects, allocation_home, exclude_availability_zones, exclude_host, exclude_aggregates): """List all instances.""" hosts = None if host is None else parse_nodes(host) if aggregate: hosts = _find_hosts_in_aggregates(nova, aggregate, hosts) if availability_zone: hosts = _find_hosts_in_azs(nova, availability_zone, hosts) if not projects and allocation_home: projects = _find_projects(allocation, allocation_home) exclude_hosts = [] if exclude_host is None else parse_nodes(exclude_host) if exclude_aggregates: exclude_hosts = _find_hosts_in_aggregates(nova, exclude_aggregates, exclude_hosts) if exclude_availability_zones: exclude_hosts = _find_hosts_in_azs(nova, exclude_availability_zones, exclude_hosts) output = [] # Caching image and flavor USER_CACHE = {} PROJECT_CACHE = {} IMAGE_CACHE = {} FLAVOR_CACHE = {} # Augment the instance info with flavor and image for i in _find_instances(nova, hosts, status, projects): if i._info['OS-EXT-SRV-ATTR:host'] in exclude_hosts: continue flavor_id = i.flavor['id'] if flavor_id not in FLAVOR_CACHE: FLAVOR_CACHE[flavor_id] = nova.flavors.get(flavor_id)._info i._info['flavor'] = FLAVOR_CACHE[flavor_id] if i.image: if i.image['id'] not in IMAGE_CACHE: image = try_assign(glance.images.get, i.image['id']) if not image: image = { 'name': '', 'vcpus': '', 'ram': '', 'swap': '', 'disk': '', 'rxtx_factor': '' } IMAGE_CACHE[i.image['id']] = image i._info['image'] = IMAGE_CACHE[i.image['id']] else: i._info['image'] = { 'name': '', 'vcpus': '', 'ram': '', 'swap': '', 'disk': '', 'rxtx_factor': '' } i._info['project_id'] = i._info['tenant_id'] if i._info['project_id'] not in PROJECT_CACHE: PROJECT_CACHE[i._info['project_id']] = keystone.projects.get( i._info['project_id']) i._info['project'] = PROJECT_CACHE[i._info['project_id']] if i._info['user_id'] not in USER_CACHE: USER_CACHE[i._info['user_id']] = keystone.users.get( i._info['user_id']) i._info['user'] = USER_CACHE[i._info['user_id']] output.append(i) return output
def security_investigate(ip): """Investigate the server at IP address. Use ssh-agent key to find the VM bridge interface and test its SSH authentication method. """ session = get_session() nova = nova_client.Client(2, session=session) glance = glance_client.Client(2, session=session) neutron = neutron_client.Client(session=session) opts = {'all_tenants': True, 'ip': ip} instances = nova.servers.list(search_opts=opts, limit=1) if not instances: return instance = instances[0] target_mac_device = None target_host = instance._info['OS-EXT-SRV-ATTR:hypervisor_hostname'] target_instance_name = instance._info['OS-EXT-SRV-ATTR:instance_name'] # Augment the retrieved instance info if instance.image: image = try_assign(glance.images.get, instance.image['id']) if image: instance._info['image'] = image.name instance_flavor = nova.flavors.get(instance.flavor['id'])._info instance._info['flavor:name'] = instance_flavor['name'] instance._info['flavor:vcpus'] = instance_flavor['vcpus'] instance._info['flavor:ram'] = instance_flavor['ram'] instance._info['os-extended-volumes:volumes_attached'] = \ ', '.join(v['id'] for v in instance._info['os-extended-volumes:volumes_attached']) for az in instance._info['addresses'].keys(): network_name = "%s network" % az network = instance._info['addresses'][az] for net in network: # Retrieve the device mac to find out the correct tap interface if net['addr'] in ip: target_mac_device = net['OS-EXT-IPS-MAC:mac_addr'] break output = ', '.join("%s" % net['addr'] for net in network) instance._info[network_name] = output # Render instance information _render_table_instance(instance) security_groups = generate_instance_sg_rules_info(neutron, instance.id) click.echo(_format_secgroups(security_groups)) nmap_ports = [] # Generate recommendation for nmap scan for sg in security_groups['security_groups']: for rule in sg['security_group_rules']: if (rule['direction'] in 'ingress' and rule['remote_ip_prefix'] and rule['remote_ip_prefix'] in '0.0.0.0/0' and rule['protocol'] in ['tcp', 'udp']): if rule['port_range_min'] == rule['port_range_max']: nmap_ports.append(str(rule['port_range_min'])) else: nmap_ports.append( "%s-%s" % (rule['port_range_min'], rule['port_range_max'])) nmap_command = _recommend_nmap_command(nmap_ports, ip) ENABLED_PASSWORD_LOGIN = False # Probe the server ssh for password login if '22' in nmap_ports: vm_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) vm_sock.connect((ip, 22)) ssh = Session() ssh.handshake(vm_sock) ssh_authlist = ssh.userauth_list('test') click.echo('SSH authentication method list: %s' % ssh_authlist) if 'password' in ssh_authlist: ENABLED_PASSWORD_LOGIN = True # Generate tcpdump host_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) host_sock.connect((target_host, 22)) ssh = Session() ssh.handshake(host_sock) ssh.agent_auth('root') channel = ssh.open_session() channel.execute("virsh dumpxml %s | grep %s -A3 | grep bridge" % (target_instance_name, target_mac_device)) size, data = channel.read() target_bridge_interface = data.split("'")[1] tcpdump_command = "ssh %s 'tcpdump -l -q -i %s not arp and not icmp'" % \ (target_host, target_bridge_interface) # Print out all recommendation click.echo('RECOMMENDATION:') if ENABLED_PASSWORD_LOGIN: click.echo('* RED FLAG: VM has password login enabled!') click.echo("* Discover VM running services by running: %s" % nmap_command) click.echo("* Discover VM network traffics by running: %s" % tcpdump_command)