Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .devcontainer/squid-https-test/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
squid-ssl
13 changes: 13 additions & 0 deletions .devcontainer/squid-https-test/.vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "squid",
"type": "shell",
"command": "stunnel /etc/stunnel/stunnel.conf & squid -N -d1 -f /etc/squid/squid.conf & sleep 2 && tail -n +1 -F /var/log/squid/access.log",
"runOptions": {
"runOn": "folderOpen"
}
}
]
}
20 changes: 20 additions & 0 deletions .devcontainer/squid-https-test/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
FROM ubuntu:latest

# squid-openssl is the Squid build with OpenSSL / SSL-Bump (TLS interception) support.
# stunnel provides the TLS-terminating proxy port in front of Squid.
RUN apt-get update \
&& apt-get install -y \
squid-openssl \
stunnel4 \
openssl \
ca-certificates \
iputils-ping \
dnsutils \
&& rm -rf /var/lib/apt/lists/*

COPY squid.conf /etc/squid/squid.conf
COPY stunnel.conf /etc/stunnel/stunnel.conf
COPY setup.sh /usr/local/bin/setup.sh
RUN chmod +x /usr/local/bin/setup.sh

CMD ["sleep", "inf"]
12 changes: 12 additions & 0 deletions .devcontainer/squid-https-test/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
## Squid HTTPS Test

A second TLS-intercepting proxy (in addition to the mitmproxy-based `HTTPS Proxy Test`), using Squid with SSL-Bump behind stunnel.

Squid can only do SSL-Bump on an explicit HTTP `http_port` (it bumps the tunneled TLS of each `CONNECT`), not on an explicit TLS `https_port`. To still expose a real TLS proxy port, stunnel terminates TLS on port `3128` and forwards the decrypted proxy traffic to Squid's localhost-only `http_port`, where SSL-Bump intercepts the connections. A single CA signs both the proxy's `localhost` certificate and the per-host certificates Squid generates, so you only install one certificate on the host.

- `Dev Containers: Reopen in Container` > `Squid HTTPS Test`.
- The dev container should show two log terminals: one for Squid and one for stunnel (the TLS proxy port).
- First time: Install the CA certificate from `.devcontainer/squid-https-test/squid-ssl/ca.crt` in the OS trust store and restart VS Code. The certificate is generated on the first container start, so it only appears after the container is up.
- Add the user setting `"http.proxy": "https://localhost:3133"`.
- Install GitHub Copilot Chat and use `Developer: GitHub Copilot Chat Diagnostics` to test connections with a HTTPS proxy. Use a second window to test connections from a local extension host.
- Verify in the log terminals of the dev container that the proxy is being used.
3 changes: 3 additions & 0 deletions .devcontainer/squid-https-test/devcontainer-lock.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"features": {}
}
6 changes: 6 additions & 0 deletions .devcontainer/squid-https-test/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "Squid HTTPS Test",
"dockerComposeFile": "docker-compose.yml",
"service": "devcontainer",
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}/.devcontainer/squid-https-test"
}
13 changes: 13 additions & 0 deletions .devcontainer/squid-https-test/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
version: '3.4'

services:
devcontainer:
build:
context: .
dockerfile: Dockerfile
volumes:
- ../../..:/workspaces
- ./squid-ssl:/etc/squid/ssl
ports:
- "127.0.0.1:3133:3128"
command: /bin/sh -c "/usr/local/bin/setup.sh && sleep inf"
54 changes: 54 additions & 0 deletions .devcontainer/squid-https-test/setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#!/bin/bash
# Generates the CA used as the signing CA for the certificates Squid generates
# on the fly when bumping (intercepting) TLS connections, plus the localhost
# server certificate stunnel presents on the TLS proxy port. Both are signed by
# the same CA, so installing ca.crt in the host trust store covers everything.
# Idempotent: safe to run on every start.
set -e

SSL_DIR=/etc/squid/ssl
SSL_DB=/var/lib/squid/ssl_db

mkdir -p "$SSL_DIR"

if [ ! -f "$SSL_DIR/ca.crt" ] || [ ! -f "$SSL_DIR/ca.key" ]; then
echo "Generating CA certificate ..."
openssl req -x509 -newkey rsa:2048 -sha256 -days 3650 -nodes \
-keyout "$SSL_DIR/ca.key" \
-out "$SSL_DIR/ca.crt" \
-subj "/CN=Squid HTTPS Test CA" \
-addext "basicConstraints=critical,CA:TRUE" \
-addext "keyUsage=critical,keyCertSign,cRLSign"
fi

# The localhost server certificate stunnel presents on the TLS proxy port.
if [ ! -f "$SSL_DIR/proxy.crt" ] || [ ! -f "$SSL_DIR/proxy.key" ]; then
echo "Generating proxy server certificate ..."
openssl req -new -newkey rsa:2048 -nodes \
-keyout "$SSL_DIR/proxy.key" \
-out "$SSL_DIR/proxy.csr" \
-subj "/CN=localhost"
# macOS (SecTrustEvaluateWithError) enforces Apple's TLS server cert policy:
# leaf validity must be <= 398 days and the serverAuth EKU must be present,
# otherwise the cert is rejected as "not standards compliant" (errSecCertificateNotStandardsCompliant / -67901).
openssl x509 -req -in "$SSL_DIR/proxy.csr" \
-CA "$SSL_DIR/ca.crt" -CAkey "$SSL_DIR/ca.key" -CAcreateserial \
-out "$SSL_DIR/proxy.crt" -days 397 -sha256 \
-extfile <(printf "subjectAltName=DNS:localhost,IP:127.0.0.1\nbasicConstraints=CA:FALSE\nkeyUsage=digitalSignature,keyEncipherment\nextendedKeyUsage=serverAuth")
rm -f "$SSL_DIR/proxy.csr"
fi

# Squid drops privileges to the 'proxy' user, which must be able to read the key.
chmod 644 "$SSL_DIR/ca.crt" "$SSL_DIR/proxy.crt"
chmod 640 "$SSL_DIR/ca.key" "$SSL_DIR/proxy.key"
chgrp proxy "$SSL_DIR/ca.key" 2>/dev/null || true

# Initialize the database used to cache the per-host certificates Squid generates.
if [ ! -d "$SSL_DB" ]; then
echo "Initializing SSL certificate database ..."
mkdir -p "$(dirname "$SSL_DB")"
/usr/lib/squid/security_file_certgen -c -s "$SSL_DB" -M 20MB
fi
chown -R proxy:proxy "$SSL_DB" 2>/dev/null || true

echo "CA certificate to install on the host: .devcontainer/squid-https-test/squid-ssl/ca.crt"
28 changes: 28 additions & 0 deletions .devcontainer/squid-https-test/squid.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Minimal Squid configuration for a TLS-intercepting proxy.
#
# The TLS-terminating proxy port is provided by stunnel (see stunnel.conf), which
# forwards the decrypted proxy traffic to this plaintext, localhost-only port.
# Squid is a normal HTTP forward proxy here; SSL-Bump intercepts (bumps) the
# tunneled TLS connections established via CONNECT. The CA (ca.crt / ca.key) is
# the signing CA for the per-host certificates Squid generates on the fly.
# (Squid only allows ssl-bump on http_port for explicit forward proxies, not on
# an explicit https_port.)

http_port 127.0.0.1:3130 ssl-bump cert=/etc/squid/ssl/ca.crt key=/etc/squid/ssl/ca.key \
generate-host-certificates=on dynamic_cert_mem_cache_size=20MB

sslcrtd_program /usr/lib/squid/security_file_certgen -s /var/lib/squid/ssl_db -M 20MB
sslcrtd_children 5

acl step1 at_step SslBump1
ssl_bump peek step1
ssl_bump bump all

http_access allow all

# Squid runs as the 'proxy' user and cannot write to /dev/stdout, so log to
# files under /var/log/squid; the `squid` task tails them into the terminal.
logfile_rotate 0
access_log stdio:/var/log/squid/access.log squid

coredump_dir /var/spool/squid
15 changes: 15 additions & 0 deletions .devcontainer/squid-https-test/stunnel.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# stunnel provides the TLS-terminating HTTPS proxy port. It accepts TLS on 3128
# (presenting the localhost server certificate) and forwards the decrypted proxy
# traffic to Squid's plaintext, localhost-only port, where SSL-Bump intercepts
# the tunneled TLS connections.

foreground = yes
pid =
debug = 4
output = /dev/stdout

[https-proxy]
accept = 0.0.0.0:3128
connect = 127.0.0.1:3130
cert = /etc/squid/ssl/proxy.crt
key = /etc/squid/ssl/proxy.key
Loading