So, with the new year approaching I’m also joining the future when it comes to fiber to the home networking. Well really, my subscription with the other ISP was coming to an end, and it was time to upgrade to something that was both cheaper and faster.
With the new ISP, I’m finally getting out of the “only one IP per customer”, and into a more realistic setup. This allows me to finally get rid of the NAT box and all the problems it entails .( Instant messenger, UPnP and various protocols still do not act well with NAT. And probably never will )
However, you don’t get any amount of IP-addresses, so there has to be some limit, and for things like the wifi, I do not see a good reason to bridge anyone into the ISP network without some sanity checking.
Now, I wouldn’t be a proper geek if that was the only thing on my requirements. See, I also want to maintain good speed with my NAS storage, ( nfs + samba ) which unfortunately my router cannot manage ( only 100Mbit, while my switch is Gigabit ). However, lets be serious, this is a minor issue.
Add to this that I have, quite a number of various devices speaking ethernet ( Embedded systems galore, 10-15 ‘computers’ around here ), so we can’t really just assume that I’ll get enough public IP’s for all of them.
So, what I’d _REALLY_ want is a server on my home router (OpenWRT 10.03.1-rcX Backfire based) that would set up a private LAN for most machines, but for a few select MAC-addresses would instead of allocating a private IP, do a DHCP proxy call and allocate a public IP-address for those.
Preferrably the DHCP-proxy would then re-write certain fields like “default route” ( the router ) DNS ( Well, doh ) as well as update the DNS-entries for the internal lookup so you could use consistent for your own machines. ( MAC-based to start with )
Well. Right now, there is no such software, and for this weekend I didn’t have the urge to even try and scope it up, much less create it.
So, That leaves me with two “obvious” solutions.
*) DHCP Proxy (dhrelay from ISC and dhcp-forwarder)
*) Transparent Bridging
For these to work I had to do some magic in either way. First and foremost, set up VLAN’s on the internal switch of my WRT160nl. There I’d dedicate 1 port to be “outbound” ( and hook a switch to that) and the remaining 3 to be “local net only”.
Figuring this out took me a bit longer than I’d thought, as I managed to lock myself out by the ways of firewalling whenever I attempted it, causing quite a few reboots into safe mode while I was attempting in blind to figure out what worked and what didn’t. Below will be some documentation on how to get this just right (tm)
Also note that the default documentation on setting up VLAN on the OpenWRT page is broken, as it will create RFC-noncomformant tagged VLAN’s . VLAN 1 is not supposed to be tagged, see 802.1D standard.
So, the relevant parts of /etc/config/network :
option ‘name’ ‘eth0‘
option ‘reset’ ‘1‘
option ‘enable_vlan’ ‘1‘
option ‘enable’ ‘1‘
config ‘switch_vlan’ ‘eth0_0‘
option ‘vlan’ ‘0‘
option ‘device’ ‘eth0‘
option ‘ports’ ‘0u 1u 2u 4* 5*’
config ‘switch_vlan’ ‘eth0_10‘
option ‘vlan’ ‘10‘
option ‘device’ ‘eth0‘
option ‘ports’ ‘3u 4t 5t’
config ‘interface’ ‘vlan0‘
option ‘proto’ ‘static’
option ‘ifname’ ‘eth0.0‘
option ‘ipaddr’ ‘172.27.1.1‘
option ‘netmask’ ‘255.255.255.0‘
option ‘defaultroute’ ‘0‘
option ‘peerdns’ ‘0‘
This first turns on VLAN and the switch on eth0.
the part that reads : 0u 1u 2u 4* 5* has a magic meaning. It means that vlan 0 will be _untagged_ as it leaves ports 0 1 and 2, and _tagged_ if an untagged packet LEAVES port 4 and 5. It also makes this the _default_ vlan.
the part that reads “3u 4t 5t” is similarly magic. it means that packets leaving port 3 shall be untagged if they were tagged with vlan 10. 4t 5t also means they get tagged going out of the two internal ports. However, it’s uncertain if this actually does anything.
Next, we assign a local, static IP-address to the vlan0, and serve DHCP off that as normal. That means that physical port 3 on the switch is now magic, and assigned to vlan10 ( eth0.10 ) and free to perform experiments on.
Also note, you _NEED_ to add vlan0 to the /etc/config/firewall zone for your lan. (replace eth0 with “eth0 vlan0“ and do similar in your /etc/config/dhcp
So, My first few hours was spent digging through how to do this without bridging, so I spent many hours getting dnsmasq not to bind the external interface nor the eth0.10 interface, and attempting to get dhcp-forwarder or dhcrelay to work. Unfortunately I got neither to work with my ISP (Telia). However, this may work in the future? I wouldn’t know. I still haven’t compiled up dhcp-helper from the same guy who creates dnsmasq
So. After some time I scrapped this position, and decided that it would be simpler to create a bridged interface between eth1 (external, WAN) and eth0.10 (internal, VLAN 10, port 3 on the switch ) said and done. It was actually quite simple.
config ‘interface’ ‘wan’
option ‘peerdns’ ‘0'
option ‘type’ ‘bridge’
option ‘ifname’ ‘eth1 eth0.10'
option ‘proto’ ‘dhcp’
option ‘auto’ ‘1'
And that about solves it.
Now, I can hook my swtich to that port, and the machines on this side
also get nice external IP addresses.
There’s just one snag. I do not get any firewall anymore. For cited performance reasons, ( I’m unable to find numbers anywhere ) the bridged filtering is disabled in the OpenWRT Backfire kernels. This does put a hinder to my plans, as I’m unable to actually perform what I wanted to do here.
Also, performance stinks right now. Why? My ISP has proxy-arp. This means, that their gateway is responding to _ALL_ arp requests for any IP-address in their range as belonging to them. This in turn is enough to make my gigabit switch scratch it’s head, and forward packets through my bridge and up into the ISP, and then back again. Effectively degrading my gigabit ethernet into 100Mbit or less.
This would ofc. be easy to stop by blocking arp-requests at the firewall. Except that the firewall isn’t enabled on bridged interfaces.
So, for the future:
a) Check out the performance of a custom kernel with bridging. Does it kill the upstream?
b) Investigate in dhcp-helper.
c) Look at creating a patch for dnsmasq that does custom proxying of DHCP based on certain mac-addresses.
d) Kill everyone, NAT and just go with ipv6 whenever it arrives?