Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Ubuntu VM images #1909

Merged
merged 15 commits into from
Jun 28, 2024
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,9 @@ def __init__(
):
super().__init__(*args, **kwargs)
self.image_reference_args = compute.ImageReferenceArgs(
offer="0001-com-ubuntu-server-focal",
offer="0001-com-ubuntu-server-jammy",
publisher="Canonical",
sku="20_04-LTS",
sku="22_04-LTS-gen2",
version="latest",
)
self.os_profile_args = compute.OSProfileArgs(
Expand Down
38 changes: 38 additions & 0 deletions data_safe_haven/infrastructure/programs/sre/firewall.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
)
from data_safe_haven.types import (
FirewallPriorities,
ForbiddenDomains,
PermittedDomains,
Ports,
)
Expand Down Expand Up @@ -224,6 +225,43 @@ def __init__(
source_addresses=props.subnet_workspaces_prefixes,
target_fqdns=PermittedDomains.UBUNTU_KEYSERVER,
),
network.AzureFirewallApplicationRuleArgs(
description="Allow external Ubuntu Snap Store access",
name="AllowUbuntuSnapcraft",
protocols=[
network.AzureFirewallApplicationRuleProtocolArgs(
port=int(Ports.HTTPS),
protocol_type=network.AzureFirewallApplicationRuleProtocolType.HTTPS,
),
],
source_addresses=props.subnet_workspaces_prefixes,
target_fqdns=PermittedDomains.UBUNTU_SNAPCRAFT,
),
],
),
network.AzureFirewallApplicationRuleCollectionArgs(
action=network.AzureFirewallRCActionArgs(
type=network.AzureFirewallRCActionType.DENY
),
name="workspaces-deny",
priority=FirewallPriorities.SRE_WORKSPACES,
rules=[
network.AzureFirewallApplicationRuleArgs(
description="Deny external Ubuntu Snap Store upload and login access",
name="DenyUbuntuSnapcraft",
protocols=[
network.AzureFirewallApplicationRuleProtocolArgs(
port=int(Ports.HTTP),
protocol_type=network.AzureFirewallApplicationRuleProtocolType.HTTP,
),
network.AzureFirewallApplicationRuleProtocolArgs(
port=int(Ports.HTTPS),
protocol_type=network.AzureFirewallApplicationRuleProtocolType.HTTPS,
),
JimMadge marked this conversation as resolved.
Show resolved Hide resolved
],
source_addresses=props.subnet_workspaces_prefixes,
target_fqdns=ForbiddenDomains.UBUNTU_SNAPCRAFT,
),
Comment on lines +242 to +264
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking further - I'm happy with this rule, but I think AzureFirewall behaviour defaults to DENY, so it might not be needed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I'm in two minds.

I know we block everything we don't explicitly allow. It feels like we should capture the fact that these domains in particular should always be blocked though. You might be tempted to allow them when debugging for example.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tend to agree, feels like it's worth being explicit here

],
),
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ apt:
preserve_sources_list: true # Append to the existing /etc/apt/sources.list
sources:
microsoft-general.list:
source: "deb https://packages.microsoft.com/ubuntu/20.04/prod focal main"
source: "deb https://packages.microsoft.com/ubuntu/22.04/prod jammy main"
keyid: BC528686B50D79E339D3721CEB3E94ADBE1229CF # Microsoft (Release signing) <gpgsecurity@microsoft.com>

# Install necessary apt packages
Expand Down
2 changes: 2 additions & 0 deletions data_safe_haven/types/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
AzureDnsZoneNames,
DatabaseSystem,
FirewallPriorities,
ForbiddenDomains,
JimMadge marked this conversation as resolved.
Show resolved Hide resolved
NetworkingPriorities,
PermittedDomains,
Ports,
Expand All @@ -33,6 +34,7 @@
"EmailAddress",
"EntraGroupName",
"FirewallPriorities",
"ForbiddenDomains",
"Fqdn",
"Guid",
"IpAddress",
Expand Down
21 changes: 21 additions & 0 deletions data_safe_haven/types/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,22 @@ class FirewallPriorities(int, Enum):
SRE_WORKSPACES = 3400


@verify(UNIQUE)
class ForbiddenDomains(tuple[str, ...], Enum):
# Block snap upload to the Snap store at snapcraft.io
# Upload is through dashboard.snapscraft.io and requires a client to be logged in to
# an Ubuntu account.
# Login is through login.ubuntu.com.
# However, once successfully authorised, it is not necessary to reach
# login.ubuntu.com before uploading.
# Therefore we should block access to both domains.
UBUNTU_SNAPCRAFT = (
"dashboard.snapcraft.io", # upload endpoint
"login.ubuntu.com", # login endpoint (provides auth for upload)
"upload.apps.ubuntu.com",
)


@verify(UNIQUE)
class NetworkingPriorities(int, Enum):
"""Priorities for network security group rules."""
Expand Down Expand Up @@ -114,6 +130,10 @@ class PermittedDomains(tuple[str, ...], Enum):
SOFTWARE_REPOSITORIES_R = ("cran.r-project.org",)
SOFTWARE_REPOSITORIES = SOFTWARE_REPOSITORIES_PYTHON + SOFTWARE_REPOSITORIES_R
UBUNTU_KEYSERVER = ("keyserver.ubuntu.com",)
UBUNTU_SNAPCRAFT = (
"api.snapcraft.io",
"*.snapcraftcontent.com",
)
ALL = tuple(
sorted(
set(
Expand All @@ -125,6 +145,7 @@ class PermittedDomains(tuple[str, ...], Enum):
+ SOFTWARE_REPOSITORIES_PYTHON
+ SOFTWARE_REPOSITORIES_R
+ UBUNTU_KEYSERVER
+ UBUNTU_SNAPCRAFT
)
)
)
Expand Down
Loading