NAT 1: 1 с несколькими одинаковыми локальными сетями

13

Я хочу подключить несколько локальных сетей, расположенных на удаленных зданиях.
На «центральном» сайте установлен компьютер Linux с OpenVPN. На каждом удаленном сайте также работает OpenVPN.

  1. центральный сайт имеет локальную сеть с номером 192.168.0.0/24
  2. несколько удаленных сайтов также пронумерованы 192.168.0.0/24
  3. Я не могу / не буду / не хочу / что-либо изменить нумерацию локальной сети
  4. У меня нет контроля над большинством удаленных OpenVPN

Затем мне нужно:
1. определить виртуальные ЛВС
2. настроить 1: 1 NAT для каждого сайта
3. 1: 1 NAT должен быть настроен на центральном маршрутизаторе

Карта локальной сети ,
Таким образом, каждый сайт имеет локальную сеть 10.10.x.0 / 24.
Когда компьютер хочет, скажем, 192.168.0.44 на сайте 12, он просто должен отправить пакет на 10.10.12.44

Использование VPN не проблема для меня. В настоящее время я подключаю более 60 сайтов. Но я не нахожу простой способ сделать это 1: 1 NAT.

Вот пример пакета, отправленного с центрального сайта на удаленный сайт, и его ответного пакета:

введите описание изображения здесь

Я провел несколько тестов с iptables NETMAP, но мне не удалось заставить его работать, потому что я не нашел способа изменить источник + назначение после решения о маршрутизации.
Я предпочитаю избегать новой функции --client-natOpenVPN.
Может быть, я должен заставить маршрутизацию с ip route? Или дважды зацикливаться на сетевом стеке veth?

Примечание: я не хочу использовать маскарад. Только 1/1 NAT.

РЕДАКТИРОВАТЬ:
Это невозможно при обычной настройке openVPN. Поскольку пакет с удаленного сайта неотличим от пакета с другого сайта: оба имеют одинаковые адреса отправителя и получателя, и оба имеют одинаковый интерфейс tun (или tap). Так что это не возможно для источника-NAT это.

Решение 1: сделать NAT на удаленных сайтах. В моем случае это невозможно. Я должен сделать это только на центральном сайте.

Решение 2: настроить один VPN для каждого удаленного сайта. Так что у меня будет по одному тюну на каждого. Я думаю, что это может быть хорошо. Не очень эффективная память, но хорошо.

Решение 3: настроить (незашифрованный) туннель внутри VPN для каждого сайта. Это даст один интерфейс для каждого. Простые туннели не являются кроссплатформенными (к моему знанию). Например, GRE или ipip или sit подходят для Linux, но на некоторых удаленных сайтах работает только один компьютер с Windows, поэтому на нем установлен openVPN. Поэтому невозможно настроить простой туннель. Другой вариант - использовать более сложный туннель (что?), Но издержки в системе и на системном администраторе могут быть больше, чем при наличии нескольких VPN

Решение 4: скомпилируйте последнюю версию openVPN, поскольку она включает функцию NAT 1: 1. Я проверяю это на этой неделе.

Бертран Щитс
источник
1
Для решения 4 вам не нужно компилировать. Большинство основных дистрибутивов Linux имеют скомпилированные пакеты на официальном сайте openVPN. Но это не сработает для вас, потому что опция --client-nat - это опция, которую можно использовать. Таким образом, ваши клиенты также должны использовать последнюю версию RC (и вы говорите, что не можете контролировать удаленные сайты).
Грегори МУССАТ
1
Ну, я ошибаюсь: функция --client-nat на 100% внутри OpenVPN (я думал, что она использует ipfilter). Я только что проверил: он работает и на Windows. Смотрите мое решение ниже.
Грегори МУССАТ
Я хотел бы знать, работали ли вы когда-нибудь и чем занимались.
Майкл Грант

Ответы:

2

Очень простое решение:
1. использовать OpenVPN 2.3 или более позднюю (в настоящее время последняя версия 2.3-alpha) для сервера + клиентов
2. использовать опцию конфигурации OpenVPN ниже
3. не использовать ничего другого (без ipfilter, без хитростей)

На стороне сервера вам нужно вручную распределить VPN-адреса (так что никакой serverопции, вы должны использовать ifconfigили ifconfig-push):

# /etc/openvpn/server.conf
ifconfig 10.99.99.1 10.99.99.2
route 10.99.99.0 255.255.255.0
push "route 10.99.99.0 255.255.255.0"
push "client-nat dnat 10.99.99.11 255.255.255.255 10.10.111.11"
push "client-nat dnat 10.99.99.12 255.255.255.255 10.10.112.12"
push "client-nat dnat 10.99.99.13 255.255.255.255 10.10.113.13"

routeИ push routeи client-natлинии необходимы , если вы хотите общаться непосредственно между маршрутизаторами ( ping 10.99.99.1от отдаленного сайта Повсеместно на VPN). В противном случае вы можете отказаться от них.

,

,

Теперь вам нужно выбрать виртуальный сетевой адрес. Я сохранил то же, что вы использовали в своем примере: 10.10.0.0/16
Вы разрешаете маршрутизацию для этого:

# /etc/openvpn/server.conf
route 10.10.0.0 255.255.0.0
push "route 10.10.0.0   255.255.0.0"

,

,

