iptables --set-mark - Rota diferentes portas através de diferentes interfaces

12

História curta

3 interfaces, eth0 (LAN), eth1 (ADSL), eth2 (4G).
eth0 - > eth1: Works
(portas 80, 443, 4070) eth0 - > eth2: não acontece


Esta é uma representação gráfica da ideia:

Porta 80 & 443 via eth2
e o resto via eth1

Netscheme:

eth0:-ip10.0.0.1-net10.0.0.0/8-gw10.0.0.1(theserversownintf)eth1:-ip192.168.1.74-net192.168.1.0/24-gw192.168.1.254eth2:-ip192.168.1.91-net192.168.0.0/24-gw192.168.0.1





Essenovoscriptredirecionao22eo4070paraatabelacorreta,euacho.
Noentanto,depoisdechegaraessamesa,elanãoéredirecionadaparaaeth2.



Estescriptfunciona,exceto22e4070!

(aporta80nãofoicomentadaefunciona,masviaeth1,queestáerrada.)

modprobeiptable_natmodprobeip_conntrackecho"1" > /proc/sys/net/ipv4/ip_forward

iptables -P INPUT ACCEPT
iptables -F INPUT
iptables -P OUTPUT ACCEPT
iptables -F OUTPUT
iptables -P FORWARD DROP
iptables -F FORWARD
iptables -F PREROUTING
iptables -t nat -F
iptables -t mangle -F
iptables -F
# This next line restores any issues trying to connect to something
# if you get weird ACK packets when trying to connect (at least i did)!
iptables -t mangle -A PREROUTING -p tcp -j CONNMARK --restore-mark
ip route flush table main

iptables -A PREROUTING -i eth0 -t mangle -p tcp --dport 22 -j MARK --set-mark 1
###  iptables -A PREROUTING -i eth0 -t mangle -p tcp --dport 80 -j MARK --set-mark 1
iptables -A PREROUTING -i eth0 -t mangle -p tcp --dport 4070 -j MARK --set-mark 1

## Setup routes
# LAN
route add -net 10.0.0.0 netmask 255.0.0.0 dev eth0
# ADSL
route add -net 192.168.1.0 netmask 255.255.255.0 dev eth1
# 4G (Only accessible if marking packages with \x01
route add -net 192.168.0.0 netmask 255.255.255.0 dev eth2
# Default via ADSL
## -- Does the same as ip route below? route add default gw 192.168.1.254


echo "201 eth2.out" >> /etc/iproute2/rt_tables

ip rule add fwmark 1 table eth2.out
ip route add default via 192.168.0.1 dev eth2 table eth2.out
ip route add default via 192.168.1.254 dev eth1



## Setup forwards
# From 4G to LAN
iptables -A FORWARD -i eth2 -o eth0 -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT
# From ADSL to LAN
iptables -A FORWARD -i eth1 -o eth0 -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT
# From LAN to ADSL (Default route out)
# - Note: If marked packages is sent to ADSL they will be mangled and rerouted to 4G
iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
iptables -t nat -A POSTROUTING -o eth2 -j MASQUERADE





Roteiro antigo:

  Ignore everything below unless you're interested in retracing my steps!!



Eu criei um script router.sh para configurar meu ambiente no caso de eu fazer algo ruim. Eu tenho 3 portas que eu quero enviar para uma conexão 4G e o resto através de uma conexão ADSL fixa. Para fazer isso, eu instrui o iptables para manipular pacotes na rota padrão e enviá-los através da minha interface 4G se o --dport == 443 | 80 | 4070

No entanto, isso não funciona; Ainda estou sendo encaminhado pelo meu telefone fixo, não importa o que aconteça.

É assim que meu script se parece:

#!/bin/bash

## routing tables
# wireless = 4G via eth2
# adsl = adsl via eth1

modprobe iptable_nat
modprobe ip_conntrack

echo "1" > /proc/sys/net/ipv4/ip_forward

iptables -P INPUT ACCEPT
iptables -F INPUT
iptables -P OUTPUT ACCEPT
iptables -F OUTPUT
iptables -P FORWARD DROP
iptables -F FORWARD
iptables -t nat -F
ip route flush table main
ip route flush table wireless
ip route flush table adsl

## Setup routing tables
# ADSL
ip route add table adsl to 192.168.1.0/24 dev eth1
# 4G
ip route add table wireless to 192.168.0.0 dev eth2
ip rule add fwmark 0x1 table wireless

## Setup routes
# LAN
route add -net 10.0.0.0 netmask 255.0.0.0 dev eth0
# ADSL
route add -net 192.168.1.0 netmask 255.255.255.0 dev eth1
# 4G (Only accessible if marking packages with \x01
route add -net 192.168.0.0 netmask 255.255.255.0 dev eth2
# Default via ADSL
route add default gw 192.168.1.254


