示例#1
0
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))
示例#2
0
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)
示例#3
0
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))
示例#4
0
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")
示例#5
0
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))
示例#6
0
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
示例#7
0
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)