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

Squid использует блок IPv6 / 48, подключенный через туннель

У меня есть сервер Ubuntu 14.05, на котором работает Squid. Он имеет соединение IPv6 через службу Hurricane Electric. Я стараюсь, чтобы каждый IP-адрес был доступен серверу из / 48, которое они предлагают.

Я много искал и не нашел рабочего решения. Я могу использовать любой адрес из / 48, если я настрою IP-адреса индивидуально в / etc / network / interfaces, хотя попытки общего добавления / 48 не сработали. Вот моя рабочая конф.

auto he-ipv6
iface he-ipv6 inet6 v4tunnel
    address 2xxx:xxx:xxx:0:0:0:0:1
    netmask 64
    endpoint xx.xx.xx.xx
    local xx.xx.xx.xx
    ttl 255
    gateway 2xxx:xxx:xxxx:xxxx::1

В попытках назначить / 48 я попытался добавить это к интерфейсам

   post-up ip -6 addr add 2001:xx:xx::/48

Этот вопрос предлагает использовать параметр ipv6 non local bind или привязку к локальному интерфейсу, я пробовал этот пример, хотя я не уверен в использовании net.ipv6.ip_nonlocal_bind вариант.

/sbin/ip -6 addr add 2001:db8::ffff:1/64 dev lo

При тестировании с помощью wget --bind-address [платье в пределах диапазона] google.com я получаю следующее

--2017-02-04 15:07:26--  (try: 3)  http://ipv6.google.com/
Connecting to ipv6.google.com (ipv6.google.com)|2a00:1450:4001:814::200e|:80... failed: Cannot assign requested address.
Retrying.

Никаких кубиков. Я смотрю на это неправильно? Есть ли у кого-нибудь предложения?

Прежде всего, вам нужно понять, что три префикса, которые вы получили от HE, не все одинаковы.

Вам был назначен один /64 префикс ссылки. Это единственный префикс, который вы должны использовать в интерфейсе туннеля.

Вам также были выделены два маршрутизируемых префикса: один /64 и один /48. Вы можете узнать больше о разнице между префиксами ссылок и маршрутизируемыми префиксами в этом вопросе: IPv6: различия между «префиксом маршрутизации» и «префиксом ссылки»?

Разгромленный /64 может использоваться непосредственно как префикс ссылки на другом подключенном сетевом интерфейсе. В /48 при необходимости могут быть разделены на другие префиксы маршрутизации и ссылки.

Если вам нужно много адресов на одном хосте, вам следует выделить локальный префикс из одного из ваших маршрутизируемых префиксов. Я настоятельно не рекомендую использовать префикс короче, чем /64 для этой цели. Локальный префикс может быть длиннее, чем /64.

Команда для добавления локального маршрута может выглядеть так:

ip -6 route add to local 2001:db8:f918:b1e2:086a:cee6::/96 dev lo

Вы можете узнать больше об использовании локальных маршрутов в этом вопросе: Добавление всего блока IPv6 / 64 к сетевому интерфейсу на debian

Приложения слушают :: будет получать трафик для любого IP в префиксе вашего локального маршрута. Если вам нужно явно привязать к отдельным IP-адресам, покрытым локальным маршрутом, приложение должно установить опцию сокета.

Я хотел сделать то же самое и для этого успешно модифицировал Squid. Я использовал исходный код пакета Debian Squid 3 (версия 3.4.8-6 + deb8u4). Он будет работать, если вы используете ту же сетевую конфигурацию, которую вы использовали для этого с wget. Вам не нужно назначать каждый IP-адрес, который вы хотите использовать, для вашего сетевого интерфейса. Извините за то, что не предоставил нужные исправления, но вот что я сделал.

В src/FwdState.cc, в самом начале функции getOutgoingAddress () я добавил следующее:

String ipv6;
ipv6 = request->header.getByName("IPV6-Bind");
if (ipv6 != "") {
  AclAddress l;
  struct sockaddr_in6 sa6;
  inet_pton(AF_INET6, ipv6.rawBuf(), &(sa6.sin6_addr));
  /* don't do conn->local = sa6 because of operator overloading */
  l.addr = sa6;
  conn->local = l.addr;
  ipv6.clean();
  conn->flags |= COMM_FREEBIND;
  return;
}
ipv6.clean();

Я также добавил заголовочный файл #include <arpa/inet.h> на вершине src/FwdState.cc.

Затем в src/comm.cc, Я добавил этот блок кода в comm_openex () сразу после создания сокета (т.е. после new_socket = socket(AI->ai_family, AI->ai_socktype, AI->ai_protocol);):

if ((flags & COMM_FREEBIND)) {
  int v = 1;
  if (setsockopt(new_socket, SOL_IP, IP_FREEBIND, (char *) &v, sizeof(v)) < 0) {
    debugs(50, DBG_IMPORTANT, "comm_openex: setsockopt() on FD " << new_socket << ": " << xstrerror());
  }
}

Наконец, в src/comm/Connection.h, Я добавил это:

#define COMM_FREEBIND           0x40

Эти изменения позволяют вам выбрать исходный адрес IPv6, добавив в запрос заголовок HTTP с именем IPV6-Bind. Например: IPV6-Bind: 2001:db8:f918:b1e2:086a:cee6::1.

Вы можете протестировать с помощью wget:

http_proxy='http://localhost:3128' wget -4 --header="IPV6-Bind: 2001:db8:f918:b1e2:086a:cee6::1" http://whatismyip.org/

Примечание: вы можете предотвратить отправку заголовка IPV6-Bind на веб-сайт с помощью директивы request_header_access в вашем squid.conf.