Squid: Блокируем ipv4 — Fastenv

Fastenv - системное администрирование от профессионалов индустрии. Работаем с linux, уважаем opensource.

Squid: Блокируем ipv4
Сложность: Низкая | Автор: fastenv | July 4, 2016

В продолжение нашей заметки поговорим о блокировке IPv4 трафика. Вопрос этот важен и актуален, а простого ответа не имеет. Ввиду последнего мы предложим несколько решений и поговорим об их недостатках.

В чём проблема?

Перед IPv6 прокси иной раз ставится такая задача — обойти ip-фильтры социальных сетей. С этой точки зрения единый IPv4 адрес может стать маркером того, что за всеми адресами стоит один и тот же человек.

Как узнать ipv4?

Механизм прост. Со стороны сервиса подсовываем какой-нибудь ресурс доступный только по v4, например невидимую, никому не нужную картинку. Не найдя ipv6 он произведет подключение по ipv4 адресу, тем самым раскрыв последний.

Позиция squid

Штатными средствами можно с легкостью заблокировать ipv4, но, увы, нет механизма управления резолвингом dns имён. Иными словами инструкция: для такого-то сайта использовать только ipv6 затруднительна в сквиде. Точка зрения разработчиков на этот счет — если у Вас возникла такая задача, то решайте её на уровне операционной системы.

Методы блокировки

Squid http_access deny

Первый и простейший способ — запретить весь не ipv6 трафик:

acl to_ipv6 dst ipv6
http_access deny !to_ipv6

Это хорошее решение, только если Вы готовы пожертвовать всем протоколом. Вы можете комбинировать его с:

acl domain_allow dstdomain .fastenv.ru

но всегда должны отдавать себе отчет, что желающий вычислить Вас сайт — это далеко не один домен, и Вам заранее не известно, на какой ресурс он попросит сходить Ваш браузер.

Iptables

Решение аналогично прошлому, но на уровне операционной системы:

iptables -A OUTPUT -p tcp --dport 80 -j DROP
iptables -A OUTPUT -p tcp --dport 443 -j DROP

Используя сетевой фильтр мы запрещаем обращения к 80 и 443 портам по ipv4.

Squid cache_dns_program

На этот раз рассмотрим наиболее корректное решние нашей задачи, но худшее по мнению squid. До версии 2.3 у него по техническим причинам не было встроенного днс резолвера и они использовали внешнюю программу — dnsserver. Путь до которой и определялся опцией cache_dns_program. Стоит заметить, что в современных версиях этот механизм выключен, а для включения требуется пересобрать сквид с опцией ‐‐disable-internal-dns. Разработчики рекомендуют никогда так не делать, но пойдем до конца:

  • Пересобираем squid с ‐‐disable-internal-dns.
  • Напишем скрипт, который займется у нас резолвингом:
    #!/bin/bash
    # dnsserver.sh
     
    resolve(){
    	local domain
    	local result
     
    	domain="${1}"
    	result=$(dig +short -t AAAA "${domain}")
    	if ! [[ "${result}" ]]
    	then
    		echo "\$fail"
    		return
    	fi
    	echo "\$addr 0" ${result}
    }
     
    while read domain
    do
    	resolve "${domain}"
    done
    • Формат успешного ответа:
      ('$addr') (время актуальности) (ответ днс сервера в порядке приоритета)
    • Формат неуспешного ответа:
      ('$fail')
  • Добавляем в конфигурационный файл:
    cache_dns_program /path/to/dnsserver.sh

Теперь разрешением dns имен занимается наш собственный скрипт, которым мы можем контролировать процесс. В примере выше, благодаря dig -t AAAA он отдает только ipv6 адреса. Данный метод, как и прочие — далек от идеала. Он требует не всегда тривиальной пересборки сквида, повышает нагрузку на процессор, увеличивает задержку на днс. За то он единственный, кто формально сохраняет работоспособность ipv4(открывающиеся по ip сайты продолжат открываться).