How to create correct firewall for IoT

I did set up a firewall for IOT devices with reject forwarding settings, however, this makes my IOT devices useless because now they can't reach Home Assistant out behind the firewall. IOT has its own wireless set up. How do I configure the server so that the IOT system can work correctly?

There’s multiple ways to accomplish this

The easiest - physically put the home assistant server in the same network as the rest of the IoT devices

Another - if you insist on keeping the home assistant server on a different network, you’ll need to allow forward of the zone the home assistant is in to the IoT zone

1 Like

VLANs?

The best way to determine the "correct" firewall configuration is for you to explain your larger objectives (i.e. is the IoT network forbidden from reaching the other network(s)? forbidden from internet? Can the other network(s) reach the IoT network? etc.), and then we need to see your network and firewall configuration files:

Please copy the output of the following commands and post it here using the "Preformatted text </> " button:
grafik
Remember to redact passwords, MAC addresses and any public IP addresses you may have:

cat /etc/config/network
cat /etc/config/wireless
cat /etc/config/dhcp
cat /etc/config/firewall

IoT network should be if possible forbidden from the rest of the world but all the stuff should obviously be able to communicate to IoT server. When all the local stuff finally works I want to be able access to IoT server from the outside world with the help of secure tunneling.
Obviously, for easy solution, I could connect IoT server to the same wifi as my network of things, but server access over wifi is really not recommended and it is at the moment connected to the local vlan. Everything actually works but now I started to migrate all the IoT stuff to a separate network.

Put commands where? I have not seen a terminal in Luci

Thanks

Home Assistant is connected to my local vlan. I could disconnect it and connect to the same wifi as IoT but server access over wifi is not recommended. When some update screws it up I would be in big trouble. Also, I want at some point to set up an outside connection to the server with some secure tunneling.

Then it should be just as easy as editing your local lan zone and adding the IoT zone in the “allow forward to destination zone” (along with the wan that should already be listed there). This will allow the lan devices to see the IoT devices, but the IoT devices won’t see the lan devices.

you will use the CLI by means of SSH. You can use any standard SSH client (built in for Mac OS and Linux, Windows users typically use PuTTY).

Username is root, password is either blank (for a new install), or whatever you set in the LuCI web interface.

