Squid: Проксируем ipv4 -> ipv6 — Fastenv

Fastenv - системное администрирование от профессионалов индустрии. Работаем с linux, уважаем opensource.

Squid: Проксируем ipv4 -> ipv6
Сложность: Низкая | Автор: fastenv | May 20, 2016

Squid — один из лучших представителей forward proxy серверов. В этой статье мы поговорим о:

  1. Авторизации.
  2. Проксировании IPv4 в IPv6.
  3. Производительности.

В чём задача?

Предположим, у нас имеется сервер с одним IPv4 адресом и уймой IPv6. Требуется так настроить squid, чтобы при изменении логина, менялся исходящий IPv6 адрес.

Концепция

Решение опирается на два механизма:

  1. Через acl proxy_auth создается условие, которое возвращает true только тогда, когда заданный пользователь авторизовался с верным паролем.
  2. Директива tcp_outgoing_address задает исходящий IPv6 адрес.

Установка

Весь необходимый функционал имеется в стандартном пакете вашего дистрибутива. В debian-based системах сводится к простой установке squid:

apt-get update
apt-get install squid3

Общие настройки

Для дальнейшего удобства все общие настройки сгруппируем по отдельным файлам:

  1. Разрешаем порты 80 и 443, разрешаем использовать метод CONNECT только с 443:
    # allow-port.conf
    acl allow_port port 80
    acl allow_port port 443
    acl https_port port 443
    acl CONNECT method CONNECT
     
    http_access deny !allow_port
    http_access deny CONNECT !https_port
  2. Запрещаем некоторые http заголовки:
    # deny-headers.conf
    request_header_access X-Forwarded-For deny all
    request_header_access Via deny all
    request_header_access Proxy deny all
    request_header_access Cache-Control deny all

    Данные правила делают http прокси анонимным. Важно отметить — при работе с https сайтами squid не имеет возможности вмешиваться в трафик, таким образом он не может ни удалить, ни добавить заголовки. Таким образом https прокси изначально являются анонимными.
    Замечание про анонимность.

  3. Настройки авторизации:
    # auth.conf
    auth_param basic children 100
    auth_param basic realm Fastenv Proxy
    auth_param basic credentialsttl 2 hours
     
    acl auth_required proxy_auth REQUIRED
    http_access deny !auth_required
  4. Список разрешенных доменов:
    # allow-domain.conf
    acl allow_domain dstdomain .fastenv.ru
    acl allow_domain dstdomain .instagram.com
    acl allow_domain dstdomain .whatismyv6.com
     
    http_access deny !allow_domain

    Мы разрешаем доступ только к определенным сайтам. Если это не требуется, то просто не подключайте этот файл в основном конфиге.

  5. Прочие настройки(рабочая директория, таймауты, etc):
    # other-settings.conf
    coredump_dir /var/spool/squid
     
    connect_timeout 10 minute
    read_timeout 50 minutes

Авторизация

Принцип работы следующий. Из имени username, пароля password клиент формирует строку username:passowrd и конвертирует в base64. Примерно так:

echo -n 'username:password' | base64

Результат помещается в заголовок Authorization, который добавляется к запросу.
Теперь в дело вступает squid. Он принимает запрос и начинает последовательно обрабатывать правила до первого подходящего http_access (allow|deny). Если на этом пути встретилась acl вида proxy_auth, то проверяется заголовок Authorization (как именно описано ниже). Теперь у запроса два пути:

  1. Быть выполненным — если достигнут http_access allow.
  2. Быть прерванным — если достигнут http_access deny. В этом случае возвращается код ответа 407, который браузеры расценивают как запрос авторизации.

Как проверяется авторизация?

Squid декодирует base64 значение заголовка Authorization в текст. Примерно так:

echo -n 'dXNlcm5hbWU6cGFzc3dvcmQ=' | base64 -d
username:password

Имя пользователя и пароль передаются на стандартный вход программе аутентификации, которая должна дать ответ, пользователь хороший или нет. Регламент простой: OK — успешно, ERR — нет. Пример программы, которая всем доверяет:

#!/bin/bash
 
while read input
do
  echo "OK"
done
Программа, которая доверяет только нам.

Что делают опции?

  1. auth_param basic program /usr/lib/squid3/basic_ncsa_auth /etc/squid/users-3128
    • Задает программу аутентификации basic_ncsa_auth с аргументом /etc/squid/users-3128. Используется как простейший стандартный способ управления пользователями. Примеры.
  2. auth_param basic children 100
    • Максимальное число процессов аутентификации. Важно отметить, что это отдельные, дочерние процессы. Squid общается с ними по tcp через localhost.
  3. auth_param basic realm Fastenv Proxy
    • Приветствие формы авторизации.
  4. auth_param basic credentialsttl 2 hours
    • Срок действия успешной авторизации. По его истечению будет запрошена повторно.

Выбираем IPv6

Допустим пользователь fastenv должен выходить с 2400:cb00:2048:1::6812:3e7b IPv6 адреса, тогда:

  1. Создаем acl fastenv1 и правило использовать такой-то source адрес в случае истинности fastenv1:
    # access-rules-3128.conf
    acl fastenv1 proxy_auth fastenv
    tcp_outgoing_address 2400:cb00:2048:1::6812:3e7b fastenv1
    • Где fastenv — имя пользователя.
  2. Добавляем IP:
    ip -6 addr add 2400:cb00:2048:1::6812:3e7b/64 dev eth0
    • Где 64 маска сети, а eth0 внешний интерфейс.

Конфиг squid

# squid1.conf
include /etc/squid/allow-port.conf
include /etc/squid/deny-headers.conf
auth_param basic program /usr/lib/squid3/basic_ncsa_auth /etc/squid/users-3128
include /etc/squid/auth.conf
include /etc/squid/access-rules-3128.conf
include /etc/squid/domain-allow.conf
http_access allow all
http_port 3128
access_log /var/log/squid/squid-3128.log
cache_log /var/log/squid/cache-3128.log
pid_filename /var/log/squid/squid-3128.pid
include /etc/squid/other-settings.conf

Производительность

Squid — однопоточный прокси-сервер. В один момент его пропускная способоность упирается в частоту одного ядра процессора. Для обхода этого ограничения на многоядерных системах можно запускать несколько процессов на разных портах. По нашему опыту нагрузка также растет и от количества proxy_auth правил. Имея это в виду, все общие настройки вынесены в отдельные файлы, а создание еще одного процесса сводится к замене конфига и правки стартового скрипта.