## Forward ports into the LAN
iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -j DNAT --to 10.0.0.3:80


## Lets mark all packets we want for 4G forward
# HTTPS
iptables -A OUTPUT -t mangle -o eth1 -p tcp --dport 443 -j MARK --set-mark 1
# HTTP
iptables -A OUTPUT -t mangle -o eth1 -p tcp --dport 80 -j MARK --set-mark 1
# Spotify
iptables -A OUTPUT -t mangle -o eth1 -p tcp --dport 4070 -j MARK --set-mark 1

## Setup forwards
# From 4G to LAN
iptables -A FORWARD -i eth2 -o eth0 -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT
# From ADSL to LAN
iptables -A FORWARD -i eth1 -o eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
# From LAN to ADSL (Default route out)
# - Note: If marked packages is sent to ADSL they will be mangled and rerouted to 4G
iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT
iptables -A FORWARD -j LOG
#iptables --table nat --append POSTROUTING --out-interface eth2 --jump SNAT --to-source "192.168.1.74"
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE

Eu também tentei adicionar estes 3 ao bottomg do script:

iptables -t nat -A POSTROUTING -o eth2 -p tcp --dport 80 -j SNAT --to "192.168.0.91"
iptables -t nat -A POSTROUTING -o eth2 -p tcp --dport 443 -j SNAT --to "192.168.0.91"
iptables -t nat -A POSTROUTING -o eth2 -p tcp --dport 4070 -j SNAT --to "192.168.0.91"

Também tentei sem sucesso:

iptables -A PREROUTING -t mangle -i eth0 -p tcp --dport 80 -j MARK --set-mark 1

Por último, mas não menos importante, tentei:

## Lets mark all packets we want for 4G forward
# HTTPS
iptables -A POSTROUTING -t mangle -o eth1 -p tcp --dport 443 -j MARK --set-mark 1
# HTTP
iptables -A POSTROUTING -t mangle -o eth1 -p tcp --dport 80 -j MARK --set-mark 1
# Spotify
iptables -A POSTROUTING -t mangle -o eth1 -p tcp --dport 4070 -j MARK --set-mark 1

O roteamento funciona, eu posso navegar na web, ouvir música e outras coisas, mas estou fazendo isso através da interface errada. Eu pesquisei por um longo tempo agora e encontrei pedaços para entender o que estou fazendo e por que estou fazendo isso. Eu poderia fazer traffic shaping via tc, mas se for possível marcar pacotes no iptables, isso me ajudaria muito.

Meu palpite é que estou fazendo a ordem errada nas diferentes regras, principalmente na parte MASQUERADE ? ou se isso deveria estar lá?

Além disso, se alguém puder explicar como dizer DNAT porta, tcp: 80 de uma interface externa (um ou ambos os protocolos) para um espaço de endereço 10.0.0.0 interno, isso seria ótimo!

Eu não colocaria isso aqui normalmente, mas estou com muita pressa para colocar isso em prática ou estou em apuros!



Saídas:

root@Netbridge:~# route -n Kernel IP routing table Destination    

Gateway         Genmask         Flags Metric Ref    Use Iface<br>
0.0.0.0         192.168.1.254   0.0.0.0         UG    0      0        0 eth1<br>
10.0.0.0        0.0.0.0         255.0.0.0       U     0      0        0 eth0<br>
192.168.0.0     0.0.0.0         255.255.255.0   U     0      0        0 eth2<br>
192.168.1.0     0.0.0.0         255.255.255.0   U     0      0        0 eth1


root@Netbridge:~# ifconfig

eth0      Link encap:Ethernet  HWaddr 00:0c:29:7e:9e:4e  
          inet addr:10.0.0.1  Bcast:10.255.255.255  Mask:255.0.0.0

eth1      Link encap:Ethernet  HWaddr 00:0c:29:7e:9e:58  
          inet addr:192.168.1.74  Bcast:192.168.1.255  Mask:255.255.255.0

eth2      Link encap:Ethernet  HWaddr 00:0c:29:7e:9e:62  
          inet addr:192.168.0.91  Bcast:192.168.0.255  Mask:255.255.255.0

Seguiu estas instruções: output-traffic-on-different-interfaces-based-on-destination-por - iptables-forward-specific-port-para-specific-nic
Entre alguns outros tópicos relacionados.

    
por Torxed 07.02.2018 / 01:49

2 respostas

4

O BatchyX já deu uma explicação muito boa sobre o iptables e o roteamento, então exercerei minha preguiça e vou diretamente para o script.

