Дооолгое время я бился над этой задачей. Как обычно решение в голову пришло очень внезапно на курилке одновременно с ударом по голове (она и так болела и думать не хотела). Ведь все отдельные составляющие, как обычно, были известны, но соединить знания воедино для решения задачки я традиционно не мог.
Задача была следующая — при помощи чего-нибудь (неважно чего) сделать так, чтобы ip адрес фактически «работал» на другом сервере. То есть, все запросы к ip-адресу перенаправлялись на другой сервер, а этот самый «другой» сервер вполне себе нормально отвечал на запросы к этому адресу.
Зачем это нужно?
- на виртуалочку на своём домашнем сервере (где, само собой, белым адресом и не пахнет (или пахнет только одним, а нужен второй)) притащить белый адрес для прямого доступа из интернета на неё. В топку DynDNS, да.
- при миграции содержимого сервера на новый сервер временно перевесить старый адрес на новый сервер не заморачиваясь с проксированием/форвардингом чего-либо куда-либо
- мигрировать виртуалки между физическими машинами в hetzner без заказа failover-ip =) Само собой, не в качестве постоянного решения, а в качестве «блин, надо вот эту виртуалку на другую железку на время перетащить».
- можно ipv6 таким образом притаскивать на машины без ipv6 (хотя для этого есть несколько более удачных способов)
Что будем использовать? ppptd. Всё. Никаких iptables с nat/forwarding-правилами, никаких проксирований — всё на честной маршрутизации и pptp. Такой вариант будет работать пошустрее и понадежнее за счёт того, что не будет использоваться conntrack, таблица которого достаточно бодро забивается при большом количестве соединений (и пакеты начинают дропаться). Можно pppoe, l2tp или opencensored — что сами сможете настроить. PPTP просто очень быстро настраивается сам по себе (и с ним этот вариант точно пройдет) — потому и пишу именно о нём.
Что нужно:
- Сервер с двумя адресами. В моём примере это будут 46.4.251.90 (адрес, который я повешу на клиент) и 46.4.251.85 (адрес, который будет адресом исходного сервера).
- Клиент с доступом к интернету и отсутствием запрета на использование gre-passthrough. Учтите, что домашние провайдеры (особенно те, что по pppoe) и дешевые роутеры частенько блокируют gre.
- Второй адрес на сервере не должен в текущий момент использоваться на сервере. Попингуйте его, что ли =)
- минимальные познания в linux networking.
Само собой, чудеса невозможны. Нельзя просто взять и перевесить ip-адрес, привязанный к дата-центру в Германии на машинку на нашу виртуалку в Москве (да ещё и за NAT-ом, например). Поэтому в результате мы получим такую схему:
клиент делает запрос на ip-адрес 46.4.251.90 -> пакетики попадают на сервер 46.4.251.85 -> пакеты отправляются в pptp-туннель на адрес 46.4.251.90 -> пакеты попадают на вторую машину -> вторая машина смотрит в свою таблицу маршрутизации и исходящие пакеты отправляет обратно клиенту через pptp-туннель -> сервер 46.4.251.85 получает пакеты из туннеля, видит, что получатель не он (и что отправитель «не он») -> пакеты уходят клиенту, делавшему запрос.
Поехали.
Настраиваем сервер pptpd:
В файл /etc/pptpd.conf пишем следующее:
logwtmp
# localip-адрес не должен пересекаться ни с одним из адресов, доступных машине-клиенту через, например, локальную сеть.
localip 192.168.10.1
# во многих мануалах описывается ещё и параметр remoteip - но нам он в данном случае не нужен, т.к. все адреса мы будем прибивать к логину/паролю в следующем файле.
Теперь напишем файлик с авторизацией и ip-адресами клиентов — /etc/ppp/chap-secrets :
# client server secret IP addresses
user1 pptpd password1 46.4.251.90
# если нужен другой пользователь с другим адресом, то:
#user2 pptpd password2 xx.xx.xx.xx
# адрес в четвертой колонке может быть любым, главное, чтобы он маршрутизировался на ваш сервер и не был, собственно, занят этим сервером.
Рестартим pptpd на всякий:
Теперь настроим клиент. Ставим пакет для клиента:
В файл /etc/ppp/peers/yourpeername пишем такое:
name user1
password password1
remotename PPTP
require-mppe-128
persist
maxfail 0
holdoff 20
noauth
В файл /etc/ppp/ip-up _дописываем_ в конец такое:
/sbin/ip ro add default via ${5} dev ${1} src ${4} table 17 mtu 1450 advmss 1410
В файл /etc/ppp/ip-down _дописываем_ в конец такое:
/sbin/ip ru del pref 17
Что мы дописали? Первая команда создаёт дополнительную таблицу маршрутизации внутри системы. Вторая команда, соответственно, «говорит» нашему тазику использовать эту таблицу через нужный интерфейс с нужным default-шлюзом. Такая конструкция позволит нам отвечать на входящие пакеты исходящими пакетами с нужного адреса/интерфейса, через нужный шлюз, в тех случаях, когда на машинке несколько адресов из нескольких сетей с разными шлюзами. Собственно, аналогичную конструкцию я использовал, когда писал про VLAN-ы.
Запускаем наше соединение:
С другой машинки проверяем, что всё заработало:
PING 46.4.251.90 (46.4.251.90) 56(84) bytes of data.
64 bytes from 46.4.251.90: icmp_req=1 ttl=52 time=85.1 ms
64 bytes from 46.4.251.90: icmp_req=2 ttl=52 time=84.9 ms
...
12 46.4.251.85 56.923 ms 56.921 ms 56.875 ms
13 46.4.251.90 85.020 ms 84.822 ms 84.606 ms
Ну и последний штрих — обеспечить автостарт этой конструкции. Например, в /etc/rc.local перед exit 0 вписать
Рестарт подвисшего соединения можно сделать командой:
Или около того.
Хотя при обрывах оно будет само рестартиться.
Из известных проблем такой схемы — провайдеры с отключенной фрагментацией проходящих пакетов. В таком случае большие пакеты, проходящие через туннель, могут дропаться. В этом случае следует снижать значение mtu/mss в файлах /etc/ppp/ip-{up,down}
Привет, у меня вопрос маленько не в тему , но все ж…
Когда появятся видеозаписи для скачивания с прошлых вебинаров/семинаров?
А черт его знает(
У меня осталась запись только одного вебинара, обрабатывать некому. Теран в Мирантис ушел уже)
Рассматривали тунель: ipip/gre?
Да всё то же самое будет.
Вся магия в этом:
/sbin/ip ru add from ${ip} lookup 17 priority 17
/sbin/ip ro add default via ${remote_ip} dev ${iface} src ${ip} table 17 mtu 1450 advmss 1410
ip — локальный адрес в туннеле, remote_ip — адрес второй точки ptp-соединения (ну или default gatewy для туннеля, по-простому, если у нас более сложная сеть), iface — локальный интерфейс соединения, на котором адрес висит.
Просто с pptp всем понятно и автоматизировать там всё легко )
«Магия» понятно, ipip/gre тунель по надежнее будет, + работает в ядре.
Ага. Напишу потом статью тоже, наверное. Только придумаю, как persistence конфигурацию сделать.
t3mp:
Я хоть и не прочитал статью (ибо слишком банальная задача и поэтому статья скучная), но там упоминается использование pptpd-сервера, которые уже достаточно давно как работает почти полностью на уровне ядра.
Ранее использовался accel-pptpd, но его наработки успешно перенесли в ядро, IIRC.
IPv6 не пробовали телепортировать таким образом?
> IPv6 не пробовали телепортировать таким образом?
Через pptp нет, через ipip делал — https://debian.pro/1578
Если на dst нет ipv6 «родного», то и вовсе достаточно на src сделать /128 маршрут в туннель для адреса.