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
10 changes: 10 additions & 0 deletions images/chromium-headful/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,16 @@ RUN chmod +x /images/chromium-headful/start-pulseaudio.sh
COPY images/chromium-headful/wrapper.sh /wrapper.sh
COPY images/chromium-headful/supervisord.conf /etc/supervisor/supervisord.conf
COPY images/chromium-headful/supervisor/services/ /etc/supervisor/conf.d/services/
COPY shared/envoy/supervisor-envoy.conf /etc/supervisor/conf.d/services/envoy.conf

# Install Envoy proxy
COPY shared/envoy/install-proxy.sh /usr/local/bin/install-proxy.sh
RUN chmod +x /usr/local/bin/install-proxy.sh && /usr/local/bin/install-proxy.sh && rm /usr/local/bin/install-proxy.sh

# Copy Envoy configuration files
COPY shared/envoy/bootstrap.yaml /etc/envoy/templates/bootstrap.yaml
COPY shared/envoy/init-envoy.sh /usr/local/bin/init-envoy.sh
RUN chmod +x /usr/local/bin/init-envoy.sh

# copy the kernel-images API binary built in the builder stage
COPY --from=server-builder /out/kernel-images-api /usr/local/bin/kernel-images-api
Expand Down
2 changes: 2 additions & 0 deletions images/chromium-headful/wrapper.sh
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,8 @@ fi
sleep 0.2
done

init-envoy.sh

echo "[wrapper] Starting Xorg via supervisord"
supervisorctl -c /etc/supervisor/supervisord.conf start xorg
echo "[wrapper] Waiting for Xorg to open display $DISPLAY..."
Expand Down
10 changes: 10 additions & 0 deletions images/chromium-headless/image/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,16 @@ COPY images/chromium-headless/image/wrapper.sh /usr/bin/wrapper.sh
# Supervisord configuration
COPY images/chromium-headless/image/supervisord.conf /etc/supervisor/supervisord.conf
COPY images/chromium-headless/image/supervisor/services/ /etc/supervisor/conf.d/services/
COPY shared/envoy/supervisor-envoy.conf /etc/supervisor/conf.d/services/envoy.conf

# Install Envoy proxy
COPY shared/envoy/install-proxy.sh /usr/local/bin/install-proxy.sh
RUN chmod +x /usr/local/bin/install-proxy.sh && /usr/local/bin/install-proxy.sh && rm /usr/local/bin/install-proxy.sh

# Copy Envoy configuration files
COPY shared/envoy/bootstrap.yaml /etc/envoy/templates/bootstrap.yaml
COPY shared/envoy/init-envoy.sh /usr/local/bin/init-envoy.sh
RUN chmod +x /usr/local/bin/init-envoy.sh

# Copy the kernel-images API binary built in the builder stage
COPY --from=server-builder /out/kernel-images-api /usr/local/bin/kernel-images-api
Expand Down
2 changes: 2 additions & 0 deletions images/chromium-headless/image/wrapper.sh
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,8 @@ for i in {1..30}; do
sleep 0.2
done

init-envoy.sh

echo "[wrapper] Starting system D-Bus daemon via supervisord"
supervisorctl -c /etc/supervisor/supervisord.conf start dbus
for i in {1..50}; do
Expand Down
79 changes: 79 additions & 0 deletions shared/envoy/bootstrap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Envoy bootstrap configuration for xDS-managed proxy
# This config connects to a control plane for dynamic configuration management
# Requires: INST_NAME, METRO_NAME, XDS_SERVER, XDS_JWT environment variables

# Node identity sent to xDS server for configuration targeting, authenticated by JWT
node:
id: "{INST_NAME}-{METRO_NAME}"
cluster: "kernel"

# Dynamic configuration via xDS protocol
dynamic_resources:
# Aggregated Discovery Service - single gRPC stream for all config types
ads_config:
api_type: GRPC
transport_api_version: V3
grpc_services:
- envoy_grpc:
# Reference to xDS server cluster below
cluster_name: xds_server
authority: "{XDS_SERVER}"
# Send JWT authentication for all xDS requests
initial_metadata:
- key: "authorization"
value: "Bearer {XDS_JWT}"

