Using proxy servers with Google Cloud Client Libraries

2021-12-15

This section covers how to use Google Cloud Client Libraries with both HTTP and SOCKS proxies.

When a proxy is set, the following traffic should flow through the proxy:

Any exceptions or special accounting required at the per-language library is described in the corresponding tabs.

For gcloud proxy configuration, see Configuring Cloud SDK for use behind a proxy/firewall

HTTP Proxy

HTTP proxies such as squid or haproxy act as intermediaries to gate and optionally inspect traffic to Cloud Services based on rules configured into the proxy.

These proxies can operate in several modes such as requiring Authentication or terminating and optionally inspects TLS.

Most Google Cloud SDK libraries generally comply with the conventional environment variables directing clients to use a proxy:

export http_proxy=http://${PROXY_SERVER}:3128
export https_proxy=http://${PROXY_SERVER}:3128
export no_proxy=google.com

Any exceptions or special handling per language is described below within their respective tabs

Note that google publishes a dynamic range of IP addresses described in Obtain Google IP address ranges). Note that the range is dynamic which implies setting allow or bypass ranges using IP address may not be sufficient.

Proxy Auto-Configuration (PAC) files is not supported.

The script provided in the Appendix describes how to configure and verify the proxy functionality

HTTP Without Proxy Authorization

curl -vvv -x http://${PROXY_SERVER}:3128 https://httpbin.org/get

you will see connectivity through the proxy

1639864357.394    108 192.168.9.1 TCP_TUNNEL/200 6047 CONNECT httpbin.org:443 - HIER_DIRECT/3.223.33.229 -

Requires both

export http_proxy=http://${PROXY_SERVER}:3128
export https_proxy=http://${PROXY_SERVER}:3128

The following sample uses both REST and gRPC clients (Google Storage and PubSub, respectively) and the proxy server shown in the Appendix.

project='your_project_id'

from google.cloud import storage
client = storage.Client(project=project)
for b in client.list_buckets():
   print(b.name)

from google.cloud import pubsub_v1
publisher = pubsub_v1.PublisherClient()
project_path = f"projects/{project}"
for topic in publisher.list_topics(request={"project": project_path}):
  print(topic)

Proxy logs shows both authentication and service traffic

1639934640.098    359 192.168.9.1 TCP_TUNNEL/200 7840 CONNECT pubsub.googleapis.com:443 - HIER_DIRECT/142.251.45.106 -
1639934640.099    329 192.168.9.1 TCP_TUNNEL/200 7198 CONNECT oauth2.googleapis.com:443 - HIER_DIRECT/172.217.2.106 -
1639934640.123   1250 192.168.9.1 TCP_TUNNEL/200 34952 CONNECT storage.googleapis.com:443 - HIER_DIRECT/172.217.13.80 -

Requires

export https_proxy=http://${PROXY_SERVER}:3128

Proxy logs shows both authentication and service traffic

1639835873.403    430 192.168.9.1 TCP_TUNNEL/200 4887 CONNECT pubsub.googleapis.com:443 - HIER_DIRECT/172.217.15.106 -
1639835873.403   1130 192.168.9.1 TCP_TUNNEL/200 8091 CONNECT oauth2.googleapis.com:443 - HIER_DIRECT/172.217.2.106 -
1639835873.403   1004 192.168.9.1 TCP_TUNNEL/200 115190 CONNECT storage.googleapis.com:443 - HIER_DIRECT/172.217.15.112 -

Requires System variables https.proxyHost, https.proxyPort and proxySet

mvn -DproxySet=true -Dhttps.proxyHost=${PROXY_SERVER} -Dhttps.proxyPort=3128 clean install exec:java

Proxy logs shows both authentication and service traffic

1639836482.500   1934 192.168.9.1 TCP_TUNNEL/200 162227 CONNECT storage.googleapis.com:443 - HIER_DIRECT/172.217.12.240 -
1639836482.500    723 192.168.9.1 TCP_TUNNEL/200 7828 CONNECT pubsub.googleapis.com:443 - HIER_DIRECT/172.217.15.106 -
1639836482.500   2184 192.168.9.1 TCP_TUNNEL/200 6933 CONNECT oauth2.googleapis.com:443 - HIER_DIRECT/142.251.45.10 -

Requires either

export https_proxy=http://${PROXY_SERVER}:3128

