Skip to content

network

Sample rules

A few rules that use objects from this package:

non_car_unused_network_security_group
from typing import Dict, List

from cloudrail.knowledge.context.azure.azure_environment_context import AzureEnvironmentContext
from cloudrail.knowledge.rules.azure.azure_base_rule import AzureBaseRule
from cloudrail.knowledge.rules.base_rule import Issue
from cloudrail.knowledge.rules.rule_parameters.base_paramerter import ParameterType


class UnusedNetworkSecurityGroupRule(AzureBaseRule):

    def get_id(self) -> str:
        return 'non_car_unused_network_security_group'

    def execute(self, env_context: AzureEnvironmentContext, parameters: Dict[ParameterType, any]) -> List[Issue]:
        issues: List[Issue] = []
        for nsg in env_context.net_security_groups:
            if not nsg.subnets and not nsg.network_interfaces:
                issues.append(
                    Issue(
                        f'{nsg.get_type()}  `{nsg.get_friendly_name()}` is unused',
                        nsg,
                        nsg))
        return issues

    def should_run_rule(self, environment_context: AzureEnvironmentContext) -> bool:
        return bool(environment_context.net_security_groups)
non_car_vpn_gateway_disallow_basic_sku
from typing import Dict, List

from cloudrail.knowledge.context.azure.azure_environment_context import AzureEnvironmentContext
from cloudrail.knowledge.context.azure.resources.network.azure_vnet_gateway import VirtualNetworkGatewayType
from cloudrail.knowledge.rules.azure.azure_base_rule import AzureBaseRule
from cloudrail.knowledge.rules.base_rule import Issue
from cloudrail.knowledge.rules.rule_parameters.base_paramerter import ParameterType


class VpnGatewayDisallowBasicSkuRule(AzureBaseRule):

    def get_id(self) -> str:
        return 'non_car_vpn_gateway_disallow_basic_sku'

    def execute(self, env_context: AzureEnvironmentContext, parameters: Dict[ParameterType, any]) -> List[Issue]:
        issues: List[Issue] = []
        for vnet_gw in env_context.vnet_gateways:
            if vnet_gw.gateway_type == VirtualNetworkGatewayType.VPN and vnet_gw.sku_tier == 'Basic':
                issues.append(
                    Issue(
                        f'{vnet_gw.get_type()} `{vnet_gw.get_friendly_name()}` uses "basic" SKU',
                        vnet_gw,
                        vnet_gw))
        return issues

    def should_run_rule(self, environment_context: AzureEnvironmentContext) -> bool:
        return bool(environment_context.vnet_gateways)
car_vm_not_publicly_accessible_rdp
from abc import abstractmethod
from dataclasses import dataclass
from typing import List, Dict, Optional, Union, Iterable

from cloudrail.knowledge.context.azure.resources.network.azure_network_interface import AzureNetworkInterface
from cloudrail.knowledge.context.azure.resources.network.azure_network_security_group import AzureNetworkSecurityGroup
from cloudrail.knowledge.context.azure.resources.network.azure_network_security_group_rule import AzureNetworkSecurityRule, \
    NetworkSecurityRuleActionType
from cloudrail.knowledge.context.azure.resources.network.azure_public_ip import AzurePublicIp
from cloudrail.knowledge.context.azure.resources.network_resource import NetworkResource
from cloudrail.knowledge.context.connection import ConnectionType, PortConnectionProperty, ConnectionDirectionType
from cloudrail.knowledge.context.azure.azure_environment_context import AzureEnvironmentContext
from cloudrail.knowledge.rules.azure.azure_base_rule import AzureBaseRule
from cloudrail.knowledge.rules.base_rule import Issue
from cloudrail.knowledge.rules.rule_parameters.base_paramerter import ParameterType
from cloudrail.knowledge.utils.port_set import PortSet


@dataclass
class ViolationData:
    violating_resource: Optional[Union[AzureNetworkSecurityGroup, AzureNetworkSecurityRule, AzurePublicIp]]
    public_ip: Optional[str]