At the moment it seems that my IoT server is able to communicate to IoT zone and firewall rule for IoT says forwarding reject, but when I log on to IoT wifi with my phone I can browse the internet without any problems. (I think I shouldn't be able to do that?) It is probably best when I could also move homeassistant server in IoT bubble but I have no idea if it is possible.


root@WRT1900ac:~# cat /etc/config/network

config interface 'loopback'
        option device 'lo'
        option proto 'static'
        option ipaddr '127.0.0.1'
        option netmask '255.0.0.0'

config globals 'globals'
        option ula_prefix 'fd27:xxxxxx'

config device
        option name 'br-lan'
        option type 'bridge'
        list ports 'lan1'
        list ports 'lan2'
        list ports 'lan3'
        list ports 'lan4'

config device
        option name 'lan1'
        option macaddr '94:xxxxxx'

config device
        option name 'lan2'
        option macaddr '94:xxxxxx'

config device
        option name 'lan3'
        option macaddr '94:xxxxxx'

config device
        option name 'lan4'
        option macaddr '94:xxxxxx'

config interface 'lan'
        option device 'br-lan'
        option proto 'static'
        option ipaddr '192.168.1.1'
        option netmask '255.255.255.0'
        option ip6assign '60'

config device
        option name 'wan'
        option macaddr '94:xxxxxx'

config interface 'wan'
        option device 'wan'
        option proto 'dhcp'

config interface 'wan6'
        option device 'wan'
        option proto 'dhcpv6'

config interface 'Quest'
        option proto 'static'
        option device 'br-lan'
        option ipaddr '10.20.30.40'
        option netmask '255.255.255.0'

config interface 'IOT'
        option proto 'static'
        option device 'br-lan'
        option ipaddr '172.16.0.1'
        option netmask '255.255.255.0'

root@WRT1900ac:~# cat /etc/config/wireless

config wifi-device 'radio0'
        option type 'mac80211'
        option path 'soc/soc:pcie@82000000/pci0000:00/0000:00:02.0/0000:02:00.0'
        option channel '1'
        option band '2g'
        option htmode 'HT20'
        option cell_density '0'
        option country 'EE'

config wifi-iface 'default_radio0'
        option device 'radio0'
        option network 'lan'
        option mode 'ap'
        option macaddr '94:xxxxxx'
        option ssid 'Y'
        option dtim_period '3'
        option ieee80211r '1'
        option ft_over_ds '0'
        option ft_psk_generate_local '1'
        option encryption 'psk2'
        option key 'xxx'

config wifi-device 'radio1'
        option type 'mac80211'
        option path 'soc/soc:pcie@82000000/pci0000:00/0000:00:03.0/0000:03:00.0'
        option channel '36'
        option band '5g'
        option htmode 'VHT80'
        option country 'US'
        option cell_density '0'

config wifi-iface 'default_radio1'
        option device 'radio1'
        option network 'lan'
        option mode 'ap'
        option macaddr '94:xxxxxx'
        option ssid 'Y5'
        option dtim_period '3'
        option encryption 'psk2'
        option key 'xxxxx'

config wifi-iface 'wifinet2'
        option device 'radio0'
        option mode 'ap'
        option ssid 'YQ'
        option encryption 'psk2'
        option key 'xxxxxx'
        option network 'Quest'
        option dtim_period '3'
        option ieee80211r '1'
        option ft_over_ds '0'
        option ft_psk_generate_local '1'

config wifi-iface 'wifinet3'
        option device 'radio0'
        option mode 'ap'
        option ssid 'Y_iot'
        option encryption 'psk2'
        option key 'xxxxxx'
        option network 'IOT'

root@WRT1900ac:~# cat /etc/config/dhcp

config dnsmasq
        option domainneeded '1'
        option localise_queries '1'
        option rebind_protection '1'
        option rebind_localhost '1'
        option local '/lan/'
        option domain 'lan'
        option expandhosts '1'
        option authoritative '1'
        option readethers '1'
        option leasefile '/tmp/dhcp.leases'
        option resolvfile '/tmp/resolv.conf.d/resolv.conf.auto'
        option localservice '1'
        option ednspacket_max '1232'

config dhcp 'lan'
        option interface 'lan'
        option start '100'
        option limit '150'
        option leasetime '12h'
        option dhcpv4 'server'
        option dhcpv6 'server'
        option ra 'server'
        option ra_slaac '1'
        list ra_flags 'managed-config'
        list ra_flags 'other-config'

config dhcp 'wan'
        option interface 'wan'
        option ignore '1'

config odhcpd 'odhcpd'
        option maindhcp '0'
        option leasefile '/tmp/hosts/odhcpd'
        option leasetrigger '/usr/sbin/odhcpd-update'
        option loglevel '4'

config domain
        option name 'Thermostat'
        option ip '192.xxxxx'

config domain
        option name 'Yg'
        option ip '192.xxxxxxx'

config host
        option ip '192.xxxxxx'
        option mac '2C:xxxxxx'
        option name 'Thermostat'
        option dns '1'

config host
        option mac '00:xxxxxx'
        option ip '192.xxxxx'
        option name 'WIRELESS-AC1200'
        option dns '1'

config domain
        option name 'Smartplug'
        option ip '192.xxxxx'

config host
        option name 'homeassistant'
        option ip '192.xxxxxx'
        option mac 'B8:xxxxxx'

config domain
        option name 'Temperature_probe'
        option ip '192.xxxxxx'

config dhcp 'Quest'
        option interface 'Quest'
        option start '100'
        option limit '150'
        option leasetime '12h'

config dhcp 'IOT'
        option interface 'IOT'
        option start '100'
        option limit '150'
        option leasetime '12h'

root@WRT1900ac:~# cat /etc/config/firewall

config defaults
        option input 'ACCEPT'
        option output 'ACCEPT'
        option forward 'REJECT'
        option synflood_protect '1'

config zone
        option name 'lan'
        list network 'lan'
        option input 'ACCEPT'
        option output 'ACCEPT'
        option forward 'ACCEPT'

config zone
        option name 'wan'
        list network 'wan'
        list network 'wan6'
        option input 'REJECT'
        option output 'ACCEPT'
        option forward 'REJECT'
        option masq '1'
        option mtu_fix '1'

config forwarding
        option src 'lan'
        option dest 'wan'

config rule
        option name 'Allow-DHCP-Renew'
        option src 'wan'
        option proto 'udp'
        option dest_port '68'
        option target 'ACCEPT'
        option family 'ipv4'

config rule
        option name 'Allow-Ping'
        option src 'wan'
        option proto 'icmp'
        option icmp_type 'echo-request'
        option family 'ipv4'
        option target 'ACCEPT'

config rule
        option name 'Allow-IGMP'
        option src 'wan'
        option proto 'igmp'
        option family 'ipv4'
        option target 'ACCEPT'

config rule
        option name 'Allow-DHCPv6'
        option src 'wan'
        option proto 'udp'
        option dest_port '546'
        option family 'ipv6'
        option target 'ACCEPT'

config rule
        option name 'Allow-MLD'
        option src 'wan'
        option proto 'icmp'
        option src_ip 'fe80::/10'
        list icmp_type '130/0'
        list icmp_type '131/0'
        list icmp_type '132/0'
        list icmp_type '143/0'
        option family 'ipv6'
        option target 'ACCEPT'

config rule
        option name 'Allow-ICMPv6-Input'
        option src 'wan'
        option proto 'icmp'
        list icmp_type 'echo-request'
        list icmp_type 'echo-reply'
        list icmp_type 'destination-unreachable'
        list icmp_type 'packet-too-big'
        list icmp_type 'time-exceeded'
        list icmp_type 'bad-header'
        list icmp_type 'unknown-header-type'
        list icmp_type 'router-solicitation'
        list icmp_type 'neighbour-solicitation'
        list icmp_type 'router-advertisement'
        list icmp_type 'neighbour-advertisement'
        option limit '1000/sec'
        option family 'ipv6'
        option target 'ACCEPT'

config rule
        option name 'Allow-ICMPv6-Forward'
        option src 'wan'
        option dest '*'
        option proto 'icmp'
        list icmp_type 'echo-request'
        list icmp_type 'echo-reply'
        list icmp_type 'destination-unreachable'
        list icmp_type 'packet-too-big'
        list icmp_type 'time-exceeded'
        list icmp_type 'bad-header'
        list icmp_type 'unknown-header-type'
        option limit '1000/sec'
        option family 'ipv6'
        option target 'ACCEPT'

config rule
        option name 'Allow-IPSec-ESP'
        option src 'wan'
        option dest 'lan'
        option proto 'esp'
        option target 'ACCEPT'

config rule
        option name 'Allow-ISAKMP'
        option src 'wan'
        option dest 'lan'
        option dest_port '500'
        option proto 'udp'
        option target 'ACCEPT'

config zone
        option name 'Quests'
        option output 'ACCEPT'
        option forward 'REJECT'
        option input 'REJECT'
        option mtu_fix '1'
        list network 'Quest'

config zone
        option name 'IOT'
        option output 'ACCEPT'
        list network 'IOT'
        option forward 'REJECT'
        option input 'REJECT'

config forwarding
        option src 'lan'
        option dest 'IOT'

config forwarding
        option src 'Quests'
        option dest 'wan'

config rule
        option name 'Quest DHCP DNS'
        option src 'Quests'
        option dest_port '53 67 68'
        option target 'ACCEPT'

root@WRT1900ac:~#

Currently, these two networks are setup on the same bridge as your main network. This is not a proper configuration.

Do you need the Quest and/or IOT networks to have ethernet connectivity, or are they wifi only?

You could reserve a port on the LAN switch for the IoT network, and connect the HA server there.

Hopefully you can show me how I could do it correctly.
Is it possible to separate guests and me in ethernet? With mac addresses?
I'm pretty sure that an IoT network will never need an ethernet connection. As for the guest network, it depends on the difficulty level of the setup :slight_smile:
Thanks

No, this is using different subnets (often discussed as VLANs).

Ok... so for wifi only, this becomes fairly easy.

This isn't difficult, but it does require potentially splitting a physical port off from your current br-lan (so you'd have 3 ports on your LAN and one for the guest network). Do you want to do it this way? It all depends what else might be on your guest network -- will there be wired devices?.


