Я пытаюсь немного узнать о трансляциях NAT в Linux, но не видел ни одного доказательства концепции, которое было бы максимально упрощено.
Ну ладно. Вот рисунок моей установки:
У меня очень простой маршрутизатор для Интернета. Он может делать только 2 вещи:
- Подключитесь к Интернету.
- Выдайте IP-адрес только в 1 подсети.
Этоне могувообще не делайте статическую маршрутизацию.
... и он даже не знает, как выглядит адрес IPv6! (Без шуток!)
Я хочу иметь возможность подключаться к Интернету из Raspberry 3
, а также иметь возможность подключаться из или My Computer
к Raspberry 3
любому другому устройству в другой подсети.
Это натолкнуло меня на мысль реализовать на моем сервере NAT 1:1 Raspberry 4
, при котором все IP-адреса из диапазона 192.168.10.x/24 преобразуются в диапазон 192.168.1.x/24.
Таким образом, по крайней мере с точки зрения моего маршрутизатора, все хосты в сети принадлежат к одной и той же подсети, поскольку пул адресов 192.168.0.0/23 находится в диапазоне от 192.168.0.0 до 192.168.1.255.
Но как это сделать?
Достаточно ли просто добавить два правила в iptables на Raspberry 4, например:
iptables -t nat -A PREROUTING -d 192.168.10.0/24 -j NETMAP --to 192.168.1.0/24
iptables -t nat -A POSTROUTING -d 192.168.1.0/24 -j NETMAP --to 192.168.10.0/24
Или мне нужно более конкретно указать направление IP-пакетов?
Обновлять:
Чтобы помочь в устранении неполадок, могу сообщить, что Raspberry 4 выступает в качестве DHCP-сервера для обеих моих подсетей.
Он объявляет себя первым узлом при трассировке маршрута от любого компьютера к Интернету — в любой сети.
Допустим, трассировка маршрута от My computer
до Google покажет что-то вроде:
- 1: Малина 4
- 2: Примитивный маршрутизатор
- 3: Шлюз интернет-провайдера
- 4: ...
- ...
- н: Google.com
Однако traceroute дает сбой, если выполняется из моего Raspberry 3
.
Первым шагом будет Raspberry 4
, так что ничего удивительного, но маршрут не даст ответа на ping, так как он не знает, как добраться до подсети 192.168.10.0/24.
К вашему сведению, я Raspberry 4
уже работаю как VPN-клиент типа «сеть-сеть», поэтому, если все остальное не сработает, я могу просто использовать маршрутизацию на основе источника и отправлять весь трафик через свое VPN-подключение, хотя и со значительным снижением скорости (падение скорости составляет около 70%).
Обновление 2:
Вывод с Raspberry 4:
# ip rule show
0: from all lookup local
32766: from all lookup main
32767: from all lookup default
# ip route show table main
default via 192.168.0.1 dev eth0 src 192.168.0.136 metric 202
192.168.0.0/23 dev eth0 proto dhcp scope link src 192.168.0.136 metric 202
192.168.100.0/24 dev tun-ipv6 proto kernel scope link src 192.168.100.10
- Маршрутизатор находится по адресу 192.168.0.1.
- Подсеть 192.168.100.0/24 находится внутри моего VPN.
Эта часть работает отлично, поскольку я не собираюсь отправлять весь трафик через VPN.
Для меня не составит труда создать новую таблицу маршрутизации для перенаправления с 192.168.10.0/24 через VPN, поскольку я уже проделывал этот трюк однажды, чтобы использовать IPv6 в своей локальной сети. :-)
Однако решение Тома Яна выглядит вполне соответствующим тому, что я искал, особенно его намек на «AnyIP». :-)
Мне нужно провести небольшое тестирование, но я приму его ответ. :-)
решение1
Прежде всего, исходный NAT должен быть:
iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -j NETMAP --to 192.168.1.0/24
( POSTROUTING
со -s
спичкой)
и конечный NAT должен быть:
iptables -t nat -A PREROUTING -d 192.168.1.0/24 -j NETMAP --to 192.168.10.0/24
( PREROUTING
со -d
спичкой)
Примечание: Насколько мне известно, правило NAT назначения необходимо только для "НОВОГО" трафика (из локальной сети). Правило NAT источника достаточно для обратного трафика, поскольку NAT назначения для любого из них "подразумевается" им.
Но тут возникает проблема: как My Computer
узнать Primitive Router
, куда следует направить трафик 192.168.1.0/24
(который «на самом деле» 192.168.10.0/24
) Raspberry Pi 4
для дальнейшей маршрутизации?
Ответ таков: вам необходимо Raspberry Pi 4
отвечать на ARP-запросы для 192.168.1.0/24
.
Один из способов добиться этого — настроить нечто под названием «AnyIP» (по крайней мере, я слышал такой термин). По сути, это означает добавление маршрута подсети типа local
для 192.168.1.0/24
:
ip r add local 192.168.1.0/24 dev eth0
Примечание: я точно не помню, будет ли это работать, если для arp_ignore
sysctl установлено значение eg 1
.
Убедитесь, что вы включили пересылку IP(v4) с помощью sysctl и что ни один брандмауэр не Raspberry Pi 4
блокирует пересылку необходимого вам трафика (согласно правилу или политике цепочки).
решение2
Я пытаюсь немного узнать о трансляциях NAT в Linux, но не видел ни одного доказательства концепции, которое было бы максимально упрощено.
Вот мой максимально простой скрипт, который я использую на своем настольном ПК для «раздачи интернета» при подключении к нему другого устройства по локальной сети:
#!/bin/bash
# masquerade $1 (e.g. eth0, ppp0) as $2 (default wlan0)
INTIF="$1"
EXTIF=${2:-wlan0}
echo $INTIF $EXTIF
echo "1" > /proc/sys/net/ipv4/ip_forward
iptables -P INPUT ACCEPT
iptables -F INPUT
iptables -P OUTPUT ACCEPT
iptables -F OUTPUT
iptables -P FORWARD DROP
iptables -F FORWARD
iptables -t nat -F
iptables -A FORWARD -i $EXTIF -o $INTIF -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i $INTIF -o $EXTIF -j ACCEPT
iptables -t nat -A POSTROUTING -o $EXTIF -j MASQUERADE
Вам нужно вызвать его с помощью "внутреннего" интерфейса (сеть с клиентами, которым нужен NAT) и "внешнего" интерфейса (в сторону Интернета). Настройка внутреннего интерфейса, DHCP и т. д. не включена (вы спрашивали только о NAT).
Это натолкнуло меня на мысль реализовать 1:1 NAT на моем Raspberry 4, где все IP-адреса из диапазона 192.168.10.x/24 транслируются в диапазон 192.168.1.x/24.
Это намного сложнее, чем «базовый NAT».
Но вам не обязательно это делать, и на самом деле это не будет хорошо работать с вашей примитивной комбинацией маршрутизатора и Raspberry Pi 4. Вместо этого просто выполните базовый NAT на Raspberry Pi 4. Это будет означать, что все на 192.168.10.*/24 будет преобразовываться в 192.168.0.0, и маршрутизатор прекрасно это поймет.
(А в реальной жизни вы бы просто соединили два коммутатора и получили бы одну подсеть, предоставляемую вашим маршрутизатором. Кстати, если ваш примитивный маршрутизатор можно перепрошить с помощью OpenWRT и т. д., он также сможет выполнять маршрутизацию).
решение3
Нет, добавления правил NAT недостаточно. Поскольку обнаружение хостов IPv4 в локальной сети (сегмент широковещательной рассылки) работает с использованием ARP. Широковещательный трафик ARP не будет проходить через ваш внутренний блок NAT, и блок NAT также не будет отвечать. Чтобы заставить его отвечать, вам нужно proxy_arp
.
Однако неясно, чего можно добиться с помощью такой настройки. Просто поместить все в одну сеть или добавить маршруты к ПК (вместо маршрутизатора) и МАСКАРАДИТЬ только на внешний маршрутизатор.