Три способа по-быстрому поднять forward proxy

Date January 24th, 2014 Author Vitaly Agapov

У них, милсдарь ведьмак, такой принцип: если цель привлекает, средство должно найтись.

Анджей Сапковский «Владычица озера»

3ways

Forward proxy – это (обычно) анонимный прокси, к которому клиент обращается и сообщает адрес хоста, к которому он хочет подключиться.

При обращении на такой прокси браузер особым образом формирует запросы. В случае обычного HTTP протокола он просто добавляет обязательный заголовок Host:, а сам URL в запросе формирует в абсолютном виде. В этом случае принципиальной разницы с reverse proxy нет. Но при обращении на HTTPS или любой нестандартный порт происходит установление сквозного туннеля  с целевым сервером с помощью метода CONNECT, отправляемого на прокси. Прокси при этом использует заголовки этого запроса для установления соединения, но не может ни ловить сессионные SSL-ключи, ни тем более смотреть проходящий трафик.

Работать в режиме forward proxy могут многие серверы, но не все. Тот же Nginx, например, хоть и считается одним из лучших reverse proxy, категорически не работает как forward и вообще не умеет обрабатывать метод CONNECT. Поэтому я по-быстрому рассмотрю Apache TrafficServer, Apache/mod_proxy и Squid. Плюс задача будет усложнена условием, чтобы прокси-сервер пропускал только трафик, идущий на определённый домен и его суб-домены, и не все серверы с этим справятся (по крайней мере "по-быстрому").

Настройка браузера для тестирования

Для автоматической настройки сервиса прокси в браузере можно использовать PAC-файл на основе JavaScript. Вот его пример:

function FindProxyForURL(url, host)
{
    url = url.toLowerCase();
    host = host.toLowerCase();
    if (dnsDomainIs(host, "www.example.com"))
        return "PROXY proxy.addr;" +
                "DIRECT";
}

Для отправки всего трафика на прокси:

function FindProxyForURL(url, host)
{
        return "PROXY proxy.addr;" +
                "DIRECT";
}

В том же Firefox этот файл можно подсунуть в меню Правка -> Настройки -> Дополнительные -> Соединение.

Apache Traffic Server

После установки ATS (apt-get install trafficserver, если речь идёт об Ubuntu/Debian) нужно разрешить старт сервера init'ом, для чего в /etc/default/trafficserver надо прописать

TC_START=yes

Для включения forward proxy надо в /etc/trafficserver/records.config установить значения:

CONFIG proxy.config.http.server_port INT 80
CONFIG proxy.config.http.no_dns_just_forward_to_parent INT 1
CONFIG proxy.config.reverse_proxy.enabled INT 0
# Эта опция непосредственно включает режим forward_proxy
CONFIG proxy.config.url_remap.remap_required INT 0
CONFIG proxy.config.dns.round_robin_nameservers INT 1

ACL здесь нет, но можно настроить ремаппинг (в файле remap.config) для переправки даже неразрешённых запросов на нужный нам бэкенд. Правда, он срабатывает только для HTTP.

regex_map http://^(?!.*example.com).* http://www.example.com

Apache2/mod_proxy

Apache может работать в режиме forward proxy при включении модулей mod_proxy, mod_proxy_http и mod_proxy_connect. Базовый функционал внутри виртуального хоста:

ProxyRequests On
ProxyVia On
AllowCONNECT 443
# Ремаппинг
ProxyRemoteMatch http://(?!.*example.com).* http://www.example.com
ProxyRemoteMatch ^(?!.*example.com).*:443 https://www.example.com
 
<Proxy *>
    Order allow,deny
    Allow from all
</Proxy>

Удобных Squid-like ACL здесь так же нет, но будет работать ремаппинг. Для http он будет работать корректно, а для https просто ограничивать доступ. То есть функциональность лучше, чем у ATS, и мы на пол-шага ближе к совершенству.

Squid

Базовый конфиг squid.conf, реализующий функции forward proxy с запретом обращения на посторонние сайты:

acl manager proto cache_object
acl localhost src 127.0.0.1/32 ::1
acl ourdomain dstdomain .example.com
acl SSL_ports port 443
acl Safe_ports port 80      # http
acl Safe_ports port 443     # https
acl CONNECT method CONNECT
http_access allow manager localhost
http_access deny manager
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow ourdomain
http_access deny all
http_port 80
logformat squid %tl %6tr %>a %Ss/%03>Hs %<st %rm %ru %Sh/%<A
coredump_dir /var/spool/squid3
refresh_pattern .       0   20% 4320
cache_mgr mail@example.com
httpd_suppress_version_string on
visible_hostname example.com

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

Правда, если мы всё-таки захотим сделать ремаппинг урлов, то его можно сделать с помощью внешней программы и директивы

url_rewrite_program /path/to/script

Сама программа (например redirect.sh) может выглядеть примерно так:

#!/bin/sh
while read url rest; do
   echo $url ... $rest >>/tmp/redirect.log
   if  [[ $url == *example.com* ]]
   then
      echo
   else
      echo http://www.example.com/
   fi
done

С HTTPS по традиции и понятным причинам ремаппинг не сработает.

Tags: ,
Category: Linux | No comments »

Comments

Leave a comment

 Comment Form