Назад | Перейти на главную страницу

Iptables перенаправляет порт 80 на удаленный squid

У меня есть сервер A с IP 192.0.2.2, у которого нет подключения к Интернету, поэтому он должен передавать весь Интернет-трафик http на прокси-сервер squid на сервере B с ip 192.0.2.3, прослушивающим порт 8080.

Я использовал следующее правило, которое устанавливает соединение с прокси-сервером squid, однако при запуске wget я получаю сообщение об ошибке 400 bad request:

iptables -t nat -A OUTPUT -p tcp --dport 80 -j DNAT --to-destination IP:8080

wget:

wget external.example.net/v4/Picture/pic1.jpg
--2015-09-05 18:42:01--  http://external.example.net/v4/Picture/pic1.jpg
Resolving external.example.net... 60.192.194.32, 61.54.192.95, 77.36.14.19, ...
Connecting to external.example.net|60.192.194.32|:80... connected.
HTTP request sent, awaiting response... 400 Bad Request
2015-09-05 18:42:01 ERROR 400: Bad Request.

Когда я проверяю журнал squid, я вижу, что в URL-адресе отсутствует домен.

1 192.0.2.2 NONE/400 1186 GET /v4/Picture/pic1.jpg - NONE/- -

Если я использую bash http_proxy вместо правила iptables, я могу успешно загрузить изображение, и squid регистрирует полный URL-адрес

export http_proxy=http://192.0.2.3:8080
wget external.example.net/v4/Picture/pic1.jpg

wget:

2015-09-05 18:55:48--  http://external.example.net/v4/Picture/pic1.jpg
Connecting to 192.0.2.3:8080... connected.
Proxy request sent, awaiting response... 200 OK
Length: 83760 (82K) [image/jpeg]
Saving to: `pic1.jpg'

Журнал кальмаров

 7 1.2.3.4 TCP_HIT/200 84455 GET http://external.example.net/v4/Picture/pic1.jpg - NONE/- image/jpeg

Почему мой первый запрос не работает?

Не совсем так работают прокси.

Когда вы отправляете запрос через HTTP-прокси, он выглядит примерно так, где proxy.example.net - это прокси, а target.example.net - это сайт, который вы пытаетесь получить:

GET http://target.example.net/path/to/resource HTTP/1.1
Host: proxy.example.net

Это иллюстративно, потому что вы заметите, что URL-адрес, используемый для выполнения этого HTTP-запроса к прокси, выглядит следующим образом:

http://proxy.example.net/http://target.example.net/path/to/resource

Когда вы используете DNAT для простого перенаправления трафика, wget разрешает target.example.net и отправляет часть пути URI в качестве тела запроса вместо URL-адреса прокси-серверу, поэтому он отправляет только это:

GET /path/to/resource HTTP/1.1
Host: target.example.net

Сервер squid по понятным причинам смущен этим, поскольку он не является target.example.net и не обслуживает документ по адресу / path / to / resource.

Если вы сконфигурируете squid как прозрачный прокси, вы действительно можете сделать это с помощью следующих директив для squid до версии 2.6:

httpd_accel_host virtual
httpd_accel_port 8080
httpd_accel_with_proxy on
httpd_accel_uses_host_header on

Тот последний, httpd_accel_uses_host_header on, говорит Squid использовать Host: заголовок из приведенных выше примеров (для которого требуется HTTP 1.1), чтобы выяснить, откуда взять ресурс, вместо использования явного прокси-запроса, о котором я упоминал выше. Видеть http://squidconfiguration.com/config-manual-2-4/httpd-accelerator-options/httpd_accel_uses_host_header/.

Для более новых версий squid (3.1 и выше) используйте эту директиву listen:

http_port 8080 intercept

Посмотреть здесь: http://www.squid-cache.org/Doc/config/http_port/

Для некоторых старых версий Squid он «прозрачный», а не «перехватывающий».

И хороший учебник из вики по Squid: http://wiki.squid-cache.org/ConfigExamples/Intercept/LinuxRedirect