Теперь вы должны указать клиенту использовать NAT 1: 1:

# /etc/openvpn/ccd/client_11
ifconfig-push 10.99.99.11 10.99.99.1
push "client-nat snat 10.99.99.11 255.255.255.255 10.10.111.11"
push "client-nat snat 192.168.0.0 255.255.255.0 10.10.11.0"
push "client-nat dnat 10.10.10.0 255.255.255.0 192.168.0.0"
iroute 10.10.11.0 255.255.255.0
iroute 10.10.111.0 255.255.255.0

Первая строка устанавливает адрес удаленного маршрутизатора. Остерегайтесь драйверов Windows, требующих специальных адресов.
Вторая и последняя строки позволяют удаленному маршрутизатору обмениваться данными через интерфейс 10.99.99.x.
Третья и четвертая строки делают NAT и источник 1: 1.
Пятая строка сообщает OpenVPN, что делать с соответствующими пакетами.

Этот метод позволяет подключать сайты с одинаковыми (или нет) сетевыми адресами без какого-либо теневого хоста.

Грегори МУССАТ
источник
1
Просто, блестяще.
Бертран Щитс
Я попробовал это, но не смог заставить его работать. Я использую Linux с обеих сторон. Что-то странное, или я чего-то не понимаю полностью. Ваш ifconfig-push в файле client_11 (первая строка), не должен ли он быть маской для второго аргумента вместо 10.99.99.1? Во-вторых, почему вы используете эту третью сеть 10.10.111.0/24? Кажется, вы пытаетесь использовать сеть 111 для связи между сайтами, разве сеть 10.10 не может использоваться для этого напрямую? И наконец, что бы я ни пытался, я не вижу (в tcpdump) пакетов snat и dnat, влияющих на клиента.
Майкл Грант
Не очень просто, но все же блестяще.
Нейротрансмиттер
4

Я сделал нечто подобное с реальными интерфейсами, но я не понимаю, почему это не будет работать с интерфейсами VPN.

Идея состоит в том, что, поскольку у вас есть одна и та же подсеть, доступная на разных интерфейсах на этом маршрутизаторе, это усложняет маршрутизацию. В основном, когда пакет для 10.10.13.123 поступает в маршрутизатор, он перед началом маршрутизации к 192.168.0.123 подвергается DNAT, поэтому вы должны иметь возможность указать маршрутизации, что он предназначен для 192.168.0.123 на интерфейсе VPN13 .

Это можно сделать с помощью меток межсетевого экрана и правил маршрутизации, которые используют эти метки. SNAT и DNAT должны выполняться с целью брандмауэра NETMAP. Для SNAT это та же проблема: в POSTROUTING вы потеряли информацию о том, что пакет поступил с того или иного интерфейса, и все они получили адрес источника 192.168.0.x. Таким образом, вам также нужна отметка для передачи этой информации от mangle-PREROUTING к nat-POSTROUTING. Вы можете использовать ту же метку, но тогда это будет означать, что эти пакеты будут использовать эту альтернативную таблицу маршрутизации, поэтому вам придется дублировать глобальную таблицу маршрутизации на всех.

Для каждой сети вы должны сделать:

lnet=192.168.0.0/24
if10=eth0 if11=tun0 if12=tun1 if13=tun2

n=0
for site in 10 11 12 13; do
  table=$site
  net=10.10.$site.0/24
  n=$(($n + 1))
  eval "interface=\$if$site"
  inmark=$(($n * 2)) outmark=$(($n * 2 + 1))

  iptables -t nat -A PREROUTING -d "$net" -j NETMAP --to "$lnet"
  iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -m mark --mark "$inmark"/0xf -j NETMAP --to "$net"
  iptables -t mangle -A PREROUTING -i "$interface" -j MARK --set-mark "$inmark"/0xf
  iptables -t mangle -A PREROUTING -d "$net" -j MARK --set-mark "$outmark"/0xf
  ip rule add fwmark "$outmark"/0xf table "$table"
  ip route add "$lnet" dev "$interface" table "$table"
done

Выше мы используем первые 4 бита метки , чтобы таким образом можно было маршрутизировать до 7 сетей.

Стефан Шазелас
источник
1
Спасибо за Ваш ответ. Я проверял это, но это не работает. Я тестировал только с одной локальной сетью, результата больше нет. Я использую tcpdump для мониторинга пакетов, и когда я отправляю пакет с удаленного на центральный сайт, я даже ничего не вижу (?! Как это возможно?). С твоими указаниями я постараюсь составить свой пошаговый ответ. Не уверен, что у меня все получится.
Бертран Щитс
2
Мой ответ охватывает только то, что нужно делать на центральном сайте. Я предполагаю, что вы правильно настроили маршрутизацию на других сайтах. Например, вам, вероятно, нужно добавить маршрут к 10.10.0.0/16 через VPN-туннель на удаленных сайтах. Вам также может понадобиться указать openvpn пропустить эти пакеты. В любом случае, использование tcpdump, чтобы увидеть, какие пакеты получают, где и как это правильный подход. цель iptables LOG также является вашим другом.
Стефан Шазелас
2
Если вы не видите пакетов, вы должны заглянуть в ваш журнал openvpn. Вы, вероятно, найдете упавшие пакеты. Если это так, используйте «iroute 192.168.0.0 255.255.255.0» для каждого клиента в вашей
директории