0

I need to get a list of VMs that have unrestricted SSH.

I've been browsing the Azure SDK for Python documentation. There is an SshConfiguration class in the compute module, but it only has info about the public keys. There is a different SshConfiguration class in the batch AI module that can be used to get a list of public IPs that are allowed to connect, which is what I want. But I'm not using batch AI.

How can I get the information I want programmatically?

Bhargavi Annadevara
  • 4,923
  • 2
  • 13
  • 30
supernova
  • 149
  • 4
  • 17

1 Answers1

3

You'll have to take a detour for this as there is no direct method in the Compute module that gives this information directly.

Using methods from both the Compute and Network modules, I coded up the following script to list all VMs in the Subscription with unrestricted SSH access, i.e., list all the Inbound rules allowing access to the VM over port 22 from the Internet.

# Imports
from azure.common.credentials import ServicePrincipalCredentials
from azure.mgmt.network import NetworkManagementClient
from azure.mgmt.compute import ComputeManagementClient

# Set subscription ID
SUBSCRIPTION_ID = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'


def get_credentials():
    credentials = ServicePrincipalCredentials(
        client_id='xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
        secret='xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
        tenant='xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
    )

    return credentials


# Get credentials
credentials = get_credentials()

# Initialize management client
network_client = NetworkManagementClient(
    credentials,
    SUBSCRIPTION_ID
)

# Initialize management client
compute_client = ComputeManagementClient(
    credentials,
    SUBSCRIPTION_ID
)


def get_unrestricted_ssh_rules():

    print('\nListing all VMs in Subscription with unrestricted SSH access:')
    for vm in compute_client.virtual_machines.list_all():
        # Get the VM Resource Group name
        vm_rg_name = vm.id.split('/')[4]

        # Loop through NICs
        for nic in vm.network_profile.network_interfaces:
            # Get the NIC name and Resource Group
            nic_name = nic.id.split('/')[-1]
            nic_rg_name = nic.id.split('/')[4]

            # Get the associated NSG and its Resource Group
            nsg = network_client.network_interfaces.get(
                nic_rg_name, nic_name).network_security_group

            nsg_name = nsg.id.split('/')[-1]
            nsg_rg_name = nsg.id.split('/')[4]

            # Get the associated Security Rules
            for rule in network_client.security_rules.list(nsg_rg_name, nsg_name):
                # Conditions:
                # Rule direction: Inbound
                # Rule Access: Allow
                # Port: 22
                # Source Address Prefix: 'Internet' or '*'

                unrestricted = (rule.direction == 'Inbound' and rule.access == 'Allow' and ('22' in (rule.destination_port_ranges, rule.destination_port_range)
                                or rule.destination_port_range == '*') and (rule.source_address_prefix == '*' or rule.source_address_prefix == 'Internet'))
                # Print all the Inbound rules allowing access to the VM over port 22 from the Internet
                if unrestricted:
                    print "\nVM Name: ", vm.name, "\nResource Group Name: ", vm_rg_name, "\nRule Name: ", rule.name


# List all VMs in the Subscription with unrestricted SSH access
get_unrestricted_ssh_rules()

You may repeat the same with Subnets as well if the NSG is associated with a Subnet instead of a NIC.

References:

Hope this helps!

Bhargavi Annadevara
  • 4,923
  • 2
  • 13
  • 30