For the quest network, make the network config file look like this:

config device
        option name 'br-quest'
        option type 'bridge'

config interface 'quest'
        option proto 'static'
        option device 'br-quest'
        option ipaddr '10.20.30.40'
        option netmask '255.255.255.0'

Note that I have made everything lowercase -- this is best practice, but it also must be consistent across the other config files.
(technically, the bridge is only necessary if you plan to offer the network on multiple radios (2.4G + 5G) and/or multiple SSIDs, but it is easy to use a bridge, so you might as well).

Next, in the wireless file:

config wifi-iface 'wifinet2'
        option device 'radio0'
        option mode 'ap'
        option ssid 'YQ'
        option encryption 'psk2'
        option key 'xxxxxx'
        option network 'quest'
        option dtim_period '3'
        option ieee80211r '1'
        option ft_over_ds '0'
        option ft_psk_generate_local '1'

(just changing quest to lowercase)

and in the DHCP file:

config dhcp 'quest'
        option interface 'quest'
        option start '100'
        option limit '150'
        option leasetime '12h'

also just making it lowercase

and finally the firewall file:

config zone
        option name 'quests'
        option output 'ACCEPT'
        option forward 'REJECT'
        option input 'REJECT'
        option mtu_fix '1'
        list network 'quest'

config forwarding
        option src 'quests'
        option dest 'wan'