Deveria NAT todo o tráfego para a porta 80.443,22,4070 até 192.168.0.91. Todo o resto vai NAT através de 192.168.1.254.

Eu refiz meus testes e acabo seguindo este guia . O que está faltando nesse guia são as últimas 3 linhas do meu script. Que eu descobri de outro porto, mas perdi o controle desse link.

É um script de trabalho testado.

Precisa da rota padrão

Uma coisa que eu não coloquei no script é configurar a rota padrão. Deve ser

route add default gw 192.168.1.254

Quando você faz route -n , deve ser a única rota padrão (Dest: 0.0.0.0)

0.0.0.0    192.168.1.254    0.0.0.0    UG    0    0    0    eth1

fw-router.sh

# Reset/Flush iptables
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT

#Reset/Flush/Setup IP Route (table 4)
ip route flush table 4
ip route show table main | grep -Ev ^default | while read ROUTE ; do ip route add table 4 $ROUTE ; done
ip route add table 4 default via 192.168.0.1

#Mark Packet with matching D.Port
iptables -t mangle -A PREROUTING -p tcp --dport 22   -s 10.0.0.0/24 -j MARK --set-mark 4
iptables -t mangle -A PREROUTING -p tcp --dport 80   -s 10.0.0.0/24 -j MARK --set-mark 4
iptables -t mangle -A PREROUTING -p tcp --dport 443  -s 10.0.0.0/24 -j MARK --set-mark 4
iptables -t mangle -A PREROUTING -p tcp --dport 4070 -s 10.0.0.0/24 -j MARK --set-mark 4

#SNAT Rules
iptables -t nat -A POSTROUTING -o eth1 -j SNAT --to-source 192.168.1.74
iptables -t nat -A POSTROUTING -o eth2 -j SNAT --to-source 192.168.0.91

#IP Route
ip rule add fwmark 4 table 4
ip route flush cache

#IP Stack
#This is the missing part from the guide
echo 1 > /proc/sys/net/ipv4/ip_forward
for f in /proc/sys/net/ipv4/conf/*/rp_filter ; do echo 0 > $f ; done
echo 0 > /proc/sys/net/ipv4/route/flush

PS1: Em suma, MASQUERADE não funciona (na maioria dos casos, e definitivamente no seu caso) para NAT com vários IPs externos que precisam de algum tipo de balanceamento de carga ou precisam de DNAT para manipular tráfego de entrada. Você precisa de SNAT para controle de direção.

PS2: iptables puros não são suficientes.

    
por 27.12.2012 / 21:30
5

Nota: Eu considerei apenas o primeiro script, ignorando o antigo.

  • Você não precisa modificar os módulos do netfilter manualmente com os iptables atuais. Isso é necessário apenas para rastreadores de conexão personalizados.
  • Não misture route e ip route . Isso é puro mal. Basta usar ip em todos os lugares e esquecer ifconfig e route
  • /etc/iproute2/rt_tables não é redefinido nas reinicializações. Acrescentar a mesma entrada repetidamente não é uma boa ideia, você só precisa fazer isso uma vez. Lembre-se de que rt_tables apenas define aliases de nomes para valores numéricos, não altera nenhuma configuração.

  • Agora, para iptables : Na sua corrente FORWARD , você descarta pacotes vindos da LAN para o 4G. Isto é mau. o gancho FORWARD é usado após o roteamento ser concluído. Neste ponto, todo o roteamento de políticas é feito e já se sabe se o pacote deve ser enviado para 4G ou ADSL. Não há reencaminhamento feito em FORWARD ou após FORWARD (bem, tecnicamente, reencaminhamento pode ser feito após POSTROUTING em casos graves, mas de volta ao ponto).

Agora para o seu roteamento: Lembre-se que o Ubuntu ativa a filtragem de caminho reverso por padrão. A filtragem de caminho inverso funciona da seguinte maneira: Quando o kernel recebe um pacote (pode ser encaminhado ou não) de uma interface A, ele inverte o endereço de origem e o endereço de destino e verifica se o pacote resultante deve ser roteado pela interface A. Se não estiver, o pacote será descartado como tentativa de falsificação de endereço.

Para pacotes recebidos de eth0 , isso não é um problema. Para pacotes recebidos de eth1 , isso também não é um problema, porque ao inverter o endereço IP de origem e o endereço IP de destino, o kernel será a rota padrão na tabela main . Para pacotes recebidos de eth2 , que você não marca, isso é um problema, porque o kernel atingirá a rota padrão na tabela main e considerará que esses pacotes devem ter sido recebidos de eth1 . A solução mais fácil é desabilitar a filtragem de caminho reverso na eth1:

sysctl -w net.ipv4.conf.eth1.rp_filter=0
    
por 03.01.2014 / 01:35