Source-MAC Filtro iptables

2

Eu tenho uma caixa HAProxy com centos7 e faço proxy de balanceamento de carga para um cluster smtp que fornece retransmissão de email para nossos clientes.

default gateway => 10.0.0.1
master-relay.example.net => 10.0.0.254
relay1.example.net => 10.0.0.10 | gateway 10.0.0.1
relay2.example.net => 10.0.0.11 | gateway 10.0.0.1
relay3.example.net => 10.0.0.12 | gateway 10.0.0.1

Cada relé tem o postfix configurado para escutar nas portas 25 e 587.

O que eu preciso alcançar é quando alguém tenta enviar um e-mail conectando-se diretamente a um dos três relés (relé1, relé2 ou relé3) e encaminha os pacotes de resposta para o gateway padrão. Geralmente, isso ocorre quando qualquer servidor de email externo tenta nos enviar um email e se conecta aleatoriamente a um dos três servidores MX com a mesma prioridade.

MAS, quando um cliente móvel ou de webmail se conecta ao cluster para retransmitir um email que ele faz para retransmissão-mestre e este se conecta a um dos três servidores MX para entregar o email.

Esta é a configuração do HAProxy para o cluster:

# Puerto 25 - SMTP (Postfix Cluster)
frontend frontend-smtp-25
        bind 10.0.0.254:25 transparent
        option tcplog
        default_backend backend-smtp-25

backend backend-smtp-25
        option tcplog
        source 0.0.0.0 usesrc clientip
        server mx1 10.0.0.10:25 check
        server mx2 10.0.0.11:25 check
        server mx3 10.0.0.12:25 check

# Puerto 587 - STARTTLS (Postfix Cluster)
frontend frontend-smtp-587
        bind 10.0.0.254:587 transparent
        option tcplog
        default_backend backend-smtp-587

backend backend-smtp-587
        option tcplog
        source 0.0.0.0 usesrc clientip
        server mx1 10.0.0.10:587 check
        server mx2 10.0.0.11:587 check
        server mx3 10.0.0.12:587 check

Parâmetros do kernel:

net.ipv4.tcp_tw_reuse
net.ipv4.tcp_tw_recycle
net.ipv4.ip_local_port_range = 1025 65535

net.ipv4.ip_nonlocal_bind = 1
net.ipv4.ip_forward = 1

Regras do firewall:

iptables -t mangle -N DIVERT
iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT
iptables -t mangle -A DIVERT -j MARK --set-mark 1
iptables -t mangle -A DIVERT -j ACCEPT
ip rule add fwmark 1 lookup 100
ip route add local 0.0.0.0/0 dev lo table 100

Agora, com esta configuração, se eu alterar o gateway padrão das minhas caixas de retransmissão para as retransmissões-mestre, tudo corre bem e no log do postfix eu posso ver o endereço IP do cliente e não o do retransmissor-mestre, mas aqui eu tenho problema, se alguém se conecta diretamente ao relay1, por exemplo, este responde através do relé mestre e não através do gateway e o cliente descarta o pacote porque não vem da caixa relay1.

O que eu estava tentando fazer é marcar o endereço MAC de origem do relé mestre em todas as 3 caixas de relés e todas as que correspondem às marcas mudam o gateway padrão para o do mestre-relay.

Todos os IPs são IP públicos e todos são visíveis na Internet.

O que eu posso fazer é colocar 2 IP's na mesma interface e se algum pacote chegar ao IP1 então responder a um gateway e se for IP2 responder ao outro gateway mas eu realmente prefiro as regras do mac se for possível.

Não consigo fazer uma regra para forçar que, se os pacotes vierem do endereço IP de retransmissão-mestre, responda a ele novamente porque ele chegará ao proxy com o endereço IP do cliente.

Obrigado antecipadamente

    
por Radu Radu 30.08.2018 / 16:33

1 resposta

0

Aqui estão as metas e os meios para um relé (ou seja, relay1 , relay2 ou relay3 ) lidar corretamente com o tráfego proveniente de default-gateway ( 10.0.0.1 ) ou através do HAProxy master-relay ( 10.0.0.254 ) no modo transparente, agindo como um gateway:

  1. O relé deve usar o gateway normal default-gateway para o tráfego normal, ou seja:

    • tráfego iniciado localmente,
    • respostas de saída do tráfego iniciado remotamente que já passaram por default-gateway .
  2. O relé deve usar o gateway alternativo master-relay para o tráfego transmitido de forma transparente do HAProxy, portanto apenas para:

    • respostas de saída do tráfego iniciado remotamente que já passaram por master-relay agindo como um gateway alternativo.
  3. O seletor para distinguir o caso de roteamento 1. do caso 2. é o endereço MAC de origem do gateway alternativo master-relay . Digamos que 02:03:04:05:06:07 .

  4. A escolha, uma vez feita no primeiro pacote de uma conexão, deve permanecer a mesma para todos os outros pacotes parte desta conexão.

