Hoje resolvi sujar as mãos um pouquinho e resolver um problema pertinente lá na empresa: fazer com que o Squid utilize uma rota alternativa a rota padrão do gateway. Temos dois links de internet conectados ao gateway e queriamos definir as rotas de acordo com o tráfego. O problema era o tráfego gerado pelo próprio gateway, como o Proxy, DNS e Atualização do DNS dinâmico com ddclient.
Vasculhando um pouco pelo google achei uma alternativa interessante, que seria usar o módulo owner do iptables para marcar o tráfego vindo do usuário proxy (usamos Debian no gateway) para uma tabela de roteamento alternativa.
O script requer o pacote iproute2 instalado, bem como o Squid já configurado.
A tabela de Roteamento
Nosso gateway padrão atualmente é 192.168.15.254, na subrede 192.168.15.0/24. Com a função set_route() é criada uma nova tabela de roteamento com identificação numérica armazenada na variável $TABELA.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | declare LAN="192.168.1.0/24" declare WAN="10.0.0.0/24" declare IFLAN="eth0" declare IFWAN="eth2" declare GATEWAY="10.0.0.254" declare TABELA="100" declare IPROUTE="/sbin/ip route" #Cria a tabela de roteamento alternativa com o iproute function set_route() { $IPROUTE add $LAN dev $IFLAN table $TABELA $IPROUTE add $WAN dev $IFWAN table $TABELA $IPROUTE add default via $GATEWAY dev $IFWAN table $TABELA $IPROUTE flush cache } |
As Regras de Roteamento
A função set_rule() primeiro marca os pacotes oriundos do usuário proxy usando os matchers MARK e CONMARK. Em seguida é criada uma regra de roteamento para capturar os pacotes marcados e roteá-los através da nova tabela.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | declare IPTABLES="/sbin/iptables" declare IPRULE="/sbin/ip rule" #Cria as regras para o trafego que utilizara a tabela de roteamento alternativa function set_rule() { $IPTABLES -t mangle -A PREROUTING -j CONNMARK --restore-mark #A regra que marca o trafego gerado pelo usuario do proxy $IPTABLES -t mangle -A OUTPUT -m owner --uid-owner proxy -j MARK --set-mark $TABELA $IPTABLES -t mangle -A POSTROUTING -o $IFWAN -j MARK --set-mark $TABELA $IPTABLES -t mangle -A POSTROUTING -j CONNMARK --save-mark #A regra que captura os pacotes marcados e os insere na nova tabela $IPRULE add fwmark $TABELA table $TABELA } |
Você pode ampliar as regras como, por exemplo, fazer com que todo tráfego pop3 e smtp sejam roteados através da nova tabela.
1 2 | $IPTABLES -t mangle -A PREROUTING -p TCP --dport smtp -j MARK --set-mark $TABELA $IPTABLES -t mangle -A PREROUTING -p TCP --dport pop3 -j MARK --set-mark $TABELA |
Juntando tudo
Se você já possui mais de uma tabela de roteamento configurada com o iproute basta adaptar o script conforme a sua necessidade.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | #!/bin/bash # Desctiption: Script de roteamendo avancado # Author: Fabiano Sobreira #Variaveis declare LAN="192.168.1.0/24" declare WAN="10.0.0.0/24" declare IFLAN="eth0" declare IFWAN="eth2" declare GATEWAY="10.0.0.254" declare TABELA="100" declare IPTABLES="/sbin/iptables" declare IPROUTE="/sbin/ip route" declare IPRULE="/sbin/ip rule" #Cria a tabela de roteamento alternativa com o iproute function set_route() { $IPROUTE add $LAN dev $IFLAN table $TABELA $IPROUTE add $WAN dev $IFWAN table $TABELA $IPROUTE add default via $GATEWAY dev $IFWAN table $TABELA $IPROUTE flush cache } function unset_route() { $IPROUTE flush table $TABELA } #Cria as regras para o trafego que utilizara a tabela de roteamento alternativa function set_rule() { $IPTABLES -t mangle -A PREROUTING -j CONNMARK --restore-mark #A regra que marca o trafego gerado pelo usuario do proxy $IPTABLES -t mangle -A OUTPUT -m owner --uid-owner proxy -j MARK --set-mark $TABELA #Regras que marcam o trafego smtp e pop3 $IPTABLES -t mangle -A PREROUTING -p TCP --dport smtp -j MARK --set-mark $TABELA $IPTABLES -t mangle -A PREROUTING -p TCP --dport pop3 -j MARK --set-mark $TABELA $IPTABLES -t mangle -A POSTROUTING -o $IFWAN -j MARK --set-mark $TABELA $IPTABLES -t mangle -A POSTROUTING -j CONNMARK --save-mark #A regra que captura os pacotes marcados e os insere na nova tabela $IPRULE add fwmark $TABELA table $TABELA } function unset_rule() { $IPTABLES -t mangle -D PREROUTING -j CONNMARK --restore-mark $IPTABLES -t mangle -D OUTPUT -m owner --uid-owner proxy -j MARK --set-mark $TABELA $IPTABLES -t mangle -D PREROUTING -p TCP --dport smtp -j MARK --set-mark $TABELA $IPTABLES -t mangle -D PREROUTING -p TCP --dport pop3 -j MARK --set-mark $TABELA $IPTABLES -t mangle -D PREROUTING -p TCP --dport imap -j MARK --set-mark $TABELA $IPTABLES -t mangle -D POSTROUTING -o $IFWAN -j MARK --set-mark $TABELA $IPTABLES -t mangle -D POSTROUTING -j CONNMARK --save-mark $IPRULE del fwmark $TABELA table $TABELA } function do_start() { set_route set_rule } function do_stop() { unset_rule unset_route } case $1 in start) printf "%s\n" "Iniciando o roteamento" do_start exit ;; stop) printf "%s\n" "Parando o roteamento" do_stop exit ;; restart) printf "%s\n" "Reiniciando o roteamento" do_stop do_start exit ;; *) printf "%s\n" "Uso: ${SCRIPT} (start|stop|restart)" exit ;; esac |
Links Sobre o Assunto
Linux Advanced Routing & Traffic Control
Linux Packet Filtering and Iptables