# Listener Discovery Service and Cluster Discovery Service use ADS
lds_config:
ads: {}
resource_api_version: V3
cds_config:
ads: {}
resource_api_version: V3

# Static configuration (always present)
static_resources:
clusters:
# xDS server: control plane for configuration
- name: xds_server
# Resolve hostname via DNS, for DNS lookup
type: STRICT_DNS
connect_timeout: 2s
http2_protocol_options: {}
dns_lookup_family: V4_ONLY
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
"@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
explicit_http_config:
# Used to detect reconnect needed when resuming from standby.
# HTTP/2 keepalive adds minimal overhead: only 17 bytes per request.
http2_protocol_options:
connection_keepalive:
interval: 1s
timeout: 1s
interval_jitter:
value: 10.0
# TLS configuration for secure xDS connection
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
# Uses TLS to verify xDS server, and SNI hostname for TLS handshake
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
sni: {XDS_SERVER}
load_assignment:
cluster_name: xds_server
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: {XDS_SERVER}
port_value: 443

# Envoy admin interface for debugging (disabled by default for security)
# To enable locally, uncomment the admin block below
# admin:
# address:
# socket_address:
# address: 0.0.0.0
# port_value: 9901
105 changes: 105 additions & 0 deletions shared/envoy/init-envoy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#!/bin/bash

set -o pipefail -o errexit -o nounset

# Check for required environment variables, to see if envoy is enabled
if [[ -z "${INST_NAME:-}" || -z "${METRO_NAME:-}" || -z "${XDS_SERVER:-}" || -z "${XDS_JWT:-}" ]]; then
echo "[envoy-init] Required environment variables not set. Skipping Envoy initialization."
exit 0
fi

# Also check for template file
if [[ ! -f /etc/envoy/templates/bootstrap.yaml ]]; then
echo "[envoy-init] Template file /etc/envoy/templates/bootstrap.yaml not found. Skipping Envoy initialization."
exit 0
fi

echo "[envoy-init] Preparing Envoy bootstrap configuration"
mkdir -p /etc/envoy

# Generate self-signed certificates for TLS forward proxy
echo "[envoy-init] Generating self-signed certificates for TLS forward proxy"
mkdir -p /etc/envoy/certs

if [[ ! -f /etc/envoy/certs/proxy.crt || ! -f /etc/envoy/certs/proxy.key ]]; then
echo "[envoy-init] Creating new self-signed certificate"
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
-keyout /etc/envoy/certs/proxy.key \
-out /etc/envoy/certs/proxy.crt \
-subj "/C=US/ST=CA/O=Kernel/CN=localhost" \
-addext "subjectAltName = DNS:localhost,IP:127.0.0.1" \
2>&1 | sed 's/^/[envoy-init] /'
echo "[envoy-init] Certificate generated successfully"

# Add certificate to system trust store for Chrome/Chromium
echo "[envoy-init] Adding certificate to system trust store"
cp /etc/envoy/certs/proxy.crt /usr/local/share/ca-certificates/kernel-envoy-proxy.crt
cp /etc/envoy/certs/proxy.crt /kernel-envoy-proxy.crt
update-ca-certificates 2>&1 | sed 's/^/[envoy-init] /'
echo "[envoy-init] Certificate added to system trust store"
if [[ "${RUN_AS_ROOT:-}" == "true" ]]; then
mkdir -p /root/.pki/nssdb
certutil -d /root/.pki/nssdb -N --empty-password 2>/dev/null || true
certutil -d /root/.pki/nssdb -A -t "C,," -n "Kernel Envoy Proxy" -i /etc/envoy/certs/proxy.crt
echo "[envoy-init] Certificate added to nssdb as root"
else
mkdir -p /home/kernel/.pki/nssdb
certutil -d /home/kernel/.pki/nssdb -N --empty-password 2>/dev/null || true
certutil -d /home/kernel/.pki/nssdb -A -t "C,," -n "Kernel Envoy Proxy" -i /etc/envoy/certs/proxy.crt
chown -R kernel:kernel /home/kernel/.pki
echo "[envoy-init] Certificate added to nssdb as kernel"
fi
echo "[envoy-init] Certificate added to nssdb"
else
echo "[envoy-init] Certificates already exist, skipping generation"
fi