Isso requer roteamento de política, com uma tabela de roteamento alternativa ( ip route add table ... , uma decisão de roteamento adicional ( ip rule add fwmark... ) confiando em iptables usando o mac para o seletor de endereço MAC, o MARK destinado a alterar a decisão de roteamento e os CONNMARK alvo para memorizar a decisão para toda a conexão.

Caso 1. sendo o caso padrão sem manipulação especial e caso 2. a exceção, você deve reverter sua mudança de roteamento, para usar default-gateway como gateway padrão, como de costume:

ip route replace default via 10.0.0.1

O caso 2. será armazenado em uma tabela de roteamento alternativa. Não há necessidade de nomeá-lo, qualquer número é bom, vamos escolher 1000254 ( 254 foi reservado, é a tabela principal ...):

ip route add table 1000254 default via 10.0.0.254

A decisão de roteamento para usá-lo será acionada por um valor de marca (vindo de iptables ' MARK target'). Vamos escolher 254 :

ip rule add fwmark 254 lookup 1000254

Como pode ser visto em Fluxo de pacotes no Netfilter e na rede geral , uma regra iptables em mangle/PREROUTING ou mangle/OUTPUT pode definir uma marca antes que a decisão de roteamento (ou a verificação de reencaminhamento) seja feita. É assim que no final iptables mudará a rota. Então, para um único pacote de entrada, isso seria:

iptables -t mangle -A PREROUTING -m mac --mac-source 02:03:04:05:06:07 -j MARK --set-mark 254

Agora, para memorizá-lo para toda a conexão, ele deve ser agrupado com CONNMARK chamadas, que armazenam e recuperam a marca na entrada conntrack para este fluxo e permitem defini-lo apenas na primeira vez, sem esquecer a direção da SAÍDA. Algumas explicações estão neste blog: Para o Linux e além! Netfilter Connmark . Não há necessidade de marcar pacotes para o tráfego da LAN, então filtre (e isso pode ajudar quando usar conntrack -L no final). No final, incluindo a regra anterior, torna-se:

iptables -t mangle -A PREROUTING -j CONNMARK --restore-mark
iptables -t mangle -A PREROUTING -m mark ! --mark 0 -j RETURN
iptables -t mangle -A PREROUTING ! -s 10.0.0.0/24 -m mac --mac-source 02:03:04:05:06:07 -j MARK --set-mark 254
iptables -t mangle -A PREROUTING -j CONNMARK --save-mark
iptables -t mangle -A OUTPUT -j CONNMARK --restore-mark

É isso. Este caso nem requer configuração rp_filter para perder o modo porque existe apenas uma interface de rede envolvida.

Por favor, note que você pode facilmente inserir mais tabelas, regras e marcas para ter mais de um master-relay , caso precise de redundância (ou simplesmente adicione um MAC adicional a master-relay se seu IP mudar seu endereço MAC para qualquer razão). Exemplo para um HAProxy adicional com IP 10.0.0.250 e MAC 0A:09:08:07:06:05 :

ip route add table 1000250 default via 10.0.0.250
ip rule add fwmark 250 lookup 1000250
iptables -t mangle -I PREROUTING 4 ! -s 10.0.0.0/24 -m mac --mac-source 0A:09:08:07:06:05 -j MARK --set-mark 250

conntrack -L exibirá o connmark e poderá ser usado para distinguir se uma conexão veio por master-relay em vez do padrão, porque sua marca será 254 em vez de 0 :

# conntrack -L -s 198.51.100.1
tcp      6 431635 ESTABLISHED src=198.51.100.1 dst=10.0.0.10 sport=50230 dport=25 src=10.0.0.10 dst=198.51.100.1 sport=25 dport=50230 [ASSURED] mark=0 secctx=system_u:object_r:unlabeled_t:s0 use=1
tcp      6 431527 ESTABLISHED src=198.51.100.1 dst=10.0.0.10 sport=49554 dport=25 src=10.0.0.10 dst=198.51.100.1 sport=25 dport=49554 [ASSURED] mark=254 secctx=system_u:object_r:unlabeled_t:s0 use=1
conntrack v1.4.4 (conntrack-tools): 2 flow entries have been shown.
    
por 31.08.2018 / 02:55