Skip to content

Commit

Permalink
[u] Disable split tunneling for GitLab VPN in prod and anvilprod (Dat…
Browse files Browse the repository at this point in the history
  • Loading branch information
dsotirho-ucsc committed May 1, 2024
2 parents 35156d5 + 5dcfc3d commit fe8cec3
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 44 deletions.
17 changes: 17 additions & 0 deletions UPGRADING.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,23 @@ reverted. This is all fairly informal and loosely defined. Hopefully we won't
have too many entries in this file.


DataBiosphere/azul-private#133 Disable split tunneling for GitLab VPN in prod and anvilprod
===========================================================================================

This change requires an update to your existing VPN connections for `prod` and
`anvilprod`.

Run the following commands::

_select prod.gitlab # or anvilprod.gitlab
cd terraform/gitlab/vpn
make config > ~/azul-gitlab-prod.ovpn # or azul-gitlab-anvilprod.ovpn

Then, remove the existing VPN connection and import the generated `.ovpn` file
to recreate it. Finally, delete the `.ovpn` file to prevent proliferation of the
private key.


#6046 Fix: VPC CIDR in ``anvildev`` is wrong
============================================

Expand Down
36 changes: 18 additions & 18 deletions environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -772,24 +772,24 @@ def env() -> Mapping[str, Optional[str]]:
# purposes. A lower (aka unstable) deployment is a main deployment that
# is not stable.
#
# ╔════════════╗ ╔══════════════════════════════════════════════════╗
# ║ Personal ║ ║ Shared ║
# ║ ║ ║ ╔═════════════╗ ╔══════════════════════════════╗ ║
# ║ ║ ║ ║ Sandbox ║ ║ Main ║ ║
# ║ ║ ║ ║ ║ ║ ╔═════════════╗ ╔══════════╗ ║ ║
# ║ ║ ║ ║ ║ ║ ║ Lower ║ ║ Stable ║ ║ ║
# ║ ┌────────┐ ║ ║ ║ ┌─────────┐ ║ ║ ║ ┌─────────┐ ║ ║ ┌──────┐ ║ ║ ║
# ║ │ hannes │ ║ ║ ║ │ sandbox │ ║ ║ ║ │ dev │ ║ ║ │ prod │ ║ ║ ║
# ║ └────────┘ ║ ║ ║ └─────────┘ ║ ║ ║ └─────────┘ ║ ║ └──────┘ ║ ║ ║
# ║ ║ ║ ║ ┌─────────┐ ║ ║ ║ ┌─────────┐ ║ ║ ║ ║ ║
# ║ ║ ║ ║ │anvilbox │ ║ ║ ║ │anvildev │ ║ ║ ║ ║ ║
# ║ ║ ║ ║ └─────────┘ ║ ║ ║ └─────────┘ ║ ║ ║ ║ ║
# ║ ║ ║ ║ ┌─────────┐ ║ ║ ║ ┌─────────┐ ║ ║ ║ ║ ║
# ║ ║ ║ ║ │hammerbox│ ║ ║ ║ │anvilprod│ ║ ║ ║ ║ ║
# ║ ║ ║ ║ └─────────┘ ║ ║ ║ └─────────┘ ║ ║ ║ ║ ║
# ║ ║ ║ ║ ║ ║ ╚═════════════╝ ╚══════════╝ ║ ║
# ║ ║ ║ ╚═════════════╝ ╚══════════════════════════════╝ ║
# ╚════════════╝ ╚══════════════════════════════════════════════════╝
# ╔════════════╗ ╔═════════════════════════════════════════════════════
# ║ Personal ║ ║ Shared
# ║ ║ ║ ╔═════════════╗ ╔═════════════════════════════════╗ ║
# ║ ║ ║ ║ Sandbox ║ ║ Main ║ ║
# ║ ║ ║ ║ ║ ║ ╔═════════════╗ ╔═════════════╗ ║ ║
# ║ ║ ║ ║ ║ ║ ║ Lower ║ ║ Stable ║ ║ ║
# ║ ┌────────┐ ║ ║ ║ ┌─────────┐ ║ ║ ║ ┌─────────┐ ║ ║ ┌─────────┐ ║ ║ ║
# ║ │ hannes │ ║ ║ ║ │ sandbox │ ║ ║ ║ │ dev │ ║ ║ │ prod │ ║ ║ ║
# ║ └────────┘ ║ ║ ║ └─────────┘ ║ ║ ║ └─────────┘ ║ ║ └─────────┘ ║ ║ ║
# ║ ║ ║ ║ ┌─────────┐ ║ ║ ║ ┌─────────┐ ║ ║ ║ ║ ║
# ║ ║ ║ ║ │anvilbox │ ║ ║ ║ │anvildev │ ║ ║ ║ ║ ║
# ║ ║ ║ ║ └─────────┘ ║ ║ ║ └─────────┘ ║ ║ ║ ║ ║
# ║ ║ ║ ║ ┌─────────┐ ║ ║ ║ ║ ║ ┌─────────┐ ║ ║ ║
# ║ ║ ║ ║ │hammerbox│ ║ ║ ║ ║ ║ │anvilprod│ ║ ║ ║
# ║ ║ ║ ║ └─────────┘ ║ ║ ║ ║ ║ └─────────┘ ║ ║ ║
# ║ ║ ║ ║ ║ ║ ╚═════════════╝ ╚═════════════╝ ║ ║
# ║ ║ ║ ╚═════════════╝ ╚═════════════════════════════════╝ ║
# ╚════════════╝ ╚═════════════════════════════════════════════════════
#
'azul_shared_deployments': json.dumps({
'develop': ['dev', 'sandbox', 'anvildev', 'anvilbox'],
Expand Down
28 changes: 19 additions & 9 deletions src/azul/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1013,18 +1013,28 @@ def is_shared_deployment(self, deployment: Optional[str] = None) -> bool:
deployment = self.deployment_stage
return deployment in set(chain.from_iterable(self._shared_deployments.values()))

def is_stable_deployment(self, deployment: Optional[str] = None) -> bool:
#: The set of branches that are used for development and that are usually
#: deployed to personal, lower and main deployments, but never stable ones.
#: The set member ``None`` represents a feature branch or detached HEAD.
#:
unstable_branches = {'develop', None}

@property
def is_stable_deployment(self) -> bool:
"""
Returns `True` if the deployment of the specified name must be kept
functional for public use at all times.
Returns `True` if the current deployment must be kept functional for
public use at all times.
"""
if deployment is None:
deployment = self.deployment_stage
if deployment in {'prod'}:
assert self.is_shared_deployment(deployment)
return True
else:
if self.is_sandbox_deployment:
return False
else:
deployment = self.deployment_stage
branches = set(
branch
for branch, deployments in self._shared_deployments.items()
if deployment in deployments
)
return bool(branches) and branches.isdisjoint(self.unstable_branches)

@property
def is_sandbox_deployment(self) -> bool:
Expand Down
66 changes: 51 additions & 15 deletions terraform/gitlab/gitlab.tf.json.template.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
from collections.abc import (
Iterable,
)
import ipaddress
from itertools import (
chain,
)
import json

from more_itertools import (
nth,
)
import yaml

from azul import (
Expand Down Expand Up @@ -177,10 +181,14 @@
# https://github.com/docker/libnetwork/blob/a79d3687931697244b8e03485bf7b2042f8ec6b6/ipamutils/utils.go#L10
#

all_ipv4 = '0.0.0.0/0'

vpc_cidr = config.vpc_cidr

vpn_subnet = config.vpn_subnet

split_tunnel = not config.is_stable_deployment

# The public key of that keypair
#
administrator_key = (
Expand Down Expand Up @@ -999,7 +1007,7 @@ def sq(*words):
},
'aws_route': {
'gitlab': {
'destination_cidr_block': '0.0.0.0/0',
'destination_cidr_block': all_ipv4,
'gateway_id': '${aws_internet_gateway.gitlab.id}',
'route_table_id': '${aws_vpc.gitlab.main_route_table_id}'
}
Expand All @@ -1024,7 +1032,7 @@ def sq(*words):
f'gitlab_{zone}': {
'route': [
{
'cidr_block': '0.0.0.0/0',
'cidr_block': all_ipv4,
'nat_gateway_id': f'${{aws_nat_gateway.gitlab_{zone}.id}}',
'egress_only_gateway_id': None,
'gateway_id': None,
Expand Down Expand Up @@ -1074,25 +1082,35 @@ def sq(*words):
'name': 'azul-gitlab-vpn',
'vpc_id': '${aws_vpc.gitlab.id}',
'egress': [
vpc.security_rule(description='Any traffic to the VPC',
cidr_blocks=['${aws_vpc.gitlab.cidr_block}'],
vpc.security_rule(description='Any traffic to the '
f"{'VPC' if split_tunnel else 'internet'}",
cidr_blocks=[
'${aws_vpc.gitlab.cidr_block}'
if split_tunnel else
all_ipv4
],
protocol=-1,
from_port=0,
to_port=0),
vpc.security_rule(description='ICMP for PMTUD',
cidr_blocks=['0.0.0.0/0'],
cidr_blocks=[all_ipv4],
protocol='icmp',
from_port=3, # Destination Unreachable
to_port=4) # Fragmentation required DF-flag set
],
'ingress': [
vpc.security_rule(description='Any traffic from the VPC',
cidr_blocks=['${aws_vpc.gitlab.cidr_block}'],
vpc.security_rule(description='Any traffic from the '
f"{'VPC' if split_tunnel else 'internet'}",
cidr_blocks=[
'${aws_vpc.gitlab.cidr_block}'
if split_tunnel else
all_ipv4
],
protocol=-1,
from_port=0,
to_port=0),
vpc.security_rule(description='ICMP for PMTUD',
cidr_blocks=['0.0.0.0/0'],
cidr_blocks=[all_ipv4],
protocol='icmp',
from_port=3, # Destination Unreachable
to_port=4) # Fragmentation required DF-flag set
Expand All @@ -1108,7 +1126,7 @@ def sq(*words):
from_port=0,
to_port=0),
vpc.security_rule(description='ICMP for PMTUD',
cidr_blocks=['0.0.0.0/0'],
idr_blocks=[all_ipv4],
protocol='icmp',
from_port=3, # Destination Unreachable
to_port=4) # Fragmentation required DF-flag set
Expand All @@ -1120,7 +1138,7 @@ def sq(*words):
from_port=443,
to_port=443),
vpc.security_rule(description='ICMP for PMTUD',
cidr_blocks=['0.0.0.0/0'],
cidr_blocks=[all_ipv4],
protocol='icmp',
from_port=3, # Destination Unreachable
to_port=4) # Fragmentation required DF-flag set
Expand All @@ -1132,7 +1150,7 @@ def sq(*words):
'vpc_id': '${aws_vpc.gitlab.id}',
'egress': [
vpc.security_rule(description='Any traffic to anywhere (to be routed by NAT Gateway)',
cidr_blocks=['0.0.0.0/0'],
cidr_blocks=[all_ipv4],
protocol=-1,
from_port=0,
to_port=0),
Expand All @@ -1153,7 +1171,7 @@ def sq(*words):
from_port=4789,
to_port=4789),
vpc.security_rule(description='ICMP for PMTUD',
cidr_blocks=['0.0.0.0/0'],
cidr_blocks=[all_ipv4],
protocol='icmp',
from_port=3, # Destination Unreachable
to_port=4) # Fragmentation required DF-flag set
Expand All @@ -1178,7 +1196,7 @@ def sq(*words):
from_port=4789,
to_port=4789),
vpc.security_rule(description='ICMP for PMTUD',
cidr_blocks=['0.0.0.0/0'],
cidr_blocks=[all_ipv4],
protocol='icmp',
from_port=3, # Destination Unreachable
to_port=4) # Fragmentation required DF-flag set
Expand Down Expand Up @@ -1214,7 +1232,12 @@ def sq(*words):
'security_group_ids': ['${aws_security_group.gitlab_vpn.id}'],
'server_certificate_arn': '${data.aws_acm_certificate.gitlab_vpn.arn}',
'transport_protocol': 'udp',
'split_tunnel': True,
'split_tunnel': split_tunnel,
'dns_servers': [] if split_tunnel else [
# https://docs.aws.amazon.com/vpc/latest/userguide/vpc-dns.html#AmazonDNS
str(nth(ipaddress.ip_network(vpc_cidr).hosts(), 1)),
'169.254.169.253'
],
'authentication_options': {
'type': 'certificate-authentication',
'root_certificate_chain_arn': '${data.aws_acm_certificate.gitlab_vpn.arn}'
Expand All @@ -1234,10 +1257,23 @@ def sq(*words):
}
for zone in range(num_zones)
},
'aws_ec2_client_vpn_route': {
f'gitlab_{zone}': {
'client_vpn_endpoint_id': '${aws_ec2_client_vpn_endpoint.gitlab.id}',
'target_vpc_subnet_id': '${aws_subnet.gitlab_public_%s.id}' % zone,
'destination_cidr_block': all_ipv4
}
for zone in range(num_zones)
if not split_tunnel
},
'aws_ec2_client_vpn_authorization_rule': {
'gitlab': {
'client_vpn_endpoint_id': '${aws_ec2_client_vpn_endpoint.gitlab.id}',
'target_network_cidr': '${aws_vpc.gitlab.cidr_block}',
'target_network_cidr': (
'${aws_vpc.gitlab.cidr_block}'
if split_tunnel else
all_ipv4
),
'authorize_all_groups': True
}
},
Expand Down
4 changes: 3 additions & 1 deletion terraform/gitlab/vpn/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ config: _client
&& aws ec2 export-client-vpn-client-configuration \
--client-vpn-endpoint-id $$endpoint \
--output=text
@echo "pull-filter ignore redirect-gateway"
@if [ "$$(AZUL_DEBUG=0 python -m azul config.is_stable_deployment)" != True ]; then \
echo "pull-filter ignore redirect-gateway"; \
fi
@echo "<cert>"
@cat $(EASYRSA_PKI)/issued/$(client_cn).crt | openssl x509 -inform pem
@echo "</cert>"
Expand Down
2 changes: 1 addition & 1 deletion test/integration_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,7 @@ def _reset_indexer(self):
self.azul_client.reset_indexer(catalogs=config.integration_test_catalogs,
# Can't purge the queues in stable deployment as
# they may contain work for non-IT catalogs.
purge_queues=not config.is_stable_deployment(),
purge_queues=not config.is_stable_deployment,
delete_indices=True,
create_indices=True)

Expand Down

0 comments on commit fe8cec3

Please sign in to comment.