Полностью открытый маршрутизатор FreeBSD в VirtualBox

Полностью открытый маршрутизатор FreeBSD в VirtualBox

TL;DR — я хотел бы настроить виртуальную машину FreeBSD с одной сетевой картой в домашней локальной сети (192.168.1.0/24) и одной в частной внутренней сети virtualbox (10.9.9.0/24) и передавать весь трафик туда и обратно между ними.

Давно пользуюсь Linux (Debian на серверах), но FreeBSD использую всего около дня :)

В любом случае, для моих экспериментов у меня есть машина virtualbox с 2 сетевыми интерфейсами - один подключен к моей домашней локальной сети, один - к внутренней сети. Эта машина настроена как маршрутизатор без блоков, просто передающий пакеты между eth0 и eth1 независимо от источника или назначения. Достаточно просто сделать с помощью iptables -

iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT
iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT

Но я пытался заставить это работать с pf, и у меня был лишь частичный успех.

С

gateway_enable="YES"
pf_enable="YES"
pf_rules="/etc/pf.conf"

в моем /etc/rc.confи /etc/pf.confсодержащий

pass from em1:network to any keep state
pass from em0:network to any keep state
pass in inet proto tcp to any keep state
pass in inet proto udp to any keep state
pass out inet proto tcp to any keep state
pass out inet proto udp to any keep state

Я могу запустить виртуальную машину Live Disc, подключенную только к внутренней системе, и установить IP-адрес em1 в качестве шлюза по умолчанию, а также выполнить ping em1, ping em0, но я не могу выполнить ping хост-машины, на которой запущен vbox, или любой другой машины в моей локальной сети или подключиться через http, ssh и т. д.

[root@bsdtest ~]# pfctl -sa
FILTER RULES:
pass in inet proto tcp all flags S/SA keep state
pass in inet proto udp all keep state
pass out inet proto tcp all flags S/SA keep state
pass out inet proto udp all keep state
pass inet from 10.9.9.0/24 to any flags S/SA keep state
pass inet from 192.168.1.0/24 to any flags S/SA keep state

STATES:
all tcp 192.168.1.90:22 <- 192.168.1.10:48102       ESTABLISHED:ESTABLISHED
all udp 192.168.1.2:53 <- 10.9.9.5:59075       NO_TRAFFIC:SINGLE
all udp 10.9.9.5:59075 -> 192.168.1.2:53       SINGLE:NO_TRAFFIC
all udp 192.168.1.2:53 <- 10.9.9.5:34207       NO_TRAFFIC:SINGLE
all udp 10.9.9.5:34207 -> 192.168.1.2:53       SINGLE:NO_TRAFFIC
all udp 192.168.1.2:53 <- 10.9.9.5:43515       NO_TRAFFIC:SINGLE
all udp 10.9.9.5:43515 -> 192.168.1.2:53       SINGLE:NO_TRAFFIC
all udp 192.168.1.2:53 <- 10.9.9.5:1636       NO_TRAFFIC:SINGLE
all udp 10.9.9.5:1636 -> 192.168.1.2:53       SINGLE:NO_TRAFFIC
all udp 192.168.1.2:53 <- 10.9.9.5:60124       NO_TRAFFIC:SINGLE
all udp 10.9.9.5:60124 -> 192.168.1.2:53       SINGLE:NO_TRAFFIC
all udp 192.168.1.2:53 <- 10.9.9.5:8866       NO_TRAFFIC:SINGLE
all udp 10.9.9.5:8866 -> 192.168.1.2:53       SINGLE:NO_TRAFFIC
all udp 192.168.1.2:53 <- 10.9.9.5:25534       NO_TRAFFIC:SINGLE
all udp 10.9.9.5:25534 -> 192.168.1.2:53       SINGLE:NO_TRAFFIC
all udp 192.168.1.2:53 <- 10.9.9.5:30141       NO_TRAFFIC:SINGLE
all udp 10.9.9.5:30141 -> 192.168.1.2:53       SINGLE:NO_TRAFFIC

