Want to restrict a smart thermostat's WAN access/what is min set of ports needed?

I'd like to restrict a smart thermostat on my IoT VLAN. I setup two traffic rules:

  1. udp/53 from it's IP to my pi-hole box
  2. tcp/443 and 80 to WAN

Even with these two, the device claims to offline/cannot connect to the internet. Any thoughts on what else I need to open up?

Note that if I temporarily change my IoT zone's "Allow forward to destination zones" policy from "unspecified" to "WAN" the thermostat immediately goes into "connected/online" mode.

Thanks for the ideas.

It almost certainly depends on the specific brand/model thermostat. There are so many ways that these things can work, so the best option would be to provide full access to the internet and then monitor the connections it makes.

Look at the PiHole's responses here -- in the event that PiHole has blocked any of the domains that your thermostat uses, it would cause DNS failures and thus the device would think it is offline. You may need to allow list certain domains in that context.

This assumes that it uses those ports for connection to some service (such as a cloud service or other)... this may or may not be the right set of ports.

Also keep in mind that just restricting ports doesn't necessarily restrict what can be done/sent over those ports.

Let's take a look at your complete firewall file to understand how you have attempted to create these rules.

2 Likes

To allow only 80 and 443:

uci add firewall rule
uci set firewall.@rule[-1].name='IoT_00 (default, block)'
uci set firewall.@rule[-1].src='lan'
uci add_list firewall.@rule[-1].src_mac='aa:bb:cc:dd:ee:ff'
uci set firewall.@rule[-1].dest='wan'
uci set firewall.@rule[-1].proto='all'
uci set firewall.@rule[-1].target='DROP'
uci commit firewall

uci add firewall rule
uci set firewall.@rule[-1].name='IoT_01 (out, tcp 80)'
uci add_list firewall.@rule[-1].proto='tcp'
uci set firewall.@rule[-1].src='lan'
uci add_list firewall.@rule[-1].src_mac='aa:bb:cc:dd:ee:ff'
uci set firewall.@rule[-1].dest='wan'
uci set firewall.@rule[-1].dest_port='80'
uci set firewall.@rule[-1].target='ACCEPT'
uci commit firewall

uci add firewall rule
uci set firewall.@rule[-1].name='IoT_02 (out, tcp 443)'
uci add_list firewall.@rule[-1].proto='tcp'
uci set firewall.@rule[-1].src='lan'
uci add_list firewall.@rule[-1].src_mac='aa:bb:cc:dd:ee:ff'
uci set firewall.@rule[-1].dest='wan'
uci set firewall.@rule[-1].dest_port='443'
uci set firewall.@rule[-1].target='ACCEPT'
uci commit firewall

service firewall restart

This is exactly what I did! In approx 10 h, it made 266 connections. None of them were blocked by pi-hole:

      2 fwuprod.clouddevice.io
     40 provprod.clouddevice.io
     88 weather.clouddevice.io
    136 lcc-prodsf-lcc02sf-iothub.azure-devices.net

I know. For others curious, see this thread.

I'll spare you the complete one and just show the two rules unless you think there value in see the entire one:

/etc/config/firewall
config rule
  list proto 'udp'
  option src 'iot'
  option dest 'lxc'
  option dest_port '53'
  option target 'ACCEPT'
  option family 'ipv4'
  option name 'IoT DNS whitelist'
  list src_ip '10.9.5.107'

config rule
  option name 'thermostat'
  list proto 'tcp'
  option src 'iot'
  option dest 'wan'
  option target 'ACCEPT'
  option dest_port '443 80'
  list src_ip '10.9.5.107'
  option family 'ipv4'

I have the entire IOT zone forwarding to REJECT so no access by default. I don't think a traffic rule is needed, no?

These are connections or dns queries to pihole? They are different things.

Is the default forwarding policy set to drop/reject?

I believe these are queries found by searching for the device in pi-hole's long-term data filtered by hostname. No sure how to see connections vs queries.

Yes!

You can try with tcpdump to see what connections are opening from the thermostat.

Does this look right?

tcpdump -i eth0 host 10.9.5.107 -U -s0 -w /tmp/dump.txt

That gives a non-text format that I recall importing into wirehark directly.

I don't see the reason to capture the whole packet. You are interested in the ports primarily.

What set of switches would you recommend?

Just that to see them on the screen. Or add the -w file to save it.

Well, this is interesting... seems to be using port 58755

# tcpdump -i eth0 host 10.9.5.107
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
06:38:27.736521 IP thermostat.lan.58755 > 20.49.110.135.5671: Flags [.], ack 3124799523, win 1475, length 0
06:38:27.885323 IP thermostat.lan.58755 > 20.49.110.135.5671: Flags [.], ack 1, win 1544, length 0
06:38:32.754060 ARP, Reply thermostat.lan is-at aa:bb:cc:dd:ee:ff  (oui Unknown), length 46
06:38:57.567921 IP thermostat.lan.58755 > 20.49.110.135.5671: Flags [P.], seq 0:741, ack 1, win 1544, length 741
06:38:57.782125 IP thermostat.lan.58755 > 20.49.110.135.5671: Flags [.], ack 86, win 1544, length 0

This is the source port. 5671 is the destination.

Hi,

How this IoT device gets his ip ?
If it's DHCP from your pihole, you have to allow also port 67.

Right. I am not allowing traffic on 5671 so this request should be ignored, no?

It is blocked, there is no return traffic from what I can see.

1 Like

Good question! I have this rule a bit further up in my /etc/config/firewall which allows it:

config rule
  option src 'iot'
  option target 'ACCEPT'
  list proto 'tcp'
  list proto 'udp'
  option dest_port '53 67 68 123'
  option name 'iot dhcp dns and ntpd'
  option family 'ipv4'

keep in mind that blocking this service (asb) will broke the service running from this device.