У меня есть сервер 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