Next revision | Previous revision |
make_a_dd-wrt_bridge_silently_eat_dhcp_traffic [2008/04/01 18:28] – created tkbletsc | make_a_dd-wrt_bridge_silently_eat_dhcp_traffic [2008/04/11 21:17] (current) – tkbletsc |
---|
| ===== Introduction ===== |
| |
We have a pair of WRT54GL's running DD-WRT as a WDS bridge. It works great, except we both have our own cable modem and routers. Each router functions as a DHCP server. Because we're bridged, this means that we have two competing DHCP servers on the same LAN, so sometimes a machine will pick the other router as it's gateway. This means that Internet traffic would be crammed through our tenuous bridge, making much sadness. | We have a pair of WRT54GL's running DD-WRT as a WDS bridge. It works great, except we both have our own cable modem and routers. Each router functions as a DHCP server. Because we're bridged, this means that we have two competing DHCP servers on the same LAN, so sometimes a machine will pick the other router as it's gateway. This means that Internet traffic would be crammed through our tenuous bridge, making much sadness. |
| |
The correct solution is to have separate subnets with routing and blah blah blah. | The correct solution is to have separate subnets with routing and blah blah blah. |
| |
Screw that. The quick and dirty solution is just to ban DHCP traffic from the bridge. After some trial and error, I found the iptables rules that would do that: | Screw that. The quick and dirty solution is just to ban DHCP traffic from the bridge. |
| |
iptables -t mangle -I PREROUTING 1 -p UDP --sport 67 -j DROP | ===== HOWTO ===== |
iptables -t mangle -I PREROUTING 1 -p UDP --sport 68 -j DROP | |
iptables -t mangle -I PREROUTING 1 -p UDP --dport 67 -j DROP | |
iptables -t mangle -I PREROUTING 1 -p UDP --dport 68 -j DROP | |
| |
The only question then is how to make these rules get applied automatically at bootup. [[http://linuxwhore.com/modules.php?name=News&file=article&sid=155&mode=thread&order=0&thold=0|This article]] covers that: just use the 'rc_firewall' value in the nvram. At the router's command prompt: | Go to Administration | Commands, and paste this: |
| <file> |
| echo "begin-base64 644 -" > /tmp/ebt_ip.o.gz.u64 |
| echo "H4sIADwAAAACA5VWz28bVRD+dteON20KG9eq3BJUB21UVy1m2+RQRCO5cX5w" >> /tmp/ebt_ip.o.gz.u64 |
| echo "yMGHHpAQcr32Eq9wHMveIFAPNSkHDq7wIb1H5R+p0gpx7J8QtaH8EBfuSGbm" >> /tmp/ebt_ip.o.gz.u64 |
| echo "vbdh8whEHelp9ps3883Mm/ecPFhZXzUMA7EYsPEPAv5Ikc1BdUGgIt7CWSQl" >> /tmp/ebt_ip.o.gz.u64 |
| echo "i5ejFJY8B2VntjrAecIFPByyLUM2B4cjA43RGDveN6g4HJMD7CxeH9nvo5KT" >> /tmp/ebt_ip.o.gz.u64 |
| echo "XK9HNva9KsUxPo/fiKvyyMZ7N5hrmrgmVUxHcV0hrmm8OrK3FBfbJmC6FnyK" >> /tmp/ebt_ip.o.gz.u64 |
| echo "M92P4At7AUuPBsRZwHMPWBq+TXUOHBN5DJzZsg8T5uM8DnfHqHi4ZMHMmpjL" >> /tmp/ebt_ip.o.gz.u64 |
| echo "+7hWaCKNQW62CFzCy91rTgUW1VSg2gykXdZpwgae3FpDWeRap9oc6qeCPYH5" >> /tmp/ebt_ip.o.gz.u64 |
| echo "+6LqDZQnd0qeCyqPqWI4D5+vQzXHua6rXBvqTIsqlzzffS9LfiZpORc+y8Oh" >> /tmp/ebt_ip.o.gz.u64 |
| echo "oWYD/Dycgj90nWXqaUXkuE887B/bc1gRfGzL8YwdiBmniIf5TMU1hV+GjohZ" >> /tmp/ebt_ip.o.gz.u64 |
| echo "QwbLgsvGgcX+sd1K2A2aCe/xtzybH76fIdsNmtPv47Rr49muTfh9NbcU9kXd" >> /tmp/ebt_ip.o.gz.u64 |
| echo "V1W/WboLT8lvjIee6wR0ZtLOtbnOipgN4x8pBfN58L0zYl47Xh73HLbpdyR7" >> /tmp/ebt_ip.o.gz.u64 |
| echo "dEd21N1l31e78bwpXtTmqP14RjnyUXMS+2yXve9x5beBi7Q+vGKjQL1+655s" >> /tmp/ebt_ip.o.gz.u64 |
| echo "Oy5hF6fKx+a/bX9l8ARvIO/SuvwfXMn9gvX/+wun7LfDRtDpB4tr1XV8EfQ6" >> /tmp/ebt_ip.o.gz.u64 |
| echo "Qbv2ZdDrh1udxZulhdK8x86l/tebUd0nHfWkbsVfvaBdioKvIvnVrEd1lPx+" >> /tmp/ebt_ip.o.gz.u64 |
| echo "n+FG2Pl8S9q7zR5Km83A394o1f1w/iahrabYfwO5LN4aMKFwmVY10Z96wHiH" >> /tmp/ebt_ip.o.gz.u64 |
| echo "1mQi7hMb4LFNqfiUuOvAVYVjipElOXW+OY3vJwrOKz4rwfeB0jHfC+3sY74F" >> /tmp/ebt_ip.o.gz.u64 |
| echo "2UPXTPjlE37Mx/iOqi+WX8lvoPmxLGr1Hdj8VmR9mUR9qxpfK3W8vnjvrvo2" >> /tmp/ebt_ip.o.gz.u64 |
| echo "E37uCXmnE72y0B8XfHYCX5KLZYaKOiB9TtWdUmczqfHRm8GnJ/DpYhyr7c9x" >> /tmp/ebt_ip.o.gz.u64 |
| echo "cs/SoixYGk5reFLDZzQ8oeGM8OB3mBO/fwb99sh3F+M57Q7Ma3hVvyOBH9XC" >> /tmp/ebt_ip.o.gz.u64 |
| echo "bqmBsBNGNXop2+0AjXZQ72x3Y1irRa2wHyOO4BfXj4JebbMeNVrCtN3RjOLu" >> /tmp/ebt_ip.o.gz.u64 |
| echo "pUx5j1jPGFJ/p/QLpfdMqelHGGm6SEXSE1OyzzQtjzGtW4xpkLcZn5N98/6y" >> /tmp/ebt_ip.o.gz.u64 |
| echo "2i/y7InnutKc31T/qjAuKF1W+p7SfwMbOFhxAAkAAA==" >> /tmp/ebt_ip.o.gz.u64 |
| echo "====" >> /tmp/ebt_ip.o.gz.u64 |
| uudecode /tmp/ebt_ip.o.gz.u64 | gzip -cd > /tmp/ebt_ip.o |
| insmod ebtables |
| insmod ebtable_filter |
| insmod /tmp/ebt_ip.o |
| ebtables -I INPUT -i tap0 -p IPv4 --ip-protocol udp --ip-destination-port 67:68 -j DROP |
| </file> |
| |
nvram set rc_firewall="iptables -t mangle -I PREROUTING 1 -p UDP --sport 67 -j DROP | Then hit "Save commands". Finally, reboot. You can check to see if it works by telnetting in and typing "ebtables -L". You should see: |
iptables -t mangle -I PREROUTING 1 -p UDP --sport 68 -j DROP | <file> |
iptables -t mangle -I PREROUTING 1 -p UDP --dport 67 -j DROP | Bridge table: filter |
iptables -t mangle -I PREROUTING 1 -p UDP --dport 68 -j DROP" | |
nvram commit | |
| |
Reboot, and presto, the bridge is eating all DHCP traffic: | Bridge chain: INPUT, entries: 1, policy: ACCEPT |
| -p IPv4 -i tap0 --ip-proto udp --ip-dport 67:68 -j DROP |
| |
<file> | Bridge chain: FORWARD, entries: 0, policy: ACCEPT |
# iptables -t mangle -vL | |
Chain PREROUTING (policy ACCEPT 262 packets, 50464 bytes) | Bridge chain: OUTPUT, entries: 0, policy: ACCEPT |
pkts bytes target prot opt in out source destination | |
0 0 DROP udp -- any any anywhere anywhere udp dpt:bootpc | |
37 14776 DROP udp -- any any anywhere anywhere udp dpt:bootps <=== Counter shows 37 DHCP packets have been eaten! | |
0 0 DROP udp -- any any anywhere anywhere udp spt:bootpc | |
0 0 DROP udp -- any any anywhere anywhere udp spt:bootps | |
</file> | </file> |
| |
| ===== What does that crap do? ===== |
| |
| Because we need to hook into the bridging system, iptables is insufficient. [[http://www.dd-wrt.com/phpBB2/viewtopic.php?t=12372&highlight=ebtables|This thread]] explains that we need to use //ebtables// to do that. This requires 2 included modules: ''ebtables'' and ''ebtable_filter'', plus one module that's not included: ''ebt_ip.o'' (attached in the thread). How can we add this extra module, given that the flash filesystem is read only? Answer: we crap it into the NVRAM as a series of commands. |
| |
| I took the original ebt_ip.o, and ran "gzip -c ebt_ip.o | uuencode -m -", which means "compress with gzip, then uuencode with base-64 mode". This turns the binary file into safe ASCII. We then wrap all this ASCII in that giant pile of "echo ... >> /tmp/ebt_ip.o.gz.u64" commands. We then decode it back into binary with "gzip -cd ... | uudecode -". Then we load the required modules: ''ebtables'', ''ebtable_filter'', and our hacked up ''/tmp/ebt_ip.o''. Finally, we input the ebtables rule to drop all the DHCP packets it sees. |
| |