On Aug 2 2007 15:45, Cameron Schaus wrote:
Jan Engelhardt wrote:
How can I make sure packets get routed instead of bridged? Does this involve using the brouting feature of ebtables?
Yes.
In some network layouts, you can use a half-bridge (which is a cool thing but probably requires the same number of steps) to reduce the number of needed ebt rules.
Thanks, using ebtables brouting does appear to work. However, it may be cumbersome for my application to use ebtables rules to keep certain traffic off the bridge while allowing unproxied traffic across the bridge.
I have a proxy application running on the bridge IP address, and iptables rules currently direct traffic of interest to the proxy. I want to use the tproxy code to perform a foreign connect using the client's IP address. So the client's and server's addresses are more or less arbitrary. This makes generating ebtables brouting rules that preserve the bridge behavior for non-proxied traffic difficult. [...]
I'll just give an example case: eth0 -- ISP-side -- my address 192.168.34.2 Objects: Exactly one ISP router at 192.168.34.1 eth1 -- LAN -- my address 192.168.34.2 Objects: Any number of clients in 192.168.34.0/24 And we'd like to filter some URLs with a squid running on .34.2. Step 1: Interfaces (of course you do this with your distro-specific config files), but the outline is: ip a a 192.168.34.1/32 dev eth0 ip a a 192.168.34.0/24 dev eth1 Yes, we have got overlapping networks, but that does not hurt, as the one with the tighter prefix length (32 wins over 24) has higher precedence. As I said, this cannot be used for all setups (especially where both segments contain changing hosts). So everything works as usual. On the clients, you may need an extra route: ip r a 192.168.34.1/32 via 192.168.34.2 but only if they should send packets there. [Default gateway for clients is of course .34.2.] Step 2: Configure eth0 to do ARP reply # Our so-called "half bridge" brctl addbr br0 brctl addif br0 eth0 # # ARP requests need to be handled by ebtables - hence they # _do_ need to be bridged (ACCEPT). # ebtables -t broute -P BROUTING DROP; ebtables -t broute -A BROUTING -p arp \ --opcode request -j ACCEPT; ebtables -t nat -A PREROUTING -p arp --opcode request \ -j arpreply --arpreply-mac `cat /sys/class/net/br0/address` \ --arpreply-target DROP; Note that you can also bridge all ARP traffic, i.e. let the clients answer ARP. I do not consider that necessary. That's it already. On the .34.2 server, squid is run with server-side-transparency ("tproxy") and, optionally client-side-transparency if wanted. The benefit of this is that no packet can ever be accidentally bridged ("slip through"), because the bridge consists of only one port. The other benefit (of using DROP in broute) is that packets come through regular interfaces instead of br0, making accounting more precise, and you do not have to use -m physdev in iptables.
What is currently stopping the packets from being diverted locally once they enter the bridge? As I understand it now, the packets destined for the foreign IP address should enter the bridge, and since they are destined for the bridge MAC address
Generally, people set it up differently, so that br0 encompasses both eth0 and eth1. It works too, but needs a bit more thought: Your bridge sends a packet with a foreign address. So the ISP router will ask "arp who-has .34.99", and a client responds with ".34.99 at MAC macof3499". Then the router will send whatever IPv4 packet it wanted to send -- to macof3499, NOT to macofbridge. Hence, the packet gets bridged through the blue level (see http://www.imagestream.com/~josh/PacketFlow-new.png ). But for tproxying to be effective, the packet needs to hit the "routing decision (PRDB)" circle.[1] There are ways to achieve that: - DROP non ARP-packets in the broute table (= inject them into the route stack - and hence tproxy) path: bridging process, brouting, routing process, Green Level. - ebt_dnat packets in the nat table (= change macof3499 to macofbridge) path: bridging process, brouting, blue prerouting, bridging decision, *then* moves up to the Green Level Hope this explains things a bit :-)
they should enter the correct protocol handler. At some point the frames should enter IP tables PREROUTING where the tproxy code is invoked. However, something isn't right. Perhaps it's because the packet device is replaced with the bridge device and this doesn't match the socket information? I'd like to understand what isn't working in this case.
One way around this is to add a check in br_handle_frame to get the socket and check if inet->freebind is set, similar to the tproxy prerouting code. One drawback of this is that fragmented IP packets cannot be reassembled to obtain the IP addresses and ports, and would end up lost in the stack. An ebtables module could likely be written to avoid modifying the bridge code.
Are there better ways of getting these foreign packets into the network stack when they are destined for a local bridge interface?
Thanks, Cam
[ And if you are concerned about xt_socket from Krisztian's tproxy, well, that's related to the routing process, where we also have to either send the packet upwards (into INPUT - yes we want this) - since if we did not, it would be forwarded to the right to the real client. ] Jan --