У меня есть сервер с IP 192.0.2.2, который не имеет соединения с Интернетом, таким образом, это должно передать весь интернет-трафик HTTP прокси сквида на сервере B с IP 192.0.2.3 слушания на порте 8080.
Я использовал следующее правило, которое действительно устанавливает соединение с прокси сквида, однако я возвращаю 400 плохих ошибок запроса, когда я инициирую wget:
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.
Когда я проверяю журнал сквида, я вижу, что домен отсутствует в URL.
1 192.0.2.2 NONE/400 1186 GET /v4/Picture/pic1.jpg - NONE/- -
Если я использую удар http_proxy вместо правила iptables, что я могу успешно загрузить изображение, и сквид регистрирует полный 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 - это прокси, а цель .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 на
, говорит squid использовать заголовок Host:
из моих примеров выше (для которого требуется HTTP 1.1), чтобы выяснить, откуда взять ресурс, вместо использования явный запрос прокси, о котором я упоминал выше. См. http://squidconfiguration.com/config-manual-2-4/httpd-accelerator-options/httpd_accel_uses_host_header/ .
Для более новых версий squid (3.1 и выше) используйте эту директиву прослушивания :
http_port 8080 intercept
См. Здесь: http://www.squid-cache.org/Doc/config/http_port/
Для некоторых старых версий squid он «прозрачный», а не «перехватывающий».
И хороший учебник из вики по Squid: http://wiki.squid-cache.org/ConfigExamples/Intercept/LinuxRedirect