# Render template with provided environment variables
echo "[envoy-init] Rendering template with INST_NAME=${INST_NAME}, METRO_NAME=${METRO_NAME}, XDS_SERVER=${XDS_SERVER}, XDS_JWT=***"
inst_esc=$(printf '%s' "$INST_NAME" | sed -e 's/[\/&]/\\&/g')
metro_esc=$(printf '%s' "$METRO_NAME" | sed -e 's/[\/&]/\\&/g')
xds_esc=$(printf '%s' "$XDS_SERVER" | sed -e 's/[\/&]/\\&/g')
jwt_esc=$(printf '%s' "$XDS_JWT" | sed -e 's/[\/&]/\\&/g')
sed -e "s|{INST_NAME}|$inst_esc|g" \
-e "s|{METRO_NAME}|$metro_esc|g" \
-e "s|{XDS_SERVER}|$xds_esc|g" \
-e "s|{XDS_JWT}|$jwt_esc|g" \
/etc/envoy/templates/bootstrap.yaml > /etc/envoy/bootstrap.yaml

echo "[envoy-init] Starting Envoy via supervisord"
supervisorctl -c /etc/supervisor/supervisord.conf start envoy

# Wait for Envoy port to be open
echo "[envoy-init] Waiting for Envoy port to open..."
port_open=false
for i in {1..50}; do
if nc -z 127.0.0.1 "3128" 2>/dev/null; then
echo "[envoy-init] Envoy port confirmed open"
port_open=true
break
fi
sleep 0.2
done

if [[ "$port_open" != "true" ]]; then
echo "[envoy-init] ERROR: Envoy port 3128 failed to open after 10 seconds"
exit 1
fi

# Test proxy functionality
echo "[envoy-init] Testing proxy functionality..."
proxy_working=false
for i in {1..50}; do
if curl -s -f -x https://127.0.0.1:3128 --max-time 2 https://public-ping-bucket-kernel.s3.us-east-1.amazonaws.com/index.html >/dev/null 2>&1; then
echo "[envoy-init] Confirmed a request is proxied"
proxy_working=true
break
fi
echo "[envoy-init] Check failed, trying again..."
sleep 0.2
done

if [[ "$proxy_working" != "true" ]]; then
echo "[envoy-init] ERROR: Envoy proxy test failed after 10 seconds"
exit 1
fi
20 changes: 20 additions & 0 deletions shared/envoy/install-proxy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/bash
set -eux

# Install Envoy proxy (official apt.envoyproxy.io)
ENVOY_PACKAGE="${ENVOY_PACKAGE:-envoy-1.32}"

echo "Installing Envoy proxy package: ${ENVOY_PACKAGE}"
mkdir -p /etc/apt/keyrings
curl -fsSL https://apt.envoyproxy.io/signing.key | gpg --dearmor -o /etc/apt/keyrings/envoy-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/envoy-keyring.gpg] https://apt.envoyproxy.io jammy main" > /etc/apt/sources.list.d/envoy.list
apt-get update
apt-get install -y --no-install-recommends "${ENVOY_PACKAGE}" || (apt-cache policy "${ENVOY_PACKAGE}" envoy && exit 1)
# nss tools used to add certificate to chrome
apt-get install -y libnss3-tools curl netcat
apt-mark hold "${ENVOY_PACKAGE}"
apt-get clean -y
rm -rf /var/lib/apt/lists/* /var/cache/apt/

# Create directory structure for Envoy configuration
mkdir -p /etc/envoy/templates
7 changes: 7 additions & 0 deletions shared/envoy/supervisor-envoy.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[program:envoy]
command=envoy -c /etc/envoy/bootstrap.yaml --log-level warn --drain-time-s 1 --drain-strategy immediate
autostart=false
autorestart=true
startsecs=2
stdout_logfile=/var/log/supervisord/envoy
redirect_stderr=true
Loading