Proxy arp local

Материал из noname.com.ua
Перейти к навигацииПерейти к поиску

PROXY ARP LOCAL

Решил сгородить SuperVlan на линуксе, но столкнулся с проблемой - proxy_arp в классическом понимании работает только между интерфейсами. А мне нужно было что бы роутрер отвечал своим маком на любой запрос на ТОМ ЖЕ интерфейсе.
В новых (выше 2.6.36) ядрах есть соответвующяя опция, но у меня старое ядро и обновлять его я не имел возможности (не хотел поломать случйно что-то что делалось до меня, в частности ядерный accel pptp )

Текущяя конфигурация

Ядро:

# uname -a Linux impexmedia 2.6.23.8-sirmax2 #4 SMP Tue Dec 4 22:29:36 EET 2007 i686 06/17 GenuineIntel GNU/Linux

SuperVlan

SuperVlan по сути просто бридж между вланами, и ничего более:

brctl addbr SVL0

brctl addif SVL0 eth5.3000
brctl addif SVL0 eth5.3001
brctl addif SVL0 eth5.3002
brctl addif SVL0 eth5.3003
brctl addif SVL0 eth5.3004
brctl addif SVL0 eth5.3005
ip link set up dev SVL0
brctl stp SVL0  off

Не забыть отключить iptables для бриджей.

sysctl net.bridge.bridge-nf-call-iptables=0
sysctl net.ipv4.conf.all.send_redirects=0

ebtables

Есть интересная утилита - ebtables, которая позволяет сделать то что мне нужно.

# eix ebtables [I] net-firewall/ebtables Available versions: 2.0.9.2-r1 2.0.9.2-r2 ~2.0.10.2 {static} Installed versions: 2.0.9.2-r2(21:17:37 10/29/11)(-static) Homepage: http://ebtables.sourceforge.net/ Description: Utility that enables basic Ethernet frame filtering on a Linux bridge, MAC NAT and brouting.

Потому применяю следующюю конструкцию:

ebtables -t nat -F
ebtables -F

ebtables -t nat -N reply_ir_arp

ebtables -t nat -A reply_ir_arp -p arp --arp-ptype IPv4 -j arpreply --arpreply-mac 00:15:17:67:6b:53 --log-level 7 --log-arp --log-ip
# MAC интерфейса

ebtables -t nat -N spoof_ir_nets_SVL0
ebtables -t nat -A spoof_ir_nets_SVL0   -p arp --arp-ptype IPv4 --arp-ip-dst 178.255.255.0/24   --arp-ip-src 178.151.247.0/24   -j reply_ir_arp

ebtables -t nat -N input_from_SVL0
ebtables -t nat -A input_from_SVL0      -p arp --arp-ptype IPv4 --arp-opcode 1 ! --arp-gratuitous -j spoof_ir_nets_SVL0


ebtables -t nat -A PREROUTING   -p arp --arp-ptype IPv4 --arp-opcode 1 ! --arp-gratuitous --log-level 7 --log-arp --log-ip --log-prefix "ARP_GRAT"
ebtables -t nat -A PREROUTING   -p arp --arp-ptype IPv4 --arp-opcode 1  --arp-gratuitous --log-level 7 --log-arp --log-ip --log-prefix "ARP_GRAT_1"

ebtables -t nat -A PREROUTING   --logical-in    SVL0                            -j input_from_SVL0
ebtables        -A FORWARD      --logical-in    SVL0    --logical-out SVL0      -j DROP


Gratuitous ARP

Обратить внмаение на конструкцию - "! --arp-gratuitous" - это нужно для того что бы не отвечать на запросы "а не пользует ли кто уже мой IP?".

Gratuitous ARP

Gratuitous ARP could mean both gratuitous ARP request or gratuitous ARP reply. Gratuitous in this case means a request/reply that is
not normally needed according to the ARP specification (RFC 826) but could be used in some cases. A gratuitous ARP request is an 
AddressResolutionProtocol request packet where the source and destination IP are both set to the IP of the machine issuing the packet 
and the destination MAC is the broadcast address ff:ff:ff:ff:ff:ff. Ordinarily, no reply packet will occur. A gratuitous ARP reply is 
a reply to which no request has been made.

Однако в ядре присутвует баг - эта опция на моем ядре НЕ отрабатывала. Это вызывало эффект "занятого IP" - любая система видела что ее IP уже используется, и, соответвенно, отказывалась работать.

Для того что бы обойти эту проблему - добавляю для каждого IP правило (на примере 67-го IP)

ebtables -t nat -A spoof_ir_nets_SVL0   -p arp --arp-ptype IPv4 --arp-ip-dst 178.255.255.67     --arp-ip-src 178.151.247.67     -j ACCEPT

Естественно, в моем случае таких правил будет 253 штуки.

В новых ядрах - уже не нужно, ошибка исправлена но информации о багфиксе я не нашел.

И в самых новых ядрах уже можно обойтись (в примере интерфейс br1)

echo 1 > /proc/sys/net/ipv4/conf/br1/proxy_arp_pvlan


Но я решился остановиться на варианте с ebtables и для новых ядер как более гибком - у меня на интерфейсе много алиасов, но проксировать арп я хочу только для одной сети.

Еще одно решение

Вообще то можно было давать абонентам /32 и обойтись без прокси-арп, но я не знаю все ли клиентские устройства воспринимают такое - потому решил не использовать.