Blog

How To Use Squid Proxy To Access Services In Another VPC Using Private Service Connect

11 Feb, 2024
Xebia Background Header Wave

This blog uses a Squid Proxy VM to access services in another Google Cloud VPC. Clients connect to the Squid Proxy VM using Private Service Connect. This prevents overlapping IP address issues and reduces networking complexities such as peering and routing.

Solution overview

Clients connect to Destination VPC-services via the Squid Proxy using:

curl -x http://proxy.xebia:3128 http://example-server.xebia/

While Squid can be used as a transparent proxy, this blog uses an explicit proxy for simplicity’s sake.

The Destination VPC-services are exposed by the Squid Proxy using Private Service Connect:

Connectivity overview

A service published using Private Service Connect is available for consumers in other VPCs via endpoints and/or backends. Endpoints are based on a forwarding rule. Backends are based on a load balancer. Previous figure shows an Endpoint-based connection.

Services are published using a service attachment. The service attachment allows/denies (client) connection requests and specifies how the service is hosted in the Destination VPC.

Find the full example on GitHub.

Solution deployment

The following configuration enables the Squid Proxy to receive Source VPC requests:

  • Setup Squid Proxy server

The Squid configuration listens on port 3128 and happily forwards all HTTP traffic:

http_port 3128

...

# Allow all HTTP traffic, use a more fine-grained setup in production..
http_access allow all
  • Publish Squid Proxy service

The service is published using a service attachment that targets the Squid Proxy server load balancer:

resource "google_compute_service_attachment" "proxy" {
  project = var.project_id
  region  = "europe-west1"
  name    = "squid-proxy"

  nat_subnets           = [google_compute_subnetwork.destination_vpc_psc.self_link]
  target_service        = google_compute_forwarding_rule.proxy.self_link

  ...
}

Clients – service consumers – connect to the service using an IP address from the dedicated NAT subnet. Each client connection consumes one IP address from the subnet. When multiple connections are created, each connection consumes one IP address. Hence, size the subnet sufficiently:

resource "google_compute_subnetwork" "destination_vpc_psc" {
  project       = var.project_id
  network       = google_compute_network.destination_vpc.id
  name          = "${google_compute_network.destination_vpc.name}-psc"
  region        = "europe-west1"
  ip_cidr_range = "10.10.0.0/24"

  purpose = "PRIVATE_SERVICE_CONNECT"
}
  • Configure Squid Proxy client connection

First, add the Private Service Connect endpoint to the Source VPC:

resource "google_compute_forwarding_rule" "proxy_endpoint" {
  project = var.project_id
  region  = "europe-west1"
  name    = "squid-proxy-endpoint"

  ip_address = google_compute_address.proxy_endpoint.id
  load_balancing_scheme = "" # Prevent default to 'EXTERNAL'

  network    = google_compute_network.source_vpc.id
  subnetwork = google_compute_subnetwork.source_vpc_proxy.id

  target = google_compute_service_attachment.proxy.id
}

Finally, accept the client connection via the service attachment:

resource "google_compute_service_attachment" "proxy" {
  project = var.project_id
  region  = "europe-west1"
  name    = "squid-proxy"

  ...

  connection_preference = "ACCEPT_MANUAL"

  # Accept up to 4 connections from the example project
  consumer_accept_lists {
    project_id_or_num = var.project_id
    connection_limit  = 4
  }
}
  • Consume Squid Proxy service

Access Destination VPC services via the Squid Proxy:

curl -x http://proxy.xebia:3128 http://example-server.xebia/

Check the full example on GitHub which includes the DNS configuration.

Discussion

Private Service Connect simplifies service networking. Peering and routing technicalities no longer apply. While this makes it easier to connect services, it might be a downside for Squid Proxy use cases. With Private Service Connect the Squid Proxy server moves to the Destination VPC network, causing it to lose the Source VPC network details. Without this details Squid Proxy access control list capabilities can not rely on client IP addresses (both NAT’ed and/or included in the PROXY protocol header). Alternatively, Squid Proxy can use Proxy authentication (username/password) to detect clients and enforce access control lists. But, perhaps it makes more sense to directly publish the services you plan to expose.

While Private Service Connect simplifies connecting to services in other VPCs, it has it’s own trade-offs. First, communication is still limited to one-way communication. Two-way communication would require a reverse connection. Furthermore, the usage of dedicated NAT subnets puts a demand on the Destination VPC design, more so because these subnets can only be used by a single service attachment.

Conclusion

There are endless ways to connect Google Cloud VPCs. Squid Proxy VMs published via Private Service Connect allow clients from any VPC to access services in the target VPC and monitor traffic. Additional efforts, such as Proxy Authentication, are required to control traffic using access control lists. Finally, note that clients must be made aware of the proxy to access services. Perhaps this could be further simplified by exposing the target services directly.

Image by Pexels from Pixabay

Laurens Knoll
As a cloud consultant I enjoy taking software engineering practices to the cloud. Continuously improving the customers systems, tools and processes by focusing on integration and quality.
Questions?

Get in touch with us to learn more about the subject and related solutions

Explore related posts