class NotPubliclyAccessibleBaseRule(AzureBaseRule):

    def __init__(self, port: int, port_protocol: str):
        self.port: int = port
        self.port_protocol: str = port_protocol

    def execute(self, env_context: AzureEnvironmentContext, parameters: Dict[ParameterType, any]) -> List[Issue]:
        issues: List[Issue] = []
        for resource in self.get_resources(env_context):
            violating = self._get_violating(resource.network_interfaces)

            if violating:
                resource_msg = f'The {resource.get_type()} `{resource.get_friendly_name()}`'
                if isinstance(violating.violating_resource, (AzureNetworkSecurityGroup, AzurePublicIp)):
                    if violating.public_ip:
                        public_ip_msg = f'with public IP address `{violating.public_ip}`'
                    else:
                        public_ip_msg = 'with unknown public IP address'
                    issues.append(Issue(f'{resource_msg} '
                                        f'{public_ip_msg} is reachable from the internet via {self.port_protocol} port', resource, violating.violating_resource))
                else:
                    issues.append(Issue(
                        f'{resource_msg} with NAT rule '
                        f'`{violating.violating_resource.get_friendly_name()}` is reachable from the internet via {self.port_protocol} port',
                        resource, violating.violating_resource))
        return issues

    def _get_violating(self, network_interfaces: List[AzureNetworkInterface]) -> Optional[ViolationData]:
        for nic in network_interfaces:
            for ip_config in nic.ip_configurations:
                for inbound_connection in ip_config.inbound_connections:
                    if inbound_connection.connection_type == ConnectionType.PUBLIC \
                            and isinstance(inbound_connection.connection_property, PortConnectionProperty) \
                            and self.port in PortSet(inbound_connection.connection_property.ports):
                        if nic.network_security_group is None and ip_config.subnet.network_security_group is None:
                            return ViolationData(ip_config.public_ip, ip_config.public_ip.public_ip_address)
                        return ViolationData(self._get_violating_nsg_or_rule(nic.network_security_group, ip_config.subnet.network_security_group),
                                             ip_config.public_ip.public_ip_address)
        return None

    def _get_violating_nsg_or_rule(self, nic_nsg: Optional[AzureNetworkSecurityGroup], subnet_nsg: Optional[AzureNetworkSecurityGroup]):
        for nsg in list(filter(None, [nic_nsg, subnet_nsg])):
            for nsg_rule in nsg.network_security_rules:
                if nsg_rule.direction == ConnectionDirectionType.INBOUND and nsg_rule.access == NetworkSecurityRuleActionType.ALLOW and self.port in nsg_rule.destination_port_ranges:
                    if nsg_rule.is_managed_by_iac:
                        return nsg_rule
                    return nsg
        return None

    @abstractmethod
    def get_id(self) -> str:
        pass

    @staticmethod
    @abstractmethod
    def get_resources(env_context: AzureEnvironmentContext) -> Iterable[NetworkResource]:
        pass

    def should_run_rule(self, environment_context: AzureEnvironmentContext) -> bool:
        return bool(self.get_resources(environment_context))


class VirtualMachineNotPubliclyAccessibleRdpRule(NotPubliclyAccessibleBaseRule):

    def __init__(self):
        super().__init__(3389, 'RDP')

    def get_id(self) -> str:
        return 'car_vm_not_publicly_accessible_rdp'

    @staticmethod
    def get_resources(env_context: AzureEnvironmentContext):
        return env_context.virtual_machines


class VirtualMachineNotPubliclyAccessibleSshRule(NotPubliclyAccessibleBaseRule):

    def __init__(self):
        super().__init__(22, 'SSH')

    def get_id(self) -> str:
        return 'car_vm_not_publicly_accessible_ssh'

    @staticmethod
    def get_resources(env_context: AzureEnvironmentContext):
        return env_context.virtual_machines

AzureNetworkInterface (AzureResource)

Attributes:

Name Type Description
name str

The name of this network interface.

network_security_group Optional[AzureNetworkSecurityGroup]

The security group that's attached to this network interface.

ip_configurations List[IpConfiguration]

IP configurations of a network interface.

custom_invalidation(self) inherited

A list of manual reasons why this resource should be invalidated

exclude_from_invalidation(self) inherited

A list of attributes that should be excluded from the invalidation process

IpConfiguration (ConnectionInstance)

Attributes:

Name Type Description
public_ip_id str

The ID of the PublicIp resource that's attached to this IP Configuration resource.

public_ip AzurePublicIp

The actual PublicIp resource that's attached to this IP Configuration resource.

subnet_id str

The ID of the Subnet that this IP Configuration resource is attached to.

subnet AzureSubnet

The actual Subnet that this IP Configuration resource is attached to.

private_ip Optional[str]

The private ip address of this IP Configuration.

application_security_groups_ids List[str]

List of ASG's id's that's attached to this IP Configuration resource.

application_security_groups List[AzureApplicationSecurityGroup]

List of actual ASG's that's attached to this IP Configuration resource.

AzureSubnet (AzureResource)

Attributes:

