77
88from data_safe_haven .external import AzureIPv4Range
99from data_safe_haven .functions import ordered_private_dns_zones
10- from data_safe_haven .infrastructure .common import NetworkingPriorities
10+ from data_safe_haven .infrastructure .common import NetworkingPriorities , Ports
1111
1212
1313class SHMNetworkingProps :
@@ -22,8 +22,6 @@ def __init__(
2222 ) -> None :
2323 # Virtual network and subnet IP ranges
2424 self .vnet_iprange = AzureIPv4Range ("10.0.0.0" , "10.0.255.255" )
25- # Bastion subnet must be at least /26 in size (64 addresses)
26- self .subnet_bastion_iprange = self .vnet_iprange .next_subnet (64 )
2725 # Firewall subnet must be at least /26 in size (64 addresses)
2826 self .subnet_firewall_iprange = self .vnet_iprange .next_subnet (64 )
2927 # Monitoring subnet needs 2 IP addresses for automation and 13 for log analytics
@@ -61,137 +59,6 @@ def __init__(
6159 )
6260
6361 # Define NSGs
64- nsg_bastion = network .NetworkSecurityGroup (
65- f"{ self ._name } _nsg_bastion" ,
66- network_security_group_name = f"{ stack_name } -nsg-bastion" ,
67- resource_group_name = resource_group .name ,
68- security_rules = [
69- # Inbound
70- network .SecurityRuleArgs (
71- access = network .SecurityRuleAccess .ALLOW ,
72- description = "Allow inbound https connections from admins connecting from approved IP addresses." ,
73- destination_address_prefix = "*" , # required by https://learn.microsoft.com/en-us/azure/bastion/bastion-nsg
74- destination_port_ranges = ["443" ],
75- direction = network .SecurityRuleDirection .INBOUND ,
76- name = "AllowAdminHttpsInbound" ,
77- priority = NetworkingPriorities .AUTHORISED_EXTERNAL_ADMIN_IPS ,
78- protocol = network .SecurityRuleProtocol .TCP ,
79- source_address_prefixes = props .admin_ip_addresses ,
80- source_port_range = "*" ,
81- ),
82- network .SecurityRuleArgs (
83- access = network .SecurityRuleAccess .ALLOW ,
84- description = "Allow inbound gateway management service traffic." ,
85- destination_address_prefix = "*" , # required by https://learn.microsoft.com/en-us/azure/bastion/bastion-nsg
86- destination_port_ranges = ["443" ],
87- direction = network .SecurityRuleDirection .INBOUND ,
88- name = "AllowGatewayManagerServiceInbound" ,
89- priority = NetworkingPriorities .AZURE_GATEWAY_MANAGER ,
90- protocol = network .SecurityRuleProtocol .TCP ,
91- source_address_prefix = "GatewayManager" , # required by https://learn.microsoft.com/en-us/azure/bastion/bastion-nsg
92- source_port_range = "*" ,
93- ),
94- network .SecurityRuleArgs (
95- access = network .SecurityRuleAccess .ALLOW ,
96- description = "Allow inbound load balancer service traffic." ,
97- destination_address_prefix = "*" , # required by https://learn.microsoft.com/en-us/azure/bastion/bastion-nsg
98- destination_port_ranges = ["443" ],
99- direction = network .SecurityRuleDirection .INBOUND ,
100- name = "AllowLoadBalancerServiceInbound" ,
101- priority = NetworkingPriorities .AZURE_LOAD_BALANCER ,
102- protocol = network .SecurityRuleProtocol .TCP ,
103- source_address_prefix = "AzureLoadBalancer" , # required by https://learn.microsoft.com/en-us/azure/bastion/bastion-nsg
104- source_port_range = "*" ,
105- ),
106- network .SecurityRuleArgs (
107- access = network .SecurityRuleAccess .ALLOW ,
108- description = "Allow inbound internal bastion host communication." ,
109- destination_address_prefix = "VirtualNetwork" , # required by https://learn.microsoft.com/en-us/azure/bastion/bastion-nsg
110- destination_port_ranges = ["5701" , "8080" ],
111- direction = network .SecurityRuleDirection .INBOUND ,
112- name = "AllowBastionHostInbound" ,
113- priority = NetworkingPriorities .INTERNAL_SELF ,
114- protocol = network .SecurityRuleProtocol .ASTERISK ,
115- source_address_prefix = "VirtualNetwork" , # required by https://learn.microsoft.com/en-us/azure/bastion/bastion-nsg
116- source_port_range = "*" ,
117- ),
118- network .SecurityRuleArgs (
119- access = network .SecurityRuleAccess .DENY ,
120- description = "Deny all other inbound traffic." ,
121- destination_address_prefix = "*" ,
122- destination_port_range = "*" ,
123- direction = network .SecurityRuleDirection .INBOUND ,
124- name = "DenyAllOtherInbound" ,
125- priority = NetworkingPriorities .ALL_OTHER ,
126- protocol = network .SecurityRuleProtocol .ASTERISK ,
127- source_address_prefix = "*" ,
128- source_port_range = "*" ,
129- ),
130- # Outbound
131- network .SecurityRuleArgs (
132- access = network .SecurityRuleAccess .ALLOW ,
133- description = "Allow outbound connections to DSH VMs." ,
134- destination_address_prefix = "VirtualNetwork" , # required by https://learn.microsoft.com/en-us/azure/bastion/bastion-nsg
135- destination_port_ranges = ["22" , "3389" ],
136- direction = network .SecurityRuleDirection .OUTBOUND ,
137- name = "AllowRdpOutbound" ,
138- priority = NetworkingPriorities .INTERNAL_SHM_BASTION ,
139- protocol = network .SecurityRuleProtocol .ASTERISK ,
140- source_address_prefix = "*" , # required by https://learn.microsoft.com/en-us/azure/bastion/bastion-nsg
141- source_port_range = "*" ,
142- ),
143- network .SecurityRuleArgs (
144- access = network .SecurityRuleAccess .ALLOW ,
145- description = "Allow outbound connections to Azure public endpoints." ,
146- destination_address_prefix = "AzureCloud" , # required by https://learn.microsoft.com/en-us/azure/bastion/bastion-nsg
147- destination_port_ranges = ["443" ],
148- direction = network .SecurityRuleDirection .OUTBOUND ,
149- name = "AllowAzureCloudOutbound" ,
150- priority = NetworkingPriorities .AZURE_CLOUD ,
151- protocol = network .SecurityRuleProtocol .TCP ,
152- source_address_prefix = "*" , # required by https://learn.microsoft.com/en-us/azure/bastion/bastion-nsg
153- source_port_range = "*" ,
154- ),
155- network .SecurityRuleArgs (
156- access = network .SecurityRuleAccess .ALLOW ,
157- description = "Allow outbound internal bastion host communication." ,
158- destination_address_prefix = "VirtualNetwork" , # required by https://learn.microsoft.com/en-us/azure/bastion/bastion-nsg
159- destination_port_ranges = ["5701" , "8080" ],
160- direction = network .SecurityRuleDirection .OUTBOUND ,
161- name = "AllowBastionHostOutbound" ,
162- priority = NetworkingPriorities .INTERNAL_SELF ,
163- protocol = network .SecurityRuleProtocol .ASTERISK ,
164- source_address_prefix = "VirtualNetwork" , # required by https://learn.microsoft.com/en-us/azure/bastion/bastion-nsg
165- source_port_range = "*" ,
166- ),
167- network .SecurityRuleArgs (
168- access = network .SecurityRuleAccess .ALLOW ,
169- description = "Allow outbound connections for session and certificate validation." ,
170- destination_address_prefix = "Internet" ,
171- destination_port_ranges = ["80" ],
172- direction = network .SecurityRuleDirection .OUTBOUND ,
173- name = "AllowCertificateValidationOutbound" ,
174- priority = NetworkingPriorities .EXTERNAL_INTERNET ,
175- protocol = network .SecurityRuleProtocol .ASTERISK ,
176- source_address_prefix = "*" , # required by https://learn.microsoft.com/en-us/azure/bastion/bastion-nsg
177- source_port_range = "*" ,
178- ),
179- network .SecurityRuleArgs (
180- access = network .SecurityRuleAccess .DENY ,
181- description = "Deny all other outbound traffic." ,
182- destination_address_prefix = "*" ,
183- destination_port_range = "*" ,
184- direction = network .SecurityRuleDirection .OUTBOUND ,
185- name = "DenyAllOtherOutbound" ,
186- priority = NetworkingPriorities .ALL_OTHER ,
187- protocol = network .SecurityRuleProtocol .ASTERISK ,
188- source_address_prefix = "*" ,
189- source_port_range = "*" ,
190- ),
191- ],
192- opts = child_opts ,
193- tags = child_tags ,
194- )
19562 nsg_monitoring = network .NetworkSecurityGroup (
19663 f"{ self ._name } _nsg_monitoring" ,
19764 network_security_group_name = f"{ stack_name } -nsg-monitoring" ,
@@ -235,7 +102,7 @@ def __init__(
235102 access = network .SecurityRuleAccess .ALLOW ,
236103 description = "Allow outbound connections to local monitoring tools." ,
237104 destination_address_prefix = str (props .subnet_monitoring_iprange ),
238- destination_port_ranges = ["443" ],
105+ destination_port_ranges = [Ports . HTTPS ],
239106 direction = network .SecurityRuleDirection .OUTBOUND ,
240107 name = "AllowMonitoringToolsOutbound" ,
241108 priority = NetworkingPriorities .INTERNAL_SHM_MONITORING_TOOLS ,
@@ -247,7 +114,7 @@ def __init__(
247114 access = network .SecurityRuleAccess .ALLOW ,
248115 description = "Allow outbound connections to Linux update servers." ,
249116 destination_address_prefix = "Internet" ,
250- destination_port_ranges = ["80" , "443" ],
117+ destination_port_ranges = [Ports . HTTP , Ports . HTTPS ],
251118 direction = network .SecurityRuleDirection .OUTBOUND ,
252119 name = "AllowLinuxUpdatesOutbound" ,
253120 priority = NetworkingPriorities .EXTERNAL_LINUX_UPDATES ,
@@ -290,7 +157,6 @@ def __init__(
290157
291158 # Define the virtual network and its subnets
292159 subnet_firewall_name = "AzureFirewallSubnet" # this name is forced by https://docs.microsoft.com/en-us/azure/firewall/tutorial-firewall-deploy-portal
293- subnet_bastion_name = "AzureBastionSubnet" # this name is forced by https://learn.microsoft.com/en-us/azure/bastion/configuration-settings#subnet
294160 subnet_monitoring_name = "MonitoringSubnet"
295161 subnet_update_servers_name = "UpdateServersSubnet"
296162 virtual_network = network .VirtualNetwork (
@@ -300,15 +166,6 @@ def __init__(
300166 ),
301167 resource_group_name = resource_group .name ,
302168 subnets = [ # Note that we define subnets inline to avoid creation order issues
303- # Bastion subnet
304- network .SubnetArgs (
305- address_prefix = str (props .subnet_bastion_iprange ),
306- name = subnet_bastion_name ,
307- network_security_group = network .NetworkSecurityGroupArgs (
308- id = nsg_bastion .id
309- ),
310- route_table = None , # the bastion subnet must NOT be attached to the route table
311- ),
312169 # AzureFirewall subnet
313170 network .SubnetArgs (
314171 address_prefix = str (props .subnet_firewall_iprange ),
@@ -427,11 +284,6 @@ def __init__(
427284 self .private_dns_zone_base_id = private_zone_ids [0 ]
428285 self .resource_group_name = Output .from_input (resource_group .name )
429286 self .route_table = route_table
430- self .subnet_bastion = network .get_subnet_output (
431- subnet_name = subnet_bastion_name ,
432- resource_group_name = resource_group .name ,
433- virtual_network_name = virtual_network .name ,
434- )
435287 self .subnet_firewall = network .get_subnet_output (
436288 subnet_name = subnet_firewall_name ,
437289 resource_group_name = resource_group .name ,
@@ -454,9 +306,6 @@ def __init__(
454306 "fqdn_nameservers" : self .dns_zone .name_servers ,
455307 "private_dns_zone_base_id" : self .private_dns_zone_base_id ,
456308 "resource_group_name" : resource_group .name ,
457- "subnet_bastion_prefix" : self .subnet_bastion .apply (
458- lambda s : str (s .address_prefix ) if s .address_prefix else ""
459- ),
460309 "subnet_monitoring_prefix" : self .subnet_monitoring .apply (
461310 lambda s : str (s .address_prefix ) if s .address_prefix else ""
462311 ),
0 commit comments