config rule
        option name 'Quest DHCP DNS'
        option src 'quests'
        option dest_port '53 67 68'
        option target 'ACCEPT'

(just correcting the case here, too)

Now the quest network can only reach the internet.

simplicity is highly relative, when somebody asks me or 6 year medical student to remove the appendix the answer about the simplicity of such an operation would be cardinally different.

You must also consider some differences here when I (probably) struggle with something, you are making simply changes to the setup file. I am sure there is an easier way to do this but at my level, I move around Luci GUI and change things there. Also I am not sure that in GUI I can change everything to lowercase

when I create a new device here don't I need also to bridge some ports here?
I suppose I need to create for IoT a similar new device br-iot?
Thanks

Ok... then leave it as is. All that matters is that it is consistent.

No, although it is possible you'll need to add the "bridge empty" option.

Yes, but let's get one thing working at a time.

Then I suppose the quest network is working

If you have tested it and have confirmed it is working based on your requirements/goals, then yes, you can move on to the next network.

The IoT network will look very similar (make a br-iot device). If you want to have physical ethernet connectivity, remove one of the LAN ports from br-lan and then add it to br-iot.

Then, consider what the firewall should allow/prohibit in terms of IoT connectivity. You can get as granular as you want, but for basic/coarse controls, you'd generally look to answer these questions?

  • IoT > internet? (yes/no)
  • IoT > main LAN? (yes/no)
  • main LAN > IoT? (yes/no)

The intent here is to determine which network/zone is allowed to initiate connections to what other zones (the response will always be allowed unless you make granular firewall rules to prohibit it, but that would be unusual for most scenarios). You can get much more granular if you want, but obviously you need to define the behavior you want to achieve.

Thanks
Meanwhile I already did create IoT bridge. Question about empty bridge device - do I need here also check option Bring up the bridge interface even if no ports are attached?

About Iot I think the best option is to restrict everything. I already had firewall rule forward 'REJECT'. The only thing here is that devices in iot zone must see iot server connected to lan port.
I did add traffic rule from IoT zone to homeassistant IP. Is that good enough, or is a better solution to move homeassistant port to br-iot? I cannot test IoT extensivly bcs at the moment I have there only one device but this one looks OK. The idea was when everything works I would deal with rest.

If you ever have time, maybe you can also show me how to separate me and the guests on ethernet. I'm not really sure if I'm up to the skill level here, but I won't know until I try.

I don't believe this is necessary, but it doesn't hurt. If a bridge doesn't come up, you'll probably notice that the quest and/or IoT networks aren't working properly, and then you could change the setting.

This firewall rule only affects intra-zone forwarding. In other words, you can have multiple networks assigned to the same zone. The forward control in the zone is what allows/prohibits forwarding between those networks that are in the same zone.

For inter-zone forwarding, you define those explicitly with forwarding rules such as this:

If you don't have a forwarding rule setup from a source zone to a destination zone, the firewall will not forward traffic (unless you have created more granular rules, but that's not happening here).

For this, you'll want to create a traffic rule that specifically allows this. You can get very granular (down to the ports allowed and the source IP address, if you want), or make it fairly broad.

I don't see that rule above (unless I'm just skimming over it)... feel free to post the rule for review. But yes, that traffic rule in theory should be fine.

Sounds fine.

It's really pretty simple. You'll edit br-lan and remove one of the ethernet ports, so you might remove lan4 as an example. Then you'd add that port into the bridge that will use it... so for example, if is the quest network...

config device
        option name 'br-lan'
        option type 'bridge'
        list ports 'lan1'
        list ports 'lan2'
        list ports 'lan3'

config device
        option name 'br-quest'
        option type 'bridge'
        list ports 'lan4'

Once you have those changes applied, lan4 would belong to the quest network while lan1-3 would be on the main network.

I added it now but basically, it is what it says: allow incoming ipv4 and ipv6 from IoT to homeassistant IPxxxxxxx

Ok the result will be dedicated ethernet sockets for quests and those that stay connected to mane lan will be for me. I will deal with this tomorrow

Question. When I move all ports to quest zone and create the rule that allows to main lan everything that contains my mac addresses all ethernet sockets should be available to me and also for quests?

Just in case, I'm also asking if the IoT firewall setting is enough to close the IoT device zone from both internet and main lan or something else should be changed.
when I did login to IoT wifi with my phone I was still able to communicate with internet.

config zone
        option name 'IOT'
        option output 'ACCEPT'
        list network 'IOT'
        option forward 'REJECT'
        option input 'REJECT'

Thanks