Name Type Description
name str

The name of this subnet

network_security_group Optional[AzureNetworkSecurityGroup]

The actual security group that's attached to this subnet.

custom_invalidation(self) inherited

A list of manual reasons why this resource should be invalidated

exclude_from_invalidation(self) inherited

A list of attributes that should be excluded from the invalidation process

AzureNetworkInterfaceSecurityGroupAssociation (AzureResource)

Attributes:

Name Type Description
network_interface_id str

The network interface id which needs to be connected to the network security group.

network_security_group_id

The network security group id which needs to be connected to the network interface.

custom_invalidation(self) inherited

A list of manual reasons why this resource should be invalidated

exclude_from_invalidation(self) inherited

A list of attributes that should be excluded from the invalidation process

AzureSecurityGroupToSubnetAssociation (AzureResource)

Attributes:

Name Type Description
subnet_id str

The subnet id which needs to be connected to the network security group.

network_security_group_id

The network security group id which needs to be connected to the subnet.

custom_invalidation(self) inherited

A list of manual reasons why this resource should be invalidated

exclude_from_invalidation(self) inherited

A list of attributes that should be excluded from the invalidation process

AzureNetworkSecurityGroup (AzureResource)

Attributes:

Name Type Description
name str

The network security group name.

subnets List['AzureSubnet']

List of subnets which the network security group is connected to.

network_interfaces List['AzureNetworkInterface']

List of actual network interfaces which the network security group is connected to.

network_security_rules List[AzureNetworkSecurityRule]

The rules that are assigned to this network security group.

custom_invalidation(self) inherited

A list of manual reasons why this resource should be invalidated

exclude_from_invalidation(self)

A list of attributes that should be excluded from the invalidation process

AzureNetworkSecurityRule (AzureResource)

Attributes:

Name Type Description
name str

The NSG name.

priority int

The rule's priority. The lower the number, the higher priority.

direction ConnectionDirectionType

The rule direction. Either inbound or outbound.

access NetworkSecurityRuleActionType

The rule's access type. Either Allow or Deny.

protocol IpProtocol

The IpProtocol this rule affects. For example, TCP, UDP, etc.

destination_port_ranges PortSet

The set of ports this rule addresses.

source_address_prefixes List[str]

The addresses of the source. These can be CIDR blocks, VirtualNetwork/AzureLoadBalancer/Internet/* or a service tags.

destination_address_prefixes List[str]

The addresses of the destination. These can be CIDR blocks, VirtualNetwork/AzureLoadBalancer/Internet/* or a service tags.

network_security_group_name str

The NSG name this rule is assigned to.

source_application_security_group_ids List[str]

The application security group id of the source that this rule addresses.

destination_application_security_group_ids List[str]

The application security group id of the destination that this rule addresses.

custom_invalidation(self) inherited

A list of manual reasons why this resource should be invalidated

exclude_from_invalidation(self) inherited

A list of attributes that should be excluded from the invalidation process

NetworkSecurityRuleActionType (str, Enum)

An enumeration.

AzureVirtualNetworkGateway (AzureResource)

Attributes:

Name Type Description
name str

The GW name

gateway_type VirtualNetworkGatewayType

The GW type

sku_tier str

The GW SKU tier (Basic, Standard, etc)

custom_invalidation(self) inherited

A list of manual reasons why this resource should be invalidated

exclude_from_invalidation(self) inherited

A list of attributes that should be excluded from the invalidation process

VirtualNetworkGatewayType (Enum)

An enumeration.

AzurePublicIp (AzureResource)

Attributes:

Name Type Description
name

The name of this Public IP

public_ip_address

The actual public ip address.

custom_invalidation(self) inherited

A list of manual reasons why this resource should be invalidated

exclude_from_invalidation(self) inherited

A list of attributes that should be excluded from the invalidation process

AzureApplicationSecurityGroup (AzureResource)

Attributes:

Name Type Description
name str

The application security group name.

custom_invalidation(self) inherited

A list of manual reasons why this resource should be invalidated

exclude_from_invalidation(self) inherited

A list of attributes that should be excluded from the invalidation process

AzureNetworkInterfaceApplicationSecurityGroupAssociation (AzureResource)

Attributes:

Name Type Description
network_interface_id str

The network interface id which needs to be connected to the application security group.

application_security_group_id

The application security group id which needs to be connected to the network interface.

custom_invalidation(self) inherited

A list of manual reasons why this resource should be invalidated

exclude_from_invalidation(self) inherited

A list of attributes that should be excluded from the invalidation process