Enrutador FreeBSD totalmente abierto en VirtualBox

Enrutador FreeBSD totalmente abierto en VirtualBox

TL;DR: Me gustaría configurar una máquina virtual FreeBSD con una tarjeta de red en la LAN de mi casa (192.168.1.0/24) y otra en una red privada interna a virtualbox (10.9.9.0/24) y aprobar todo el tráfico de ida y vuelta entre los dos.

Usuario de Linux desde hace mucho tiempo (Debian en servidores), pero solo he estado usando FreeBSD durante aproximadamente un día :)

De todos modos, para mis cosas experimentales tengo una máquina virtualbox con 2 interfaces de red: una conectada a la LAN de mi casa y otra en una red solo interna. Esta máquina está configurada para ser un enrutador que no bloquea nada, simplemente pasando paquetes entre eth0 y eth1 sin importar el origen o el destino. Bastante fácil de hacer con iptables.

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

Pero he estado intentando que esto funcione con pf y solo estoy teniendo un éxito parcial.

Con

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

en mi /etc/rc.confy /etc/pf.confconteniendo

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

Puedo iniciar una máquina virtual de disco en vivo conectada solo a la interna y configurar la IP de em1 como puerta de enlace predeterminada, y poder hacer ping a em1, ping a em0, pero no puedo hacer ping a la máquina host en la que se ejecuta vbox ni a ninguna otra máquina en mi LAN o conectarse a través de http, ssh, etc.

[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 ~]# 

¿Algunas ideas? Las líneas relacionadas con el tráfico udp a 192.168.1.2 desde 10.9.9.5 (mi disco en vivo) serían para DNS al servidor de nombres de LAN de mi casa, pero nunca llegan respuestas... Esto es lo que muestra una solicitud 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

¿Ideas?

Respuesta1

Bien, solución encontrada.

Mi /etc/rc.conf está bien tal como está...

El /etc/pf.conf necesita ser

# 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

Probablemente demasiadas variables, podría usar el em0/em1 original. De todos modos, esto te da...

[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

Respuesta2

Algunas conjeturas a continuación, así que tenga cuidado. Sin embargo, es una configuración muy típica que confunde a muchas personas que comienzan combinando enrutamiento, filtrado de paquetes (firewall) y NAT (traducción de direcciones de red).

No lo dice claramente, pero supongo que su red se ve así:

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

Su servidor DNS está en la red B que es 192.168.1.0/24

Supongo que su enrutador SOHO de Internet es 192.168.1.1 y está configurado como puerta de enlace predeterminada para la red. Esta sería una configuración extremadamente común.

Usted mismo afirma que el servidor DNS está en 192.168.1.2 y la interfaz en puente del servidor es 192.168.1.10. Detrás de eso tienes la red 10.9.9.0/24.

Tu configuración de iptables se reenviarátodopaquetes en elinterfaz. En la práctica, envía todos los paquetes de una red a otra, incluso los paquetes locales. Ésa es la diferencia importante.

En tu configuración pf lo hacesnoadelantetodopaquetes en elinterfaz. Has especificado unred em1:network. No tenemos la configuración completa, pero supongo que en realidad tienes una configuración básica agradable y funcional. Lo que te muerde son las rutas perdidas.

Cuando envía un paquete desde 10.9.9.0/24, llegará a la red 192.168.1.0/24. Su servidor tiene acceso a esa red, por lo que accederá directamente a su DNS. Pero el servidor DNS de la red B no tiene idea de cómo llegar a la red C 10.9.9.0/24 no local. Luego, todas las respuestas se enviarán al "enrutador predeterminado", que supongo que es su enrutador SOHO. Este enrutador también sólo sabe dónde encontrar la red 192.168.1.0/24 (no 10.9.9.0/24) y normalmente enrutaría todo a su enlace externo de Internet. En este caso, está utilizando direcciones privadas adecuadas, por lo que el paquete se descartará ya que las direcciones privadas no se enrutan en Internet.

La solución "adecuada" sería configurar una ruta en su enrutador SOHO que le indique enrutar paquetes de 10.9.9.0/24 a 192.168.1.10. Un enrutador decente te permitirá hacer eso. Desafortunadamente, muchos enrutadores SOHO baratos no lo hacen. En ese caso, podrías agregar la ruta en tu servidor DNS para probarla.

  • La razón por la que funciona con iptables es que el paquete de respuesta se ve en la interfaz eth0 y todos los paquetes se reenvían. Todo el tráfico de la red B se envía a la red C (y viceversa). Esto incluye el tráfico que podría/debería haber permanecido local. De hecho, ha configurado un puente de red.
  • La razón por la que no funciona con su primera configuración de pf es que ha especificado qué red espera ver. Sólo una máquina en la red B sabe dónde encontrar la red C. Este es 192.168.1.10 ya que tiene una interfaz en la red C. De hecho, ha configurado un firewall básico. El filtrado está listo pero aún no filtra nada. Pero falta el enrutamiento.
  • La razón por la que funciona en su segunda configuración de pf (su propia respuesta) es que realiza una NAT de la red 10.9.9.0/24 en el espacio de direcciones de 192.168.1.0/24. Todo el tráfico de la red C 10.9.9.0/24 en la red B parecerá provenir de 192.168.1.10.NAT debe evitarsesiempre que sea posible y sólo se utilizará como último recurso.

Si no necesita/quiere filtrar paquetes, le recomendaría que no utilice un firewall. Lo que estás intentando hacer debe ser manejado porenrutamiento simple.

Respuesta3

Si buscaba tener una puerta de enlace "totalmente abierta", podría hacerlo con una sola regla:

pass all allow-opts

No era necesario meterse con el "mantener estado" explícito ni con las banderas.

información relacionada