SCROLL
Среднее время на прочтение: 7 мин.

Установка Squid 5.5 с поддержкой HTTPS (ssl_bump) на Debian 10 Buster

Squid — это программный пакет, реализующий функцию кэширующего прокси-сервера для протоколов HTTP, FTP, Gopher и (в случае соответствующих настроек) HTTPS.

Разберем как установить из исходников актуальную (на момент написания статьи) версию кеширующего прокси-сервера Squid 5.5 на Debian 10 Buster.

Хочу сообщить что ниже описанное руководство, так же применимо к установке младших версии Squid 4, 5.x

Установка прокси-сервера Squid

Устанавливаем необходимые зависимости для сборки и работы Squid:

apt-get update
apt-get install build-essential make libssl-dev libkrb5-dev libldap2-dev libk5crypto3 libsasl2-dev libpam0g libcap2-dev

Скачиваем и распаковываем исходники Squid:

cd /opt/
wget http://www.squid-cache.org/Versions/v5/squid-5.5.tar.gz
tar -zxvf squid-5.5.tar.gz
cd squid-5.5

Выполняем конфигурирование с поддержкой HTTPS:

./configure --prefix=/usr --localstatedir=/var --libexecdir=/usr/lib/squid --datadir=/usr/share/squid --sysconfdir=/etc/squid --enable-ssl-crtd --with-openssl --enable-translation --enable-cpu-profiling --disable-dependency-tracking --disable-ipv6 --enable-removal-policies="lru,heap" -enable-delay-pools --enable-icmp --enable-linux-netfilter --enable-external-acl-helpers --with-large-files --with-default-user=proxy --with-logdir=/var/log/squid --with-pidfile=/var/run/squid.pid

Собираем и устанавливаем пакет Squid:

make
make install

Создаем необходимые каталоги, для работы Squid и назначаем для них права доступа:

mkdir -p /var/log/squid
mkdir -p /etc/squid/ssl

chown proxy:proxy /var/log/squid
chown proxy:proxy /etc/squid/ssl
chmod 700 /var/log/squid
chmod 700 /etc/squid/ssl

Создаем стартовый скрипт Squid — /etc/init.d/squid:

/etc/init.d/squid
#! /bin/sh
#
# squid         Startup script for the SQUID HTTP proxy-cache.
#
# Version:      @(#)squid.rc  1.0  07-Jul-2006  luigi@debian.org
#
# pidfile: /var/run/squid.pid
#
### BEGIN INIT INFO
# Provides:          squid
# Required-Start:    $network $remote_fs $syslog
# Required-Stop:     $network $remote_fs $syslog
# Should-Start:      $named
# Should-Stop:       $named
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Squid HTTP Proxy version 4.x
### END INIT INFO

NAME=squid
DESC="Squid HTTP Proxy"
DAEMON=/usr/sbin/squid
PIDFILE=/var/run/$NAME.pid
CONFIG=/etc/squid/squid.conf
SQUID_ARGS="-YC -f $CONFIG"

[ ! -f /etc/default/squid ] || . /etc/default/squid

. /lib/lsb/init-functions

PATH=/bin:/usr/bin:/sbin:/usr/sbin

[ -x $DAEMON ] || exit 0

ulimit -n 65535

find_cache_dir () {
        w="     " # space tab
        res=`$DAEMON -k parse -f $CONFIG 2>&1 |
                grep "Processing:" |
                sed s/.*Processing:\ // |
                sed -ne '
                        s/^['"$w"']*'$1'['"$w"']\+[^'"$w"']\+['"$w"']\+\([^'"$w"']\+\).*$/\1/p;
                        t end;
                        d;
                        :end q'`
        [ -n "$res" ] || res=$2
        echo "$res"
}

grepconf () {
        w="     " # space tab
        res=`$DAEMON -k parse -f $CONFIG 2>&1 |
                grep "Processing:" |
                sed s/.*Processing:\ // |
                sed -ne '
                        s/^['"$w"']*'$1'['"$w"']\+\([^'"$w"']\+\).*$/\1/p;
                        t end;
                        d;
                        :end q'`
        [ -n "$res" ] || res=$2
        echo "$res"
}

create_run_dir () {
        run_dir=/var/run/squid
        usr=`grepconf cache_effective_user proxy`
        grp=`grepconf cache_effective_group proxy`

        if [ "$(dpkg-statoverride --list $run_dir)" = "" ] &&
           [ ! -e $run_dir ] ; then
                mkdir -p $run_dir
                chown $usr:$grp $run_dir
                [ -x /sbin/restorecon ] && restorecon $run_dir
        fi
}