Proxy logs shows both authentication and service traffic

1639837735.924     85 192.168.9.1 TCP_TUNNEL/200 7024 CONNECT oauth2.googleapis.com:443 - HIER_DIRECT/142.250.81.202 -
1639837736.567    219 192.168.9.1 TCP_TUNNEL/200 45157 CONNECT storage.googleapis.com:443 - HIER_DIRECT/172.217.13.80 -
1639837738.152   2356 192.168.9.1 TCP_TUNNEL/200 7839 CONNECT pubsub.googleapis.com:443 - HIER_DIRECT/172.217.15.106 -

Requires either

export https_proxy=http://${PROXY_SERVER}:3128

Proxy logs shows both authentication and service traffic

1639838631.388    230 192.168.9.1 TCP_TUNNEL/200 7879 CONNECT pubsub.googleapis.com:443 - HIER_DIRECT/172.217.15.106 -
1639838631.389    859 192.168.9.1 TCP_TUNNEL/200 7352 CONNECT oauth2.googleapis.com:443 - HIER_DIRECT/142.251.33.202 -
1639838631.389    627 192.168.9.1 TCP_TUNNEL/200 45137 CONNECT storage.googleapis.com:443 - HIER_DIRECT/142.250.73.240 -

PHP-gRPC would use the underlying cpp libraries for gRPC so the same http_proxy= environment variables would work here too

export http_proxy=http://${PROXY_SERVER}:3128

Just remember to install grpc support for php first.

tehn use as usual

<?php
require __DIR__ . '/vendor/autoload.php';
use Google\Cloud\PubSub\PubSubClient;
$projectId = 'your_projectID';
$pubsub = new PubSubClient([
	'projectId' => $projectId
]);
$topicName = 'my-new-topic-2';
$topic = $pubsub->createTopic($topicName);
echo 'Topic ' . $topic->name() . ' created.';
return $topic;

HTTP with Proxy Authorization

Proxies may require authentication to even use the proxy. see Proxy Authorization. The examples below covers BASIC Authorization where the username is user1 and the password is also user1.

curl -vvv -x http://user1:user1@${PROXY_SERVER}:3128 https://httpbin.org/get

you will see connectivity through the proxy

1639864426.944     84 192.168.9.1 TCP_TUNNEL/200 6047 CONNECT httpbin.org:443 user1 HIER_DIRECT/52.5.64.83 -

Requires both

export https_proxy=http://user1:user1@${PROXY_SERVER}:3128

Proxy logs shows both authentication and service traffic. Note the logs display the proxy user (user)

1639839294.542    303 192.168.9.1 TCP_TUNNEL/200 7878 CONNECT pubsub.googleapis.com:443 user1 HIER_DIRECT/142.251.45.10 -
1639839294.542    272 192.168.9.1 TCP_TUNNEL/200 6964 CONNECT oauth2.googleapis.com:443 user1 HIER_DIRECT/142.251.45.106 -
1639839294.576   1316 192.168.9.1 TCP_TUNNEL/200 34952 CONNECT storage.googleapis.com:443 user1 HIER_DIRECT/142.250.188.48 -

Requires

export https_proxy=http://user1:user1@${PROXY_SERVER}:3128

Proxy logs shows both authentication and service traffic. Note the logs display the proxy user (user)

1639839600.950   1479 192.168.9.1 TCP_TUNNEL/200 4885 CONNECT pubsub.googleapis.com:443 user1 HIER_DIRECT/142.251.45.10 -
1639839600.950   2123 192.168.9.1 TCP_TUNNEL/200 7937 CONNECT oauth2.googleapis.com:443 user1 HIER_DIRECT/142.250.81.202 -
1639839600.950   1996 192.168.9.1 TCP_TUNNEL/200 115185 CONNECT storage.googleapis.com:443 user1 HIER_DIRECT/142.250.73.240 -

Configuring JAVA to use Proxy authorization is fairly complex and requires overriding transport handlers for HTTP and gRPC at the authentication and service api call layers.

Consider the following code snippet invoked using maven:

mvn clean install exec:java

with source that specifies the proxy inline

package com.test;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;

