Estoy intentando configurar un DNAT en mi nuevo centos 8 usando nftables. Esta utilidad (y centos 8) es nueva para mí, he estado usando iptables (centos a 6) durante años.
Mi suposición es que no configuré algo correctamente para que DNAT se active, sin embargo, es posible que simplemente no esté usando las herramientas correctamente. O ambos.
De todos modos, en caso de que sea importante, aquí hay una pregunta mía anterior sobre algunos problemas de enrutamiento en el mismo cuadro:Múltiples conexiones a Internet, paquetes entrantes en un puerto NIC incorrecto (¿problema de enrutamiento entrante?)(El problema era un flujo ARP, resuelto).
A continuación se muestra un boceto de mi configuración actual y la línea azul marca lo que quiero que suceda (la "ruta" esperada)
Básicamente, los paquetes provienen de Internet, pasan por la interfaz 2 (ens2), se ADNan a través de la interfaz local (ens5, IP local 192.168.1.10) a 192.168.1.2. (Una vez que esto funcione, se configurará lo mismo para los ens 3 y 4, yendo a un par de máquinas virtuales diferentes en la misma LAN)
He verificado que los paquetes llegan a la interfaz correcta (el registro nft esperado se activa), sin embargo, conntrack -E
no muestra nada.
Además, el registro de iptables en el cuadro de centos 6 (el objetivo real, 192.168.1.2) no muestra nada (el mismo registro implementado hace años mostraba el resultado esperado la última vez que marqué, hace unos meses, por lo que ese cuadro en teoría debería estar bien)
Aquí está mi script de nftables tal como está en este momento, con las IP/IF traducidas para que coincidan con el boceto.
table ip nat {
chain PREROUTING {
type nat hook prerouting priority -100; policy accept;
iif "ens2" goto PREROUTING_RDS2
iif "ens3" goto PREROUTING_RDS3
}
chain PREROUTING_RDS2 {
tcp dport { http, https } log prefix "RDS2_dnat-3 "
tcp dport { http, https } dnat to IP_6
}
chain PREROUTING_RDS3 {
tcp dport { http, https } log prefix "RDS3_dnat-3 "
tcp dport { http, https } dnat to IP_6
}
}
table inet filter {
chain INPUT {
type filter hook input priority 0; policy drop;
#
iif "lo" accept
#
# allow ping
ip protocol icmp icmp type echo-request limit rate 1/second log prefix "PING "
ip protocol icmp icmp type echo-request limit rate 1/second accept
# following is required and must be BEFORE the ct state established otherwise the ping flooding will not be stopped
ip protocol icmp drop
#
ct state established,related accept
ct status dnat accept
#
iifname "ens5" goto INPUT_LOCAL
#
# now we drop the rest
ct state invalid log prefix "INPUT_STATE_INVALID_DROP: "
ct state invalid drop
log prefix "INPUT_FINAL_REJECT: "
reject with icmpx type admin-prohibited
}
chain FILTER {
type filter hook forward priority 50; policy drop;
iif "ens2" goto FILTER_RDS2
iif "ens3" goto FILTER_RDS3
}
chain INPUT_LOCAL {
tcp dport ssh goto INPUT_LOCAL_ssh
}
chain INPUT_LOCAL_ssh {
ip saddr IP_MY_PC accept
}
chain FILTER_RDS2 {
oifname "ens5" ip daddr IP_6 tcp dport { http, https } accept
}
chain FILTER_RDS3 {
oifname "ens5" ip daddr IP_6 tcp dport { http, https } accept
}
}
Gracias de antemano.
Respuesta1
En realidad, esta pregunta es difícil de responder sin echar un buen vistazo a lapreguntas y respuestas anterioresresolviendo la configuración inicial paracentos8. La solución se vuelve muy compleja. Teniendo en cuenta el tipo de configuración que se debe implementar para esto, probablemente no valga la pena tener una IP por interfaz, con múltiples interfaces en la misma LAN, en lugar de todas las IP en la misma interfaz, especialmente considerando que se trata de un entorno virtual: hay No habrá ninguna aceleración. Cualquier cambio en la configuración deberá reflejarse en todos los comandos siguientes, por lo que gestionarlo correctamente será difícil.
centos8enrutador
Dado que para resolver el problema de múltiples interfaces en la misma LAN existen tablas de enrutamiento adicionales, ahora que en esta sesión de preguntas y respuestascentos8está actuando como un enrutador, se deben duplicar más entradas de ruta desde la tabla principal a las tablas de enrutamiento adicionales:
# ip route add 192.168.1.0/24 dev ens5 table 1001 src 192.168.1.10
# ip route add 192.168.1.0/24 dev ens5 table 1002 src 192.168.1.10
# ip route add 192.168.1.0/24 dev ens5 table 1003 src 192.168.1.10
# ip route add 192.168.1.0/24 dev ens5 table 1004 src 192.168.1.10
de lo contrario, cualquier paquete recibido enens1,ens2,ens3oens4yADNed a través deens5fallaráfiltro de ruta inversaya que no hay ruta a travésens5en esas mesas.
Por supuesto, eso no es suficiente: no hay información en los paquetes de respuesta (por ejemplo: volver decentos6) sobre qué interfaz se utilizó y debería reutilizarse al revés. Por lo tanto, esta información debe memorizarse por flujo, utilizando el conntrack de netfilter. En las reglas de nftables, elimine toda la ip nat
tabla:
# nft delete table ip nat
y reemplácelo con esta nueva tabla ip markandnat
:
# nft -f - << 'EOF'
table ip markandnat {
map iif2mark {
type iface_index : mark;
elements = {
ens1 : 101,
ens2 : 102,
ens3 : 103,
ens4 : 104
}
}
map mark2daddr {
type mark : ipv4_addr;
elements = {
102 : 192.168.1.2,
103 : 192.168.1.2, # same IP, as per OP's config
104 : 192.168.1.4 # some other VM
}
}
chain premark {
type filter hook prerouting priority -150; policy accept;
meta mark set ct mark meta mark != 0 return
meta mark set iif map @iif2mark meta mark != 0 ct mark set meta mark
}
chain prenat {
type nat hook prerouting priority -100; policy accept;
tcp dport { http, https } dnat to meta mark map @mark2daddr
}
}
EOF
Esto asignará la interfaz => marca => destino dnat, mientras guarda la marca como marca de conntrack (consulte el enlace al final sobremarca de connmarkuso). Ahora esta marca estará disponible y será utilizada por la pila de enrutamiento agregando las reglas a continuación, para apuntar a las mismas tablas de enrutamiento adicionales:
# ip rule add pref 11001 fwmark 101 table 1001
# ip rule add pref 11002 fwmark 102 table 1002
# ip rule add pref 11003 fwmark 103 table 1003
# ip rule add pref 11004 fwmark 104 table 1004
pero todavía falta una parte: nuevamente sobre el filtro de ruta inversa. Cuando las marcas están en uso, el filtro de ruta inversa no vuelve a verificar usando las nuevas rutas alteradas por las marcas y generalmente falla la verificación. En realidad hay unCaracterística no documentada, agregada en el kernel 2.6.33/2.6.32.8 en 2009/2010., lo que resuelve este problema, sin la necesidad de utilizar el modo de ruta inversa flexible: src_valid_mark
.
# sysctl -w net.ipv4.conf.ens1.src_valid_mark=1
# sysctl -w net.ipv4.conf.ens2.src_valid_mark=1
# sysctl -w net.ipv4.conf.ens3.src_valid_mark=1
# sysctl -w net.ipv4.conf.ens4.src_valid_mark=1
centos6servidor
Si desea utilizar una puerta de enlace alternativa temporalmente, incluso si eso vuelve a agregar complejidad y probablemente efectos secundarios sutiles imprevistos, es posible, nuevamente usando marcas. Como es CentOS 6,nftablesno está disponible, entoncesiptablesse utilizará.
Consideraré que elcentos6VM tiene IP 192.168.1.2/24 en la interfaz (única)eth0y gw predeterminado 192.168.1.1. Agreguemos una nueva tabla de enrutamiento y regla para la puerta de enlace alternativa 192.168.1.10:
# ip route add table 10 default via 192.168.1.10
# ip rule add fwmark 10 lookup 10
Pon eliptablesreglas (aquí sólo elmutilarse necesita tabla):
# iptables-restore << 'EOF'
*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A PREROUTING -j CONNMARK --restore-mark
-A PREROUTING -m mark ! --mark 0 -j RETURN
-A PREROUTING -i eth0 -p tcp -m tcp --dport 80 -j MARK --set-mark 10
-A PREROUTING -i eth0 -p tcp -m tcp --dport 443 -j MARK --set-mark 10
-A PREROUTING -m mark ! --mark 0 -j CONNMARK --save-mark
-A OUTPUT -m connmark ! --mark 0 -j CONNMARK --restore-mark
COMMIT
EOF
Ahora cualquier flujo recibido en los puertos 80 o 443 marcará los paquetes entrantes y sus respuestas. Esta marca será utilizada por la pila de enrutamiento para cambiar la puerta de enlace a 192.168.1.10 para entradas y respuestas (destrozar/SALIDAactiva una verificación de redireccionamiento, consulte el segundo enlace a continuación).
Parece que no es necesario usarlo src_valid_mark
en este caso, pero simplemente configúrelo o configúrelo rp_filter=2
si no funciona. Esta configuración no permitirá recibir tambiénADNtráfico ed a través de 192.168.1.1.
Algunos enlaces:
Respuesta2
A juzgar por los comentarios, la omisión más inmediata e importante es desactivar el reenvío de IP. Justo:
echo 1 > /proc/sys/net/ipv4/ip_forward
y verifique si ahora los paquetes DNAT llegan a IP6.
El segundo problema es el enrutamiento asimétrico. Los paquetes DNATted llegan a IP6 a través de 192.168.1.10 (IP5) donde se modifican (se altera la dirección de destino). Los paquetes de retorno pasarán por la puerta de enlace predeterminada en la LAN (182.168.1.1) y no se modificarán en la ruta al origen de la conexión. Probablemente mantendrán su dirección RFC1918 o se les asignará SNAT a algo diferente en 192.168.1.1 y nunca coincidirán con ninguna conexión en su destino y probablemente se desconectarán.
EDITAR:
Entonces, para abordar la cadena ADELANTE, la reescribiría de la siguiente manera (mucho más simple en mi humilde opinión):
table inet filter {
:
chain FORWARD {
type filter hook forward priority 0; policy drop;
ct state established,related accept
ct status dnat accept
}
:
}