start () {
        cache_dir=`find_cache_dir cache_dir`
        cache_type=`grepconf cache_dir`
        run_dir=/var/run/squid

        #
        # Create run dir (needed for several workers on SMP)
        #
        create_run_dir

        #
        # Create spool dirs if they don't exist.
        #
        if test -d "$cache_dir" -a ! -d "$cache_dir/00"
        then
                log_warning_msg "Creating $DESC cache structure"
                $DAEMON -z -f $CONFIG
                [ -x /sbin/restorecon ] && restorecon -R $cache_dir
        fi

        umask 027
        ulimit -n 65535
        cd $run_dir
        start-stop-daemon --quiet --start \
                --pidfile $PIDFILE \
                --exec $DAEMON -- $SQUID_ARGS < /dev/null
        return $?
}

stop () {
        PID=`cat $PIDFILE 2>/dev/null`
        start-stop-daemon --stop --quiet --pidfile $PIDFILE --exec $DAEMON
        #
        #       Now we have to wait until squid has _really_ stopped.
        #
        sleep 2
        if test -n "$PID" && kill -0 $PID 2>/dev/null
        then
                log_action_begin_msg " Waiting"
                cnt=0
                while kill -0 $PID 2>/dev/null
                do
                        cnt=`expr $cnt + 1`
                        if [ $cnt -gt 24 ]
                        then
                                log_action_end_msg 1
                                return 1
                        fi
                        sleep 5
                        log_action_cont_msg ""
                done
                log_action_end_msg 0
                return 0
        else
                return 0
        fi
}

cfg_pidfile=`grepconf pid_filename`
if test "${cfg_pidfile:-none}" != "none" -a "$cfg_pidfile" != "$PIDFILE"
then
        log_warning_msg "squid.conf pid_filename overrides init script"
        PIDFILE="$cfg_pidfile"
fi

case "$1" in
    start)
        res=`$DAEMON -k parse -f $CONFIG 2>&1 | grep -o "FATAL: .*"`
        if test -n "$res";
        then
                log_failure_msg "$res"
                exit 3
        else
                log_daemon_msg "Starting $DESC" "$NAME"
                if start ; then
                        log_end_msg $?
                else
                        log_end_msg $?
                fi
        fi
        ;;
    stop)
        log_daemon_msg "Stopping $DESC" "$NAME"
        if stop ; then
                log_end_msg $?
        else
                log_end_msg $?
        fi
        ;;
    reload|force-reload)
        res=`$DAEMON -k parse -f $CONFIG 2>&1 | grep -o "FATAL: .*"`
        if test -n "$res";
        then
                log_failure_msg "$res"
                exit 3
        else
                log_action_msg "Reloading $DESC configuration files"
                start-stop-daemon --stop --signal 1 \
                        --pidfile $PIDFILE --quiet --exec $DAEMON
                log_action_end_msg 0
        fi
        ;;
    restart)
        res=`$DAEMON -k parse -f $CONFIG 2>&1 | grep -o "FATAL: .*"`
        if test -n "$res";
        then
                log_failure_msg "$res"
                exit 3
        else
                log_daemon_msg "Restarting $DESC" "$NAME"
                stop
                if start ; then
                        log_end_msg $?
                else
                        log_end_msg $?
                fi
        fi
        ;;
    status)
        status_of_proc -p $PIDFILE $DAEMON $NAME && exit 0 || exit 3
        ;;
    *)
        echo "Usage: /etc/init.d/$NAME {start|stop|reload|force-reload|restart|status}"
        exit 3
        ;;
esac

exit 0

Делаем скрипт исполняемым, добавляем в автозагрузку и запускаем сервис Squid:

chmod a+x /etc/init.d/squid
update-rc.d squid defaults

/etc/init.d/squid start
/etc/init.d/squid status

Настройка SSL Bumping в сервисе Squid

Для работы SSL Bumping требуется CA SSL-сертификат и приватный ключ в формате PEM.  Этот сертификат будет использоваться Squid для создания динамических сертификатов для проксируемых сайтов.

Можно создать новый самоподписанный CA SSL-сертификат или использовать CA SSL-сертификат выданный центром сертификации организации.

 

Создание самоподписанного CA SSL-сертификата

openssl req -new -newkey rsa:2048 -days 365 -nodes -x509 -keyout /etc/squid/squidca.key -out /etc/squid/squidca.crt

Настраиваем права на файлы SSL-сертификата

chown proxy:proxy /etc/squid/squidca*
chmod 400 /etc/squid/squidca*

Конвертируем сертификат формата DER для импорта на пользовательские системы:

openssl x509 -outform der -in /etc/squid/squidca.crt -out squidca.crt
Полученный сертификат необходимо установить в «Доверенные корневые сертификаты» на все пользовательские компьютеры, которые будут работать через Squid. В доменной среде это проще всего сделать при помощи GPO (Group Policy objects).

Использование CA SSL-сертификата выданным центром сертификации организации

В случае если в организации имеется действующий ЦС, то логично чтобы Squid работал в рамках цепочки сертификатов действующего ЦС.

Генерируем запрос (CSR) на SSL-сертификат, далее выпускаем его при помощи действующего ЦС (используя шаблон с правами CA):

openssl genrsa -out /etc/squid/squidca.key 2048
openssl req -new -key /etc/squid/squidca.key -out /etc/squid/squidca.csr