import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.apache.v2.ApacheHttpTransport;
import com.google.api.core.ApiFunction;
import com.google.api.gax.core.FixedCredentialsProvider;
import com.google.api.gax.rpc.TransportChannelProvider;
import com.google.auth.http.HttpTransportFactory;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.cloud.TransportOptions;
import com.google.cloud.http.HttpTransportOptions;
import com.google.cloud.pubsub.v1.TopicAdminClient;
import com.google.cloud.pubsub.v1.TopicAdminClient.ListTopicsPagedResponse;
import com.google.cloud.pubsub.v1.TopicAdminSettings;
import com.google.cloud.storage.Bucket;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;
import com.google.pubsub.v1.ListTopicsRequest;
import com.google.pubsub.v1.ProjectName;
import com.google.pubsub.v1.Topic;

import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.ProxyAuthenticationStrategy;

import io.grpc.HttpConnectProxiedSocketAddress;
import io.grpc.ManagedChannelBuilder;
import io.grpc.ProxiedSocketAddress;
import io.grpc.ProxyDetector;

public class TestApp {
	public static void main(String[] args) {
		TestApp tc = new TestApp();
	}

	private ApacheHttpTransport mHttpTransport;
	private GoogleCredentials credential;

	private String proxyHost = "localhost";
	private Integer proxyPort = 3128;
	private String proxyUser = "user1";
	private String proxyPassword = "user1";

	public TestApp() {
		try {

			HttpHost proxy = new HttpHost(proxyHost, proxyPort);

			org.apache.http.client.CredentialsProvider credsProvider = new BasicCredentialsProvider();
			credsProvider.setCredentials(
					new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT),
					new UsernamePasswordCredentials(proxyUser, proxyPassword));
			HttpClientBuilder clientBuilder = HttpClientBuilder.create();

			clientBuilder.useSystemProperties();
			clientBuilder.setProxy(proxy);
			clientBuilder.setDefaultCredentialsProvider(credsProvider);
			clientBuilder.setProxyAuthenticationStrategy(new ProxyAuthenticationStrategy());

			CloseableHttpClient httpClient = clientBuilder.build();

			mHttpTransport = new ApacheHttpTransport(httpClient);

			HttpTransportFactory hf = new HttpTransportFactory() {
				@Override
				public HttpTransport create() {
					return mHttpTransport;
				}
			};

			credential = GoogleCredentials.getApplicationDefault(hf);

			TransportOptions options = HttpTransportOptions.newBuilder().setHttpTransportFactory(hf).build();
			Storage storage_service = StorageOptions.newBuilder().setCredentials(credential)
					.setTransportOptions(options)
					.build()
					.getService();
			for (Bucket b : storage_service.list().iterateAll()) {
				System.out.println(b);
			}

			GoogleCredentials creds = GoogleCredentials.getApplicationDefault();
			FixedCredentialsProvider credentialsProvider = FixedCredentialsProvider.create(creds);

			TransportChannelProvider channelProvider = TopicAdminSettings.defaultGrpcTransportProviderBuilder()
					.setChannelConfigurator(new ApiFunction<ManagedChannelBuilder, ManagedChannelBuilder>() {
						@Override
						public ManagedChannelBuilder apply(ManagedChannelBuilder managedChannelBuilder) {
							return managedChannelBuilder.proxyDetector(
									new ProxyDetector() {
										@Override
										public ProxiedSocketAddress proxyFor(SocketAddress socketAddress)
												throws IOException {
											return HttpConnectProxiedSocketAddress.newBuilder()
													.setUsername(proxyUser)
													.setPassword(proxyPassword)
													.setProxyAddress(new InetSocketAddress(proxyHost, proxyPort))
													.setTargetAddress((InetSocketAddress) socketAddress)
													.build();
										}
									});
						}
					})
					.build();

			TopicAdminClient topicClient = TopicAdminClient.create(
					TopicAdminSettings.newBuilder()
							.setTransportChannelProvider(channelProvider)
							.setCredentialsProvider(credentialsProvider)
							.build());

			ListTopicsRequest listTopicsRequest = ListTopicsRequest.newBuilder()
					.setProject(ProjectName.format("your_project_id"))
					.build();
			ListTopicsPagedResponse response = topicClient.listTopics(listTopicsRequest);
			Iterable<Topic> topics = response.iterateAll();
			for (Topic topic : topics)
				System.out.println(topic);

		} catch (Exception ex) {
			System.out.println("Error:  " + ex);
		}
	}

}

