IPv6-only ресурсы в lighttpd

Впервые опубликовано 2011-07-13

Иногда может возникнуть необходимость предоставить доступ к администрируемому вами веб-ресурсу только по протоколу IPv6. К примеру, ваш провайдер предоставляет бесплатный IPv6-доступ на скорости 100 мегабит, при этом IPv4 тоже есть, но он платный и в разы более медленный. В этой ситуации у вас есть возможность выкладывать тяжёлый контент (скажем, организовать файловое зеркало популярного opensource-проекта), но давать доступ к нему вы хотели бы только IPv6-клиентам. Как это лучше всего сделать (при использовании на веб-сервере lighttpd)?

Отдельный домен или поддомен

Простейшее решение – создать альтернативный домен (или поддомен, к примеру ipv6.example.com), на котором прописать только AAAA-запись. Сами же материалы, которые должны быть доступны только по IPv6, разместить в каталоге virtual host, соответствующем этому домену.

У этого способа есть несколько недостатков:

  • Если ваш веб-сервер слушает также и на IPv4, клиенты смогут в своих файлах /etc/hosts прописать в соответствие этому домену ваш IPv4-адрес, и таким образом получить доступ к нужному им виртуальному хосту, даже подключаясь к серверу по IPv4;
  • Необходимость размещать IPv6-ресурсы на отдельном домене, а это не всегда удобно;
  • Нет возможности выдать пытающимся подключиться к такому домену, но не имеющим IPv6-доступа пользователям, понятное сообщение об ошибке (к примеру: «данный сайт доступен только по IPv6, установите/настройте его по этой инструкции [ссылка]»). Браузер просто выдаст им своё сообщение «Адрес не найден».

Проверка клиентского адреса

Гораздо более гибкий способ заключается в проверке адреса, с которого подключился клиент. В простейшем варианте, отличать IPv6 от IPv4 можно по наличию в последнем точек. :) Можно и наоборот, смотреть на наличие двоеточия в IPv6, но такой вариант менее надёжен, т.к. в зависимости от настройки, ваша ОС и сервер могут работать с т.н. IPv6-mapped IPv4-адресами, и все клиентские IPv4 будут видны вам в логах и проверках как ::ffff:a.b.c.d (соотв-но двоеточие в адресе будет присутствовать всегда).

Также, при использовании этого способа lighttpd даёт возможность переопределить отображаемую клиенту страницу с сообщением об ошибке на произвольный HTML-файл.

По поводу выдаваемого кода HTTP для подключающихся по IPv4 клиентов, мне видится два варианта:

  • 403 Forbidden, с собственным текстом сообщения в HTML-странице («403 No IPv4 Allowed» :).
  • 303 See Other, среди существующих кодов ответа HTTP, этот малоизвестный код редиректа показался мне более всего подходящим для перенаправления части посетителей на страницу с информацией о том, почему им не доступен ресурс, который они пытались открыть. К сожалению, возможность переопределять код редиректа появилась только начиная с ветки lighttpd 1.5, я же пока пользуюсь 1.4, поэтому данный вариант не тестировал.

Запрет IPv4-доступа

Запрещаем IPv4-доступ к каталогу goodies/ на сайте example.com:

/var/www/error-ipv6only-403.html
<html><body>
<h1>403 No IPv4 Allowed</h1>
<p>Sorry, this is an IPv6-only resource. Please get yourself IPv6 if you want to access it.</p>
</body></html>
/etc/lighttpd/lighttpd.conf
$HTTP["host"] == "example.com" {
  $HTTP["url"] =~ "^/goodies.*" {
    $HTTP["remoteip"] =~ "\." {
      url.access-deny = ("")
      server.errorfile-prefix = "/var/www/error-ipv6only-"
    }
  }
}

Сохраняем конфиг, перезапускаем веб-сервер, и всё готово. :)

Проверяем:

$ curl -I4 http://example.com/goodies/
HTTP/1.1 403 Forbidden
<...>

$ curl -I6 http://example.com/goodies/
HTTP/1.1 200 OK
<...>

Ограничение скорости

Помимо полного запрета доступа с IPv4, lighttpd также предоставляет нам возможность вместо этого ограничить его скорость любой величиной, начиная от 32 КБ/сек. К примеру, вместо полного запрета выставляем суммарный лимит скорости всех IPv4-соединений, загружающих файлы из каталога goodies/, в 256 КБ/сек:

/etc/lighttpd/lighttpd.conf
$HTTP["host"] == "example.com" {
  $HTTP["url"] =~ "^/goodies.*" {
    $HTTP["remoteip"] =~ "\." {
      server.kbytes-per-second = 256
    }
  }
}

lighttpd-ipv6-only.txt · Последние изменения: 2011-07-29 08:37 UTC От rm