Linux — two subnets, one interface, one gateway — NAT the additional subnet
We want to run some VMs (VirtualBox) on these servers. We can set them up to bridge onto the host’s eth0, but we cannot use addresses from the 10.0.0.0/24 range since they may be allocated in future. So we figured we’d use a different subnet:
Host1VM: eth0 192.168.0.1/24 (bridge to host eth0) Host2VM: eth0 192.168.0.2/24 (bridge to host eth0) Host3VM: eth0 192.168.0.3/24 (bridge to host eth0)
That’s fine and all the VMs can communicate with each other since they’re on the same subnet which uses the same physical interface. The issue we face is we need to give those VMs access to the internet via the 10.0.0.254 gateway. So we figured why not pick one of the hosts and use it as a router/NAT?
Host1: eth0 10.0.0.1/24, eth0:0 192.168.0.254/24
Now we can give the VMs a gateway of 192.168.0.254. The problem we then see is that Host1 doesn’t seem to NAT properly.
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o eth0 -j SNAT --to 10.0.0.1
I thought that would work, and we do see it matching packets. If a VM pings the internet, we see the ICMP packet come IN to Host1 (since it’s the router), and then the host re-sends the ICMP because it’s NAT’ing, the internet host responds back to the host — but then it dies there. I expected the host to then forward the packet back to the VM, but it doesn’t. What am I missing, or is this setup simply not possible? Edit: Just to clarify, we have no DENY rules within iptables, everything is default ACCEPT. We have also enable IP forwarding. Update1 — iptables Ignore the virbr0 — that’s not related to VirtualBox VMs
# Completed on Fri Sep 20 16:50:45 2013 # Generated by iptables-save v1.4.12 on Fri Sep 20 16:50:45 2013 *nat :PREROUTING ACCEPT [171383:10358740] :INPUT ACCEPT [1923:115365] :OUTPUT ACCEPT [192:21531] :POSTROUTING ACCEPT [169544:10254463] -A POSTROUTING -s 192.168.0.0/24 -o eth0 -j SNAT --to-source 10.0.0.1 COMMIT # Completed on Fri Sep 20 16:50:45 2013 # Generated by iptables-save v1.4.12 on Fri Sep 20 16:50:45 2013 *filter :INPUT ACCEPT [96628707:25146145432] :FORWARD ACCEPT [195035595:22524430122] :OUTPUT ACCEPT [44035412:304951330498] -A INPUT -i virbr0 -p udp -m udp --dport 53 -j ACCEPT -A INPUT -i virbr0 -p tcp -m tcp --dport 53 -j ACCEPT -A INPUT -i virbr0 -p udp -m udp --dport 67 -j ACCEPT -A INPUT -i virbr0 -p tcp -m tcp --dport 67 -j ACCEPT -A FORWARD -d 192.168.122.0/24 -o virbr0 -m state --state RELATED,ESTABLISHED -j ACCEPT -A FORWARD -s 192.168.122.0/24 -i virbr0 -j ACCEPT -A FORWARD -i virbr0 -o virbr0 -j ACCEPT -A FORWARD -o virbr0 -j REJECT --reject-with icmp-port-unreachable -A FORWARD -i virbr0 -j REJECT --reject-with icmp-port-unreachable COMMIT # Completed on Fri Sep 20 16:50:45 2013 # Generated by iptables-save v1.4.12 on Fri Sep 20 16:50:45 2013 *mangle :PREROUTING ACCEPT [291641356:47665886851] :INPUT ACCEPT [96628707:25146145432] :FORWARD ACCEPT [195035595:22524430122] :OUTPUT ACCEPT [44035838:304951365412] :POSTROUTING ACCEPT [239078922:327477732680] -A POSTROUTING -o virbr0 -p udp -m udp --dport 68 -j CHECKSUM --checksum-fill -A POSTROUTING -o virbr0 -p udp -m udp --dport 68 -j CHECKSUM --checksum-fill COMMIT # Completed on Fri Sep 20 16:50:45 2013
16:58:37.189758 IP 192.168.0.2 > 74.125.128.106: ICMP echo request, id 1, seq 2, length 40 16:58:37.189805 IP 10.0.0.1 > 74.125.128.106: ICMP echo request, id 1, seq 2, length 40 16:58:37.194607 IP 74.125.128.106 > 10.0.0.1: ICMP echo reply, id 1, seq 2, length 40 (no final reply back to the VM)
Маршрутизация в Linux
Эта статья одна из статей про работу сетей в Linux. Вы уже знаете, что все данные в сети передаются в виде пакетов, а чтобы компьютер знал куда нужно отправить тот или иной пакет используются IP адреса. Но пакету, перед тем, как он достигнет точки назначения нужно пройти множество компьютеров и маршрутизаторов.
Каждому из маршрутизаторов нужно знать на какой компьютер передавать пакет дальше. Именно это мы и обсудим в этой статье. Сегодня нас будет интересовать маршрутизация в Linux, как это работает, как настроить правила и заставить все работать как нужно.
Сетевые маршруты в Linux
Как я уже сказал, сетевые маршруты необходимы чтобы компьютеры могли определить по какой цепочке должен пойти пакет, чтобы достигнуть цели. Маршруты можно настроить на уровне интерфейса или маршрутизатора.
Когда компьютеру нужно отправить пакет в сеть он смотрит таблицу маршрутизации, в ней указанны ip адреса пунктов назначения и адреса интерфейсов и роутеров в домашней сети, которые могут отправить пакет по нужному адресу. Если для цели маршрут не указан то используется так называемый шлюз по умолчанию или маршрут по умолчанию. Точно такая же картина наблюдается на роутере. Устройство смотрит на IP адрес назначения и сверяет его со своей таблицей маршрутизации, а потом отправляет дальше.
Ниже мы рассмотрим как проверить текущие маршруты в системе, а также как настроить новые.
Как посмотреть таблицу маршрутизации
Перед тем как что-либо менять, нужно понять какие правила уже используются. В Linux для этого существует несколько команд. Чтобы посмотреть таблицу маршрутизации можно использовать команду route:
Вот так выглядит таблица маршрутизации linux. Тут выводится достаточно простая информация, которой не всегда достаточно чтобы понять суть дела. Более подробно можно посмотреть с помощью команды routel:
Тут вы уже можете видеть IP адрес цели (target), IP адрес шлюза (gateway), IP отправителя (source), протокол, и даже сетевой интерфейс. Но самый удобный способ посмотреть таблицу маршрутизации linux — это команда ip:
Вывод похож на результат предыдущей команды, но выглядит не совсем привычно, это потому, что вывод команды можно использовать в качестве аргумента для ip route add или ip route del. Это очень удобно. Как вы видите, в качестве шлюза по умолчанию везде используется 192.168.1.1. Рассмотрим подробнее что означает вывод этой команды:
- default — в данной строке означает вариант по умолчанию. Здесь должен быть ip адрес цели или маска подсети;
- via 192.168.1.1 — указывает через какой шлюз мы можем добраться до этой цели, у нас это 192.168.1.1;
- dev enp2s0 — сетевой интерфейс, с помощью которого будет доступен этот шлюз;
- proto static — означает, что маршрут был установлен администратором, значение kernel значит что он был установлен ядром;
- metric — это приоритет маршрута, чем меньше значение — тем выше приоритет.
А теперь рассмотрим выполняется настройка маршрутов Linux.
Настройка маршрутов в Linux
Вы можете настраивать таблицу маршрутизации с помощью команды ip. Например, чтобы изменить маршрут по умолчанию достаточно выполнить:
ip route add default via 192.168.1.1
Так вы можете добавить маршрут для любого IP адреса, например, для 243.143.5.25:
sudo ip route add 243.143.5.25 via 192.168.1.1
Все очень просто, сначала указывается IP адрес цели, а затем шлюз в локальной сети, через который можно достичь этого адреса. Но такие маршруты будут активны только до перезагрузки, после перезагрузки компьютера они будут автоматически удалены. Чтобы маршруты сохранились их нужно добавить в файл конфигурации.
В операционных системах семейства Red Hat используются конфигурационные файлы /etc/sysconfig/network-scripts/route-ethX. Каждый файл может описывать несколько маршрутов, например:
GATEWAY=10.10.0.1
NETMASK=255.0.0.0
IPADDR=10.10.0.22
Здесь gateway — шлюз по умолчанию для этого интерфейса, netmask — маска сети, а ipaddr — ip адрес интерфейса. В Debian и основанных на нем дистрибутивах можно настроить маршруты в файле /etc/network/interfaces. Здесь команда route добавляется в секцию iface. Например:
up route add -net 10.10.0.0 netmask 255.0.0.0 gw 10.10.0.1
С помощью опции -net мы указываем целевую сеть, netmask — это маска сети, а gw — шлюз. Все очень просто. Теперь добавленные маршруты останутся даже после перезагрузки.
Выводы
В этой небольшой статье мы кратко рассмотрели как работает маршрутизация в Linux, как выполняется настройка маршрутизации в linux, а также зачем это нужно. Надеюсь, эта информация была полезной для вас.
Обнаружили ошибку в тексте? Сообщите мне об этом. Выделите текст с ошибкой и нажмите Ctrl+Enter.
How can I use Linux as a Gateway?
NOTE: If client devices ( computer B in this example) want to obtain internet through the gateway computer, maybe they still need to configure nameserver resolution. This is not explained here (a gateway does not necessarily serve internet).
I am trying to understand the fundamentals of networks routing.
So I am experimenting with my LAN (I don’t need internet for now, just LAN communications). I know the network configuration matters are a rather complex thing, but I am just trying to make a computer (say A) to act as a gateway for another (say B) (both running Ubuntu Linux).
I only need B to be capable to reach the router, that is only reachable for A. This is the case:
Router for computer A --> 192.168.0.1 Computer A - eth0 --> 192.168.0.2 Computer A - eth1 --> 192.168.1.1 Computer B - eth0 --> 192.168.1.2
Computer A connects fine to router.
Computer A and B connect fine (ping, SSH. etc) between them.
Computer B can not reach the router for computer A. I was thinking that just adding on B Computer A as default gateway and activating IP Forwarding on A would make B to be able to reach the router for A:
luis@ComputerB:~$ sudo route add default gw 192.168.1.1 luis@ComputerB:~$ sudo routel target gateway source proto scope dev tbl 127.0.0.0 broadcast 127.0.0.1 kernel link lo local 127.0.0.0 8 local 127.0.0.1 kernel host lo local 127.0.0.1 local 127.0.0.1 kernel host lo local 127.255.255.255 broadcast 127.0.0.1 kernel link lo local 192.168.1.0 broadcast 192.168.1.2 kernel link eth0 local 192.168.1.2 local 192.168.1.2 kernel host eth0 local 192.168.1.255 broadcast 192.168.1.2 kernel link eth0 local default 192.168.1.1 eth0 169.254.0.0 16 link eth0 192.168.1.0 24 192.168.1.2 kernel link eth0
root@ComputerA:~$ echo 1 > /proc/sys/net/ipv4/ip_forward
luis@ComputerB:~$ ping 192.168.0.1 PING 192.168.0.1 (192.168.0.1) 56(84) bytes of data. ^C
(No ping response) Is this the correct procedure to make a computer running Linux to act as a gateway for another computer in a simple manner?