Proxy logs shows both authentication and service traffic

1639840150.182   2301 192.168.9.1 TCP_TUNNEL/200 7028 CONNECT oauth2.googleapis.com:443 user1 HIER_DIRECT/142.250.188.42 -
1639840150.182    843 192.168.9.1 TCP_TUNNEL/200 7826 CONNECT pubsub.googleapis.com:443 user1 HIER_DIRECT/142.251.45.10 -
1639840150.182   2086 192.168.9.1 TCP_TUNNEL/200 162250 CONNECT storage.googleapis.com:443 user1 HIER_DIRECT/142.251.16.128 -

Requires either

export https_proxy=http://user1:user1@${PROXY_SERVER}:3128

Proxy logs shows both authentication and service traffic

1639840590.362     94 192.168.9.1 TCP_TUNNEL/200 7177 CONNECT oauth2.googleapis.com:443 user1 HIER_DIRECT/172.217.15.74 -
1639840590.904    159 192.168.9.1 TCP_TUNNEL/200 45157 CONNECT storage.googleapis.com:443 user1 HIER_DIRECT/142.250.73.240 -
1639840590.926    689 192.168.9.1 TCP_TUNNEL/200 7837 CONNECT pubsub.googleapis.com:443 user1 HIER_DIRECT/142.251.45.10 -

Requires either

export https_proxy=http://user1:user1@${PROXY_SERVER}:3128

Proxy logs shows both authentication and service traffic

1639841045.783    258 192.168.9.1 TCP_TUNNEL/200 7879 CONNECT pubsub.googleapis.com:443 user1 HIER_DIRECT/142.251.45.10 -
1639841045.783    779 192.168.9.1 TCP_TUNNEL/200 7350 CONNECT oauth2.googleapis.com:443 user1 HIER_DIRECT/172.217.2.106 -
1639841045.783    615 192.168.9.1 TCP_TUNNEL/200 45145 CONNECT storage.googleapis.com:443 user1 HIER_DIRECT/142.250.73.240 -

HTTP With Custom Certificate Authority

In this mode, the proxy server listens for the CONNECT request over TLS and allow decryption of the underlying traffic. This requires each client to setup TLS trust with the proxy server itself.

Note that the examples below uses a test certificate for use with the test squid proxy described in the appendix.

Configuring and overriding the Trusted CA certificates is shown in a separate article (Override Trust certificates for TLS). This section will show the proxy configurations needed

# with env for intercept
$ export https_proxy=http://squid.yourdomain.com:3128
$ curl -vvv --proxy-cacert /etc/ssl/certs/ca-certificates.crt \
  --cacert /etc/ssl/certs/ca-certificates.crt \
   https://httpbin.org/get

# or switch
curl -vvv  --cacert /etc/ssl/certs/ca-certificates.crt \
  -x http://squid.yourdomain.com:3128 https://httpbin.org/get

## for https_proxy
curl -vvv -x https://squid.yourdomain.com:3128 \
  --proxy-cacert /etc/ssl/certs/ca-certificates.crt https://httpbin.org/get

NOTE, /etc/ssl/certs/ca-certificates.crt includes the certificate chain (root-ca and sub)

The output on the proxy server will show the CONNECT and traffic within the reuquest

1639933306.535      0 192.168.9.1 TAG_NONE/200 0 CONNECT httpbin.org:443 - HIER_NONE/- -
1639933306.555      8 192.168.9.1 TCP_MISS/200 695 GET https://httpbin.org/get - HIER_DIRECT/3.223.33.229 application/json

First add the cacert chain to the python trust store

$ python3

>>> import certifi
>>> print(certifi.where())
/etc/ssl/certs/ca-certificates.crt
export https_proxy=http://squid.yourdomain.com:3128
1639933396.720      0 192.168.9.1 TAG_NONE/200 0 CONNECT oauth2.googleapis.com:443 - HIER_NONE/- -
1639933396.850    116 192.168.9.1 TCP_MISS/200 1661 POST https://oauth2.googleapis.com/token - HIER_DIRECT/172.217.12.234 application/json
1639933396.857      0 192.168.9.1 TAG_NONE/200 0 CONNECT storage.googleapis.com:443 - HIER_NONE/- -
1639933397.093    207 192.168.9.1 TCP_MISS/200 29212 GET https://storage.googleapis.com/storage/v1/b? - HIER_DIRECT/172.217.13.80 application/json

