Hey, Siri, let’s start a fire.

Almost immediately after moving into our house, I wanted to get our gas fireplace in HomeKit. We’re heavily invested in HomeKit, and I really wanted the fireplace to (a) turn on and off via HomeKit and (b) have a switch that matched the other HomeKit switches in the house. However, the specifics of doing so were a bit challenging, and it took me an embarrassingly long time to figure out a really pretty simple solution.

The Challenge

The fireplace is a typical gas fireplace with a switch that connects via low-voltage wiring to an AC powered control unit which lives in an open space under the fireplace. When the switch is in the “on” position, the circuit is closed, and the control unit opens the gas valve and repeatedly fires the starter until the gas ignites. Super simple.

However, HomeKit and other “smart” switches require high-voltage AC to operate, and the control switch doesn’t have AC in the gang box.

The Solution

I spent a year thinking about how to get AC to the gang box without cutting a bunch of drywall, when I realized it wasn’t worth the effort. The obvious thing to do is to use a Lutron Caseta on/off switch, a relay, and a Lutron Pico remote. This meets my needs, since I have Caseta switches throuhout the first floor.

Here’s my hardware list (affiliate links):

  1. 1 Lutron PD-6ANS Switch
  2. 1 Lutron Claro Single-Gang Wallplate
  3. 1 Lutron Non-Dimmer Pico Remote
  4. 1 Pico Remote Wall-Box Adapter
  5. 110v Coil, 10A relay
  6. Thermostat Wire
  7. 2-gang box
  8. AC Appliance Cord
  9. 18/24gauge Male and Female Disconnects (these aren't on Amazon in quantites that aren't nuts; you can find them at your hardware store)

Here’s a diagram of how I wired the switch to the relay. I did all of this on my workbench so I could easily test the relay with my multimeter, and tuck the wire nuts away as best I could. Most relays will have a diagram printed on their housing which shows which pins energize the coil, and which contacts are switched. In my case, 2 and 7 energize the coil, and 1 and 3 or 8 and 6 were switched pairs.

It took some testing to figure out which wire was switched.

It took some testing to figure out which wire was switched.

The fireplace control connnected to the low-voltage switch with 18 gauge thermostat wire using quick-disconnects, so I stuck some quick disconnects on the thermostat wires connected to the relay to make installation easier. The switch's black (hot) wire is connected to the black (hot) wire of the AC cord, the switch's switched (red) wire is connected to the relay's coil, so when the switch is switched on, the coil is energized. The neutral wires of the relay, the switch, and the AC cord are all connected to complete the circuit. The low-voltage wires to the fireplace control are connected to two switched contacts of the relay. When the coil is energized, the gate is closed, and the loop is completed, just like flipping the old switch to the "on" position. The switch's blue wire isn't used in this case, and is just wire-nutted in the two-gang box.

I assmbled all of this in a two-gang box, tested it on my workbench, then moved it under the fireplace. There's an AC outlet under the fireplace which was unused, which was a convenient place to plug in the power cord. I disconnected the low-votage switch with the disconnects under the fireplace, and reconnected the control wires to my thermostat wire coming from the relay using the disconnects that I added.

At this point I could toggle the switch in the gang box and, lo and behold, fire! I replaced the low-voltage switch with the Pico remote. Added the switch and Pico remote to the Lutron app, which in turn adds it to HomeKit, and did some minor tweaks in HomeKit.

eero and Split-Horizon DNS

Update: As of Septmber 14, 2017 eero has updated all eero networks to enable hairpinning. That means the config I laid out isn't necessary, but maybe this is still useful for some folks.

At this point, I'd guess most folks reading this are familiar with eero and similar distributed mesh home wifi products. For those that aren't, the tl;dr is that in many environments, a single router with a set of radios won't cover a whole home very well, and a distributed system with multiple radios working together is a better solution (read the linked Sweethome overview - it covers this better than I will). I'm a happy eero customer, and I'm not super interested in getting into why eero was a better fit for me than its competitors at the time I made the decision. As I said, overall I've been very happy.

