Три способа по-быстрому поднять 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. Вот его пример:

1.function FindProxyForURL(url, host)
2.{
3.    url = url.toLowerCase();
4.    host = host.toLowerCase();
5.    if (dnsDomainIs(host, "www.example.com"))
6.        return "PROXY proxy.addr;" +
7.                "DIRECT";
8.}

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

1.function FindProxyForURL(url, host)
2.{
3.        return "PROXY proxy.addr;" +
4.                "DIRECT";
5.}

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

Apache Traffic Server

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

1.TC_START=yes

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

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

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

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

Apache2/mod_proxy

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

01.ProxyRequests On
02.ProxyVia On
03.AllowCONNECT 443
04.# Ремаппинг
05.ProxyRemoteMatch http://(?!.*example.com).* http://www.example.com
06.ProxyRemoteMatch ^(?!.*example.com).*:443 https://www.example.com
07.  
08.<Proxy *>
09.    Order allow,deny
10.    Allow from all
11.</Proxy>

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

Squid

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

01.acl manager proto cache_object
02.acl localhost src 127.0.0.1/32 ::1
03.acl ourdomain dstdomain .example.com
04.acl SSL_ports port 443
05.acl Safe_ports port 80      # http
06.acl Safe_ports port 443     # https
07.acl CONNECT method CONNECT
08.http_access allow manager localhost
09.http_access deny manager
10.http_access deny !Safe_ports
11.http_access deny CONNECT !SSL_ports
12.http_access allow ourdomain
13.http_access deny all
14.http_port 80
15.logformat squid %tl %6tr %>a %Ss/%03>Hs %<st %rm %ru %Sh/%<A
16.coredump_dir /var/spool/squid3
17.refresh_pattern .       0   20% 4320
18.cache_mgr mail@example.com
19.httpd_suppress_version_string on
20.visible_hostname example.com

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

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

1.url_rewrite_program /path/to/script

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

01.#!/bin/sh
02.while read url rest; do
03.   echo $url ... $rest >>/tmp/redirect.log
04.   if  [[ $url == *example.com* ]]
05.   then
06.      echo
07.   else
08.      echo http://www.example.com/
09.   fi
10.done

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

Tags: ,
Category: Linux | No comments »

Comments

Leave a comment

 Comment Form 

Rich Text Editor, comment