Responder na mesma interface que a entrada com o DNATed IP

3

Um servidor tem 3 ifaces, 2 interno (eth1 / 2) em diferentes redes públicas, um externo (eth0).

Existe um serviço (openvpn) que não pode se ligar a alguns IPs / ifaces, apenas a todos ou a um, mas eu preciso que ele aceite conexões (UDP) somente em ifaces internos. O padrão gw é através do externo.

Eu tenho uma configuração de trabalho com duas instâncias do serviço, vinculado aos IPs de cada iface interno e roteamento definido com iproute2 ( ip route add xxx table x , ip rule add from <IP> table x ).

É possível DNAT a conexão de entrada na segunda iface interna (eth2) para o IP da primeira iface interna (eth1) e fazê-la responder através da mesma interface (eth2)? Neste caso, não seria necessário executar a segunda instância do serviço e manter 2 configurações idênticas com a única diferença do IP para escutar.

O problema é que, se eu alterar (com DNAT) o IP de destino da conexão de entrada na eth2 para o IP da eth1, a regra de IP baseada em from <IP> não funcionará. Ou, melhor dizendo, ele fará com que o serviço responda via eth1, não eth2, usando o padrão gw da eth1.

É possível definir com eficiência todos os pacotes de saída da "sessão" (UDP) DNATed, para que eu possa usar fwmark na regra ip? Alguma outra solução para o problema principal?

    
por Anatoli 25.03.2014 / 12:54

1 resposta

1

Encontrou uma solução. Esta solução deve funcionar para qualquer serviço linux que não possa escutar em interfaces específicas, mas apenas em todos (0.0.0.0) ou um particular, como MySQL, OpenVPN e muitos outros. Então, fazemos com que o serviço ouça um iface e adicione as regras do netfilter / iproute2 para redirecionar todas as solicitações para o mesmo protocolo e porta em outro iface para o nosso serviço no primeiro iface.

A "sessão" (apesar de ser UDP no caso do OpenVPN) é mantida pelo netfilter, e há um módulo conntrack que permite fazer referência a pacotes de uma sessão específica. Neste caso, adicionei uma regra para OUTPUT na tabela mangle para marcar todos os pacotes das sessões DNATed com uma marca. E então eu uso essa marca para rotear os pacotes.


Então, os comandos são:

Defina as variáveis

iface_int2=eth2         # the second internal iface
ip_int2=xx.xx.xx.xx     # the IP of the second internal iface
proto=udp               # the protocol of the connection
service_port=1194       # the incoming service port
ip_int1=yy.yy.yy.yy     # the IP of the first internal iface
ip_gw2=xx.xx.xx.1       # the IP of the default gateway for the second internal iface



Este comando instrui o netfilter a sobrescrever o IP de destino das conexões recebidas em nosso segundo iface.

iptables -t nat -A PREROUTING -i $iface_int2 -d $ip_int2 -p $proto --dport \
$service_port -j DNAT --to $ip_int1



Este comando instrui o netfilter a definir os pacotes de saída (a resposta do serviço) da conexão de entrada sobrescrita (DNATed). --ctorigdst é o IP de destino original (pré-DNATed) da conexão de entrada

iptables -t mangle -A OUTPUT -p $proto --sport $service_port -m conntrack \
--ctstate DNAT --ctorigdst $ip_int2 -j MARK --set-mark 0x75



Este comando instrui o iproute2 a rotear os pacotes marcados através das definições de rota da tabela 100. Prio é necessário para definir a prioridade mais alta para esta regra, já que é muito específica e não interfere outras regras. Se o prio não for especificado, as regras de roteamento para o primeiro iface interno poderão ter maior prioridade.

ip rule add prio 10 fwmark 0x75 table 100



Este comando adiciona um gateway padrão à tabela 100

ip route add default via $ip_gw2 table 100



Para que tudo isso funcione, é necessário diminuir a aderência do filtro do caminho de retorno no segundo iface interno.

# rp_filter - INTEGER
#   0 - No source validation.
#   1 - Strict mode as defined in RFC3704 Strict Reverse Path
#       Each incoming packet is tested against the FIB and if the interface
#       is not the best reverse path the packet check will fail.
#       By default failed packets are discarded.
#   2 - Loose mode as defined in RFC3704 Loose Reverse Path
#       Each incoming packet's source address is also tested against the FIB
#       and if the source address is not reachable via any interface
#       the packet check will fail.

echo 2 > /proc/sys/net/ipv4/conf/$iface_int2/rp_filter
# -OR-
sysctl -w "net.ipv4.conf.$iface_int2.rp_filter=2"
# -OR-
echo "net.ipv4.conf.$iface_int2.rp_filter=2" >> /etc/sysctl.conf
sysctl -p /etc/sysctl.conf
    
por 26.03.2014 / 00:26