INFO:
Status: Enabled for 0 days 00:08:28           Debug: Urgent

State Table                          Total             Rate
  current entries                       17               
  searches                            1990            3.9/s
  inserts                              253            0.5/s
  removals                             236            0.5/s
Counters
  match                                253            0.5/s
  bad-offset                             0            0.0/s
  fragment                               0            0.0/s
  short                                  0            0.0/s
  normalize                              0            0.0/s
  memory                                 0            0.0/s
  bad-timestamp                          0            0.0/s
  congestion                             0            0.0/s
  ip-option                              0            0.0/s
  proto-cksum                            0            0.0/s
  state-mismatch                         0            0.0/s
  state-insert                           0            0.0/s
  state-limit                            0            0.0/s
  src-limit                              0            0.0/s
  synproxy                               0            0.0/s
  map-failed                             0            0.0/s

TIMEOUTS:
tcp.first                   120s
tcp.opening                  30s
tcp.established           86400s
tcp.closing                 900s
tcp.finwait                  45s
tcp.closed                   90s
tcp.tsdiff                   30s
udp.first                    60s
udp.single                   30s
udp.multiple                 60s
icmp.first                   20s
icmp.error                   10s
other.first                  60s
other.single                 30s
other.multiple               60s
frag                         30s
interval                     10s
adaptive.start             6000 states
adaptive.end              12000 states
src.track                     0s

LIMITS:
states        hard limit    10000
src-nodes     hard limit    10000
frags         hard limit     5000
table-entries hard limit   200000

OS FINGERPRINTS:
758 fingerprints loaded
[root@bsdtest ~]# 

Есть идеи? Строки, касающиеся трафика udp на 192.168.1.2 с 10.9.9.5 (мой live disk) будут для DNS на моем домашнем сервере имен локальной сети, но ответы так и не приходят... Вот что показывает http-запрос -

[root@bsdtest ~]# pfctl -sa | grep 80
all tcp 192.168.1.10:80 <- 10.9.9.5:59436       CLOSED:SYN_SENT
all tcp 10.9.9.5:59436 -> 192.168.1.10:80       SYN_SENT:CLOSED
all tcp 192.168.1.10:80 <- 10.9.9.5:59438       CLOSED:SYN_SENT
all tcp 10.9.9.5:59438 -> 192.168.1.10:80       SYN_SENT:CLOSED

Идеи?

решение1

Хорошо, решение найдено.

Мой /etc/rc.conf в таком виде в порядке...

Файл /etc/pf.conf должен быть

# cat /etc/pf.conf

ext_if="em0"
int_if="em1"
boxnet = $int_if:network
homenet = $ext_if:network

nat on $ext_if from $boxnet to any -> ($ext_if)
pass quick from { lo0, $boxnet, $homenet } to any keep state

Наверное, слишком много переменных, я мог бы просто использовать оригинальные em0/em1. В любом случае, это дает вам -

[root@bsdtest ~]# pfctl -vnf /etc/pf.conf
ext_if = "em0"
int_if = "em1"
icmp_types = "echoreq"
boxnet = "em1:network"
homenet = "em0:network"
nat on em0:network inet from 10.9.9.0/24 to any -> 192.168.1.0/24
nat on em1:network inet from 192.168.1.0/24 to any -> 10.9.9.0/24
pass quick inet from 127.0.0.0/8 to any flags S/SA keep state
pass quick inet from 192.168.1.0/24 to any flags S/SA keep state

решение2

Ниже приведены некоторые догадки, поэтому будьте бдительны. Однако это очень типичная настройка, которая сбивает с толку многих людей, которые начинают с объединения маршрутизации, фильтрации пакетов (брандмауэр) и NAT (трансляции сетевых адресов).

