Skip to content

Instantly share code, notes, and snippets.

@jdeathe
Last active May 21, 2017 14:37
Show Gist options
  • Save jdeathe/81d4087da8246e9429e533c5d766db16 to your computer and use it in GitHub Desktop.
Save jdeathe/81d4087da8246e9429e533c5d766db16 to your computer and use it in GitHub Desktop.
Local Squid Proxy (Experimental)
#
# WARNING! This configures a Man-In-The-Middle proxy that decrypts HTTPS traffic.
#
# - Requires Local DNS: https://gist.github.com/jdeathe/252578a3217ab9782fed10c3b3816d30
# - Disable the SSH features and process - using local docker.
# - https://docs.docker.com/engine/userguide/networking/
# - http://www.squid-cache.org/Versions/v3/3.3/cfgman/http_port.html
# - http://www.squid-cache.org/Versions/v3/3.3/cfgman/ssl_bump.html
# - http://www.squid-cache.org/Versions/v3/3.3/cfgman/refresh_pattern.html
# - https://www.openssl.org/docs/manmaster/ssl/SSL_CTX_set_options.html
LOOPBACK_IP_ALIAS="192.168.127.1/24"
LOOPBACK_ALIAS_IP="${LOOPBACK_ALIAS%%/*}"
# Alias for loopback interface.
# Note this is not persistent accross reboots.
if [[ $(uname) == Darwin ]]; then
sudo ifconfig lo0 alias ${LOOPBACK_IP_ALIAS} up
else
sudo ip addr add ${LOOPBACK_IP_ALIAS} dev lo:0
fi
# Create an isolated infrastructure network
docker network create --driver bridge local_infra 2> /dev/null || true
LOCAL_INFRA_GATEWAY="$(
docker network inspect -f '{{ index (index .IPAM.Config 0).Gateway }}' local_infra | awk -F/ '{ print $1; }'
)"
docker pull jdeathe/centos-ssh:centos-7-2.1.2
eval "sudo -E $(
docker inspect \
-f "{{.ContainerConfig.Labels.install}}" \
jdeathe/centos-ssh:centos-7-2.1.2
) install \
--name=squid.1.0 \
--env='SSH_AUTOSTART_SSHD=false' \
--env='SSH_AUTOSTART_SSHD_BOOTSTRAP=false' \
--env='DOCKER_PORT_MAP_TCP_22=NULL' \
--setopt='--network local_infra' \
--setopt='--expose 3126-3128' \
--setopt='--publish ${LOOPBACK_ALIAS_IP}:3126-3128:3126-3128' \
--setopt='--volume {{NAME}}.data-cache:/var/spool/squid' \
--setopt='--volume {{NAME}}.data-certs:/etc/pki/tls/certs'
"
docker exec -i squid.1.0 yum -y install squid openssl ca-certificates
docker exec -i squid.1.0 tee /etc/supervisord.d/squid.conf 1> /dev/null <<-CONFIG
[program:squid]
priority = 100
command = bash -c "/usr/sbin/squid -N -z -F -f /etc/squid/squid.conf >> /var/log/squid/squid.out 2>&1; exec /usr/sbin/squid -N -f /etc/squid/squid.conf"
startsecs = 1
autorestart = true
redirect_stderr = true
stdout_logfile = /var/log/squid/cache.log
stdout_events_enabled = true
CONFIG
# - Standard port configuration done in the custom configuration later.
# - Allow SSL connections on non-standard ports.
# - Rules for refresh_pattern need to be above standard rules so redefine later.
docker exec -i squid.1.0 sed -i \
-e 's~^\(http_port 3128\)$~#\1~' \
-e 's~^\(http_access deny CONNECT !SSL_ports\)$~#\1~' \
-e 's~^\(refresh_pattern .*\)$~#\1~g' \
/etc/squid/squid.conf
docker exec -i squid.1.0 mkdir /etc/squid/conf.d
docker exec -i squid.1.0 tee -a /etc/squid/squid.conf 1> /dev/null <<-CONFIG
include /etc/squid/conf.d/*.conf
CONFIG
docker exec -i squid.1.0 tee /etc/squid/conf.d/10-large-file-cache.conf 1> /dev/null <<-CONFIG
dns_nameservers ${LOOPBACK_ALIAS_IP} 8.8.8.8 8.8.4.4 208.67.222.222 208.67.220.220
# Disk cache
maximum_object_size 1024 MB
cache_dir ufs /var/spool/squid 10240 16 256
# Extend the expiry for package files to 90 day
refresh_pattern -i .(rpm|iso)$ 129600 100% 129600 refresh-ims override-expire
refresh_pattern ^ftp: 1440 20% 10080
refresh_pattern ^gopher: 1440 0% 1440
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0
refresh_pattern . 0 20% 4320
sslcrtd_program /usr/lib64/squid/ssl_crtd -s /var/lib/ssl_db -M 4MB
sslproxy_cafile /etc/pki/tls/cert.pem
# Need a later version of squid to support certificate hash better than sha1
# sslproxy_cert_sign_hash sha256
sslproxy_cipher ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS
sslproxy_options NO_SSLv2,NO_SSLv3,SINGLE_DH_USE,CIPHER_SERVER_PREFERENCE
ssl_bump server-first all
# Transparent http
http_port 0.0.0.0:3126 intercept
# Transparent https
https_port 0.0.0.0:3127 \
intercept ssl-bump \
cert=/etc/pki/tls/certs/proxy.localdomain.pem \
dhparams=/etc/pki/tls/certs/dhparam.pem \
dynamic_cert_mem_cache_size=4MB \
generate-host-certificates=on \
options=NO_SSLv2,NO_SSLv3,SINGLE_DH_USE,CIPHER_SERVER_PREFERENCE \
cipher=ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS
# Standard http + https
http_port 0.0.0.0:3128 \
ssl-bump \
cert=/etc/pki/tls/certs/proxy.localdomain.pem \
dhparams=/etc/pki/tls/certs/dhparam.pem \
dynamic_cert_mem_cache_size=4MB \
generate-host-certificates=on \
options=NO_SSLv2,NO_SSLv3,SINGLE_DH_USE,CIPHER_SERVER_PREFERENCE \
cipher=ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS
CONFIG
# Initialise SSL Database and set permissions
docker exec -i squid.1.0 /usr/lib64/squid/ssl_crtd -c -s /var/lib/ssl_db
docker exec -i squid.1.0 chown -R squid:squid /var/lib/ssl_db
# Generate CA Certificate if one isn't already available
docker exec -it squid.1.0 bash -c "if [[ ! -f /etc/pki/tls/certs/proxy.localdomain.pem ]]; then openssl req \
-x509 \
-extensions v3_ca \
-sha256 \
-nodes \
-new \
-newkey rsa:2048 \
-days 365 \
-subj "/C=--/ST=STATE/L=LOCALITY/O=ORGANIZATION/CN=proxy.localdomain" \
-keyout /etc/pki/tls/certs/proxy.localdomain.pem \
-out /etc/pki/tls/certs/proxy.localdomain.pem; \
fi"
# Generate Diffie–Hellman parameters if not already available
docker exec -i squid.1.0 bash -c "if [[ ! -f /etc/pki/tls/certs/dhparam.pem ]]; then openssl dhparam \
-outform PEM \
-out /etc/pki/tls/certs/dhparam.pem 2048; \
fi"
# Copy certificate from conainer to distribute
docker cp squid.1.0:/etc/pki/tls/certs/proxy.localdomain.pem .
# Append ca-intermediate.pem to the cafile
if [[ -f ./ca-intermediate.pem ]]; then
docker cp ca-intermediate.pem squid.1.0:/etc/pki/ca-trust/source/anchors/
fi
# If you need to trust StartCom https://www.startssl.com/certs/sca.server3.crt
if [[ -f ./sca.server3.crt ]]; then
docker cp sca.server3.crt squid.1.0:/etc/pki/ca-trust/source/anchors/
fi
docker exec -it squid.1.0 update-ca-trust
# Restarting the container allows supervisord start the process. If you
# Upload a new configuration you will need restart for the changes to apply.
docker restart squid.1.0
# Tail the logs - Note: Use Ctl + c to exit.
docker logs -f --tail=30 squid.1.0
echo "Set up your network connection to use the proxy ${LOOPBACK_ALIAS_IP}:3128 for both HTTP and HTTPS."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment