How to open firewall for Mysa thermostats

I just got four Mysa smart wifi thermostats to control my baseboard and in-floor heat. I run OpenWrt 19.07.1, and I utilize its OpenVPN client, so that my router sends all my intenet traffic over my VPN service, which works very well.

After having my fancy wifi thermostats fail miserably to connect to the Mysa servers to allow me to control them outside my house, support said "you need to enable UPnP." I balked, and asked them for specifics, and they sent me the following information about opening specific ports and whitelisting stuff.

Can some network gurus please help me translate this into firewall rules (something I've never done before) and let me know if any of these items are more dangerous than they appear. I'm not stoked on opening up my LAN to the world, but I just spend a stupid amount of cash and I can't return them, so that's life. I might try to open the firewall up just long enough to complete the thermostat installation step and let the thermostats ping for updates, and then close it back up again one port at a time and see if any thermostat functionality breaks.

Here's what Mysa support tells me:

In order for Mysa to connect to the servers as well as receive any updates the following ports need to be opened:

  • 8883 this is the primary way Mysa sends data to and from the cloud.
  • 443 is also used to access cloud information.
  • HomeKit requires port 57959 to be open.
  • 123 is used for accessing the timezone for the thermostat.
  • 67 or 68 are also required for DHCP.

If you can, ensure these are open and the following sites are whitelisted. This will ensure communication between our servers and your Mysa device is open!

So after reading a post on whitelists and stewing over some basic firewall examples here's my first stab at this in untested pseudo-code to convey my rudimentary understanding of firewall rules:

# In /etc/dnsmasq.conf:
     # 2 domains that Mysa technical support asks to whitelist:
     list     ipset     '/a3q27gia9qg3zy.iot.us-east-1.amazonaws.com/whitelist'
     list     ipset     '/devices10010.getmysa.com/whitelist'

# In /etc/config/firewall
config ipset
     option name     'whitelist'
     option match    'dest_net'
     option family   'ipv4'

config rule
     option name     'Allow whitelist ipset'
     option src      'lan'
     option dest     'wan'
     option ipset    'whitelist'
     option target   'ACCEPT'

config rule
          option     name          'Accept WAN to LAN for (4) Mysa Thermostats'
          option     target        'ACCEPT'
          option     src           'wan'
          option     dest          'lan'

     list option     dest_mac     '1A:2B:3C:4D:5E:6F'     # Downstairs Bath thermostat
     list option     dest_mac     '2B:3C:4D:5E:6F:7A'     # Upstais Bath thermostat
     list option     dest_mac     '3C:4D:5E:6F:7A:8B'     # Living Room thermostat
     list option     dest_mac     '4D:5E:6F:7A:8B:9C'     # Bedroom thermostat

          # Per Mysa support, the following ports should be open:
          #      67,68 are for DHCP
          #      123 is used for accessing the timezone for the thermostat
          #      443 is used to access cloud information
          #      8883 is the primary way Mysa sends data to and from the cloud
          #      57959 is required by HomeKit
          option     src_port     '67 68 123 443 8883 57959'

Does it work when you disconnect the VPN?

1 Like

Gosh, I dunno: I never disable the VPN on my router. It's on a kill switch, so if the VPN provider goes down, my internet comes to a halt. I've not really wanted to go into the config and comment this stuff out, it was kind of a headache to set up and get running correctly in the first place.

I had considered switching to the stock LinkSys boot partition on my router (WRT3200ACM) and rebooting to see what would happen with these little thermostats, but I don't know if it would yield any useful information: If they suddenly work fine, where does that get me?

I had also considered installing and enabling miniupnp and just watching the logfiles to see exactly what holes these little Mysa thermostats are trying poke in my network security, but again, I'm not sure that would be anything more than academic, when all I really want to do is get the damned things working! :slight_smile:

If it works, then you need to set up PBR to bypass the VPN:
https://openwrt.org/docs/guide-user/network/routing/pbr

Yes VPNs don't allow incoming connections anyway, opening ports on your end won't change that.

So most sensibly designed IOTs use only outgoing connections, and its even better to use standard ports since ISPs and VPNs may block other than 80, 443, etc.

1 Like

Ah, I see. Since I always have my wireguard VPN connection enabled on the OpenWrt router, it sounds like I will need to enable a VPN routing policy. I think I'm in a little over my head here!

Could someone kindly help me develop a VPN policy configuration which would route traffic to and from my Mysa thermostat controllers by mac address, over the big bad unadulterated internet, bypassing my VPN? Bonus points for locking it down to specific ports, and traffic originating from / going to two specific domains specified by Mysa support.

This is my rough stab at it. I'm not sure if I need to have both an outgoing policy, where 'src' is the thermostat and dest are Mysa's servers; and, an incoming policy, where 'src' is Mysa's servers and dest are the thermostats.

# in /etc/config/vpn-policy-routing:
config policy
     option name          'Mysa Thermostat Controllers'
     option interface     'wan'

     option src_addr      '1A:2B:3C:4D:5E:6F 2B:3C:4D:5E:6F:7A 3C:4D:5E:6F:7A:8B 4D:5E:6F:7A:8B:9C'
     option src_port      '67 68 123 443 57959'

     option dest_addr     'a3q27gia9qg3zy.iot.us-east-1.amazonaws.com devices10010.getmysa.com'

One unknown is whether I need also to make changes to the firewall.

What follows are my wireguard configs, in case it helps illuminate my setup.

Relevant part of /etc/config/vpn-policy-routing:

config vpn-policy-routing 'config'
	option enabled '0'
	option verbosity '2'
	option strict_enforcement '1'
	option src_ipset '0'
	option dest_ipset 'dnsmasq.ipset'
	option ipv6_enabled '0'
	list   supported_interface ''
	list   ignored_interface 'vpnserver wgserver'
	option boot_timeout '30'
	option iptables_rule_option 'append'
	option iprule_enabled '0'
	option webui_enable_column '0'
	option webui_protocol_column '0'
	option webui_chain_column '0'
	option webui_sorting '1'
	list webui_supported_protocol 'tcp'
	list webui_supported_protocol 'udp'
	list webui_supported_protocol 'tcp udp'
	list webui_supported_protocol 'icmp'
	list webui_supported_protocol 'all'

Relevant part of /etc/config/network:

config interface 'WGINTERFACE'
	option proto 'wireguard'
	list addresses '12.34.56.789'
	option private_key 'PrivateKeyHereWM='
	option listen_port '56789'
	option force_link '1'

config wireguard_WGINTERFACE
	option endpoint_port '56789'
	list allowed_ips '0.0.0.0/0'
	option route_allowed_ips '1'
	option endpoint_host '89.12.34.567'
	option public_key 'PublicKeyHereVU='
	option description 'wireguard vpn server'

Relevant part of /etc/config/firewall:

config zone
	option name 'WGZONE'
	option mtu_fix '1'
	option input 'REJECT'
	option forward 'REJECT'
	option masq '1'
	option output 'ACCEPT'
	option network 'WGINTERFACE'

config forwarding
	option dest 'WGZONE'
	option src 'lan'
1 Like

Use only src_addr and interface for the policy.
Remove the rest options for the time being, at least for testing.
Also allow the firewall traffic forwarding from LAN to WAN.
If that works, you can create a more restrictive policy.

It seems to work. These are the config changes I ended up making. Do they seem sane?

To /etc/config/vpn-policy-config:

config policy
	option interface 'wan'
	option name 'Mysa Thermostats'
	option src_addr 'AB:CD:8E:FG:B2:CA AB:CD:8E:FG:4A:3A'
	option src_port '67 68 123 443 57959'

To /etc/config/firewall:

config redirect
	option src 'wan'
	option name 'MysaPortForwarding'
	option src_dport '67 68 123 443 57959'
	option target 'DNAT'
	option dest_mac 'AB:CD:8E:FG:B2:CA AB:CD:8E:FG:4A:3A'
	option dest 'lan'

One major problem I've noticed is that the changes made to the VPN Policy Routing cause an error when doing a fresh reboot of the router; I then have to go in and start the errored-out service, and then everything magically works fine. Obviously I can't be around to do this every time the router should happen to reboot.

When I do a fresh reboot the router and go to the 'VPN Policy Routing' page in Luci, it shows this ugly error:

When I then click 'Start' to re-start the service, it works:

From a ssh session into the router, the command-line corroborates this behavior; before reloading vpn-policy-support, none of the Mysa rules are shown in the VPN_PREROUTING chain. After issuing the reload command, they appear. This appears in the output I'm attaching to the end of this message.

In other words, whenever the router reboots, I have to go in and manually (re)start the vpn-policy-support service, which has initially errored out. I wonder if it's a timing issue, since it takes some time to establish my wireguard vpn connection during a fresh router reboot.

What follows are the logfiles requested here, when reporting issues relating to vpn policy-based routing:

Contents of /etc/config/vpn-policy-routing

root@OpenWrt:~# cat /etc/config/vpn-policy-routing 

config vpn-policy-routing 'config'
	option verbosity '2'
	option strict_enforcement '1'
	option src_ipset '0'
	option dest_ipset 'dnsmasq.ipset'
	option ipv6_enabled '0'
	list supported_interface ''
	list ignored_interface 'vpnserver wgserver'
	option boot_timeout '30'
	option iptables_rule_option 'append'
	option iprule_enabled '0'
	option webui_enable_column '0'
	option webui_protocol_column '0'
	option webui_chain_column '0'
	option webui_sorting '1'
	list webui_supported_protocol 'tcp'
	list webui_supported_protocol 'udp'
	list webui_supported_protocol 'tcp udp'
	list webui_supported_protocol 'icmp'
	list webui_supported_protocol 'all'
	option enabled '1'

config include
	option path '/etc/vpn-policy-routing.netflix.user'
	option enabled '0'

config include
	option path '/etc/vpn-policy-routing.aws.user'
	option enabled '0'

config policy
	option interface 'wan'
	option name 'Mysa Thermostats'
	option src_addr '8X:XX:XX:XX:XX:XX 8Y:YY:YY:YY:YY:YY'
	option src_port '67 68 123 443 57959'

Contents of running vpn-policy-routing support -d (note there are no references to the Mysa devices here)

root@OpenWrt:/etc/init.d# ./vpn-policy-routing support -d
vpn-policy-routing 0.2.1-7 running on OpenWrt 19.07.1. WAN (IPv4): wan/dev/12.34.56.7.
============================================================
Dnsmasq version 2.80  Copyright (c) 2000-2018 Simon Kelley
Compile time options: IPv6 GNU-getopt no-DBus no-i18n no-IDN DHCP DHCPv6 no-Lua TFTP conntrack ipset auth DNSSEC no-ID loop-detect inotify dumpfile
============================================================
Routes/IP Rules
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         *               0.0.0.0         U     0      0        0 WGINTERFACE
12.34.56.7      *               255.255.255.0   U     0      0        0 eth1.2
89.01.23.456    047-033-050-001 255.255.255.255 UGH   0      0        0 eth1.2
192.168.99.0    *               255.255.255.0   U     0      0        0 br-lan
0:	from all lookup local
32764:	from all fwmark 0x20000/0xff0000 lookup 202
32765:	from all fwmark 0x10000/0xff0000 lookup 201
32766:	from all lookup main
32767:	from all lookup default
IPv4 Table 201: default via 12.34.56.7 dev eth1.2
IPv4 Table 201 Rules:
32765:	from all fwmark 0x10000/0xff0000 lookup 201
IPv4 Table 202: default via 10.64.43.119 dev WGINTERFACE
IPv4 Table 202 Rules:
32764:	from all fwmark 0x20000/0xff0000 lookup 202
============================================================
IP Tables
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination

Chain INPUT (policy ACCEPT)
target     prot opt source               destination
VPR_INPUT  all  --  anywhere             anywhere             mark match 0x0/0xff0000

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
VPR_FORWARD  all  --  anywhere             anywhere             mark match 0x0/0xff0000
TCPMSS     tcp  --  anywhere             anywhere             tcp flags:SYN,RST/SYN /* !fw3: Zone wan MTU fixing */ TCPMSS clamp to PMTU
TCPMSS     tcp  --  anywhere             anywhere             tcp flags:SYN,RST/SYN /* !fw3: Zone WGZONE MTU fixing */ TCPMSS clamp to PMTU

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
VPR_OUTPUT  all  --  anywhere             anywhere             mark match 0x0/0xff0000

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination

Chain VPR_FORWARD (1 references)
target     prot opt source               destination

Chain VPR_INPUT (1 references)
target     prot opt source               destination

Chain VPR_OUTPUT (1 references)
target     prot opt source               destination
============================================================
Current ipsets
create wan hash:net family inet hashsize 1024 maxelem 65536 comment
create WGINTERFACE hash:net family inet hashsize 1024 maxelem 65536 comment
============================================================
Your support details have been logged to '/var/vpn-policy-routing-support'. [✓]

Reloading and updated contents of vpn-policy-routing command (and now you will see they Mysa devices show up)

root@OpenWrt:/etc/init.d# ./vpn-policy-routing reload
Creating table 'wan/eth1.2/12.34.56.7' [✓]
Creating table 'WGINTERFACE/90.12.34.256' [✓]
Routing 'Mysa Thermostats' via wan [✓]
vpn-policy-routing 0.2.1-7 started with gateways:
wan/eth1.2/12.34.56.7
WGINTERFACE/90.12.34.256 [✓]
root@OpenWrt:/etc/init.d# ./vpn-policy-routing support
vpn-policy-routing 0.2.1-7 running on OpenWrt 19.07.1. WAN (IPv4): wan/dev/12.34.56.7.
============================================================
Dnsmasq version 2.80  Copyright (c) 2000-2018 Simon Kelley
Compile time options: IPv6 GNU-getopt no-DBus no-i18n no-IDN DHCP DHCPv6 no-Lua TFTP conntrack ipset auth DNSSEC no-ID loop-detect inotify dumpfile
============================================================
Routes/IP Rules
default         *               0.0.0.0         U     0      0        0 WGINTERFACE
IPv4 Table 201: default via 12.34.56.7 dev eth1.2
IPv4 Table 201 Rules:
32763:	from all fwmark 0x10000/0xff0000 lookup 201
IPv4 Table 202: default via 10.64.43.119 dev WGINTERFACE
IPv4 Table 202 Rules:
32762:	from all fwmark 0x20000/0xff0000 lookup 202
============================================================
IP Tables PREROUTING
-N VPR_PREROUTING
-A VPR_PREROUTING -p udp -m mac --mac-source 88X:XX:XX:XX:XX:XX -m multiport --sports 67,68,123,443,57959 -m comment --comment Mysa_Thermostats -c 0 0 -j MARK --set-xmark 0x10000/0xff0000
-A VPR_PREROUTING -p tcp -m mac --mac-source 88X:XX:XX:XX:XX:XX -m multiport --sports 67,68,123,443,57959 -m comment --comment Mysa_Thermostats -c 0 0 -j MARK --set-xmark 0x10000/0xff0000
-A VPR_PREROUTING -p udp -m mac --mac-source 8Y:YY:YY:YY:YY:YY -m multiport --sports 67,68,123,443,57959 -m comment --comment Mysa_Thermostats -c 0 0 -j MARK --set-xmark 0x10000/0xff0000
-A VPR_PREROUTING -p tcp -m mac --mac-source 8Y:YY:YY:YY:YY:YY -m multiport --sports 67,68,123,443,57959 -m comment --comment Mysa_Thermostats -c 0 0 -j MARK --set-xmark 0x10000/0xff0000
-A VPR_PREROUTING -m set --match-set WGINTERFACE dst -c 0 0 -j MARK --set-xmark 0x20000/0xff0000
-A VPR_PREROUTING -m set --match-set wan dst -c 0 0 -j MARK --set-xmark 0x10000/0xff0000
============================================================
IP Tables FORWARD
-N VPR_FORWARD
============================================================
IP Tables INPUT
-N VPR_INPUT
============================================================
IP Tables OUTPUT
-N VPR_OUTPUT
============================================================
Current ipsets
create wan hash:net family inet hashsize 1024 maxelem 65536 comment
create WGINTERFACE hash:net family inet hashsize 1024 maxelem 65536 comment
============================================================
Your support details have been logged to '/var/vpn-policy-routing-support'. [✓]
root@OpenWrt:/etc/init.d# ./vpn-policy-routing support -d
vpn-policy-routing 0.2.1-7 running on OpenWrt 19.07.1. WAN (IPv4): wan/dev/12.34.56.7.
============================================================
Dnsmasq version 2.80  Copyright (c) 2000-2018 Simon Kelley
Compile time options: IPv6 GNU-getopt no-DBus no-i18n no-IDN DHCP DHCPv6 no-Lua TFTP conntrack ipset auth DNSSEC no-ID loop-detect inotify dumpfile
============================================================
Routes/IP Rules
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         *               0.0.0.0         U     0      0        0 WGINTERFACE
12.34.56.7      *               255.255.255.0   U     0      0        0 eth1.2
89.10.23.45    047-033-050-001 255.255.255.255 UGH   0      0        0 eth1.2
192.168.99.0    *               255.255.255.0   U     0      0        0 br-lan
0:	from all lookup local
32762:	from all fwmark 0x20000/0xff0000 lookup 202
32763:	from all fwmark 0x10000/0xff0000 lookup 201
32766:	from all lookup main
32767:	from all lookup default
IPv4 Table 201: default via 47.33.50.1 dev eth1.2
IPv4 Table 201 Rules:
32763:	from all fwmark 0x10000/0xff0000 lookup 201
IPv4 Table 202: default via 10.64.43.119 dev WGINTERFACE
IPv4 Table 202 Rules:
32762:	from all fwmark 0x20000/0xff0000 lookup 202
============================================================
IP Tables
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination
VPR_PREROUTING  all  --  anywhere             anywhere             mark match 0x0/0xff0000

Chain INPUT (policy ACCEPT)
target     prot opt source               destination
VPR_INPUT  all  --  anywhere             anywhere             mark match 0x0/0xff0000

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
TCPMSS     tcp  --  anywhere             anywhere             tcp flags:SYN,RST/SYN /* !fw3: Zone wan MTU fixing */ TCPMSS clamp to PMTU
TCPMSS     tcp  --  anywhere             anywhere             tcp flags:SYN,RST/SYN /* !fw3: Zone WGZONE MTU fixing */ TCPMSS clamp to PMTU
VPR_FORWARD  all  --  anywhere             anywhere             mark match 0x0/0xff0000

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
VPR_OUTPUT  all  --  anywhere             anywhere             mark match 0x0/0xff0000

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination

Chain VPR_FORWARD (1 references)
target     prot opt source               destination

Chain VPR_INPUT (1 references)
target     prot opt source               destination

Chain VPR_OUTPUT (1 references)
target     prot opt source               destination

Chain VPR_PREROUTING (1 references)
target     prot opt source               destination
MARK       udp  --  anywhere             anywhere             MAC 8X:XX:XX:XX:XX:XX multiport sports bootps,bootpc,ntp,https,57959 /* Mysa_Thermostats */ MARK xset 0x10000/0xff0000
MARK       tcp  --  anywhere             anywhere             MAC 8X:XX:XX:XX:XX:XX multiport sports bootps,bootpc,ntp,https,57959 /* Mysa_Thermostats */ MARK xset 0x10000/0xff0000
MARK       udp  --  anywhere             anywhere             MAC 8Y:YY:YY:YY:YY:YY multiport sports bootps,bootpc,ntp,https,57959 /* Mysa_Thermostats */ MARK xset 0x10000/0xff0000
MARK       tcp  --  anywhere             anywhere             MAC 8Y:YY:YY:YY:YY:YY multiport sports bootps,bootpc,ntp,https,57959 /* Mysa_Thermostats */ MARK xset 0x10000/0xff0000
MARK       all  --  anywhere             anywhere             match-set WGINTERFACE dst MARK xset 0x20000/0xff0000
MARK       all  --  anywhere             anywhere             match-set wan dst MARK xset 0x10000/0xff0000
============================================================
Current ipsets
create wan hash:net family inet hashsize 1024 maxelem 65536 comment
create WGINTERFACE hash:net family inet hashsize 1024 maxelem 65536 comment
============================================================
Your support details have been logged to '/var/vpn-policy-routing-support'. [✓]
1 Like

Is there any specific reason, why you are using both an outdated firmware and an outdated version of vpn-policy-routing?

Even if you stay in the the 19.07 branch, the current firmware version would be 19.07.8 and the vpn-policy-routing there seems to be 0.3.2

1 Like

Only because everything has been working fine for me thus far, for more than a year, and I’m terrified that if I change the firmware this device will start to exhibit errors and that Sonos speaker will start to get drop outs and … you know how it goes.

I have some spare time, I think I’ll try to do a backup, then figure out how to diff all my config files against stock so I can easily transfer all my settings to a fresh firmware. Hope nothing breaks.

Pretty sure you can safely keep the configs across minor release upgrades.