Конвертируем выпущенный SSL-сертификат в PEM формат:

openssl x509 -inform der -in certnew.cer -out squidca.crt

Настраиваем права на файлы SSL-сертификата:

chown proxy:proxy /etc/squid/squidca*
chmod 400 /etc/squid/squidca*

Продолжение настройки SSL

Генерируем файл параметров для алгоритма Diffie-Hellman:

openssl dhparam -outform PEM -out /etc/squid/squid_dhparam.pem 2048
chmod 400 /etc/squid/squid_dhparam.pem

Создаем каталог для базы данных сертификатов и инициализируем ее, предварительно остановим службу Squid, если она работает:

/etc/init.d/squid stop

mkdir -p /var/lib/squid
rm -rf /var/lib/squid/ssl_db
/usr/lib/squid/security_file_certgen -c -s /var/lib/squid/ssl_db -M 20MB
chown proxy:proxy -R /var/lib/squid

В конфигурационном файле /etc/squid/squid.conf добавляем в начало файла или перед первой директивой http_access следующие директивы:

/etc/squid/squid.conf
acl intermediate_fetching transaction_initiator certificate-fetching
http_access allow intermediate_fetching

Добавляем в любое место после последней директивы http_access следующие директивы:

/etc/squid/squid.conf
http_port 3128 ssl-bump generate-host-certificates=on dynamic_cert_mem_cache_size=20MB tls-cert=/etc/squid/squidca.crt tls-key=/etc/squid/squidca.key cipher=HIGH:MEDIUM:!LOW:!RC4:!SEED:!IDEA:!3DES:!MD5:!EXP:!PSK:!DSS options=NO_TLSv1,NO_SSLv3 tls-dh=prime256v1:/etc/squid/squid_dhparam.pem

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

acl step1 at_step SslBump1
ssl_bump peek step1
ssl_bump bump all

Запускаем Squid и проверяем:

/etc/init.d/squid start

Добавление исключений для SSL Bumping

Добавление исключений для SSL Bumping может потребоваться в следующих случаях:

  • Программное обеспечение использует протокол, отличный от HTTPS (например, SSH, RDP, VPN).
  • Программное обеспечение или веб-ресурс использует протокол WebSockets или HTTP/2.0.
  • Для доступа к веб-ресурс используются национальные алгоритмы шифрования (GOST, SM2).
  • Программное обеспечение использует привязку серверного сертификата (pinning).
  • Программное обеспечение или веб-ресурс требует авторизации по клиентскому SSL-сертификату.

Создаем файл /etc/squid/donotbump.list со списком доменных имен веб-ресурсов и хостов, которые вы необходимо добавить в исключения, пример:

/etc/squid/donotbump.list
.youtube.ru
.facebook.com

В конфигурационном файле /etc/squid/squid.conf задаем директиву ACL указывающую на созданный список исключений и приводим порядок обработки ssl_bump к виду как указано ниже:

/etc/squid/squid.conf
acl no_ssl_bump dstdomain "/etc/squid/donotbump.list"

acl step1 at_step SslBump1
ssl_bump splice no_ssl_bump
ssl_bump peek step1
ssl_bump bump all

Краткое описание механики SSL Bumping. Соединение клиента с сервером разбивается на три шага:

  • SslBump1 — получение открытой информации о соединении (из сертификатов и http-запроса);
  • SslBump2 — передача Hello info клиента (создание соединения с сервером);
  • SslBump3 — получение Hello info сервера (создание соединения с клиентом);

И для каждого из этих этапов можно определить, что Squid будет делать c запросами клиентов:

  • splice — пропустить все последующие действия, создается TCP-туннель, без ssl-bump.
  • peek — подсмотреть всю доступную информацию без ssl-bump.
  • terminate — закрыть соединение.
  • bump — ssl-bump соединения, сделать https видимым как http

После внесенных изменений не забываем перезапустить службу Squid

/etc/squid/squid restart

Обсуждение

1 комментариев
  • Конвертируем сертификат формата DER для импорта на пользовательские системы:
    openssl x509 -outform der -in /etc/squid/squidca.crt -out squidca.crt

    Мы перезатираем исходный сертификат и засовываем der в squid?

    tls-cert=/etc/squid/squidca.crt

    Сделано всё по инструкции, der сертификат squidca.crt засунут пользователю, но в логах squid’а всё равно нет полного пути сайта, а просто:
    1675938244.720 11058 172.16.120.101 TCP_TUNNEL/200 4937 CONNECT ad.adriver.ru:443 — HIER_DIRECT/195.209.108.51 —
    1675938244.721 19770 172.16.120.101 TCP_TUNNEL/200 7342 CONNECT functional.events.data.microsoft.com:443 — HIER_DIRECT/20.189.173.9 —
    1675938244.721 9963 172.16.120.101 TCP_TUNNEL/200 1693 CONNECT yandex.ru:443 — HIER_DIRECT/5.255.255.60 —