However, I did have to get a little creative to solve a specific problem:

NAT/Egress Hairpinning

I have long run a few internal services on various web-servers running inside and outside my network.

Unfortunately, eero doesn't currently support a feature called Hairpinning, which allows clients inside the network to egress the network and get a response from the public IP of the same network. As a result, I had to access these services by one name externally (eg. [server].alvani.me), and another name internally ([server-hostname].local). This is frustrating since it breaks scripts and alerts that rely on consistent DNS names for services, and it means I need a second set of bookmarks to access services inside versus outside my network, plus the congnitive load of remmebering if I should use this name or that name to access this service. The whole point of DNS is to make this easy on us simple humans.

Split Horizon DNS to the Rescue

Split Horizon is a pretty common implementation in the enterprise world. In general, it's overkill for home networks, since there aren't a lot of DNS needs for most home networks. I really didn't want to, but eventually it became clear that for the short term, it'd be a good idea to run my own internal DNS server which handled request for the *.jehanalvani.com and *.alvani.me domains, while forwarding all other requests to upstream DNS providers. I could run in this configuration until eero eventually adds support for the hairpinning.

I'm writing this to document how I configured split-horizon on a Synology with Synology's DNS Server software. There's no reason this couldn't be adapted fairly easily to BIND or whatever other DNS Server you might want to run.

I started by installing DNS Server on my DS414Play.

Then, in DNS Server, I configured my forwarders.

Forwarders

Oh, if you leave the "Limit Source IP service" box checked, make sure you add your internal network CIDR to the list of permitted IPs. Otheriwise you'll get "Forbidden" on your DNS requests.

I added the zones I care about

Zones

A Quick Aside About DNS Zones

If you're familar with DNS, this is not a section you'll need to read, but I got some feedback that the concept of DNS Zones are confusing. For our purposes, DNS Zones are any domain(s) or subdomain(s) you want your nameserver to respond for. Of course, zones are much more powerful, and can be used in a lot of ways. The bottom line is that Zones are a method of drawing a demarcation for the responsibilities of different nameservers.

Moving on:

Finally, inside the zones, I configured the subdomains and services I care about

Zone config

This matches the public DNS configuration of the same services, just replacing the IP address with the internal IP address of the server running the service. In my case, they're all the same, because I'm using a reverse proxy to interpret the requests and send them to the appropriate servers.

Now, any client that sends requests to this name server should recieve the internal record as an answer. I can test with a couple simple NSLOOKUPs from inside the network.

First, query a common public nameserver:

nslookup syno.jehanalvani.com 4.2.2.2

Which returns

>jehan.alvani@MBP $ nslookup syno.jehanalvani.com 4.2.2.2
Server:        4.2.2.2
Address:    4.2.2.2#53

Non-authoritative answer:
syno.jehanalvani.com    canonical name = dynamic.jehanalvani.com.
dynamic.jehanalvani.com    canonical name = starman.synology.me.
Name:    starman.synology.me
Address: 50.35.122.71

Where 4.2.2.2 is the nameserver that was queried, and the results of the non-autoritative answer are exactly what I've configured for my pubilc subdomain. (syno.jehanalvani.com is a CNAME to dynamic.jehanalvani.com, which is itself a CNAME to synology's dynamic DNS service). Ineffecient? Maybe a little. But I don't have to rememebr anything other than "dynamic.jehanalvani.com" after initial setup.

And a query against my Synology's private IP returns the following

`nslookup syno.jehanalvani.com 10.0.1.20`

>jehan.alvani@MBP $ nslookup syno.jehanalvani.com 10.0.1.20
Server:        10.0.1.20
Address:    10.0.1.20#53

syno.jehanalvani.com    canonical name = dynamic.jehanalvani.com.
Name:    dynamic.jehanalvani.com
Address: 10.0.1.20

Boom. That's what I want to see.

DHCP configuration

