├── Dockerfile ├── Dockerfile.build ├── LICENSE ├── Makefile ├── README.md ├── mk-certs ├── openssl.cnf ├── run └── squid.conf /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:trusty 2 | MAINTAINER Fabio Rehm 3 | 4 | RUN echo "deb http://archive.ubuntu.com/ubuntu trusty main" > /etc/apt/sources.list && \ 5 | echo "deb http://archive.ubuntu.com/ubuntu/ trusty-updates main" >> /etc/apt/sources.list && \ 6 | echo "deb http://security.ubuntu.com/ubuntu trusty-security main" >> /etc/apt/sources.list && \ 7 | echo "deb-src http://archive.ubuntu.com/ubuntu trusty main" >> /etc/apt/sources.list && \ 8 | echo "deb-src http://archive.ubuntu.com/ubuntu/ trusty-updates main" >> /etc/apt/sources.list && \ 9 | echo "deb-src http://security.ubuntu.com/ubuntu trusty-security main" >> /etc/apt/sources.list && \ 10 | apt-get update && \ 11 | apt-get -y upgrade && \ 12 | apt-get install -qq \ 13 | apache2 \ 14 | logrotate \ 15 | squid-langpack \ 16 | ca-certificates \ 17 | libgssapi-krb5-2 \ 18 | libltdl7 \ 19 | libecap2 \ 20 | libnetfilter-conntrack3 \ 21 | curl && \ 22 | apt-get clean 23 | 24 | # Install packages 25 | RUN cd /tmp && \ 26 | curl -L https://github.com/fgrehm/squid3-ssl-docker/releases/download/v20140623/squid3-20140623.tgz | tar xvz && \ 27 | dpkg -i debs/*.deb && \ 28 | rm -rf /tmp/debs && \ 29 | apt-get clean 30 | 31 | # Create cache directory 32 | VOLUME /var/cache/squid3 33 | 34 | # Initialize dynamic certs directory 35 | RUN /usr/lib/squid3/ssl_crtd -c -s /var/lib/ssl_db 36 | RUN chown -R proxy:proxy /var/lib/ssl_db 37 | 38 | # Prepare configs and executable 39 | ADD squid.conf /etc/squid3/squid.conf 40 | ADD openssl.cnf /etc/squid3/openssl.cnf 41 | ADD mk-certs /usr/local/bin/mk-certs 42 | ADD run /usr/local/bin/run 43 | RUN chmod +x /usr/local/bin/run 44 | 45 | EXPOSE 3128 46 | CMD ["/usr/local/bin/run"] 47 | -------------------------------------------------------------------------------- /Dockerfile.build: -------------------------------------------------------------------------------- 1 | # Dockerfile.build 2 | # Build debian packages for Squid3, with SSL enabled. 3 | # http://www.squid-cache.org/ 4 | 5 | FROM ubuntu:trusty 6 | MAINTAINER Fabio Rehm 7 | 8 | RUN echo "deb-src http://archive.ubuntu.com/ubuntu trusty main" >> /etc/apt/sources.list 9 | RUN echo "deb-src http://archive.ubuntu.com/ubuntu/ trusty-updates main" >> /etc/apt/sources.list 10 | RUN echo "deb-src http://security.ubuntu.com/ubuntu trusty-security main" >> /etc/apt/sources.list 11 | RUN apt-get update 12 | RUN apt-get -y upgrade 13 | 14 | # Install build dependencies 15 | RUN apt-get -y install libssl-dev 16 | RUN apt-get -y build-dep squid3 17 | 18 | # Download source 19 | RUN mkdir /src 20 | RUN cd /src && apt-get source squid3 21 | RUN apt-get build-dep openssh -y 22 | RUN apt-get build-dep openssl -y 23 | 24 | # Edit debian/rules to build with SSL 25 | RUN sed -i 's/--enable-ecap/--enable-ecap --enable-ssl --enable-ssl-crtd/' /src/squid3-3.3.8/debian/rules 26 | 27 | # Build debs 28 | RUN apt-get -y install devscripts 29 | RUN cd /src/squid3-3.3.8 && debuild -us -uc -b 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Fabio Rehm 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | current_dir:=$(shell pwd) 2 | build_tag = 'squid3-ssl-build' 3 | 4 | .PHONY: debs build_debs copy_debs 5 | 6 | debs: build_debs copy_debs 7 | 8 | build_debs: 9 | docker build -t $(build_tag) - < Dockerfile.build 10 | 11 | copy_debs: 12 | @mkdir -p debs 13 | docker run -v $(current_dir)/debs:/src/debs $(build_tag) /bin/sh -c 'cp /src/*.deb /src/debs/' 14 | 15 | release_debs: 16 | sudo chown ${USER}:${USER} debs/* 17 | tar -zcvf squid3-$(shell date +%Y%m%d).tgz debs/ 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # squid3-ssl-docker 2 | 3 | A Squid3 caching proxy with SSL enabled in a Docker container, based on 4 | https://github.com/toffer/docker-squid3-ssl and meant to be used from within 5 | other Docker containers. 6 | 7 | ## Details 8 | 9 | * Ubuntu 14.04 LTS (Trusty). 10 | * Squid (Version 3.3.8). 11 | * Built from source, with `--enable-ssl`. 12 | * Automatically generates self-signed certificate. 13 | * Configured to cache Docker images (default config for Squid3 doesn't handle 14 | Docker images very well.) 15 | 16 | ## Usage 17 | 18 | Start Squid3 setting its hostname and container name: 19 | 20 | ``` 21 | $ docker run -d -h proxy.docker.dev --name squid3 fgrehm/squid3-ssl:v20140809 22 | ``` 23 | 24 | Start another container linking it to the proxy container and setting the 25 | `http_proxy` env var to the linked container: 26 | 27 | ``` 28 | $ docker run -ti --rm \ 29 | --link squid3:proxy.docker.dev \ 30 | -e http_proxy="http://proxy.docker.dev:3128" \ 31 | ubuntu:trusty bash 32 | ``` 33 | 34 | You can check that things are working by hitting the same URL twice from within 35 | a linked container and checking the `X-Cache` header that Squid sets in the 36 | responses. The second response should show a cache hit: 37 | 38 | ``` 39 | $ curl -s -i http://httpbin.org/ip | grep 'X-Cache:' 40 | X-Cache: MISS from proxy 41 | 42 | $ curl -s -i http://httpbin.org/ip | grep 'X-Cache:' 43 | X-Cache: HIT from proxy 44 | ``` 45 | 46 | ### Caching HTTPS requests 47 | 48 | To use the proxy for HTTPS requests, the linked container needs to trust the 49 | self-signed certificate generated by the Squid3 server. To setup and install the 50 | CA certificate on an Ubuntu container, try these steps: 51 | 52 | ``` 53 | # Start Squid3 setting its hostname and container name: 54 | $ docker run -d -h proxy.docker.dev --name squid3 fgrehm/squid3-ssl:v20140809 55 | 56 | # Save the certificate into a file 57 | $ docker logs squid3 | sed -n '/BEGIN/,/END/p' > proxy.docker.dev.crt 58 | 59 | # Start a new container doing the appropriate setup 60 | $ docker run -ti --rm \ 61 | --link squid3:proxy.docker.dev \ 62 | -v `pwd`/proxy.docker.dev.crt:/usr/share/ca-certificates/proxy.docker.dev.crt \ 63 | -e http_proxy="http://proxy.docker.dev:3128" \ 64 | -e https_proxy="http://proxy.docker.dev:3128" \ 65 | ubuntu:trusty bash 66 | 67 | # From within the container, trust the certificate 68 | $ apt-get update && apt-get install -y ca-certificates curl 69 | $ echo 'proxy.docker.dev.crt' >> /etc/ca-certificates.conf 70 | $ /usr/sbin/update-ca-certificates 71 | ``` 72 | 73 | If your container gives you a way to "inject" scripts within its init process / 74 | entrypoint, you can have that process automated. 75 | 76 | For example, if you use [phusion/baseimage](https://github.com/phusion/baseimage-docker) 77 | you can create an executable script like the one below: 78 | 79 | ```sh 80 | #!/bin/bash 81 | set -e 82 | 83 | # Install ca-certificates if needed 84 | if ! [ -x /usr/sbin/update-ca-certificates ]; then 85 | apt-get update && apt-get install -y ca-certificates 86 | fi 87 | 88 | # Trust our certificate 89 | if ! $(grep -q 'proxy.docker.dev.crt' /etc/ca-certificates.conf); then 90 | echo 'proxy.docker.dev.crt' >> /etc/ca-certificates.conf 91 | /usr/sbin/update-ca-certificates 92 | fi 93 | ``` 94 | 95 | And run your containers like: 96 | 97 | ``` 98 | $ docker run -ti --rm \ 99 | --link squid3:proxy.docker.dev \ 100 | -v `pwd`/proxy.docker.dev.crt:/usr/share/ca-certificates/proxy.docker.dev.crt \ 101 | -v `pwd`/proxy-script.sh:/etc/my_init.d/proxy-script.sh \ 102 | -e http_proxy="http://proxy.docker.dev:3128" \ 103 | -e https_proxy="http://proxy.docker.dev:3128" \ 104 | phusion/baseimage /sbin/my_init -- bash -l 105 | ``` 106 | 107 | This will make sure that every time the container is brought up, it trusts the 108 | proxy certificates and you don't need to do that by hand. 109 | 110 | As with regular http requests, you can check that things are working by hitting 111 | the same https URL twice from within a linked container (after trusting the 112 | certificate) and checking the `X-Cache` header that Squid sets in the responses. 113 | The second response should show a cache hit: 114 | 115 | ``` 116 | $ curl -s -i https://httpbin.org/ip | grep 'X-Cache:' 117 | X-Cache: MISS from proxy 118 | 119 | $ curl -s -i https://httpbin.org/ip | grep 'X-Cache:' 120 | X-Cache: HIT from proxy 121 | ``` 122 | 123 | ## Where does those `.deb`s come from? 124 | 125 | I manually built the packages using a [separate Dockerfile](Dockerfile.build), 126 | created a [GitHub release](https://github.com/fgrehm/squid3-ssl-docker/releases) 127 | with a tarball of those debs and set up an [automated build](https://registry.hub.docker.com/u/fgrehm/squid3-ssl) 128 | on Docker Hub. 129 | -------------------------------------------------------------------------------- /mk-certs: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | # Generate a private key and a self-signed certificate. 6 | 7 | CERTS_DIR='/etc/squid3/certs' 8 | CONFIG='/etc/squid3/openssl.cnf' 9 | 10 | # Get domain name from config file. 11 | # Domain is used to name self-signed cert file. 12 | DOMAIN=$(grep commonName $CONFIG | cut -d'=' -f 2 | tr -d ' ') 13 | 14 | # Generate private key. 15 | openssl genrsa -out $CERTS_DIR/private.pem 1024 16 | 17 | # Generate cert signing request. 18 | openssl req -new \ 19 | -key $CERTS_DIR/private.pem \ 20 | -out $CERTS_DIR/proxy.csr \ 21 | -config $CONFIG 22 | 23 | # Generate self-signed cert. 24 | openssl x509 -req \ 25 | -days 730 \ 26 | -signkey $CERTS_DIR/private.pem \ 27 | -in $CERTS_DIR/proxy.csr \ 28 | -out $CERTS_DIR/$DOMAIN.crt \ 29 | -extensions v3_req \ 30 | -extfile $CONFIG 31 | 32 | # Delete signing request. 33 | rm $CERTS_DIR/proxy.csr 34 | -------------------------------------------------------------------------------- /openssl.cnf: -------------------------------------------------------------------------------- 1 | prompt = no 2 | HOME = . 3 | RANDFILE = $ENV::HOME/.rnd 4 | oid_section = new_oids 5 | extensions = v3_req 6 | 7 | [ new_oids ] 8 | tsa_policy1 = 1.2.3.4.1 9 | tsa_policy2 = 1.2.3.4.5.6 10 | tsa_policy3 = 1.2.3.4.5.7 11 | 12 | [ req ] 13 | default_bits = 1024 14 | default_keyfile = privkey.pem 15 | distinguished_name = req_distinguished_name 16 | attributes = req_attributes 17 | string_mask = utf8only 18 | 19 | [ req_distinguished_name ] 20 | 0.organizationName = 21 | commonName = 22 | 23 | [ req_attributes ] 24 | 25 | [ v3_req ] 26 | basicConstraints = critical,CA:TRUE 27 | keyUsage = keyCertSign, cRLSign 28 | -------------------------------------------------------------------------------- /run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | HOST=$(hostname -A | tr -d ' ') 6 | 7 | sed -i "s||${HOST}|g" /etc/squid3/openssl.cnf 8 | sed -i "s||${HOST}|g" /etc/squid3/squid.conf 9 | 10 | mkdir -p /etc/squid3/certs 11 | 12 | if ! [ -f "/etc/squid3/certs/${HOST}.crt" ]; then 13 | /usr/local/bin/mk-certs 14 | fi 15 | 16 | chown -R proxy: /etc/squid3/certs 17 | 18 | cat "/etc/squid3/certs/${HOST}.crt" 19 | 20 | # /usr/sbin/squid3 -Nz 21 | 22 | chown -R proxy: /var/cache/squid3 23 | chown -R proxy: /var/log/squid3 24 | 25 | /usr/sbin/squid3 -Nz 26 | 27 | exec /usr/sbin/squid3 -Nd2 28 | -------------------------------------------------------------------------------- /squid.conf: -------------------------------------------------------------------------------- 1 | acl localnet src 10.0.0.0/8 # RFC1918 possible internal network 2 | acl localnet src 172.16.0.0/12 # RFC1918 possible internal network 3 | acl localnet src 192.168.0.0/16 # RFC1918 possible internal network 4 | acl localnet src fc00::/7 # RFC 4193 local private network range 5 | acl localnet src fe80::/10 # RFC 4291 link-local (directly plugged) machines 6 | 7 | acl Safe_ports port 80 # http 8 | acl Safe_ports port 21 # ftp 9 | acl Safe_ports port 443 # https 10 | acl Safe_ports port 70 # gopher 11 | acl Safe_ports port 210 # wais 12 | acl Safe_ports port 1025-65535 # unregistered ports 13 | acl Safe_ports port 280 # http-mgmt 14 | acl Safe_ports port 488 # gss-http 15 | acl Safe_ports port 591 # filemaker 16 | acl Safe_ports port 777 # multiling http 17 | 18 | # Match gzipped image layers so I can remove header 19 | acl docker_image_layer url_regex docker.io/v1/images/.*/layer$ 20 | 21 | acl SSL_ports port 443 22 | acl CONNECT method CONNECT 23 | 24 | http_access allow localhost manager 25 | http_access allow localhost 26 | http_access allow localnet 27 | 28 | shutdown_lifetime 2 seconds 29 | 30 | # Remove Accept-Encoding header for image layers, otherwise 31 | # layers are doubly gzipped and don't cache well. 32 | request_header_access Accept-Encoding deny docker_image_layer 33 | 34 | maximum_object_size 256 MB 35 | cache_dir ufs /var/cache/squid3 5120 16 256 36 | 37 | # refresh_pattern ^ftp: 1440 20% 10080 38 | # refresh_pattern ^gopher: 1440 0% 1440 39 | # refresh_pattern -i (/cgi-bin/|\?) 0 0% 0 40 | # refresh_pattern . 0 20% 4320 41 | refresh_pattern . 1440 20% 10080 42 | 43 | http_port 3128 ssl-bump generate-host-certificates=on dynamic_cert_mem_cache_size=4MB key=/etc/squid3/certs/private.pem cert=/etc/squid3/certs/.crt 44 | ssl_bump server-first all 45 | always_direct allow all 46 | --------------------------------------------------------------------------------