Squid — один из лучших представителей forward proxy серверов. В этой статье мы поговорим о:
- Авторизации.
- Проксировании IPv4 в IPv6.
- Производительности.
В чём задача?
Предположим, у нас имеется сервер с одним IPv4 адресом и уймой IPv6. Требуется так настроить squid, чтобы при изменении логина, менялся исходящий IPv6 адрес.
Концепция
Решение опирается на два механизма:
- Через acl proxy_auth создается условие, которое возвращает true только тогда, когда заданный пользователь авторизовался с верным паролем.
- Директива tcp_outgoing_address задает исходящий IPv6 адрес.
Установка
Весь необходимый функционал имеется в стандартном пакете вашего дистрибутива. В debian-based системах сводится к простой установке squid:
apt-get update
apt-get install squid3 |
Общие настройки
Для дальнейшего удобства все общие настройки сгруппируем по отдельным файлам:
- Разрешаем порты 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 |
- Запрещаем некоторые 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 прокси изначально являются анонимными.
Замечание про анонимность.
Мы называем прокси анонимным следуя общепринятому формальному определению — это такой прокси, который специально не добавляет информацию о клиенте. Надо понимать, что о реальной анонимности речи не идёт и анализируя различные параметры можно установить факт работы через промежуточный узел.
- Настройки авторизации:
# 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 |
- Список разрешенных доменов:
# 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 |
Мы разрешаем доступ только к определенным сайтам. Если это не требуется, то просто не подключайте этот файл в основном конфиге.
- Прочие настройки(рабочая директория, таймауты, 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 (как именно описано ниже). Теперь у запроса два пути:
- Быть выполненным — если достигнут http_access allow.
- Быть прерванным — если достигнут 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 |
Программа, которая доверяет только нам.
#!/bin/bash
while read username password
do
if [[ "${username}" == "fastnev" ]] && [[ "${password}" == "best" ]]
then
echo "OK"
continue
fi
echo "ERR"
done |
Как Вы понимаете, тут может быть любой скрипт, да хоть авторизация через vk api.
Что делают опции?
-
auth_param basic program /usr/lib/squid3/basic_ncsa_auth /etc/squid/users-3128 |
-
Задает программу аутентификации basic_ncsa_auth с аргументом /etc/squid/users-3128. Используется как простейший стандартный способ управления пользователями. Примеры.
touch /etc/squid/users-3128 |
- Добавить пользователя fastenv:
htpasswd /etc/squid/users-3128 fastenv |
- Удалить fastenv`а:
htpasswd -D /etc/squid/users-3128 fastenv |
-
auth_param basic children 100 |
-
Максимальное число процессов аутентификации. Важно отметить, что это отдельные, дочерние процессы. Squid общается с ними по tcp через localhost.
-
auth_param basic realm Fastenv Proxy |
-
Приветствие формы авторизации.
-
auth_param basic credentialsttl 2 hours |
-
Срок действия успешной авторизации. По его истечению будет запрошена повторно.
Выбираем IPv6
Допустим пользователь fastenv должен выходить с 2400:cb00:2048:1::6812:3e7b IPv6 адреса, тогда:
- Создаем acl fastenv1 и правило использовать такой-то source адрес в случае истинности fastenv1:
# access-rules-3128.conf
acl fastenv1 proxy_auth fastenv
tcp_outgoing_address 2400:cb00:2048:1::6812:3e7b fastenv1 |
- Где fastenv — имя пользователя.
- Добавляем 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 правил. Имея это в виду, все общие настройки вынесены в отдельные файлы, а создание еще одного процесса сводится к замене конфига и правки стартового скрипта.