TODO: gRPC traffic did not traverse proxy

TODO: gRPC with TLS

For http, see crypto/x509.root_linux.go and the root certs chain to one of those files (eg /etc/ssl/certs/ca-certificates.crt)

The use environment variable:

export https_proxy=http://squid.yourdomain.com:3128

## todo: grpc 
export GRPC_DEFAULT_SSL_ROOTS_FILE_PATH=/etc/ssl/certs/ca-certificates.crt

http clients logged:

1639933212.023      0 192.168.9.1 TAG_NONE/200 0 CONNECT oauth2.googleapis.com:443 - HIER_NONE/- -
1639933212.105     69 192.168.9.1 TCP_MISS/200 1655 POST https://oauth2.googleapis.com/token - HIER_DIRECT/172.217.13.74 application/json
1639933212.106      0 192.168.9.1 TAG_NONE/200 0 CONNECT storage.googleapis.com:443 - HIER_NONE/- -
1639933212.623    514 192.168.9.1 TCP_MISS/200 108723 GET https://storage.googleapis.com/storage/v1/b? - HIER_DIRECT/172.217.13.80 application/json

For java, set the jvm truststore to include the custom CA

$ export JAVA_HOME=$(readlink -f /usr/bin/java | sed "s:bin/java::")
$ echo $JAVA_HOME
   /usr/lib/jvm/java-11-openjdk-amd64/

the cacerts would then be at /usr/lib/jvm/java-11-openjdk-amd64/lib/security/cacerts

import the custom certificates for the proxy

keytool -import -trustcacerts -alias myRootCA -file root.crt -keystore "/tmp/cacerts" -storepass changeit

keytool -list -keystore "/tmp/cacerts" -storepass changeit

Invoke maven with the truststore

mvn -Djavax.net.ssl.trustStore=/tmp/cacerts \
   -Djavax.net.ssl.trustStorePassword=changeit \
   -DproxySet=true -Dhttps.proxyHost=squid.yourdomain.com \
   -Dhttps.proxyPort=3128 clean install exec:java -q
1639935827.465      0 192.168.9.1 TAG_NONE/200 0 CONNECT oauth2.googleapis.com:443 - HIER_NONE/- -
1639935827.844     96 192.168.9.1 TCP_MISS/200 1654 POST https://oauth2.googleapis.com/token - HIER_DIRECT/172.217.1.202 application/json
1639935827.913      0 192.168.9.1 TAG_NONE/200 0 CONNECT storage.googleapis.com:443 - HIER_NONE/- -
1639935828.350    371 192.168.9.1 TCP_MISS/200 154527 GET https://storage.googleapis.com/storage/v1/b? - HIER_DIRECT/142.250.31.128 application/json

TODO:

export https_proxy=http://squid.yourdomain.com:3128

Shows GCS and Oauth requests (not GRPC)

1639933951.628      0 192.168.9.1 TAG_NONE/200 0 CONNECT oauth2.googleapis.com:443 - HIER_NONE/- -
1639933951.798     96 192.168.9.1 TCP_MISS/200 2110 POST https://oauth2.googleapis.com/token - HIER_DIRECT/142.250.188.42 application/json
1639933951.837      0 192.168.9.1 TAG_NONE/200 0 CONNECT storage.googleapis.com:443 - HIER_NONE/- -
1639933952.054    213 192.168.9.1 TCP_MISS/200 39292 GET https://storage.googleapis.com/storage/v1/b? - HIER_DIRECT/172.217.164.144 application/json

SOCKS Proxy

# create tunnel
ssh -vvv -D 8080 user@somehost.com

note socks5h means the hostname is remotely resolved (socks5 is local)


# with env
export http_proxy=socks5://localhost:8080
export https_proxy=socks5h://localhost:8080

# or switch
curl --socks5-hostname localhost:8080 https://www.httpbin.org/get

Proxy logs shows both authentication and service traffic

debug1: channel 3: free: direct-tcpip: listening port 8080 for www.httpbin.org port 443, connect from 127.0.0.1 port 32870 to 127.0.0.1 port 8080, nchannels 4
debug3: channel 3: status: The following connections are open:
  #2 client-session (t4 r0 i0/0 o0/0 e[write]/0 fd 6/7/8 sock -1 cc -1)
  #3 direct-tcpip: listening port 8080 for www.httpbin.org port 443, connect from 127.0.0.1 port 32870 to 127.0.0.1 port 8080 (t4 r1 i3/0 o3/0 e[closed]/0 fd 9/9/-1 sock 9 cc -1)