The next step is to tell the clients inside the network to use this nameserver. Clients inside the network needs to know to send requests to my nameserver. If you're configuring for your network, you might prefer not to set DHCP name servers to the your internal server, instead electing to give manual DNS server to specific clients. I wanted to be able to use any device on the network to reach these URIs, so I opted to configure eero's DHCP server to direct all clients to my internal nameserver.

DHCP Config

Caveat

On a reddit thread, someone asked if this configuration works with eero Plus. The short answer is: yes! The long answer is: yes, but with some qualifications.

eero hasn't published much about how eero Plus works. However, it seems to hijack outbound DNS requests, sending the request to a nameserver eero controls. It's important to note that this only affects outbound DNS requests, so requests that say inside your network still work, as long as there is a responder to accept the requests. In the configuration above, that means that any records in the defined zones will be successful, but anything that needs to be forwarded to an upstream server will be hijacked by eero Plus.

This breaks services like Unlocator and Unblock-Us which rely on their own DNS servers receiving all requests, and interpreting specific requests. I had to disable eero Plus for the time being, since I make use of these services (as you can tell if you're familiar with the nameservers I configured as forwarders).

Is it worth it?

Obviously, that depends on your needs and your level of comfort. I have been happy with this setup for the year+ that I've been using it. However, as soon as eero adds support for NAT hairpinning, I'll happily pull it out. This does introduce a bit of fragility I don't care for, mostly in that it forces my Synology to be powered on for anyone on my network to be able to reach any internet resources.

FiOS With an AirPort Extreme

I have FiOS, and I’m pretty happy with the service. The FiOS router, however, pretty much sucks. There’s been long-standing reports of a limited NAT table on the Actiontec routers, which leads to some pretty significant performance degradation over a relatively short period of time. I’ve noticed that it becomes overwhelmed when I’m streaming short shows from Netflix on my second-gen AppleTV, or long YouTube videos, and I’m not even bringing up what it’s like if I watch a feature-length flick. A temporary fix is to reboot the Actiontec router that Verizon provides, but after a day or two we’re back in the same boat.

Further, the router has limited uPnP and Bonjour support which leads to flaky AppleTV streaming from computers or other iOS devices. Bonjour printer discovery just doesn’t work, nor does ePrint discovery. And the overall wireless signal isn’t great. Again, the router sucks.

The fact that I noticed these issues, researched the root cause, and am inclined to fix the issue puts me into a very small group of people. And and most of us in this group would solve it the same way: use your own router. Sadly, it’s not an easy thing to do. Some features of the FiOS TV service, like Video on Demand and Remote DVR scheduling, run on an IP network across coax cable, called MoCA. The MoCA network uses the Actiontec router to get to the Internet for Video on Demand and as a connection point for the remote DVR manager (both using the iPhone/Android app and the FiOS website). So the Actiontec needs to stay online, connected to the coax network.

Marco Arment has a pretty good rundown of how to use your own router, but since he doesn’t have FiOS TV service, he stops short of a full solution for those of us who want our Video On Demand and remote DVR scheduling (from the iPhone/Android app or the web site) to continue to work. I’ll show you how I handled this.

Disclaimer: Follow my instructions at your own risk. Seriously. Your. Own. Risk.

Ingredients

  • ONT (Optical Network Terminal): The big white box that Verizon installed in your house. Mine is in my basement. It’s where the fiber terminates in your home and is converted to other media (phone, coax, and ethernet).
  • Actiontec router: I have the standard-issue MI424WR.
  • Primary Router: The one you want to be your primary router when we’re all said and done. I’m using an AirPort Extreme[1]. I’m going to assume you are, too.
  • NAT Router: You’ll need another (Yes, a third router) to do NAT translations from the MoCA network to your LAN. I picked up a Linksys E1000 from Amazon, and installed DD-WRT[2]. I’ll assume you’ve done the same.
  • Several (at least 4) straight-through Ethernet cables. Don’t pay crazy prices for them. They’re cheap from Monoprice, or really easy to make.

There’s no reason this shouldn’t work with other routers or software. I’ve tested with the AirPort Extreme and the E1000 running DD-WRT, so I’m documenting as such, but you could very well run other hardware and software while applying the same concepts.

Process

The design of the network is complex for your typical home network. But, if you’ve read this far, you’re a geek and we often have atypical setups. Don’t worry, you’re among friends, here.

I used this post as a starting point, but I made a few modification for ease-of-installation and scalability.

Let’s start with the ONT. Out of the box, your Actiontec is plugged into the coax port on the ONT, and there’s nothing plugged into the ONT’s ethernet port. Verizon actually leaves the ethernet port disabled, unless you call them to have it turned on.

In the end, you’re going to leave the Actiontec plugged into the coax port, but you’ll have Verizon turn on the ethernet port. The ethernet port will connect to your AirPort Extreme’s WAN interface. One of the LAN ports on your AirPort Extreme will connect to the WAN port on your E1000, which will have one of its LAN ports connected to the WAN ethernet port of the Actiontec. It’ll look like this:

Network Diagram

Network Diagram

Preparation

  1. Before getting started, if you have any outstanding issues with your service, call Verizon and resolve them, now. You’ll need to start with a system that’s working exactly as designed.
  2. If you haven’t already, enable the Remote DVR feature with Verizon. You if you’re using an AirPort router as your primary, you won’t be able to enable the feature after we’re done. If you’re using another router, you’ll need to spoof the WAN MAC address of the Actiontec on your primary router to be able to enable the feature later on. The easiest thing to do is enable it ahead of time.
  3. Read this post and have your internet connection moved from the coax port to the ethernet port.
    • Since you’re getting started with the Ethernet activated, you’ll have the coax port and WAN port on the Actiontec connected to the coax and ethernet port on the ONT, respectively.
  4. Read this post from beginning to end, at least once before getting started. Like I said, it’s complex. It’s worth taking the time to understand what you’re doing.

You’ll need to document the following before getting started. Here’s a subnet calculator to help out.

Device Interface Value
FiOS Service Public IP Address                                 
Public Subnet Mask
Public Default Gateway
AirPort Extreme WAN MAC Address
LAN MAC Address
LAN Network
LAN IP
LAN Subnet Mask
LAN Default Gateway
LAN Broadcast Address
Reserved LAN IP for E1000
Reserved LAN IP for Actiontec
NAT Router LAN MAC Address
WAN IP Address
WAN Subnet Mask

Now, we’ll start the step-by-step configuration.

AirPort Extreme

  1. Boot up the AirPort Extreme and connect your computer to one of the LAN Ports. You’ll obtain a DHCP address.
  2. You’ll want to create DHCP reservations for the E1000 and the NAT you’ll be creating. They’ll both be reserved to the MAC address of the WAN interface of your E1000. (I used 10.0.1.5 for the E1000, and 10.0.1.6 for the NAT). See the image below. 
  3. Click on the “Advanced” gear icon at the top of the window, then on the Port Mapping tab. Create a port mapping rule that looks like the image, below.[3] Name it whatever you want, but don’t advertise the service using Bonjour.
  4. Update the router.

DHCP Reservartions

Port Mapping

E1000

  1. Disconnect from your AirPort and plug into one of the LAN ports on the E1000. You’ll get a DHCP address.

  2. Browse to the E1000’s management interface (the Gateway address you pulled from DHCP).

  3. Connect the WAN port of the E1000 to a LAN port of your AirPort Extreme. The E1000 should pull the DHCP address you reserved for it (in my case, I reserved 10.0.1.5). (Look in the upper-right of any page).

    Under Security > Firewall, disable the SPI Firewall.

  4. Under Administration > Management, scroll to “Remote Access” and enable Web GUI Management.[4]

  5. At this point, your computer should be able to ping the AirPort Extreme by pinging the E1000’s WAN interface gateway address (which is the AirPort Extreme - 10.0.1.1).

  6. Under Setup > Basic Setup, scroll down to Network Setup and assign the E1000 an IP address in the same network as the public IP.
    1. Set the Gateway IP to the LAN IP of the AirPort Extreme.
  7. Now you’ll do the one-to-one NAT. The goal of this is to eventually present the Actiontec on the network created by the AirPort Extreme with an IP address on the AirPort’s network, allowing the Actiontec to get to the Internet.
    1. Put your computer on the network created by the AirPort, and browse to the E1000.

    2. Under Administration > Commands, you’ll see a text field, and several buttons. You use the text field to enter commands used by the router for different functions. The first series of commands you’ll need is a startup script that logically splits the WAN interface into two subinterfaces. One for the E1000, and one for the NATed Actiontec.

      Fill your values into the script below:

      # Save Statup
          WANIF=`get_wanface`
          ifconfig $WANIF:1 [Reserved IP for E1000]  netmask [AirPort LAN Netmask] broadcast [AirPort LAN Broadcast]
          ifconfig $WANIF:2 [Reserved IP for Actiontec] netmask [AirPort LAN Netmask] broadcast [AirPort LAN Broadcast]
      

      Mine looks like this:

      # Save Statup
          WANIF=`get_wanface`
          ifconfig $WANIF:1 10.0.1.5 netmask 255.255.255.0 broadcast 10.0.1.255
          ifconfig $WANIF:2 10.0.1.6 netmask 255.255.255.0 broadcast 10.0.1.255
      

      Click “Save Startup” button to save the script as a startup script.

    3. Now we need to add a firewall script that will translate the NATed address of the Actiontec to the DHCP external IP address that the Actiontec will be expecting[5].

      Again, fill your values into the script below:

       # Save Firewall
          iptables -t nat -I PREROUTING -d [Reserved IP for Actiontec] -j DNAT --to-destination [Public IP Address]
          iptables -t nat -I POSTROUTING -s [Public IP Address] -j SNAT --to-source [Reserved IP for Actiontec]
          iptables -I FORWARD -d [Public IP Address] -j ACCEPT 
      

      Mine looks like this:

      # Save Firewall
          iptables -t nat -I PREROUTING -d 10.0.1.6 -j DNAT --to-destination 50.50.25.25
          iptables -t nat -I POSTROUTING -s 50.50.25.25 -j SNAT --to-source 10.0.1.6
          iptables -I FORWARD -d 50.50.25.25 -j ACCEPT 
      
  8. Click “Apply Settings” then “Save”.

Actiontec

  1. Connect your laptop to the Actiontec and log into its web interface.
  2. Under My Network > Connection Properties > Broadband Connection (Ethernet), you’ll set a static IP, using the same IP it has pulled from Verizon via DHCP. Make sure to set the appropriate DNS servers, as well[6].
  3. Connect the WAN Port of the Actiontec to a LAN port of the E1000.

AirPort Extreme

  1. Connect the ethernet port of the ONT to the WAN port of your AirPort Extreme.

You should be cooking with gas, now, kids. Test everything, including internet access on the AirPort Extreme network, on the Actiontec network. Video on Demand, and remote DVR scheduling.

Once everything is working the way you want it, disable wireless on the E1000 and the Actiontec.


  1. If you buy stuff from any of these Amazon links, I get a little kickback.  ↩

  2. Installing DD-WRT is a tricky process, and it varies by model. Here are the install instructions for the E1000, but you should read everything you can about this and be thorough. Take your time. Don’t rush it. Come back when you’re done.  ↩

  3. Port 4567 is supposedly open to permit Verizon to remotely upgrade the Actiontec Router. I’m not really down with that, and I’ve since removed the portmap, effectively blocking Verizon’s access into the Actiontec. I’ve noticed no ill effects since doing this, but YMMV.  ↩

  4. Thanks to Justin Bowers for help making the documentation more usable in the real-world.  ↩

  5. We’ll assign the Actiontec’s WAN IP statically in a bit.  ↩

  6. I chose to use OpenDNS, seems a little slower than the Verizon-provided DNS. I’m still not sure if I’m going to stick with it.  ↩