如何以编程方式查找具有不受限制的 SSH 连接的虚拟机?

How can I programmatically find VMs with unrestricted SSH connection?

我需要获取具有不受限 SSH 的 VM 列表。

我一直在浏览 Azure SDK 以获取 Python 文档。有一个 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 可以用来获取允许连接的 public IP 列表,这就是我想要的。但我没有使用批处理 AI。

如何以编程方式获取我想要的信息?

您必须为此绕道而行,因为计算模块中没有直接提供此信息的直接方法。

使用计算和网络模块中的方法,我编写了以下脚本以列出订阅中具有不受限制的 SSH 访问权限的所有 VM,即列出所有允许通过端口 22 从 VM 访问 VM 的入站规则互联网。

# 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()

如果 NSG 与子网而不是 NIC 相关联,您也可以对子网重复相同的操作。

参考文献:

希望对您有所帮助!