Note: Python gRPC does not support SOCKS

For HTTP

pip install pysocks
export http_proxy=socks5h://localhost:8080
export https_proxy=socks5h://localhost:8080
debug3: channel 3: status: The following connections are open:
  #2 client-session (t4 r0 i0/0 o0/0 e[write]/0 fd 6/7/8 sock -1 cc -1)
  #3 direct-tcpip: listening port 8080 for oauth2.googleapis.com port 443, connect from ::1 port 54170 to ::1 port 8080 (t4 r1 i3/0 o3/0 e[closed]/0 fd 9/9/-1 sock 9 cc -1)
  #4 direct-tcpip: listening port 8080 for storage.googleapis.com port 443, connect from ::1 port 54172 to ::1 port 8080 (t4 r2 i3/0 o0/0 e[closed]/0 fd 10/10/-1 sock 10 cc -1)

TODO:

  • Authentication Traffic does not flow through sock proxy
  • Unsure if gRPC is supported

set

export https_proxy=socks5://localhost:8080

then use net/http.ProxyFromEnvironment

package main

import (
	"fmt"

	"net/http"

	"cloud.google.com/go/pubsub"
	"cloud.google.com/go/storage"
	"golang.org/x/net/context"
	"google.golang.org/api/iterator"
	"google.golang.org/api/option"
)

const (
	projectID = "mineral-minutia-820"
)

func main() {

	client := http.Client{
		Transport: &http.Transport{
			Proxy: http.ProxyFromEnvironment,
		},
	}

	// creds, err := google.FindDefaultCredentials(oauth2.NoContext, storage.ScopeReadOnly)
	// if err != nil {
	// 	panic(err)
	// }

	ctx := context.Background()
	gcs, err := storage.NewClient(ctx, option.WithHTTPClient(&client))
	if err != nil {
		panic(err)
	}
	b := gcs.Buckets(ctx, projectID)
	for {
		t, err := b.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			panic(err)
		}
		fmt.Printf("bucket: %q\n", t.Name)
	}

	pub, err := pubsub.NewClient(ctx, projectID)
	if err != nil {
		panic(err)
	}

	topics := pub.Topics(ctx)
	for {
		t, err := topics.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			panic(err)
		}
		fmt.Printf("Topic: %q\n", t)
	}
}

TODO: gRPC

mvn -DproxySet=true -DsocksProxyHost=localhost -DsocksProxyPort=8080 clean install exec:java 

Not supported in grpc-node (issue 1706)

$ node app.js 
E "socks5h:" scheme not supported in proxy URI

TODO


Appendix

GCP Domain AllowList

If your proxy sets specific domains in the ACL (see squid.conf.allow_domains), you should at a minimum include

Endpoints used for authentication:

accounts.googleapis.com
oauth2.googleapis.com

Then service specific endpoints (all over :443, certainly). For example, for pubsub and GCS, you would need to allow

storage.googleapis.com
pubsub.googleapis.com

see GCS Proxy documentation

Squid Proxy

To verify http proxy functionality locally, run a test proxy server shown here: Squid Proxy

To use these samples, override the /etc/hosts file

127.0.0.1 squid.yourdomain.com

and utilize the CA chain provided in the repository. (i.,e combine sub-CA and root-CA into the root truststore (eg /etc/ssl/certs/ca-certificates.crt or /etc/ssl/certs/java/cacerts)

Sample scenarios:

docker run  -p 3128:3128 -ti docker.io/salrashid123/squidproxy /bin/bash
# for no authentication
/apps/squid/sbin/squid -NsY -f /apps/squid.conf.forward &
# for basic authentication
/apps/squid/sbin/squid -NsY -f /apps/squid.conf.basicauth &
# for custom CA and SSL interception
/apps/squid/sbin/squid -NsY -f /apps/squid.conf.intercept &
# for https_port
/apps/squid/sbin/squid -NsY -f /apps/squid.conf.https_port &
# viewing access logs
tail -f /apps/squid/var/logs/access.log

This site supports webmentions. Send me a mention via this form.