Вы не говорите об этом четко, но я предполагаю, что ваша сеть выглядит следующим образом:

Internet <-A-> SOHO Router <-B-> Server/workstation <-C-> VM

Ваш DNS-сервер находится в сети B, которая имеет адрес 192.168.1.0/24.

Я предполагаю, что ваш маршрутизатор Internet SOHO имеет адрес 192.168.1.1 и установлен в качестве шлюза по умолчанию для сети. Это будет чрезвычайно распространенная настройка.

Вы сами утверждаете, что DNS-сервер находится на 192.168.1.2, а мостовой интерфейс сервера — 192.168.1.10. За ним у вас есть сеть 10.9.9.0/24.

Ваша настройка iptables перенаправитвсепакеты наинтерфейс. На практике вы отправляете все пакеты из одной сети в другую - даже локальные пакеты. Это важное различие.

В вашей конфигурации pf вы делаетенетвпередвсепакеты наинтерфейс. Вы указалисеть em1:network. У нас нет полной конфигурации, но я предполагаю, что у вас на самом деле хорошая и рабочая конфигурация barebone. Что вас кусает, так это отсутствующие маршруты.

Когда вы отправляете пакет из сети 10.9.9.0/24, он достигает сети 192.168.1.0/24. У вашего сервера есть ответвление в этой сети, поэтому вы напрямую доберетесь до своего DNS. Но DNS-сервер в сети B понятия не имеет, как добраться до нелокальной сети C 10.9.9.0/24. Все ответы затем будут отправлены на «маршрутизатор по умолчанию», который, как я предполагаю, является вашим маршрутизатором SOHO. Этот маршрутизатор также знает только, где найти сеть 192.168.1.0/24 (а не 10.9.9.0/24), и обычно направляет все на ваш внешний интернет-канал. В этом случае вы используете правильные частные адреса, поэтому пакет будет отброшен, поскольку частные адреса не маршрутизируются в Интернете.

«Правильным» решением было бы настроить маршрут на вашем маршрутизаторе SOHO, который сообщает ему о необходимости маршрутизации пакетов для 10.9.9.0/24 на 192.168.1.10. Приличный маршрутизатор позволит вам это сделать. Многие дешевые маршрутизаторы SOHO, к сожалению, не позволяют. В этом случае вы можете добавить маршрут на свой DNS-сервер, чтобы проверить его.

  • Причина, по которой это работает для вас с iptables, заключается в том, что ответный пакет виден на интерфейсе eth0, и все пакеты пересылаются. Весь трафик в сети B отправляется в сеть C (и обратно). Это включает трафик, который мог/должен был остаться локальным. По сути, вы настроили сетевой мост.
  • Причина, по которой это не работает у вас с первой настройкой pf, заключается в том, что вы указали, какую сеть вы ожидаете увидеть. Только одна машина в сети B знает, где найти сеть C. Это 192.168.1.10, поскольку у нее есть интерфейс в сети C. По сути, вы настроили базовый брандмауэр. Фильтрация готова, но вы пока ничего не фильтруете. Но маршрутизация отсутствует.
  • Причина, по которой это работает во второй конфигурации pf (ваш собственный ответ), заключается в том, что вы транслируете сеть 10.9.9.0/24 в адресное пространство 192.168.1.0/24. Весь трафик из сети C 10.9.9.0/24 в сети B будет выглядеть так, как будто он идет из 192.168.1.10.NAT следует избегатьвсегда, когда это возможно, и только в крайнем случае.

Если вам не нужно/не хочется фильтровать пакеты - тогда я бы посоветовал вам не использовать брандмауэр. То, что вы пытаетесь сделать, должно быть обработанопростая маршрутизация.

решение3

Если вы хотите иметь «все открытые» шлюзы, вы можете сделать это с помощью всего одного правила:

pass all allow-opts

Не потребовалось возиться ни с явным «сохранением состояния», ни с флагами.

Связанный контент