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_name |
str |
virtual network name associated with this subnet |
cidr_addresses |
List[ipaddress.IPv4Network] |
subnet cidr addresses |
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