По сути, у меня проблема с маршрутизацией, и я недостаточно хорошо разбираюсь в маршрутизации и iptables, чтобы эффективно устранять неполадки и настраивать свои сетевые потребности.
Что работает?
У меня настроена и работает сеть OpenVPN; клиенты могут подключаться к локальной сети через Интернет.
Что бы я хотел, чтобы произошло
...когда клиент подключается к VPN в заданной подсети.
- Клиент должен быть доступен из сети VPN.
Бонусные баллы, если правила позволяют сделать одно или несколько из следующих:
- клиент не должен иметь возможности инициировать подключения к VPN
- клиент должен отображаться в нашем DNS
Топология
Топология нашей сети выглядит примерно так:
______ ____________________
/ \ / \
| internet |---| client (10.8.8.0/24) |
\________/ \____________________/
|
______
/ \
| gateway |
\________/
|
-----LAN------ (10.10.10.0/24)
| | | |
L_____VPN Server `VPN1` 10.10.10.2 (fictional name/subnet)
текущие настройки
Для нашего шлюза определен следующий маршрут:
10.8.8.0 255.255.255.0 10.10.10.2 LAN & WLAN
В VPN1
iptables есть следующие правила
# Flush the filter and nat tables
iptables -t filter -F
iptables -t nat -F
iptables -A INPUT -i tun+ -j ACCEPT
iptables -A FORWARD -i tun+ -j ACCEPT
iptables -A INPUT -i eth0 -j ACCEPT -d 10.8.8.0/24
iptables -A FORWARD -i eth0 -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.10.10.0/16 -d 10.8.8.0/24 -o tun+ -j MASQUERADE
Что происходит в настоящее время
Выполнение команды mtr 10.8.8.1
(IP-адрес подключенного клиента в VPN) показывает, что текущий маршрут колеблется между VPN1 и шлюзом.
решение1
После очередного изнурительного раунда безумного онлайн-изучения iptables я нашел решение.
Во-первых, однако, есть неверное предположение относительно iptables. Мой первоначальный подход к правилам заключался в том, что при получении пакета он должен был пройти через цепочки INPUT и OUTPUT. Это не так; в ту минуту, когда правило соответствует пакету, оно покидает таблицу. Поскольку таблица фильтров предполагается, если не указано иное (например, "-t nat"), большинство перечисленных правил выполняются на таблице фильтров.
О цепях
- ВХОД: запускать пакеты, предназначенные для сервера
- ВЫХОД: запускается на пакетах, исходящих от сервера
- ВПЕРЕД: все остальное - если правило здесь совпадает, и "прыжок" (мне нравится думать, что если-джпоскольку "job" ;) имеет значение ACCEPT, пакет будет маршрутизирован соответствующим образом
Разбивка правил
Это описание правил, изложенных втекущие настройкивыше
iptables -t filter -F
iptables -t nat -F
Эти правила просто смываютфильтринаттаблицы. Обратите внимание, что есть больше таблиц и более тщательный способ очистки правил iptables.
iptables -A INPUT -i tun+ -j ACCEPT
Это правило ничего не делает, потому что:
- он работает с трафиком, предназначенным для VPN1, а не для другой сети
- для входящего трафика не установлена политика, поэтому по умолчанию он разрешен
двигаемся дальше...
iptables -A FORWARD -i tun+ -j ACCEPT
Это правило позволяет маршрутизировать трафик, поступающий с 10.8.8.0/24. Правила внаттаблица запускается на основе пакетов, соответствующих этому правилу.
iptables -A INPUT -i eth0 -j ACCEPT -d 10.8.8.0/24
Это правило также не влияет на желаемую маршрутизацию, поскольку трафик 10.8.8.0/24 не предназначен для сервера VPN1.
iptables -A FORWARD -i eth0 -j ACCEPT
Это правило позволяет маршрутизировать трафик с 10.10.10.0/16.
iptables -t nat -A POSTROUTING -s 10.10.10.0/16 -d 10.8.8.0/24 -o tun+ -j MASQUERADE
Это правило приводит к тому, что трафик, направляемый в VPN с адреса 10.10.10.0/16, выглядит так, как будто он пришел с VPN1, фактически заставляя VPN1 выглядеть как шлюз.
В чем дело?
Правила должны быть "OK", как и для передачи трафика из одной сети в другую. Никакой реальной защиты не предусмотрено - например, политики "DROP" по умолчанию и т. д., но это не суть вопроса.
Если iptables настроен так, что он может маршрутизировать трафик через VPN, что может привести к его отправке обратно черезeth0на шлюз? Если VPN1 не знал о 10.8.8.0/24. Если VPN-сервер не знал об этой сети, он бы рассматривался как интернет-трафик и отправлялся обратно на шлюз.
Исправление
Решением было сообщить VPN-серверу о сети (это сервер openvpn). Есть два способа сделать это; если сервер обслуживает только одну сеть, это простая настройка конфигурации:
server 10.8.8.0 255.255.255.0
В моем случае я настроил маршрут сервера, и мне нужно было, чтобы он знал о дополнительной сети. Конфигурация выглядела примерно так:
server 10.5.5.0 255.255.255.0
route 10.8.8.0 255.255.255.0
Вот и все! Как только VPN1 получил маршрут к сети, цепочка FORWARD может маршрутизировать трафик.
Лучшая настройка iptables
После очистки iptables лучшая конфигурация будет выглядеть примерно так:
# Forward established traffic so that (in the above case) VPN1 doesn't
# drop responses from the client, A.K.A. "the magic"
iptables -t filter -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -t filter -A FORWARD -s 10.10.10.0/16 -d 10.8.8.0/24 -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.10.10.0/16 -d 10.8.8.0/24 -j MASQUERADE
# Drop everything else that wants to be forwarded
iptables -P FORWARD DROP
Обратите внимание, что нет явных правил для трафика, исходящего из 10.8.8.0/24, что означает, что по умолчанию трафик не достигнет сети 10.10.10.0/16 — за исключением трафика в ответ на трафик, отправленный из 10.10.10.0/16. Теперь, когда iptables настроен, клиентам можно назначить IP в конфигурации VPN и добавить в DNS для полного решения.