Locally Test
Introduction
1
2
3
Create Configuration Files
.env File
.env FileAICEBERG_PROFILE_ID=your_profile_id_here
AICEBERG_API_KEY=your_api_key_here
# Optional configuration
# AICEBERG_ENVIRONMENT=prod
# LLM_SHIELD_ICAP_PORT=1344
# SQUID_PORT=3128
# SQUID_CONFIG_PATH=./squid.conf
# CERTS_DIR=./certsDockerfile for Squid
Dockerfile for SquidFROM ghcr.io/b4tman/squid-ssl-bump:latest
USER root
# Initialize SSL DB
RUN rm -rf /var/lib/ssl_db \
&& /usr/lib/squid/security_file_certgen -c -s /var/lib/ssl_db -M 4MB \
&& chown -R squid:squid /var/lib/ssl_db
USER squiddocker-compose.yml
docker-compose.ymlservices:
llm_icap_shield:
image: public.ecr.aws/n5w6j7z8/aiceberg/aiceberg_llm_shield:latest
container_name: llm_icap_shield
restart: always
ports:
- "${LLM_SHIELD_ICAP_PORT:-1344}:1344"
environment:
# Credentials loaded from .env file
- AICEBERG_PROFILE_ID=${AICEBERG_PROFILE_ID:?err}
- AICEBERG_API_KEY=${AICEBERG_API_KEY:?err}
- ICAP_HTTP_TRANSFER_ENCODING=chunked
- ICAP_ENCAPSULATED_MODE=identity
squid:
build: .
container_name: squid-proxy
ports:
- "${SQUID_PORT:-3128}:3128"
volumes:
- ./squid.conf:/etc/squid/squid.conf:ro
- ./certs:/etc/squid/certs:ro
depends_on:
- llm_icap_shield
restart: alwayssquid.conf
squid.conf########################################
# Basic proxy settings
########################################
# Listen on standard proxy port with SSL Bump enabled
http_port 3128 ssl-bump cert=/etc/squid/certs/ca.crt key=/etc/squid/certs/ca.key generate-host-certificates=on dynamic_cert_mem_cache_size=4MB
# SSL Cert generation program
sslcrtd_program /usr/lib/squid/security_file_certgen -s /var/lib/ssl_db -M 4MB
sslcrtd_children 5
# Recommended basic options
visible_hostname llm-icap-proxy
via on
forwarded_for off
# Disable ARP lookups to reduce noise in Docker
eui_lookup off
# Logging
# Custom log format for debugging errors
logformat icap_debug %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %[un %Sh/%<a %mt Err=%err_code Detail=%err_detail Adapt=%<A
access_log stdio:/dev/stdout icap_debug
cache_log stdio:/dev/stderr
icap_log stdio:/dev/stdout
cache_store_log none
# Debug options for ICAP (93), uncomment for more verbose logging
# debug_options 93,9 28,9 11,5 33,3
# Disable on-disk caching (LLM calls are usually small + sensitive)
cache deny all
maximum_object_size 0 KB
request_header_max_size 128 KB
reply_header_max_size 128 KB
########################################
# ACLs: networks and ports
########################################
# Adjust this to your internal subnet(s)
acl localnet src 10.0.0.0/8 # RFC1918 example
acl localnet src 172.16.0.0/12
acl localnet src 192.168.0.0/16
# Squid internal assets (error pages/icons)
acl squid_internal urlpath_regex -i ^/squid-internal-static/
# Safe ports
acl SSL_ports port 443
acl Safe_ports port 80 # http
acl Safe_ports port 443 # https
acl Safe_ports port 8080 # alt http
# Only allow CONNECT to HTTPS ports
acl CONNECT method CONNECT
########################################
# LLM destination ACLs (ChatGPT, Gemini, Claude)
########################################
# OpenAI / ChatGPT
acl llm_openai_dstdomain dstdomain .openai.com .chatgpt.com
acl llm_openai_sni ssl::server_name .openai.com .chatgpt.com
# Gemini (Google)
# Gemini APIs typically use *.googleapis.com / generativelanguage.googleapis.com / ai.google.dev
acl llm_gemini_dstdomain dstdomain .gemini.google.com .googleapis.com .ai.google.dev
acl llm_gemini_sni ssl::server_name .gemini.google.com .googleapis.com .ai.google.dev
# Claude (Anthropic + possible Bedrock endpoint)
acl llm_claude_dstdomain dstdomain .anthropic.com .bedrock.amazonaws.com
acl llm_claude_sni ssl::server_name .anthropic.com .bedrock.amazonaws.com
# Combined ACL for all LLM traffic
# TODO: Not used at the moment
acl llm_traffic any-of llm_openai_dstdomain llm_openai_sni \
llm_gemini_dstdomain llm_gemini_sni \
llm_claude_dstdomain llm_claude_sni
########################################
# Auth/security domains to NOT bump
########################################
# High-risk auth/security domains: NEVER bump these
# NOTE: do not include subdomains already covered by a parent.
acl auth_security_sni ssl::server_name \
.google.com \
.gstatic.com \
.googleapis.com \
.recaptcha.net \
.auth.openai.com \
.oaistatic.com \
.sentinel.openai.com \
.cloudflare.com \
.cf-binary.cloudflare.com
# Websocket endpoint(s) — treat as high-risk: DO NOT bump, DO NOT ICAP
acl chatgpt_ws_sni ssl::server_name ws.chatgpt.com
########################################
# Only care about these *paths* for monitoring
########################################
acl openai_conversation_path urlpath_regex -i ^/backend.*conversation$
########################################
# SSL Bump policy (order matters!)
########################################
# SSL Bump Steps
acl step1 at_step SslBump1
# Step 1: peek to learn SNI
ssl_bump peek step1
# Splice auth/security domains always
ssl_bump splice auth_security_sni
ssl_bump splice chatgpt_ws_sni
# Bump chatgpt/openai so we can see HTTP paths
ssl_bump bump llm_openai_sni
# Default: splice everything else
ssl_bump splice all
########################################
# Access control
########################################
# Allow local network to use the proxy
http_access allow localnet
# Let Squid serve its internal assets (error pages/icons)
http_access allow squid_internal
# Keep basic safety checks
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
########################################
# ICAP configuration: llm_icap_shield
########################################
icap_enable on
icap_connect_timeout 5 seconds
icap_io_timeout 30 seconds
icap_service_failure_limit -1
icap_send_client_ip on
icap_send_client_username on
# Optional: include client username header if you use auth
icap_client_username_header X-Client-Username
# Define the ICAP service
# Replace 'icap-server' with your ICAP host or service DNS name
icap_service llm_icap_shield_req reqmod_precache icap://llm_icap_shield:1344/llm_icap_shield bypass=0 on-overload=bypass
icap_service llm_icap_shield_resp respmod_precache icap://llm_icap_shield:1344/llm_icap_shield bypass=0 on-overload=bypass
# Disable ICAP service suspension on failure
icap_service_failure_limit -1
icap_preview_enable off
#icap_preview_size 1024
########################################
# Apply ICAP only to LLM destinations with conversation endpoints
########################################
# Define Websockets
acl is_websocket url_regex -i ^wss:// ^ws://
acl chatgpt_ws_dstdomain dstdomain ws.chatgpt.com
# Request modification: only for LLM traffic AND the path matches, exclude websocket
adaptation_access llm_icap_shield_req deny is_websocket
adaptation_access llm_icap_shield_req deny chatgpt_ws_dstdomain
adaptation_access llm_icap_shield_req allow llm_openai_dstdomain openai_conversation_path
adaptation_access llm_icap_shield_req deny all
# Response modification: only for LLM traffic AND the path matches, exclude websocket
adaptation_access llm_icap_shield_resp deny is_websocket
adaptation_access llm_icap_shield_resp deny chatgpt_ws_dstdomain
adaptation_access llm_icap_shield_resp allow llm_openai_dstdomain openai_conversation_path
adaptation_access llm_icap_shield_resp deny all
########################################
# Misc recommended options
########################################
shutdown_lifetime 5 seconds
# Keep connections alive reasonably to reduce connection churn
icap_persistent_connections on
client_persistent_connections on
server_persistent_connections on4
Generate Certificates
# Create certs directory
mkdir certs
# 1. Generate CA Key
openssl genrsa -out certs/ca.key 4096
# 2. Generate CA Certificate (Self-Signed)
openssl req -x509 -new -nodes -key certs/ca.key -sha256 -days 3650 \
-subj "/CN=Local LLM Shield CA" -out certs/ca.crt
# Note: The squid.conf expects these exact filenames (ca.key, ca.crt)5
Last updated